Skip to content

Latest commit

 

History

History
1546 lines (1004 loc) · 115 KB

File metadata and controls

1546 lines (1004 loc) · 115 KB

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Added
  • New INI HDFirearm property LegacyCompatibilityRoundsAlwaysFireUnflipped. This is used to make guns fire their projectiles unflipped, like they used to in old game versions, and should only be turned on for HDFirearms in old mods that need it.

  • New INI and Lua (R) HDFirearm property InheritsFirerVelocity, which determines whether or not the particles in a Round should inherit their firer's velocity. Defaults to true to preserve normal behavior.

  • New DataModule INI property SupportedGameVersion to define what version of the game a mod supports. This must be specified, and must match the current game version, in order for the mod to load successfully.

  • New Lua event functions for HDFirearm - OnFire(self) that triggers when the gun fires, and OnReload(self, hadMagazineBeforeReload) that triggers when the gun is reloaded.

  • New MOSRotating INI and Lua (R/W) MOSRotating property GibAtEndOfLifetime that, when set to true, will make the MOSRotating gib if its age exceeds its lifetime, rather than deleting as it normally would.

  • New Actor INI properties Organic = 0/1 and Mechanical = 0/1 and supporting Lua functions Actor:IsOrganic() and Actor:IsMechanical().
    These have no direct gameplay effect (and default to false), but will be very useful for inter-mod compatibility, as they allow scripts to know if an Actor is organic or mechanical, and treat them accordingly.

  • New INI and Lua (R/W) ACDropShip property HoverHeightModifier. This allows for modification of the height at which an ACDropShip will hover when unloading cargo, or staying at a location.

  • New Scene Lua property BackgroundLayers (R/O) to access an iterator of the Scene's SLBackground layers.

  • SLBackground layers can now be animated using the same INI and Lua animation controls as everything else (FrameCount, SpriteAnimMode, etc). (Issue #66)
    The collection of the Scene's background layers can be accessed via scene.BackgroundLayers.

  • Added SLBackground auto-scrolling INI and Lua controls. (Issue #66)
    The INI definition looks like this:

     CanAutoScrollX = 0/1 // Whether this can auto-scroll on the X axis. Scrolling will take effect only when combined with WrapX = 1, otherwise ignored.
     CanAutoScrollY = 0/1 // Whether this can auto-scroll on the Y axis. Scrolling will take effect only when combined with WrapY = 1, otherwise ignored.
    
     AutoScrollStepInterval = intValue // The duration between auto-scrolling steps on both axis, in milliseconds.
    
     AutoScrollStep = Vector
     	X = intValue // The number of pixels to progress the scrolling on the X axis each step. Float values are supported but may end up choppy and inconsistent due to internal rounding and lack of sub-pixel precision.
     	Y = intValue // The number of pixels to progress the scrolling on the Y axis each step. Float values are supported but may end up choppy and inconsistent due to internal rounding and lack of sub-pixel precision.
    

    You can read and write the following Lua properties:

     slBackground.CanAutoScrollX = bool -- this may be true even if X axis scrolling is not in effect due to WrapX = 0.
     slBackground.CanAutoScrollY = bool -- this may be true even if Y axis scrolling is not in effect due to WrapY = 0.
     slBackground.AutoScrollInterval = intValue
     slBackground.AutoScrollStep = vector
     slBackground.AutoScrollStepX = intValue
     slBackground.AutoScrollStepY = intValue
    

    slBackground:IsAutoScrolling() - (R/O) returns whether auto-scrolling is actually in effect on either axis (meaning either WrapX and CanAutoScrollX or WrapY and CanAutoScrollY are true).

    The collection of the Scene's background layers can be accessed via scene.BackgroundLayers.

  • New Settings.ini property SceneBackgroundAutoScaleMode = 0/1/2. (Issue #243)
    Auto-scaling modes are: 0 = Off, 1 = Fit Screen, 2 = Always 2x.
    This will auto-scale all Scene background layers to cover the whole screen vertically in cases where the layer's sprite is too short and creates a gap at the bottom.
    In cases where a layer is short by design, auto-scaling behavior can be disabled on a per-layer basis using the SLBackground INI property IgnoreAutoScaling, otherwise it may be excessively scaled up to 2x (maximum).
    Note that any ScaleFactor definitions in layers that aren't set to ignore auto-scaling will be overridden.

    Only relevant when playing on un-scaled vertical resolutions of 640p and above as most background layer sprites are currently around 580px tall, and comes with a minor performance impact.
    Note that in fit screen mode each layer is scaled individually so some layers may be scaled more than others, or not scaled at all.
    In always 2x mode all layers will be equally scaled to 2x.

  • New SLBackground INI property IgnoreAutoScaling = 0/1 to ignore the global background layer auto-scaling setting and use the ScaleFactor defined in the preset, if any.

  • New SLBackground INI property OriginPointOffset to offset the layer from the top left corner of the screen.

  • Added new TerrainDebris scattering functionality. (Issue #152)
    New INI properties are:

     MinRotation/MaxRotation = angleDegrees // Rotates each debris piece to a random angle within the specified values. Values in degrees, negative values are counter-clockwise.  
    
     FlipChance = floatValue // Chance for a debris piece to be flipped when either `CanHFlip` or `CanYFlip` are set true. 0-1, defaults to 0.5.  
     
     CanHFlip/CanVFlip = 0/1 // Flips each debris piece on the X, Y or both axis.
    
  • Added support for Material background textures with INI property BGTextureFile.

  • New MovableObject INI and Lua (R/W) property SimUpdatesBetweenScriptedUpdates, that lets MovableObjects run their Lua update function less frequently, for performance benefits.

  • Added faction themes.
    Faction themes apply to the BuyMenu when the faction is set as the native module (i.e. playing as the faction) in both Conquest and Scenario battle.

    The theme properties are defined in the DataModule's Index.ini (before any IncludeFile lines) like so:

     FactionBuyMenuTheme = BuyMenuTheme
     	SkinFile = pathToSkinFile // GUI element visuals (NOT actual layout).
     	BackgroundColorIndex = paletteIndex // Color of the parent box that holds all the elements. Palette colors only, no support for images.
     	BannerFile = pathToBannerImage
     	LogoFile = pathToLogoImage
    

    All properties are optional, any combination works.
    The skin and background color are also applied to the ObjectPicker (scene object placer) for visual consistency.

  • New Settings.ini property DisableFactionBuyMenuThemes = 0/1 which will cause custom faction theme definitions in all modules to be ignored and the default theme to be used instead.

  • New DataModule INI and Lua (R/O) property IsMerchant which determines whether a module is an independent merchant. Defaults to false (0). (Issue #401)
    A module defined as a merchant will stop being playable (in Conquest, etc.) but will have its buyable content available for purchase/placement when playing as any other faction (like how base content is).
    Only has a noticeable effect when the "Allow purchases from other factions" (Settings.ini ShowForeignItems) gameplay setting is disabled.

    Note that this property takes priority over the IsFaction property. A module that is set as both IsFaction = 1 and IsMerchant = 1 will be treated as IsFaction = 0.

  • Made Vector properties AbsRadAngle and AbsDegAngle writable, so you can set a Vector's direction directly, instead of rotating it by an angle via RadRotate and DegRotate.

  • New HDFirearm Lua function GetNextMagazineName(), that gets the name of the next Magazine to be loaded into the HDFirearm.

  • New INI and Lua (R/W) Actor property PieMenu. This allows you to set an Actor's PieMenu via INI and Lua. If no value is set for this, the default PieMenu for the type of Actor will be used, these can be found in Base.rte/GUIs/PieMenus/PieMenus.ini.

  • PieMenus have been completely redone, and are now fully defined in INI and customizable in Lua. Additionally, PieMenus can have sub-PieMenus to allow for better organization and more controls.

    You can define PieMenus in INI using standard INI concepts like CopyOf and PresetName, and modify their visuals as you please. They have the following INI properties:

     IconSeparatorMode // The visuals style of the PieMenu's separators. The options are "Line", "Circle" and "Square". Defaults to "Line".  
     FullInnerRadius // The inner radius of the PieMenu when it's fully expanded, in pixels. Defaults to 58.  
     BackgroundThickness // The thickness of the background ring of the PieMenu. Defaults to 16.  
     BackgroundSeparatorSize // The size of the background separators (lines, circles, squares). Defaults to 2.  
     DrawBackgroundTransparent // Whether or not the PieMenu's background should be drawn transparent. Defaults to true.  
     BackgroundColor // The color used to draw the background ring of the PieMenu. Color values are palette indexes.  
     BackgroundBorderColor // The color used to draw the border around the background ring of the PieMenu. Color values are palette indexes.  
     SelectedItemBackgroundColor // The color used to highlight selected PieSlices in the PieMenu. Color values are palette indexes.  
     AddPieSlice = PieSlice // Add a PieSlice to the PieMenu. Standard INI concepts like CopyOf, etc. apply.
    

    Additionally, PieMenus have the following Lua properties and functions:

    Owner (R) - Gets the owning Actor for the PieMenu, if there is one.
    Controller (R) - Gets the Controller controlling the PieMenu. If there's an Actor owner, it'll be that Actor's Controller, otherwise it's probably a general Controller used for handling in-game menu inputs.
    AffectedObject (R) - Gets the affected MovableObject for the PieMenu if there is one. Support isn't fully here for it yet, but PieMenus can theoretically be made to affect objects that aren't Actors.
    Pos (R) - Gets the position of the center of the PieMenu. Generally updated to move with its Owner or AffectedObject.
    RotAngle (R/W) - Gets/sets the rotation of the PieMenu. Note that changing this may cause oddities and issues, especially if the PieMenu is currently visible.
    FullInnerRadius (R/W) - Gets/sets the inner radius of the PieMenu, i.e. the radius distance before the inside of the ring.

    IsEnabled() - Gets whether or not the PieMenu is enabled or enabling.
    IsEnabling() - Gets whether or not the PieMenu is currently enabling.
    IsDisabling() - Gets whether or not the PieMenu is currently disabling.
    IsEnablingOrDisabling() - Gets whether or not the PieMenu is currently enabling or disabling.
    IsVisible() - Gets whether or not the PieMenu is currently visible (i.e. not disabled).
    HasSubPieMenuOpen() - Gets whether the PieMenu has a sub-PieMenu open, and is thus transferring commands to that sub-PieMenu.
    SetAnimationModeToNormal() - Sets the PieMenu back to normal animation mode, and disables it so it's ready for use.
    DoDisableAnimation() - Makes the PieMenu do its disabling animation.
    Wobble() - Makes the PieMenu do its wobbling animation.
    FreezeAtRadius(radius) - Makes the PieMenu freeze open at the given radius.
    GetPieCommand() - Gets the command given to the PieMenu, either by pressing a PieSlice button, or by selecting a PieSlice and closing the PieMenu.
    GetPieSlices() - Gets all of the PieSlices in the PieMenu.
    GetFirstPieSliceByPresetName(presetName) - Searches through the PieSlices in the PieMenu and returns the first one with the given PresetName.
    GetFirstPieSliceByType(pieSliceType) - Searches through the PieSlices in the PieMenu and returns the first one with the given PieSlice Type.

    AddPieSlice(pieSliceToAdd, pieSliceOriginalSource, optional_onlyCheckPieSlicesWithSameOriginalSource, optional_allowQuadrantOverflow) - Adds the given PieSlice to the PieMenu, returning whether or not the PieSlice was added.
    The pieSliceOriginalSource is the object that added the PieSlice to the PieMenu, and it's very important you set this properly (much of the time you'll want it to be self if, say, you have a gun adding a PieSlice), otherwise you can end up with ghost PieSlices.
    allowQuadrantOverflow is optional and defaults to false, it determines whether the PieSlice can only be added in its specified direction (false), or if it can overflow if that direction is full of PieSlices (true).

    AddPieSliceIfPresetNameIsUnique(pieSliceToAdd, pieSliceOriginalSource, optionalAllowQuadrantOverflow) - Like AddPieSlice, this adds the given PieSlice to the PieMenu and returns whether or not the PieSlice was added, but only if the PieMenu doesn't contain a PieSlice with this PieSlice's preset name, optionally only checking PieSlices with the same original source (by default it checks all PieSlices in the PieMenu).
    PieSlices with no preset name will always be added by this.

    RemovePieSlice(pieSliceToRemove) - Removes the given PieSlice from the PieMenu, and returns it to Lua so you can add it to another PieMenu if you want.
    RemovePieSlicesByPresetName() - Removes any PieSlices with the given preset name from the PieMenu. Note that, unlike RemovePieSlice, the PieSlice is not returned, since multiple PieSlices can be removed this way. Instead, this returns true if any PieSlices were removed.
    RemovePieSlicesByType() - Removes any PieSlices with the given PieSlice Type from the PieMenu. Note that, unlike RemovePieSlice, the PieSlice is not returned, since multiple PieSlices can be removed this way. Instead, this returns true if any PieSlices were removed.
    RemovePieSlicesByOriginalSource() - Removes any PieSlices with the original source from the PieMenu. Note that, unlike RemovePieSlice, the PieSlice is not returned, since multiple PieSlices can be removed this way. Instead, this returns true if any PieSlices were removed.

  • PieSlices have been modified to support PieMenus being defined in INI. They have the following properties:

    Type (INI, Lua R/W) - Gets or sets the PieSlice's type, useful for invoking hardcoded game actions (e.g. pickup).
    Direction (INI, Lua R/W) - Gets or sets the PieSlice's direction, i.e what direction the PieSlice should be added in to a PieMenu. Defaults to Any, which means it will be added to the least populated direction. Note that if you set this via Lua, you will need to remove and readd the PieSlice for it to take effect.
    CanBeMiddleSlice (INI, Lua R/W) - Gets or sets whether or not this PieSlice can be the middle slice (i.e. a cardinal one like reload) in its direction, when added to a PieMenu. Defaults to true. Note that if you set this via Lua, you will need to remove and readd the PieSlice for it to take effect.
    Enabled (INI, Lua R/W) - Gets or sets whether or not this PieSlice is enabled and usable.
    ScriptPath (INI, Lua R/W) - Gets or sets the filepath to the script that should be run when this PieSlice is activated. A script function name is also required for this to work.
    ScriptFunctionName (INI Lua R/W) - Gets or sets the name of the function that should be run when this PieSlice is activated. A script path is also required for this to work.
    SubPieMenu (INI Lua R/W) - Gets or sets the sub-PieMenu that should be opened when this PieSlice is activated. Note that PieSlices with sub-PieMenus will not perform any other actions, though they will run scripts.
    Icon (INI) - The icon for this PieSlice to show in its PieMenu.
    OriginalSource (Lua R) - The object that added this PieSlice to its PieMenu.

  • Added Directions enum with the following values:

     (-1) None
     (0)  Up
     (1)  Down
     (2)  Left
     (3)  Right
     (4)  Any
    
  • Added GameActivity INI property BuyMenuEnabled to match the Lua property, and made the buy menu PieSlice disappear if BuyMenuEnabled is false.
    Note that, if you toggle this from off to on in Lua for a running GameActivity, you'll need to re-add the buy menu PieSlice manually.

  • Added Controller Lua function IsGamepadControlled(), that lets you tell if a Controller is being controlled by any of the gamepad inputs, much like the pre-existing IsMouseControlled() function.

  • Added some useful global angle helper functions:

     NormalizeAngleBetween0And2PI(angle) -- Takes an angle in radians, and returns that angle modified so it's not negative or larger than 2PI.	
     NormalizeAngleBetweenNegativePIAndPI(angle) -- Takes an angle in radians, and returns that angle modified so angles larger than PI are instead represented as negative angles, and no angle is larger than PI or smaller than -PI.
     AngleWithinRange(float angleToCheck, float startAngle, float endAngle) -- Returns whether or not the angleToCheck is between the startAngle and endAngle, in a counter-clockwise direction (e.g. 0.5rad is between 0rad and 1rad, and 0.3rad is between 2.5rad and 1 rad).	 
     ClampAngle(float angleToClamp, float startAngle, float endAngle) -- Returns the angleToClamp, clamped between the startAngle and endAngle.
  • Added support for nested block comments in INI. (Issue #248)
    The reader will track block comment open tags and crash if a file ends while a block is open, reporting the line it was opened on.

  • Added thickness option to Line primitives. (Issue #403)
    New bindings with argument for thickness are:
    PrimitiveMan:DrawLinePrimitive(startPos, endPos, color, thickness)
    PrimitiveMan:DrawLinePrimitive(player, startPos, endPos, color, thickness)
    Original bindings with no thickness argument are untouched and can be called as they were.

  • New Vector Lua (R/O) property SqrMagnitude which returns the squared magnitude of the Vector.
    Should be used for more efficient comparison with vector.SqrMagnitude > (floatValue * floatValue) over vector.Magnitude > floatValue.

  • New Vector Lua convenience functions for more efficient magnitude comparison.

     -- These perform vector.SqrMagnitude > or < (floatValue * floatValue).
     vector:MagnitudeIsGreaterThan(floatValue) -- Note that you can use (not vector:MagnitudeIsGreaterThan(floatValue)) in place of (vector.SqrMagnitude <= (floatValue * floatValue)).
     vector:MagnitudeIsLessThan(floatValue) -- Note that you can use (not vector:MagnitudeIsLessThan(floatValue)) in place of (vector.SqrMagnitude >= (floatValue * floatValue)).
  • New PresetMan Lua function ReloadEntityPreset(presetName, className, optionalDefinedInModule) that allows hot-reloading Entity INI presets (along with all other entity presets referenced in the reloaded entity preset).
    If the optionalDefinedInModule argument is not specified, the game will look through every DataModule to find an Entity preset that matches the name and type.
    Once an Entity preset has been reloaded via the function, the key combination Ctrl + F2 can be used to quickly reload it as many times as necessary.
    Note that any changes made to the Entity preset will not be reflected in existing copies of the Entity, only in new ones created after the reload.
    Also note that visual changes to previously loaded sprites cannot be and will not be reflected by reloading. It is, however, possible to reload with a different set of loaded sprites, or entirely new ones.

  • Added MOSRotating INI property DetachAttachablesBeforeGibbingFromWounds that makes Attachables fall off before the MOSRotating gibs from having too many wounds, for nice visuals. Defaults to true.

Changed
  • Completely replaced ScriptFile with ScriptPath.

  • Changed the Vector function ClampMagnitude so its parameter order makes sense, it's now Vector:ClampMagnitude(lowerMagnitudeLimit, upperMagnitudeLimit).

  • Changed the MovableMan function AddItem so it now only accepts HeldDevices and sub-classes (i.e. HDFirearm, ThrownDevice, TDExplosive), because it always expected that anyway, and it's good to enforce it.

  • Scene background layer presets in INI are now defined as SLBackground rather than SceneLayer.

  • TerrainDebris INI property OnlyOnSurface = 0/1 replaced with DebrisPlacementMode = 0-6.
    Placement modes are:

     0 (NoPlacementRestrictions) // Debris will be placed anywhere where there is target material (currently not strictly enforced when being offset by min/max depth, so can end up being placed mid-air/cavity unless set to OnlyBuried = 1).
    
     1 (OnSurfaceOnly) // Debris will be placed only on the surface (scanning from top to bottom) where no background cavity material (material index 1) was encountered before the target material.
    
     2 (OnCavitySurfaceOnly) // Debris will be placed only on the surface (scanning from top to bottom) where background cavity material (material index 1) was encountered before the target material.
    
     3 (OnSurfaceAndCavitySurface) // Debris will be placed only on the surface (scanning from top to bottom) regardless whether background cavity material (material index 1) was encountered before the target material.
    
     4 (OnOverhangOnly) // Debris will be placed only on overhangs (scanning from bottom to top) where no background cavity material (material index 1) was encountered before the target material.
    
     5 (OnCavityOverhangOnly) // Debris will be placed only on overhangs (scanning from bottom to top) where background cavity material (material index 1) was encountered before the target material.
    
     6 (OnOverhangAndCavityOverhang) // Debris will be placed only on overhangs (scanning from bottom to top) regardless whether background cavity material (material index 1) was encountered before the target material.
    
  • Material INI property TextureFile renamed to FGTextureFile to accommodate new background texture property.

  • TerrainObjects no longer have a hard requirement for FG and Mat layer sprites. Any layer may be omitted as long as at least one is defined.

  • Scene layer data will now be saved as compressed PNG to reduce file sizes of MetaGame saves and is threaded to prevent the game from freezing when layer data is being saved.

  • Lua function BuyMenuGUI:SetHeaderImage renamed to SetBannerImage.

  • Lua functions run by PieSlices will now have the following signature: pieSliceFunction(pieMenu, pieSlice, pieMenuOwner). The details for these are as follows:
    pieMenu - The PieMenu that is being used, and is calling this function. Note that this may be a sub-PieMenu.
    pieSlice - The PieSlice that has been activated to call this function.
    pieMenuOwner - The Actor owner of this PieMenu, or the MovableObject affected object of it if it has no owner.

  • OnPieMenu(self) event function has been changed to WhilePieMenuOpen(self, openedPieMenu) and will run as long as the PieMenu is open.

  • Any Attachable on an Actor (not just HeldDevices) can now have a WhilePieMenuOpen(self, openedPieMenu) function, and can add PieSlices and run functions when they're pressed.

  • PieSliceIndex enum has been renamed to SliceType to better match the source. More relevantly for modders, its values have also been renamed, they are as follows:

     (0)  NoType
    
     // The following are used for inventory management:
     (1)  Pickup
     (2)  Drop
     (3)  NextItem
     (4)  PreviousItem
     (5)  Reload
    
     // The following are used for menu and GUI activation:
     (6)  BuyMenu
     (7)  FullInventory
     (8)  Stats
     (9)  Map
     (10) Ceasefire
    
     // The following is used for squad management:
     (11) FormSquad
    
     // The following are used for AI mode management:
     (12) AIModes
     (13) Sentry
     (14) Patrol
     (15) BrainHunt
     (16) GoldDig
     (17) GoTo
     (18) Return
     (19) Stay
     (20) Deliver
     (21) Scuttle
    
     // The following are used for game editors:
     (22) EditorDone
     (23) EditorLoad
     (24) EditorSave
     (25) EditorNew
     (26) EditorPick
     (27) EditorMove
     (28) EditorRemove
     (29) EditorInFront
     (30) EditorBehind
     (31) EditorZoomIn
     (32) EditorZoomOut
     (33) EditorTeam1
     (34) EditorTeam2
     (35) EditorTeam3
     (36) EditorTeam4
    
  • Having the pie menu open no longer blocks user input when using mouse+keyboard or a controller.

Fixed
  • Fixed material view not drawing correctly when viewed in split-screen. (Issue #54)

  • Fix TerrainObjects not wrapping when placed over the Y seam on Y-wrapped scenes.

Removed
  • Removed SLTerrain and SLBackground INI property Offset. Internal and shouldn't have been exposed.

  • Removed SLTerrain INI alt property AddTerrainObject. Use PlaceTerrainObject for consistency with similar properties.

  • Removed TerrainObject INI property DisplayAsTerrain. Wasn't implemented and did nothing.

  • Removed SceneMan Lua function AddTerrainObject. SceneMan:AddSceneObject should be used instead.

  • Removed Activity Lua function EnteredOrbit. This tells the Activity to consider an ACraft as having entered orbit, and should never actually have been accessible to Lua.

  • Removed OnPieMenu listeners for Activitys and GlobalScripts, and removed the ProvidesPieMenuContext concept and everything around it. These things should no longer be necessary since you can modify PieMenus on the fly at any time, and they made this already complex set of code even more complicated.


Added
  • Executable can be compiled as 64bit.

  • New Settings.ini property MeasureModuleLoadTime = 0/1 to measure the duration of module loading (archived module extraction included). For benchmarking purposes.

  • Color object's RGB values can now be set with index number.

     Color/TrailColor = Color
     	Index = 0-255 // Corresponds with index in palette.bmp
    
  • New Settings.ini property ForceDedicatedFullScreenGfxDriver to force the game to run in previously removed dedicated fullscreen mode, allowing using lower resolutions (and 1366x768) while still maintaining fullscreen.

  • Added Lua (R/W) properties for all hardcoded Attachables. You can now set them on the fly to be created objects of the relevant type. Note that trying to set things inappropriately (e.g. setting an HDFirearm as something's Leg) will probably crash the game; that's your problem to deal with.
    You can read and write the following properties:
    AHuman - Head, Jetpack, FGArm, BGArm, FGLeg, BGLeg, FGFoot, BGFoot
    ACrab - Turret, Jetpack, LeftFGLeg, LeftBGLeg, RightFGLeg, RightBGLeg
    ACDropShip - RightEngine, LeftEngine, RightThruster, LeftThruster, RightHatch, LeftHatch
    ACRocket - RightLeg, LeftLeg, MainEngine, LeftEngine, RightEngine, LeftThruster, RightThruster
    ADoor - Door
    Turret - MountedDevice
    Leg - Foot
    HDFirearm - Magazine, Flash
    AEmitter - Flash

  • Added Vector:ClampMagnitude(upperLimit, lowerLimit) Lua function that lets you limit a Vector's upper and lower magnitude.

  • Added MOSRotating GibBlastStrength INI and Lua (R/W) property. This lets you define how much force created Gibs and any Attachables will get launched with when the MOSRotating gibs.

  • New INI and Lua (R/W) properties for Attachables:
    ParentBreakWound = AEmitter... - allows you to optionally define different BreakWounds for the Attachable and its parent. By default it matches BreakWound for ease of use. BreakWound is also now R/W accessible to Lua.
    InheritsHFlipped = -1/0/1 - allows you to define whether the Attachable will inherit its parent's HFlipped value or not.
    -1 means reversed inheritance (i.e. if the parent's HFlipped value is true, this Attachable's HFlipped value will be false), 0 means no inheritance, 1 means normal inheritance. Defaults to 1 to preserve normal behavior.
    InheritedRotAngleRadOffset = angle - and InheritedRotAngleDegOffset = angle allow you specify an offset to keep an Attachable's rotation at when InheritsRotAngle is set to true. For example, InheritedRotAngleDegOffset = 90 would make the Attachable always face perpendicular to its parent. In Lua there's only InheritedRotAngleOffset, which takes/returns radians to avoid confusion. Note that this property does nothing if the Attachable's InheritsRotAngle is set to false or the Attachable has no parent.
    GibWithParentChance = 0 - 1 - allows you to specify whether this Attachable should be gibbed when its parent does and what the chance of that happening is. 0 means never, 1 means always.
    ParentGibBlastStrengthMultiplier = number - allows you to specify a multiplier for how strongly this Attachable will apply its parent's gib blast strength to itself when the parent gibs. Usually this would be a positive number, but it doesn't have to be.

  • New INI and Lua (R/W) Arm property GripStrength. This effectively replaces the JointStrength of the held HeldDevice, allowing Arms to control how tightly equipment is held.

  • New INI and Lua (R/W) HeldDevice property GripStrengthMultiplier. This allows HeldDevices to multiply the GripStrength of their Arms to support them being more or less easy to hold.

  • New Lua MovableObject function GetWhichMOToNotHit. This provides access to the MO that has been set to not be hit by SetWhichMOToNotHit.

  • Added HeldDevice handling to limit which Actor(s) can pick it up. Note that pickup limitations are all done by PresetName, so you can not use this to precisely specify individual Actors.
    The INI definition looks like this:

     PickupableBy = PickupableByEntries
     	AddPresetNameEntry = First Actor PresetName Here
     	AddPresetNameEntry = Second Actor PresetName Here
     // Alternatively, if you want this not to be pickupable
     PickupableBy = None
    

    The Lua properties and functions are as follows:

     heldDevice.HasPickupLimitations; --(R) Whether or not this HeldDevice has any limitations affecting whether it can be picked up.
     heldDevice.UnPickupable --(R/W) Whether this HeldDevice is/should be pickupable.
     heldDevice:IsPickupableBy(actor) -- Whether or not a given Actor can pick up this HeldDevice.
     heldDevice:AddPickupableByPresetName(presetName) -- Allows Actors with the given PresetName to pick up this HeldDevice.
     heldDevice:RemovePickupableByPresetName(presetName) -- Disallows Actors with the given PresetNames from picking up this HeldDevice (as long as there are other pickup limitations).
  • Added MOSRotating Lua (R) property IndividualMass. This provides access to the MOSRotating's actual mass value, not including any Attachables or inventory items. Note that the normal Mass property is still used to set the MOSRotating's mass.

  • Added Actor Lua (R) property InventoryMass. This provides access to the mass of the Actor's inventory separate from the Actor's actual mass.

  • Added LimbPath INI property EndSegCount, which allows you to specify a segment after which the owning Actor's foot will not collide with terrain. This lets you add extra visual-only frames to your LimbPaths.

  • Added AHuman INI property CrouchLimbPathBG to allow you to specify a different LimbPath for the background leg while crouching.

  • Added AHuman INI properties StandRotAngleTarget, WalkRotAngleTarget, CrouchRotAngleTarget and JumpRotAngleTarget that let you define the rot angle the body should aim towards when in the corresponding MovementState.

  • Added AHuman Lua methods GetRotAngleTarget(movementState) and SetRotAngleTarget(movementState, newRotAngleTarget) that allow you to get and set rot angle targets for MovementStates. Note that only the MovementStates mentioned above will actually work.

  • LimbPaths are now Lua accessible for ACrabs and AHumans. You can use GetLimbPath(Layer, MovementState) for AHumans and GetLimbPath(Side, Layer, MovementState) for ACrabs.
    LimbPaths have the following properties:
    limbPath.StartOffset (R/W) - the start offset for the LimbPath. Also defines its position if it has no actual path.
    limbPath.SegmentCount (R) - the number of segments in the LimbPath.
    limbPath:GetSegment(segmentIndex) - Gets the segment Vector for the given segment index. You can use this to modify LimbPaths.

  • Added OnStride special Lua function for AHumans that is called whenever they stride (i.e. when their StrideSound is played). Like playing StrideSound, this does not happen when the AHuman is climbing.

  • New AHuman and ACrab INI and Lua (R/W) property JetAngleRange which defines the rate at which the angle of the Jetpack's thrust follows the aim angle of the actor (default being 0.25).

  • New AHuman INI property LookToAimRatio at which the Head turns in the direction of aiming (default being 0.7).

  • New AHuman INI properties FGArmFlailScalar and BGArmFlailScalar. Used to change the rate at which each Arm follows the rotation angle of the Actor, regardless of aim angle. 0 means the Arm will always point in aiming direction.

  • New Actor INI and Lua (R/W) property CanRevealUnseen which can be used to disable the ability to reveal unseen areas.

  • New MOPixel Lua (R/W) property TrailLength which returns the trail length of the Atom affiliated with this MOPixel.

  • New HDFirearm INI property ShellEjectAngle which lets you define the angle at which Shell particles are ejected relative to the HDFirearm's rotation.

  • New Gib INI property IgnoresTeamHits.

  • New Atom INI property TrailLengthVariation. Used to randomize TrailLength on every frame. 0 means no randomization (default), 1 means anything between full length and zero.

  • New ACraft INI and Lua (R/W) property HatchCloseSound. This is now required separately to HatchOpenSound.

  • Exposed MOSRotating property OrientToVel to Lua (R/W).

  • Exposed DataModule properties Author, Description and Version to Lua (R).

  • Exposed Actor properties HolsterOffset and ItemInReach to Lua (R/W).

  • Exposed Arm property MaxLength to Lua (R).

  • Exposed broad range of sounds to Lua (R/W) through their relevant SoundContainers. For each class, these include:
    Actor - BodyHitSound, PainSound, DeathSound, DeviceSwitchSound, AlarmSound
    AHuman & ACrab - StrideSound
    HDFirearm - FireSound, FireEchoSound, EmptySound, ReloadStartSound, ReloadEndSound, ActiveSound, DeactivationSound, PreFireSound
    AEmitter - EmissionSound, BurstSound, EndSound
    ACraft - HatchOpenSound, HatchCloseSound, CrashSound
    MOSRotating - GibSound
    ADoor - DoorMoveStartSound, DoorMoveSound, DoorDirectionChangeSound, DoorMoveEndSound

  • Added Lua function RoundFloatToPrecision. Utility function to round and format floating point numbers for display in strings.
    RoundFloatToPrecision(floatValue, digitsPastDecimal, roundingMode) -- Rounding mode 0 for system default, 1 for floored remainder, 2 for ceiled remainder.

  • The Lua console (and all text boxes) now support using Ctrl to move the cursor around and select or delete text.

  • Added mosRotating:RemoveAttachable(attachableOrUniqueID, addToMovableMan, addBreakWounds) method that allows you to remove an Attachable and specify whether it should be added to MovableMan or not, and whether breakwounds should be added (if defined) to the Attachable and parent MOSRotating. This method returns the removed Attachable, see the Changed section for important details on that.

  • Added mosRotating:RemoveEmitter(attachableOrUniqueID, addToMovableMan, addBreakWounds) method that is identical to the RemoveAttachable function mentioned above.

  • Added attachable:RemoveFromParent() and attachable:RemoveFromParent(addToMovableMan, addBreakWounds) that allow you to remove Attachables from their parents without having to use GetParent first. Their return value is the same as RemoveAttachable above.

  • Added Settings.ini debug properties to allow modders to turn on some potentially useful information visualizations.
    DrawAtomGroupVisualizations - any MOSRotating will draw its AtomGroup to the standard view.
    DrawHandAndFootGroupVisualizations - any Actor subclasses with will draw its hand and foot AtomGroups to the standard view.
    DrawLimbPathVisualizations - any AHumans or ACrabs will draw some of their LimbPaths to the standard view.
    DrawRayCastVisualizations - any rays cast by SceneMan will be drawn to the standard view.
    DrawPixelCheckVisualizations - any pixel checks made by SceneMan:GetTerrMatter or SceneMan:GetMOIDPixel will be drawn to the standard view.

  • Added a fully featured inventory view for managing AHuman inventories (to be expanded to other things in future).

  • New Settings.ini property CaseSensitiveFilePaths = 0/1 to enable/disable file path case sensitivity in INIs. Enabled by default.
    It is STRONGLY ill-advised to disable this behavior as it makes case sensitivity mismatches immediately obvious and allows fixing them with ease to ensure a path related crash free cross-platform experience.
    Only disable this if for some reason case sensitivity increases the loading times on your system (which it generally should not). Loading times can be benchmarked using the Settings.ini property MeasureModuleLoadTime. The result will be printed to the console.

  • Added MovableObject Lua function EnableOrDisableAllScripts that allows you to enable or disable all scripts on a MovableObject based on the passed in value.

  • Added AEmitter and PEmitter Lua (R/W) properties NegativeThrottleMultiplier and PositiveThrottleMultiplier that affect the emission rate relative to throttle.

  • Added Attachable Lua function and INI property InheritsFrame which lets Attachables inherit their parent's frame. It is set to false by default.

  • Added MovableObject Lua (R/W) and INI properties ApplyWoundDamageOnCollision and ApplyWoundBurstDamageOnCollision which allow MovableObjects to apply the EntryWound damage/burst damage that would occur when they penetrate another object, without actually creating a wound.

  • Turrets can now support an unlimited number of mounted HeldDevices. Properties have been added to Lua and INI to support this:
    AddMountedDevice = ... (INI) and turret:AddMountedDevice (Lua) - this adds the specified HeldDevice or HDFirearm as a mounted device on the Turret.
    turret:GetMountedDevices (Lua) - this gives you access to all the mounted HeldDevices on the Turret. You can loop through them with a for loop, and remove or modify them as needed.
    Note that MountedDevice = ... (INI) and turret.MountedDevice (Lua R/W) deals with the first mounted HeldDevice, which is treated as the primary one for things like sharp-aiming.

  • Added Turret Lua (R/W) and INI property MountedDeviceRotationOffset that lets you specify a standard rotation offset for all mounted HeldDevices on a turret.

  • Added option for players to vote to restart multiplayer activities by holding the backslash key, \. Requires all players to vote to pass.
    This is an alternative to the existing ability to vote to end the activity and return to the multiplayer lobby, by holding Backspace key.

  • New Settings.ini properties MuteMaster = 0/1, MuteMusic = 0/1 and MuteSound = 0/1 to control muting of master/music/sound channels without changing the volume property values.

  • New Settings.ini property TwoPlayerSplitscreenVertSplit = 0/1 to force two player splitscreen into a vertical split mode (horizontal by default).

  • Controller hot-plugging is now supported (Windows only).

  • Console text can be set to use a monospace font through Settings.ini property ConsoleUseMonospaceFont = 0/1 or through the in-game settings.

  • New ThrownDevice INI property StrikerLever, which is the same as Shell for Round in HDFirearm, but for grenades. Represents the lever/pin coming off when activated.

  • New Arm INI and Lua (R/W) property ThrowStrength which now calculates how far ThrownDevices are thrown, which also takes to account the weight of the device. ThrownDevices can still define MaxThrowVel and MinThrowVel to override this.

  • New Settings.ini property DisableLuaJIT = 0/1 to disable LuaJIT (MoonJIT) to (potentially) improve performance on machines that seem to struggle with it.

  • New Settings.ini property ShowEnemyHUD which allows disabling of enemy actor HUD in its entirety.

  • New DataModule INI and Lua (R) property IsFaction which determines whether a module is a playable faction (in MetaGame, etc.). This replaces the need to put "Tech" in the module name. Defaults to false (0).

  • New MOSRotating INI and Lua (R) property WoundCountAffectsImpulseLimitRatio which can be used to make objects more prone to gibbing from impulse when they have also received wounds.

  • New Gib INI property SpreadMode which sports two new spread logic variants which alter the way velocity is applied to the GibParticles when they spawn. This can be used to create richer explosion effects.
    SpreadMode = 0 is the default, fully randomized spread according to MinVelocity, MaxVelocity and Spread values. Think: a piece of grenade fragment, launching out in an arbitrary direction.
    SpreadMode = 1 is the same as the default, but with evenly spaced out angles. Think: an air blast shockwave, dispersing evenly outward from the explosion.
    SpreadMode = 2 has an entirely different behavior of its own, which utilizes the fermat spiral as means to evenly disperse the particles in a circular area, according to MaxVelocity and MinVelocity. Since this mode will always result in a full, 360-degree spread, the Spread property can be used to add randomization to the gib particles. Think: a cloud of smoke.

  • New Actor INI and Lua (R/W) property StableRecoverDelay which determines how long it takes for an actor to regain STABLE status after being rendered UNSTABLE.

  • New AHuman Lua (R) property ThrowProgress which returns the current throw chargeup progress as a scalar from 0 to 1.

  • New HDFirearm INI and Lua (R/W) property ShellVelVariation which can be used to randomize the magnitude at which shells are ejected.

  • New HDFirearm Lua (R) property ReloadProgress which returns the current reload progress as a scalar from 0 to 1.

  • New HDFirearm INI and Lua (R/W) property Reloadable which can be used to disable the ability to reload said device.

  • New HDFirearm Lua (R) property RoundInMagCapacity which returns the maximum capacity of the Magazine or, if there's not currently a Magazine, the maximum capacity of the next Magazine.
    This means that the property will always return the maximum ammo capacity of the device, even when reloading.

  • New Entity Lua (R) property ModuleName which returns the filename of the data module from which the entity originates from.

  • Arms will now react to the recoil of HeldDevices. This is affected by the Arm's GripStrength and the HeldDevice's RecoilTransmission, in the same way as recoil itself.

  • HDFirearm reload progress now shows up as a HUD element.

  • New Round INI property LifeVariation which can be used to randomize the Lifetime of shot particles.

  • Exposed MOSprite property PrevRotAngle to Lua (R).

  • New ACraft INI and Lua (R/W) property ScuttleOnDeath which can be used to disable the automatic self-destruct sequence when the craft's health drops down to zero.

  • New Settings.ini property UnheldItemsHUDDisplayRange = numPixels that hides the HUD of stranded items at a set distance. Default is 500 (25 meters). Value of -1 or anything below means all HUDs will be hidden and the only indication an item can be picked up will be on the Actor's HUD when standing on top of it. Value of 0 means there is no range limit and all items on Scene will display the pick-up HUD. Valid range values are 1-1000, anything above will be considered as no range limit.

  • Various improvements to the Buy Menu. You can now navigate tabs with the actor swap buttons, and the menu will smartly navigate when you add an Actor to your shop list, so you can quickly select weapons, etc..
    There is also a new Settings.ini property, SmartBuyMenuNavigation = 0/1, which allows you to turn off this smart buy menu navigation, in case you prefer not to have it.

  • Exposed ACraft property HatchDelay to Lua (R/W).

  • New Settings.ini property SimplifiedCollisionDetection = 0/1 to enable more performant but less accurate MO collision detection (previously PreciseCollisions = 0). Disabled by default.

  • New INI property BuyableMode to specify in which buy lists a Buyable = 1 item should appear in.
    BuyableMode = 0 // No restrictions - item will appear in both lists as usual. Default value, does not need to be explicitly specified. BuyableMode = 1 // BuyMenu only - item will not appear in any group in the object picker during the editing phase, but will be available to purchase from the buy menu.
    BuyableMode = 2 // ObjectPicker only - item will not appear in any tab in the buy menu when making an order, but will be available for placement from the object picker during editing phase.

  • New MovableMan Lua function KillAllTeamActors, which kills all Actors on the given Team.

  • New ACRocket INI property MaxGimbalAngle, which enables automatic stabilization via tilting of the main engine.

  • Added Lua bindings for scene.Areas and area.Boxes that you can iterate through to get all the Areas in a Scene and all the Boxes in an Area.

  • Added Area Lua function area:RemoveBox(boxToRemove) which removes the given Box from the Area. Note that this removal is done by comparing the Box's Corner, Width and Height, so you're actually removing the first Box that matches the passed-in boxToRemove.

  • Added Lua binding for AudioMan:StopMusic(), which stops all playing music. AudioMan:StopAll() used to do this, but now it actually stops all sounds and music.

  • New Actor Lua (R) property SharpAimProgress, which returns the current sharp-aiming progress as a scalar from 0 to 1.

  • New HeldDevice Lua (R/W) property Supported, which indicates whether or not the device is currently being supported by a background hand.

  • New HeldDevice Lua function IsEmpty, which indicates whether the device is devoid of ammo. Can be used to skip an extra step to check for a Magazine. Will always return false for non-HDFirearm devices.

  • New SoundContainer INI and Lua (R/W) property PitchVariation, which can be used to randomize the pitch of the sounds being played.

  • New AHuman and ACrab INI and Lua (R/W) property JetReplenishRate, which determines how fast jump time (i.e. jetpack fuel) is replenished during downtime.

  • Added Entity Lua function entity:RemoveFromGroup(groupToRemoveFrom) which removes the given group from the Entity. The reverse of AddToGroup.

  • New AHuman Lua functions GetWalkAngle(layer) and SetWalkAngle(layer, angle), which can be used to read and override walk path rotation of both Legs/Layers respectively. Note that the walk path rotation is automatically updated on each step to match the curvature of the terrain, so this value resets every update.

  • New AHuman INI and Lua (R/W) property ArmSwingRate, which now controls the arms' walking animation, according to each arm's IdleOffset. 1 is the default value, 0 means that the arms stay still.

  • New Attachable Lua (R) property JointPos, which gets the position of the object's joint in scene coordinates.

  • New AHuman Lua (R) property IsClimbing, which indicates whether the actor is currently climbing using either of the arms.

  • New AHuman Lua functions UnequipFGArm() and UnequipArms() which unequip the currently held item(s) and put them into the actor's inventory.

  • You can now execute multiple copies of your delivery order by holding UP or DOWN while choosing the landing zone.

  • New MOSprite INI property IconFile, which can be used to define a separate sprite to be displayed in GUI elements, such as the Buy Menu.
    Defined similarly to SpriteFile, i.e. IconFile = ContentFile followed up by a FilePath to the sprite.

  • New MOSprite Lua functions GetIconWidth() and GetIconHeight() which return the dimensions of its GUI representation.

  • New PrimitiveMan Lua functions DrawIconPrimitive(player, pos, entity) and DrawIconPrimitive(pos, entity) which can be used to draw the GUI representation of the passed in entity.

  • New AEmitter and PEmitter Lua (R) property ThrottleFactor, which gets the throttle strength as a multiplier value that factors in either the positive or negative throttle multiplier according to throttle.

  • New AHuman Lua (R) property EquippedMass, which returns the total mass of any HeldDevices currently equipped by the actor.

  • New Settings.ini flag UseExperimentalMultiplayerSpeedBoosts = 1/0. When turned on, it will use some code that may speed up multiplayer.

Changed
  • The landing zone cursor will now show the width of the selected delivery craft.

  • ACrab actors will now default to showing their Turret sprite as their GUI icon. If no turret is defined, the ACrab's own sprite will be used.
    In a similar fashion, AHuman will now default to its torso sprite as its GUI representation if no Head has somehow been defined.

  • ThrownDevices will now use StanceOffset, SharpStanceOffset and SupportOffset in the same way as any other HeldDevice. In addition, EndThrowOffset will be used to set the BG hand position while sharp aiming or throwing.

  • AHuman throwing angle will no longer be affected by the rotation of the body.

  • Exposed MovableObject property RestThreshold to Lua (R/W).

  • ACRockets can now function without a full set of thrusters. This also means that "Null Emitter" thrusters are no longer required for rockets.

  • Changed MOSprite property SpriteAnimMode Enum LOOPWHENMOVING to LOOPWHENACTIVE as it also describes active devices.

  • Changed Activity Lua (R) properties Running, Paused and ActivityOver to IsRunning, IsPaused and IsOver respectively. (NOTE: corresponding ActivityMan functions remain unchanged)

  • Exposed ThrownDevice properties StartThrowOffset and EndThrowOffset to Lua (R/W).

  • HeldDevices can now show up as "Tools" in the buy menu, rather than just as "Shields".

  • Keyboard-only controlled AHumans and ACrabs can now strafe while sharp-aiming.

  • Lowered the default AHuman Head damage multiplier from 5 to 4.

  • "Fixed" grenades and other fast-moving objects bouncing violently off of doors and other stationary objects.

  • AEmitter and PEmitter throttle logic has changed:
    The properties MinThrottleRange and MaxThrottleRange have been changed to NegativeThrottleMultiplier and PositiveThrottleMultiplier respectively.
    The new logic uses the multipliers to multiply the emission rate relative to the absolute throttle value. NegativeThrottleMultiplier is used when throttle is negative, and vice versa.

  • Doors in Team = -1 will now open up for all actors.

  • MovableMan function KillAllActors (commonly found in activities) has been appropriately renamed KillAllEnemyActors.

  • Wound limit gibbing logic has changed for MOSRotating (and all its subclasses), where objects will now gib when they reach their GibWoundLimit rather than when they surpass it. This allows for one-wound gibbing, which was previously infeasible. For objects with low GibWoundLimits, you may want to adjust limits to account for this change.

  • TDExplosives will no longer default to a looping animation when activated. Instead, they change to the second frame (i.e 001), similarly to HDFirearm. Set SpriteAnimMode to 4 if you wish to enable the looping active animation.

  • AHuman can now manually reload BG devices.

  • Jetpack thrust angle is now properly clamped when controlled with an analog stick.

  • Aim reticle dots can now be hidden per device by setting SharpLength to 0.

  • Craft will now automatically scuttle when opening doors at a 90° angle rather than 45°.

  • AHumans can now sharp-aim slightly while walking, however not while reloading.

  • Recoil when firing weapons now affects sharp aim.

  • The distance arguments for MovableMan functions GetClosestActor and GetClosestTeamActor are now of type Vector rather than float.

  • File paths in INIs are now case sensitive.

  • Hands will now draw in transparent drawing mode, i.e. editing menu.

  • AHuman background Leg will no longer draw in front of the AHuman. The real result of this is that the background foot will no longer draw in front of the foreground one.

  • Everything draws better when flashing white, including craft which used to be terrible at it.

  • Reworked Attachable managment:
    DamageMultiplier on Attachables now works as expected, all Attachables can now transfer damage to their root parent.
    This will travel up chains of Attachables, as long as every Attachable in the chain has a non-zero DamageMultiplier (yes, negative numbers are supported if you wanna have healing instead of damage or weirdness with chaining negative multipliers). Note that the default DamageMultiplier for Attachables is 0, so you have to set it if you want it. Also note that wounds will default this value to 1 instead of 0.
    Attachable terrain collision has been reworked so that it can be changed simply by setting CollidesWithTerrainWhileAttached = true/false in INI or Lua. Also, Attachables attached to other Attachables will now collide with terrain properly.
    BreakWounds on Attachables now gets added to both the Attachable and the parent when the Attachable is broken off. If ParentBreakWound is defined, the parent will use this instead of the regular BreakWound.

  • Attachable.BreakWound now has R/W access in Lua.

  • Attachable.DeleteWithParent is now Attachable.DeleteWhenRemovedFromParent, since this more accurately describes what it does.

  • Attachable.OnlyLinearForces has been renamed to Attachable.ApplyTransferredForcesAtOffset and its effect has been reversed, so something that checked OnlyLinearForces == true would now check ApplyTransferredForcesAtOffset == false, since this makes more sense to use.

  • Arms and Legs on AHumans will no longer bleed out indefinitely. If you want this to happen, adjust their BreakWound or ParentBreakWound accordingly.

  • Reworked wound management:
    Wound management is now always done with MOSRotating functions, instead of requiring different ones for Actors. This means TotalWoundCount and RemoveAnyRandomWounds no longer exist.
    You can get all wounds with GetWounds, get the wound count with GetWoundCount (or using the pre-existing WoundCount property), get the gib wound limit with GetGibWoundLimit (or using the pre-existing GibWoundLimit property), and remove wounds with RemoveWounds.
    All of these functions have two variants, one lets you just specify any normal arguments (e.g. number of wounds to remove), the other lets you also specify whether you want to include any of the following, in order: Attachables with a positive DamageMultiplier (i.e. Attachables that damage their parent), Attachables with a negative DamageMultiplier (i.e. Attachables that heal their parent) or Attachables with no DamageMultiplier (i.e. Attachables that don't affect their parent).
    Without any arguments, GetWoundCount and RemoveWounds will only include Attachables with a positive DamageMultiplier in their counting calculations, and GetGibWoundLimit will not include any Attachables in its counting calculations. The property variants (e.g. mosr.WoundCount) behave the same way as the no-argument versions.
    Note that this process is recursive, so if an Attachable that satisfies the conditions has Attachables that also satisfy the conditions, their wounds will be included in the results.

  • Renamed Turret INI property MountedMO to MountedDevice to better match the new reality that Turrets can only mount HeldDevices and their child classes.

  • Renamed ACrab LFGLeg, LBGLeg, RFGLeg and RBGLeg Lua properties to LeftFGLeg, LeftBGLeg, RightFGLeg, RightBGLeg respectively, to be more consistent with other naming.
    For the time being, the INI properties (as well as the ones for setting FootGroups and LimbPaths) support both single letter and written out versions (i.e. LStandLimbPath and LeftStandLimbPath are both supported). This single letter versions will probably be deprecated over time.

  • To better align with the other changes, hardcoded Attachable INI definitions for ACDropShips and ACRockets can now support spelled out words. The following options are all supported in INI:
    ACDropShip - RThruster/RightThruster/RightEngine, LThruster/LeftThruster/LeftEngine, URThruster/UpRightThruster, ULThruster/UpLeftThruster, RHatchDoor/RightHatchDoor, LHatchDoor/LeftHatchDoor
    ACRocket - RLeg/RightLeg, LLeg/LeftLeg, RFootGroup/RightFootGroup, LFootGroup/LeftFootGroup, MThruster/MainThruster, RThruster/RightThruster, LThruster/LeftThruster, URThruster/UpRightThruster, ULThruster/UpLeftThruster

  • MovableMan:AddMO will now add HeldDevices (or any child class of HeldDevice) to its Items collection, making it able to provide the functionality of AddParticle, AddActor and AddItem.

  • Changed and cleaned up how gibbing works and how it affects Attachables. In particular, limbs will better inherit velocity during gibbing and things are more customizable. See Attachable properties for more details.
    As an added bonus, Attachables on ACDropShips and ACRockets can now be shot down when the craft gibs; fight back against the baleful dropship engines!

  • Improved native recoil handling! Guns transfer recoil to arms/turrets, which transfer it to AHumans/ACrabs, all of it properly accounts for joint strengths (or grip strengths) and offsets at every step. Future work will be done on this to improve it. (Issue #7 and Issue #8).

  • Attachables now use their GibImpulseLimit as well as their JointStrength when determining whether they should be detached by strong forces. To maintain backwards compatibility, if the GibImpulseLimit is less than the JointStrength, the JointStrength will be used instead for this purpose.

  • The FacingAngle function has been moved from Actor to MOSprite so it can be used more widely.

  • Lifetime and ToDelete now work on wounds, giving modders more control over them.

  • Some functionality has been moved from AudioMan to SoundContainer for consistency. As such, the following AudioMan Lua bindings have been replaced:
    AudioMan:FadeOutSound(fadeOutTime); has been replaced with soundContainer:FadeOut(fadeOutTime);
    AudioMan:StopSound(soundContainer); and AudioMan:StopSound(soundContainer, player); have been replaced with soundContainer:Stop(); and soundContainer:Stop(player);

  • Pressing escape when a buy menu is open now closes it instead of pausing the game.

  • GetParent will now return an MOSRotating instead of a MovableObject so it doesn't need to be casted with ToMOSRotating. Additionally, it will always return null for objects with no parents, instead of returning the self object for things that weren't Attachables.
    This makes things more consistent and reasonable throughout and will rarely, if ever, cause Lua problems.

  • Previews generated by the SceneEditor are now the same as ScenePreviewDumps. Also, both are now saved as PNGs.

  • Attachable terrain collisions will now propagate to any child Attachables on them. This means that Attachables will not collide with terrain, even if set to, if they're attached to a parent that doesn't collide with terrain.
    This means that the attachable.CollidesWithTerrainWhileAttached value may not represent the true state of things, you should instead use attachable.CanCollideWithTerrain to determine whether a given Attachable can collide with terrain.

  • Actor selection keys can be used to cycle the selected ObjectPicker item while it's closed during building phase and in editors.

  • The Actor property MaxMass now no longer includes the Mass of the Actor, and has been renamed to MaxInventoryMass for clarity. In mods, this is most important for ACraft, which will now need their total Mass subtracted from the old value.

  • BuyMenu tooltips now display item info as well as a description. This includes MaxInventoryMass and MaxPassengers for ACraft, Mass and PassengerSlots required for Actors, and Mass for other MoveableObjects.

  • Replaced the above-HUD pie menu inventory view with an animating inventory carousel.

  • AHuman:ReloadFirearm Lua function has been changed to AHuman:ReloadFirearms and will now reload offhand weapons as well, if appropriate.

  • ACrab:ReloadFirearm Lua function has been changed to ACrab:ReloadFirearms and will now reload all of the ACrab's weapons.

  • When using the Settings.ini flag LaunchIntoActivity, you will start with some default amount of gold; either the Activity's medium difficulty gold amount, or its funds for Team 1, which default to 2000 when not set.

  • AEmitters will now obey SpriteAnimMode set in Lua while they're emitting. When they stop emitting this will reset to NOANIM.

  • Attachable Lua method IsDrawnAfterParent has been changed to the property DrawnAfterParent, and is now R/W.

  • All mosRotating:RemoveAttachable, mosRotating:RemoveEmitter and attachable:RemoveFromParent functions will return the removed Attachable if it hasn't been added to MovableMan, or nil if it has. If the Attachable is returned, it will belong to Lua like it would if it were newly Created. You could then, for example, add it to MovableMan, an inventory, or attach it to something else.

  • Settings.ini property MenuTransitionDuration renamed to MenuTransitionDurationMultiplier.

  • Settings.ini property DisableLoadingScreen renamed to DisableLoadingScreenProgressReport.

  • Scenario scene markers are now color coded to help distinguish them visually:
    Base.rte scenes are yellow as always.
    Missions.rte scenes are now green.
    Scenes.rte or any other mod/user scenes are now cyan.

  • Main menu and sub-menus were given a major facelift.

  • Settings menu was reworked to make it less useless.

  • Esc has been disabled in server mode to not disrupt simulation for clients, use Alt+F4 or the window close button to exit.

  • Placing "Tech" in a DataModule's ModuleName no longer makes the module a playable faction (in MetaGame, etc.). The IsFaction property should be used instead.
    The word "Tech" will also not be omitted from the module name when displayed in any faction selection dropdown list.

  • Renamed Lua methods GetRadRotated and GetDegRotated to GetRadRotatedCopy and GetDegRotatedCopy for clarity.

  • Added support for multiple lines in DataModule descriptions in their Index.inis. See earlier entry on multiple lines in descriptions for details on how to use this.

Fixed
  • Fixed the logic for Gib and Emission property LifeVariation where it would round down to zero, giving particles infinite lifetime.

  • Fixed legs going bonkers for one frame when turning around.

  • HFlipped is now properly assigned to emissions, gibs and particles that are shot from a HDFirearm's Round when the source object is also flipped.

  • MovableObject:SetWhichMOToNotHit will now work properly for Attachables. They will also not hit the relevant MO. When they're removed, Attachables will check if they have the same MO for this value and, if so, unset it so they can hit that MO.

  • Craft sucking up objects now works properly again.

  • Getting the Mass of a MOSRotating has now been made more efficient. Additionally, Attachables of Attachables will now be properly included in Mass, so some things have gotten a lot heavier (e.g. Dummy Dreadnought).

  • The moment of inertia of AtomGroups now updates when the mass or Atoms change, meaning losing Attachables or changing mass will properly affect how rotational forces apply to MOSRotatings.

  • WoundDamageMultipliers on projectiles will now properly stack with wounds' DamageMultiplier. Prior to this, if you set the DamageMultiplier of a wound on some object, it'd be overwritten by the hitting projectile's WoundDamageMultiplier. Now they multiply together properly.

  • Radius and Diameter now account for Attachables on objects that can have them. If you want just the Radius or Diameter of the object, use IndividualRadius and IndividualDiameter (only available for MOSRotating and subclasses). This means that Radius and Diameter will now give you a good estimation of an object's total size.

  • Fixed various audio bugs that were in Pre3, and fixed clicking noise on sounds that played far away. The game should sound way better now!

  • Mobile sounds (i.e. generally things that aren't GUI related) will now pause and resume when you pause and resume your activity.

  • The DeactivationSound of HDFirearms now respects its SoundOverlapMode instead of never allowing overlap. If you don't want it overlapping, set it up accordingly.

  • Enabled DPI Awareness to fix issues with resolution settings when Windows scaling is enabled.

  • Fixed a bug that caused the game to crash when the crab bomb effect was triggered while there were multiple crab bomb eligible Craft in an activity.

  • Renamed Attachable INI property CollidesWithTerrainWhenAttached to more correct, consistent CollidesWithTerrainWhileAttached.

  • You can now modify all hardcoded Attachable CopyOf INI definitions without setting a new PresetName. This means you could, for example, CopyOf a predefined Leg and change it, without having to set a new PresetName. This is optional, and comes with the obvious limitation of not being able to find that modified copy in-game with Lua.

  • OnCollideWithMO now works for MOPixels and MOSParticles so you can use it to check if your bullets collide with things.

  • OnCollideWithMO and OnCollideWithTerrain (and other special functions) will run more reliably right after the object is spawned. E.g. OnCollideWithTerrain on a bullet should now work even if your gun is jammed into terrain when you shoot.

  • You can now sharp-aim through friendlies when playing as any team, instead of just as red team.

  • The reload hotkey now works even if you're on top of a pickupable object.

  • Improved LZ behaviour on wrapping maps, so your buy cursor will no longer annoyingly wrap around the LZ area.

  • Fixed a bug with metagame saves that caused Player and Team numbers to be off by 1.

  • Vote counts to end a multiplayer activity now display as intended.

  • Fixed a bug where choosing -Random- as a player's tech and pressing start game had a 1 in (number of techs + 1) chance to crash the game.

  • Console error spam will no longer cripple performance over time.

  • AudioMan:StopAll() now actually stops all sounds, instead of just stopping music.

  • Fixed incorrect mouse bounds during splitscreen when the mouse player was not Player 1.

Removed
  • Removed obsolete graphics drivers and their Settings.ini properties ForceOverlayedWindowGfxDriver and ForceNonOverlayedWindowGfxDriver.

  • Removed Attachable Lua write capability for AtomSubGroupID as changing this can cause all kinds of problems.

  • Removed MaxLength property from Leg, since it was a mostly unused leftover caused by Leg being originally copied from Arm, and was actually a fake setting that just set other properties. To replace it, set the following:

     ContractedOffset = Vector
     	X = //Old MaxLength/2
     	Y = 0
     ExtendedOffset = Vector
     	X = //Old MaxLength
     	Y = 0
    
  • Removed Attachable.RotTarget from Lua and INI. The property never worked and no longer exists.

  • Removed Attachable:CollectDamage, Attachable:TransferJointForces and Attachable:TransferJointImpulses Lua function definitions. These are internal functions that should never have been exposed to Lua.

  • Removed MOSRotating:ApplyForces and MOSRotating:ApplyImpulses Lua functions. These are both internal functions that should never have been exposed to Lua.

  • Removed hardcoded INI constraint that forced Mass of MovableObjects to not be 0. Previously, anytime a Mass of 0 was read in from INI, it was changed to 0.0001, now 0 Mass is allowed and supported.

  • Removed the quit confirmation dialog from the scenarios screen. Now pressing escape will return you to the main menu.

  • Removed Settings.ini properties HSplitScreen and VSplitScreen. Superseded by TwoPlayerSplitscreenVertSplit.


Added
  • Implemented Lua Just-In-Time compilation (MoonJIT 2.2.0).

  • Implemented PNG file loading and saving. PNGs still need to be indexed just like BMPs! Transparency (alpha) not supported (yet).

  • New Settings.ini property LoadingScreenReportPrecision = intValue to control how accurately the module loading progress reports what line is currently being read.
    Only relevant when DisableLoadingScreen = 0. Default value is 100, lower values increase loading times (especially if set to 1).
    This should be used for debugging where you need to pinpoint the exact line that is crashing and the crash message isn't helping or doesn't exist at all.

  • New Settings.ini property MenuTransitionDuration = floatValue to control how fast transitions between different menu screens happen (e.g main menu to activity selection screen and back).
    This property is a multiplier, the default value is 1 (being the default hardcoded values), lower values decrease transition durations. 0 makes transitions instant.

  • New ADoor sound properties: (Issue #106)

     // Played when the door starts moving from fully open/closed position towards the opposite end.
     DoorMoveStartSound = SoundContainer
     	AddSound = ContentFile
     		FilePath = pathToFile
    
     // Played while the door is moving, between fully open/closed position.
     DoorMoveSound = SoundContainer
     	AddSound = ContentFile
     		FilePath = pathToFile
     	LoopSetting = -1 // Doesn't have to loop indefinitely, but generally should.
    
     // Played when the door changes direction while moving between fully open/closed position.
     DoorDirectionChangeSound = SoundContainer
     	AddSound = ContentFile
     		FilePath = pathToFile
    
     // Played when the door stops moving and is at fully open/closed position.
     DoorMoveEndSound = SoundContainer
     	AddSound = ContentFile
     		FilePath = pathToFile
    
  • Exposed Actor.StableVelocityThreshold to lua. New bindings are: (Issue #101)
    Actor:GetStableVelocityThreshold() returns a Vector with the currently set stable velocity threshold.
    Actor:SetStableVelocityThreshold(xFloatValue, yFloatValue) sets the stable velocity threshold to the passed in float values.
    Actor:SetStableVelocityThreshold(Vector) sets the stable velocity threshold to the passed in Vector.

  • New Attachable and AEmitter property DeleteWithParent = 0/1. If enabled the attachable/emitter will be deleted along with the parent if parent is deleted/gibbed/destroyed. (Issue #97)

  • New Settings.ini property LaunchIntoActivity = 0/1. With PlayIntro functionality changed to actually skip the intro and load into main menu, this flag exists to skip both the intro and main menu and load directly into the set default activity.

  • Exposed AHuman.ThrowPrepTime to lua and ini: (Issue #101)
    ThrowPrepTime = valueInMS will set how long it takes the AHuman to fully charge a throw. Default value is 1000.
    AHuman.ThrowPrepTime to get/set values via lua.

  • Added new SpriteAnimMode modes:

     SpriteAnimMode = 7 // OVERLIFETIME
    

    This mode handles exactly like (now removed) MOSParticle.Framerate = 0 and will complete the sprite's animation cycle over the course of its existence. SpriteAnimDuration is inapplicable when using this mode and will do nothing.
    For example, an object that has a sprite with 10 frames and a lifetime of 10 seconds will animate at a rate of 1 frame per second, finishing its animation cycle just before being deleted from the scene.
    If this mode is used on an object that has LifeTime = 0 (infinite) it will be overridden to SpriteAnimMode = 1 (ALWAYSLOOP) otherwise it will never animate.

     SpriteAnimMode = 8 // ONCOLLIDE
    

    This mode will drive the animation forward based on collisions this object has with other MOs or the terrain. SpriteAnimDuration is inapplicable when using this mode and will do nothing.
    This mode is MOSParticle specific and used mainly for animating casings and small gibs. Using this mode on anything other than MOSParticle will do nothing.

  • New Settings.ini properties EnableCrabBombs = 0/1 and CrabBombThreshold = intValue.
    When EnableCrabBombs is enabled, releasing a number of crabs equal to CrabBombThreshold or more at once will trigger the crab bomb effect.
    If disabled releasing whatever number of crabs will do nothing except release whatever number of crabs.

  • Doors can now be stopped at their exact position using ADoor:StopDoor() via lua. When stopped, doors will stop updating their sensors and will not try to reset to a default state.
    If the door was stopped in a script, it needs to opened/closed by calling either ADoor:OpenDoor() or ADoor:CloseDoor() otherwise it will remain in the exact position it was stopped forever.
    If either DrawMaterialLayerWhenOpen or DrawMaterialLayerWhenClosed properties are set true, a material layer will be drawn when the door is stopped. This is to prevent a situation where the material layer will be drawn only if the door is travelling in one direction, without adding an extra property.

  • New value STOPPED (4) was to the ADoor.DoorState enumeration. ADoor:GetDoorState will return this if the door was stopped by the user via ADoor:StopDoor.

  • New shortcut ALT + W to generate a detailed 140x55px mini WorldDump to be used for scene previews. No relying on SceneEditor, stretches over whole image, no ugly cyan bunkers, no actors or glows, has sky gradient, indexed to palette.

  • All text in TextBox (any TextBox) can now be selected using CTRL + A.

  • Console can now be resized using CTRL + UP/DOWN (arrow keys) while open.

  • Added new lua function UInputMan:GetInputDevice(playerNum) to get a number value representing the input device used by the specified player. Should be useful for making custom key bindings compatible with different input devices.

  • Scripts can now be attached to ACrab.Turret and Leg. Additionally, a binding to get the Foot of a Leg has been added.

  • Added H/V flipping capabilities to Bitmap primitives. New bindings with arguments for flip are:
    PrimitiveMan:DrawBitmapPrimitive(pos, entity, rotAngle, frame, bool hFlipped, bool vFlipped)
    PrimitiveMan:DrawBitmapPrimitive(player, pos, entity, rotAngle, frame, bool hFlipped, bool vFlipped)
    Original bindings with no flip arguments are untouched and can be called as they were.

  • Added new primitive drawing functions to PrimitiveMan:

     -- Arc
     PrimitiveMan:DrawArcPrimitive(Vector pos, startAngle, endAngle, radius, color)
     PrimitiveMan:DrawArcPrimitive(player, Vector pos, startAngle, endAngle, radius, color)
    
     PrimitiveMan:DrawArcPrimitive(Vector pos, startAngle, endAngle, radius, color, thickness)
     PrimitiveMan:DrawArcPrimitive(player, Vector pos, startAngle, endAngle, radius, color, thickness)
    
     -- Spline (Bézier Curve)
     PrimitiveMan:DrawSplinePrimitive(Vector start, Vector guideA, Vector guideB, Vector end, color)
     PrimitiveMan:DrawSplinePrimitive(player, Vector start, Vector guideA, Vector guideB, Vector end, color)
    
     -- Box with rounded corners
     PrimitiveMan:DrawRoundedBoxPrimitive(Vector upperLeftCorner, Vector bottomRightCorner, cornerRadius, color)
     PrimitiveMan:DrawRoundedBoxPrimitive(player, Vector upperLeftCorner, Vector bottomRightCorner, cornerRadius, color)
    
     PrimitiveMan:DrawRoundedBoxFillPrimitive(Vector upperLeftCorner, Vector bottomRightCorner, cornerRadius, color)
     PrimitiveMan:DrawRoundedBoxFillPrimitive(player, Vector upperLeftCorner, Vector bottomRightCorner, cornerRadius, color)
    
     -- Triangle
     PrimitiveMan:DrawTrianglePrimitive(Vector pointA, Vector pointB, Vector pointC, color)
     PrimitiveMan:DrawTrianglePrimitive(player, Vector pointA, Vector pointB, Vector pointC, color)
    
     PrimitiveMan:DrawTriangleFillPrimitive(Vector pointA, Vector pointB, Vector pointC, color)
     PrimitiveMan:DrawTriangleFillPrimitive(player, Vector pointA, Vector pointB, Vector pointC, color)
    
     -- Ellipse
     PrimitiveMan:DrawEllipsePrimitive(Vector pos, horizRadius, vertRadius, color)
     PrimitiveMan:DrawEllipsePrimitive(player, Vector pos, horizRadius, vertRadius, color)
    
     PrimitiveMan:DrawEllipseFillPrimitive(Vector pos, short horizRadius, short vertRadius, color)
     PrimitiveMan:DrawEllipseFillPrimitive(player, Vector pos, horizRadius, vertRadius, color)
  • Added log for non-fatal loading errors. This log will show image files that have been loaded with incorrect extensions (has no side effects but should be addressed) and audio files that failed loading entirely and will not be audible.
    If errors are present the console will be forced open to notify the player (only when loading into main menu).
    Log will be automatically deleted if warnings are no longer present to avoid polluting the root directory.

  • Game window resolution can now be changed without restarting the game.

  • GUI sliders (like for music volume) can now be adjusted with the mouse scroll wheel.

  • Exposed PEmitter to lua. Bindings are identical to AEmitter bindings, except that damage-related bindings don't exist for PEmitter.

  • FLAC audio files can now be loaded through lua and ini.

  • Added new lua Vector functions: GetRadRotated(angle) and GetDegRotated(angle). They return a rotated copy of the vector without modifying it.

  • Added Enum binding for SoundSet.SoundSelectionCycleMode: RANDOM = 0, FORWARDS = 1, ALL = 2.

  • Added Enum binding for SoundContainer.SoundOverlapMode: OVERLAP = 0, RESTART = 1, IGNORE_PLAY = 2.

  • New SoundContainer function Restart, which allows you to restart a playing SoundContainer. Also another Play function, that lets you just specify the player to play the sound for.

  • New HDFirearm INI property PreFireSound, which allows you to specify a sound that will play exactly once before the weapon fires.
    Note that this was designed primarily for things like flamethrowers, semi-auto weapons may wonky with it, and full-auto weapons may fire multiple shots in the first burst, if you don't also set an ActivationDelay.

  • SoundSets have been made a bit more fully featured, they can now have sub SoundSets and their own SoundSelectionCycleMode and they now have a Lua binding so you can create them in Lua with local mySoundSet = SoundSet().
    They have the following INI and Lua properties:

    SoundSelectionCycleMode (INI and Lua R/W) - Determines how sounds in this SoundSet will be selected each time it is played (or when SelectNextSounds is called).
    Note that sub SoundSets can have different SoundSelectionCycleModes. SoundSets with sub SoundSets and sounds whose SoundSelectionCycleMode is FORWARDS will first go through their sounds, then each sub SoundSet.

    soundSet.SubSoundSets (Lua R) - An iterator over the sub SoundSets of this SoundSet, allowing you to manipulate them as you would any SoundSet.
    soundSet:HasAnySounds(includeSubSoundSets) (Lua) - Whether or not this SoundSet has any sounds, optionally including its sub SoundSets.
    soundSet:SelectNextSounds() (Lua) - Selects the next sounds for this SoundSet. Note that playing a SoundContainer will always also do this, so this is only really useful to allow you to skip sounds when SoundSelectionCycleMode is set to FORWARDS.
    soundSet:AddSound("Path/to/sound.flac") (Lua) - Adds the sound at the given path with no offset, 0 minimum audible distance, and default attenuation start distance.
    soundSet:AddSound("Path/to/sound.flac", offset, minimumAudibleDistance, attenuationStartDistance) (Lua) - Adds the sound at the given path with the given parameters.
    soundSet:AddSoundSet(soundSetToAdd) (Lua) - Adds the given SoundSet as a sub SoundSet of this SoundSet.
    soundSet:RemoveSound("Path/to/sound.flac") (Lua) - Removes any sounds with the given filepath from the SoundSet, returning whether or not any where removed. Does not remove sounds from sub-SoundSets.
    soundSet:RemoveSound("Path/to/sound.flac", removeFromSubSoundSets) (Lua) - Removes any sounds with the given filepath from the SoundSet, returning whether or not any where removed. Optionally removes matching sounds from any sub-SoundSets and their sub-SoundSets and so on.

    Additionally, AddSound and AddSoundSet INI properties work for SoundSets. They are exactly the same as they are for SoundContainers.

  • You can get the top level SoundSet of a SoundContainer with soundContainer:GetTopLevelSoundSet and manipulate it as described above. You can also set it to fully overwrite it with soundContainer:SetTopLevelSoundSet. This allows you full interaction with all levels of SoundSets in a SoundContainer.

Changed
  • Codebase now uses the C++17 standard.

  • Updated game framework from Allegro 4.2.3.1 to Allegro 4.4.3.1.

  • Major cleanup and reformatting in the Managers folder.

  • Lua error reporting has been improved so script errors will always show filename and line number.

  • Ini error reporting has been improved so asset loading crash messages (image and audio files) will also display the ini file and line they are being referenced from and a better explanation why the crash occured. (Issue #161)

  • Settings.ini will now fully populate with all available settings (now also broken into sections) when being created (first time or after delete) rather than with just a limited set of defaults.

  • Temporarily removed PreciseCollisions from Settings.ini due to bad things happening when disabled by user.

  • Settings.ini property PlayIntro renamed to SkipIntro and functionality changed to actually skip the intro and load user directly into main menu, rather than into the set default activity.

  • Lua calls for GetParent and GetRootParent can now be called by any MovableObject rather than being limited to Attachable only. (Issue #102)
    In some cases a cast to the appropriate type (ToWhateverType, e.g ToMOSRotating) will be needed when attempting to manipulate the object returned, because it will be returned as MovableObject if it is the root parent.
    In cases where you need to iterate over a parent's attachable list the parent must be cast to the appropriate type that actually has an attachable list to iterate over.
    For example:

     for attachable in ToMOSRotating(self:GetParent()).Attachables do
     	...
     end

    Or

     local parent = ToMOSRotating(self:GetParent());
     for attachable in parent.Attachables do
     	...
     end
  • Physics constants handling removed from FrameMan and now hardcoded in Constants. Lua bindings moved to RTETools and are now called without the FrameMan prefix like so:
    GetPPM(), GetMPP(), GetPPL(), GetLPP().

  • Removed hardcoded 10 second LifeTime restriction for MOPixel and MOSParticle.

  • MOSParticle animation can now be set with SpriteAnimMode and SpriteAnimDuration. If the property isn't defined it will default to SpriteAnimMode = 7 (OVERLIFETIME).

  • Reworked crab bombing behavior. When enabled through Settings.ini and triggered will gib all living actors on scene except brains and doors. Devices and non-actor MOs will remain untouched.

  • ADoor properties DrawWhenOpen and DrawWhenClosed renamed to DrawMaterialLayerWhenOpen and DrawMaterialLayerWhenClosed so they are more clear on what they actually do.

  • Specially handled Lua function OnScriptRemoveOrDisable has been changed to OnScriptDisable, and no longer has a parameter saying whether it was removed or disabled, since you can no longer remove scripts.

  • When pasting multiple lines of code into the console all of them will be executed instead of the last line being pasted into the textbox and all before it executing.

  • Input enums moved from UInputMan to Constants and are no longer accessed with the UInputManager prefix. These enums are now accessed with their own names as the prefix.
    For example: UInputManager.DEVICE_KEYB_ONLY is now InputDevice.DEVICE_KEYB_ONLY, UInputManager.INPUT_L_UP is now InputElements.INPUT_L_UP and so on.

  • CraftsOrbitAtTheEdge corrected to CraftOrbitAtTheEdge. Applies to both ini property and lua binding.

  • Game will now Abort with an error message when trying to load a copy of a non-existent AtomGroup, Attachable or AEmitter preset.

  • ComboBoxes (dropdown lists) can now also be closed by clicking on their top part.

  • Activity:IsPlayerTeam renamed to Activity:IsHumanTeam.

  • Screenshot functionality changed: (Issue #162)
    The PrintScreen button will now take a single screenshot on key release and will not take more until the key is pressed and released again.
    The Ctrl+S key combination is unchanged and will take a single screenshot every frame while the keys are held.
    The Ctrl+W and Alt+W key combinations will now take a single WorldDump/ScenePreview on W key release (while Ctrl/Alt are still held) and will not take more until the key is pressed and released again.

    Additionally, all screenshots (excluding abortscreen) will now be saved into a _Screenshots folder (_ so it's on top and not hiding between module folders) to avoid polluting the root directory. (Issue #163)
    This folder will be created automatically after modules are loaded if it is missing.

  • ScreenDumps and WorldDumps are now saved as compressed PNGs.

  • Controller deadzone setting ignores more input. Previously setting it to the maximum was just enough to eliminate stick drift.

  • Arm.HandPos will now get/set the hand position as relative to the arm's joint position, instead of relative to the arm's center of mass.

  • Resolution settings in options screen changed:
    Resolution multiplier button changed to Fullscreen button - this will set the game window resolution to match the desktop resolution. When resolution matches the desktop, this button will change to Windowed and will allow setting the game window resolution back to default (960x540).
    Added Upscaled Fullscreen button - this will change the resolution to half of the desktop and the multiplier to 2. The Fullscreen button will change to Windowed in this mode to return to non-upscaled mode (960x540).
    Selecting any resolution setting from the resolution combobox will immediately change to selected resolution. (Known bug: Clicking off the combobox without making a new selection while in Upscaled Fullscreen mode will change resolution to Fullscreen. This will be addressed later.)

    Note: Changing the game window resolution while an Activity is active requires ending the Activity. A dialog box will appear asking to confirm the change.

  • Moved from C-style random number generation to C++ standard. This includes usage of a mt19937 random number generator.

  • Resolution validation changed to support multiple screens. Incompatible/bad resolution settings will be overridden at startup with messages explaining the issue.
    Note: For multi-screen to work properly, the left-most screen MUST be set as primary. Screens having different resolutions does not actually matter but different heights will still be warned about and overridden due to the likeliness of GUI elementes being cropped on the shortest screen.
    Resolution validation can be disabled for multi-screen setups with Settings.ini property DisableMultiScreenResolutionValidation. Bad settings are likely to crash, use at own risk.
    For setups with more than 3 screens DisableMultiScreenResolutionValidation must be set true.

  • Damage to Actors from impulses is now relative to their max health instead of being on a scale from 0 to 100.

  • Scenes with a PresetName containing the strings "Test", "Editor" and "Tutorial" are no longer excluded from the scenarios screen and from the MetaGame.

  • SoundContainer is now a concrete Lua entity. This means it can now be created with CreateSoundContainer("PresetName", "DataModule.rte") and has all the standard functionality like cloning, etc.
    To support these changes, a bunch of Lua functionality has been added and modified:

    soundContainer.Immobile - Whether or not the SoundContainer is immobile. Immobile sounds are generally used for GUI elements and will never be automatically panned, pitched or attenuated.
    soundContainer.AttenuationStartDistance - Formerly INI only, this property is now gettable and settable through Lua. See previous changelog entries for details on it.
    soundContainer.Pos - Rather than updating the SoundContainer's position through AudioMan, you should now use the Pos property.
    soundContainer.Volume - In addition to attenuation based volume changes, it is now possible to set a SoundContainer's overall volume. This works together with volume changes caused by attenuation.
    soundContainer.Pitch - Rather than updating the SoundContainer's pitch through AudioMan, you should now use the Pitch property. Also note that this now works properly with the game's global pitch so no complicated handling is necessary.

  • AddSound and SelectNextSoundSet Lua bindings have been moved from SoundContainer to SoundSet. The latter has been renamed and the former have been trimmed down slightly since some complexity is no longer needed. Their speciifcs are mentioned in the Added section.

  • Pressing escape at the options, mod manager, game editors and credits screens no longer quits the game.

Fixed
  • Fix crash when returning to MetaGame scenario screen after activity end.

  • Control schemes will no longer get deleted when being configured. Resetting the control scheme will load a preset instead of leaving it blank. (Issue #121)

  • Fix glow effects being drawn one frame past EffectStartTime making objects that exist for a single frame not draw glows. (Issue #67)

  • Time scale can no longer be lowered to 0 through the performance stats interface.

  • Actors now support their held devices identically while facing to either side. (Issue #31)

  • Fixed issue where clicking a ComboBox's scrollbar would release the mouse, thus causing unexpected behavior like not being able to close the list by clicking outside of it.

  • Fixed issue where ComboBoxes did not save the current selection, thus if the ComboBox was deselected without making a selection then the selection would revert to the default value instead of the last selected value.

  • Fixed issue with double clicks and missing clicks in menus (anything that uses AllegroInput).

  • Fixed issue where OnPieMenu function wasn't working for AHuman equipped items, and made it work for BGArm equipped items as well as FGArm ones.

  • The "woosh" sound played when switching actors from a distance will now take scene wrapping into account. Additionally, attempting to switch to previous or next actor with only one actor will play the more correct "error" sound.

  • HDFirearm INI property DeactivationSound now works properly instead of constantly playing.

  • Gold mining sound has been set to restart its playback everytime it's played, making it way less annoying. It's still pretty wonky, but it's better.

  • Sound panning should now work properly around scene seams. Additionally, sounds should be less stuttery (e.g. distant jetpacks) and generally sound better.

Removed
  • Removed the ability to remove scripts from objects with Lua. This is no longer needed cause of code efficiency increases.

  • Removed Settings.ini property PixelsPerMeter. Now hardcoded and cannot be changed by the user.

  • Removed MOSParticle property Framerate and lua bindings. MOSParticle animation is now handled with SpriteAnimMode like everything else.

  • Removed ConsoleMan.ForceVisibility and ConsoleMan.ScreenSize lua bindings.

  • Removed ActivityMan.PlayerCount and ActivityMan.TeamCount setters lua bindings (obsolete and did nothing).

  • Removed Activity properties TeamCount and PlayerCount. These are handled internally and do nothing when set in ini.

  • Removed Activity property FundsOfTeam#, use Team#Funds instead.

  • Some functionality has been moved from AudioMan to SoundContainer. As such, the following AudioMan Lua bindings are no longer available:
    SetSoundPosition(soundContainer), SetSoundPitch(soundContainer, PlaySound(filePath, position, player, loops, priority, pitchOrAffectedByGlobalPitch, attenuationStartDistance, immobile)

    The lengthy PlaySound function should be replaced by making a SoundContainer in your Create function and setting properties appropriately.
    This can be done by creating one defined INI with soundContainer = CreateSoundContainer(...), or by making an empty one with soundContainer = SoundContainer().


0.1.0 pre-release 2 - 2020/05/08

Added
  • Lua binding for Box::IntersectsBox(otherBox), that returns true if 2 boxes intersect.

  • Command line arguments for launching directly into editors using -editor "EditorName".
    Valid editor names are: ActorEditor, GibEditor, SceneEditor, AreaEditor and AssemblyEditor.

  • Added handling for custom number and string values in INI.

     AddCustomValue = NumberValue
     	YourKeyName = YourNumberValue // Integer or floating point number.
    
     AddCustomValue = StringValue
     	YourKeyName = YourStringValue
    

    YourKeyName is a string value and is not limited to just numbers.

  • New Settings.ini property AdvancedPerformanceStats = 0/1 to disable/enable the performance counter graphs (enabled by default).

  • Added PassengerSlots INI and Lua property to Actors. This determines how many spaces in the buy menu an actor will take up (1 by default). It must be a whole number but can theoretically be 0 or less.

  • Added Lua bindings for IsInsideX and IsInsideY to Area. These act similarly to the pre-existing IsInside, but allow you to check for the X and Y axes individually.

  • Added the concept of SoundSets, which are collections of sounds inside a SoundContainer. This allows you to, for example, put multiple sounds for a given gunshot inside a SoundSet so they're played together.

  • SoundContainers have been overhauled to allow for a lot more customization, including per-sound customization. The following INI example shows all currently available capabilities with explanatory comments:

     AddSoundContainer = SoundContainer // Note that SoundContainers replace Sounds, so this can be used for things like FireSound = SoundContainer
     	PresetName = Preset Name Here
    
     	SoundSelectionCycleMode = RANDOM (default) | FORWARDS | ALL // How the SoundContainer will cycle through its `SoundSets` whenever it's told to select a new one. The first is prior behaviour of picking sounds at random, the second cycles through SoundSets in the order they were added, and the third plays all SoundSets at once.
    
     	LoopSetting = -1 | 0 (default) | 1+ // How the SoundContainer loops its sounds. -1 means it loops forever, 0 means it plays once, any number > 0 means it plays once and loops that many times.
    
     	Immobile = 0 (default) | 1 // Whether or not the SoundContainer's sounds should be treated as immobile. Immobile sounds are generally used for UI and system sounds; they will always play at full volume and will not be panned or affected by global pitch during game slowdown.
    
     	AttenuationStartDistance = Number (default -1) // The distance at which the SoundContainer's sounds will start to attenuate out, any number < 0 set it to the game's default. Attenuation calculations follows FMOD's Inverse Rolloff model, which you can find linked below.
    
     	Priority = 0 - 256 (default 128) // The priority at which the SoundContainer's sounds will be played, between 0 (highest priority) and 256 (lowest priority). Lower priority sounds are less likely to be played are a lot of sounds playing.
    
     	AffectedByGlobalPitch = 0 | 1 (default) // Whether or not the SoundContainer's sounds will be affected by global pitch, or only change pitch when manually made to do so via Lua (note that pitch setting is done via AudioMan).
    
     	AddSoundSet = SoundSet // This adds a SoundSet containing one or more sounds to the SoundContainer.
    
     		AddSound = ContentFile // This adds a sound to the SoundSet, allowing it to be customized as shown.
     			Filepath = "SomeRte.rte/Path/To/Sound.wav"
    
     			Offset = Vector // This specifies where the sound plays with respect to its SoundContainer. This allows, for example, different sounds in a gun's reload to come from slightly different locations.
     				X = Number
     				Y = Number
    
     			AttenuationStartDistance = Number // This functions identically to SoundContainer AttenuationStartDistance, allowing you to override it for specific sounds in the SoundContainer.
    
     			MinimumAudibleDistance = Number (default 0) // This allows you to make a sound not play while the listener is within a certain distance, e.g. for gunshot echoes. It is automatically accounted for in sound attenuation.
    
     		AddSound = "SomeRte.rte/Path/To/AnotherSound.wav" // This adds a sound to the SoundSet in oneline, allowing it to be compactly added (without customisation).
    
     	AddSound = "SomeRte.rte/Path/To/YetAnotherSound.wav" // This adds a sound to the SoundContainer, creating a new SoundSet for it with just this sound.
    

    NOTE: Here is a link to FMOD's Inverse Rolloff Model.

  • SoundContainer Lua controls have been overhauled, allowing for more control in playing and replaying them. The following Lua bindings are available:

     soundContainer:HasAnySounds() -- Returns whether or not the SoundContainer has any sounds in it. Returns True or false.
     soundContainer:IsBeingPlayed() -- Returns whether or not any sounds in the SoundContainer are currently being played. Returns True or False.
     soundContainer:Play(optionalPosition, optionalPlayer) -- Plays the sounds belonging to the SoundContainer's currently selected SoundSet. The sound will play at the position and for the player specified, or at (0, 0) for all players if parameters aren't specified.
     soundContainer:Stop(optionalPlayer) -- Stops any playing sounds belonging to the SoundContainer, optionally only stopping them for a specified player.
     soundContainer:AddSound(filePath, optional soundSetToAddSoundTo, optionalSoundOffset, optionalAttenuationStartDistance, optionalAbortGameIfSoundIsInvalid) -- Adds the sound at the given filepath to the SoundContainer. If a SoundSet index is specified it'll add it to that SoundSet. If an offset or attenuation start distance are specified they'll be set, as mentioned in the INI section above. If set to abort for invalid sounds, the game will error out if it can't load the sound, otherwise it'll show a console error.
     soundContainer:SetPosition(position) -- Sets the position at which the SoundContainer's sounds will play.
     soundContainer:SelectNextSoundSet() -- Selects the next SoundSet to play when soundContainer:Play(...) is called, according to the INI defined CycleMode.
     soundContainer.Loops -- Set or get the number of loops for the SoundContainer, as mentioned in the INI section above.
     soundContainer.Priority -- Set or get the priority of the SoundContainer, as mentioned in the INI section above.
     soundContainer.AffectedByGlobalPitch -- Set or get whether the SoundContainer is affected by global pitch, as mentioned in the INI section above.
  • MovableObjects can now run multiple scripts by putting multiple AddScript = FilePath.lua lines in the INI definition. (Issue #109)
    Scripts will have their appropriate functions run in the order they were added. Note that all scripts share the same self, so care must be taken when naming self variables.
    Scripts can be checked for with movableObject:HasScript(filePath); and added and removed with movableObject:AddScript(filePath); and movableObject:RemoveScript(filePath);. They can also be enabled and disabled in Lua (preserving their ordering) with movableObject:EnableScript(filePath); and movableObject:DisableScript(filePath);.

  • Scripts on MovableObjects and anything that extends them (i.e. most things) now support the following new functions (in addition to Create, Update, Destroy and OnPieMenu). They are added in the same way as the aforementioned scripts:

     OnScriptRemoveOrDisable(self, scriptWasRemoved) -- This is run when the script is removed or disabled. The scriptWasRemoved parameter will be True if the script was removed and False if it was disabled.
     OnScriptEnable(self) -- This is run when the script was disabled and has been enabled.
     OnCollideWithTerrain(self, terrainMaterial) -- This is run when the MovableObject this script on is in contact with terrain. The terrainMaterial parameter gives you the material ID for the terrain collided with. It is suggested to disable this script when not needed to save on overhead, as it will be run a lot!
     OnCollideWithMO(self, collidedMO, collidedRootMO) -- This is run when the MovableObject this script is on is in contact with another MovableObject. The collidedMO parameter gives you the MovableObject that was collided with, and the collidedRootMO parameter gives you the root MovableObject of that MovableObject (note that they may be the same). Collisions with MovableObjects that share the same root MovableObject will not call this function.
  • Scripts on Attachables now support the following new functions:

     OnAttach(self, newParent) -- This is run when the Attachable this script is on is attached to a new parent object. The newParent parameter gives you the object the Attachable is now attached to.
     OnDetach(self, exParent) -- This is run when the Attachable this script is on is detached from an object. The exParent gives you the object the Attachable was attached to.
Changed
  • Codebase now uses the C++14 standard.

  • Major cleanup and reformatting in the System folder.

  • Upgraded to new, modern FMOD audio library. (Issue #72).
    Sounds now play in 3D space, so they pan to the left and right, and attenuate automatically based on the player's viewpoint.

  • Sounds have been renamed to SoundContainers, and are able to handle multiple sounds playing at once. INI definitions have changed accordingly.
    They must be added using ... = SoundContainer, and individual sounds for them must be added using AddSound = ContentFile....

  • Various lua bindings around audio have been upgraded, changed or fixed, giving modders a lot more control over sounds. See documentation for more details.

  • Centered the loading splash screen image when DisableLoadingScreen is true.

  • Box:WithinBox lua bindings have been renamed:
    Box:WithinBox is now Box:IsWithinBox.
    Box:WithinBoxX is now Box:IsWithinBoxX.
    Box:WithinBoxY is now Box:IsWithinBoxY.

  • Made AHuman show both weapon ammo states when 2 one-handed weapons are equipped.

  • Added support for multiple lines in item descriptions (Issue#58). This is done as follows:

     Description = MultiLineText
     	AddLine = First line of text
     	AddLine = Second line of text
     	...
    
  • FrameMan broken down to 4 managers. New managers are:
    PerformanceMan to handle all performance stats and measurements.
    PostProcessMan to handle all post-processing (glows).
    PrimitiveMan to handle all lua primitive drawing.

  • Post-processing (glow effects) is now enabled at all times with no option to disable.

  • All lua primitive draw calls are now called from PrimitiveMan.
    For example: FrameMan:DrawLinePrimitive() is now PrimitiveMan:DrawLinePrimitive().

  • Resolution multiplier properties (NxWindowed and NxFullscreen) in settings merged into a single property ResolutionMultiplier.

  • Incompatible/bad resolution settings will be overridden at startup with messages explaining the issue instead of multiple mode switches and eventually a reset to default VGA.
    Reset to defaults (now 960x540) will happen only on horrible aspect ratio or if you managed to really destroy something.

  • You can no longer toggle native fullscreen mode from the settings menu or ini. Instead, either select your desktop resolution at 1X mode or desktop resolution divided by 2 at 2X mode for borderless fullscreen windowed mode.
    Due to limitations in Allegro 4, changing the actual resolution from within the game still requires a restart.

  • If the current game resolution is half the desktop resolution or less, you will be able to instantly switch between 1X and 2X resolution multiplier modes in the settings without screen flicker or delay.
    If the conditions are not met, the mode switch button will show Unavailable.

  • PieMenuActor and OrbitedCraft have now been removed. They are instead replaced with parameters in their respective functions, i.e. OnPieMenu(pieMenuActor); and CraftEnteredOrbit(orbitedCraft);. Their use is otherwise unchanged.

Fixed
  • Fixed LuaBind being all sorts of messed up. All lua bindings now work properly like they were before updating to the v141 toolset.

  • Explosives (and other thrown devices) will no longer reset their explosion triggering timer when they're picked up. (Issue #71)

  • Sprite Animation Mode ALWAYSPINGPONG now works properly. Sprite animation has also been moved to MOSprite instead of MOSRotating, they they'll be able to properly animate now. (Issue#77)

  • Fixed BG Arm flailing when reloading one-handed weapon, so shields are no longer so useless.

  • Fixed crash when clearing an already empty preset list in the buy menu.

  • Temporary fix for low mass attachables/emitters being thrown at ridiculous speeds when their parent is gibbed.

  • The audio system now better supports splitscreen games, turning off sound panning for them and attenuating according to the nearest player.

  • The audio system now better supports wrapping maps so sounds handle the seam better. Additionally, the game should be able to function if the audio system fails to start up.

  • Scripts on attached attachables will only run if their parent exists in MovableMan. (Issue #83)

Removed
  • Removed all Gorilla Audio and SDL Mixer related code and files.

  • Removed all Steam Workshop and Achievement related code.

  • Removed a bunch of outdated/unused sources in the repo.

  • Removed all OSX/Linux related code and files because we don't care. See Liberated Cortex for working Linux port.

  • Removed a bunch of low-level FrameMan lua bindings:
    FrameMan:ResetSplitScreens, FrameMan:PPM setter, FrameMan:ResX/Y, FrameMan:HSplit/VSplit, FrameMan:GetPlayerFrameBufferWidth/Height, FrameMan:IsFullscreen, FrameMan:ToggleFullScreen, FrameMan:ClearBackbuffer8/32, FrameMan:ClearPostEffects, FrameMan:ResetFrameTimer, FrameMan:ShowPerformanceStats.

  • Native fullscreen mode has been removed due to poor performance compared to windowed/borderless mode and various input device issues.
    The version of Allegro we're running is pretty old now (released in 2007) and probably doesn't properly support/utilize newer features and APIs leading to these issues.
    The minimal amount of hardware acceleration CC has is still retained through Windows' DWM and that evidently does a better job.

  • Removed now obsolete Settings.ini properties:
    Post-processing: TrueColorMode, PostProcessing, PostPixelGlow.
    Native fullscreen mode: Fullscreen, NxWindowed, NxFullscreen, ForceSoftwareGfxDriver, ForceSafeGfxDriver.


0.1.0 pre-release 1 - 2020/01/27

Added
  • You can now run the game with command line parameters, including -h to see help and -c to send ingame console input to cout.

  • MOSprite now has the FlipFactor property that returns -1 if the sprite is flipped and 1 if it's not.
    Using any nugNum calculations based on HFlipped is now considered criminal activity.

  • TDExplosive now has the IsAnimatedManually property that lets modders set its frames manually through lua.

  • You can now add AEmitters to MOSRotating and have them function similarly to attachables.
    Addition: parent:AddEmitter(emitterToAdd) or parent:AddEmitter(emitterToAdd, parentOffsetVector)
    Removal: parent:RemoveEmitter(emitterToRemove) or parent:RemoveEmitter(uniqueIdOfEmitterToRemove)

  • Attachables can now collide with terrain when attached.
    INI property: CollidesWithTerrainWhenAttached = 0/1
    Check value: attachable.IsCollidingWithTerrainWhileAttached
    Manipulate function: attachable:EnableTerrainCollisions(trueOrFalse)
    Collisions can be manipulated only if the attachable was set to CollidesWithTerrainWhenAttached = 1 in ini.

  • Actor.DeathSound is now accessible to lua using Actor.DeathSound = "string pathToNewFile" or Actor.DeathSound = nil for no DeathSound.

  • AHuman Feet are now accessible to lua using AHuman.FGFoot and AHuman.BGFoot. Interaction with them may be wonky.

  • Streamlined debug process and requirements so old Visual C++ Express edition is no longer needed for debugging.

  • Added minimal debug configuration for quicker debug builds without visualization.

Changed
  • ACrab aim limits now adjust to crab body rotation.

  • ACrab.AimRange can now be split into AimRangeUpperLimit and AimRangeLowerLimit, allowing asymmetric ranges.

  • Objective arrows and Delivery arrows are now color coordinated to match their teams, instead of being only green or red.

  • BuyMenu Bombs tab will now show all ThrownDevices instead of just TDExplosives.

  • The list of MOSRotating attachables (mosr.Attachables) now includes hardcoded attachables like dropship engines, legs, etc.

  • Attachable lua manipulation has been significantly revamped. The old method of doing attachable:Attach(parent) has been replaced with the following:
    Addition: parent:AddAttachable(attachableToAdd) or parent:AddAttachable(attachableToAdd, parentOffsetVector)
    Removal: parent:RemoveAttachable(attachableToRemove) or parent:RemoveAttachable(uniqueIdOfAttachableToRemove)

  • Wounds have been separated internally from emitter attachables.
    They can now be added with parent:AddWound(woundEmitterToAdd).
    Removing wounds remains the same as before.

  • Built-in Actor angular velocity reduction on death has been lessened.

Fixed
  • SFX slider now works properly.

  • BGM now loops properly.

  • Sound pitching now respects sounds that are not supposed to be affected by pitch.

  • Using actor:Clone() now works properly, there are no longer issues with controlling/selecting cloned actors.

  • TDExplosive.ActivatesWhenReleased now works properly.

  • Various bug fixed related to all the Attachable and Emitter changes, so they can now me affected reliably and safely with lua.

  • Various minor other things that have gotten lost in the shuffle.

Removed
  • All licensing-related code has been removed since it's no longer needed.

  • Wounds can no longer be added via ini, as used to be doable buggily through ini AddEmitter.

  • All usage of the outdated Slick Profiler has been removed.

  • TDExplosive.ParticleNumberToAdd property has been removed.


Note: For a log of changes made prior to the commencement of the open source community project, look here.