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
-
Added in-game pause menu when pressing
Esc. PressingShift + Escwill skip this menu and pause into scenario/conquest menu. -
Added a save/load game menu which can be accessed from the main or pause menus, which allows the user to save their current progress in an activity to resume at a later date.
-
Massive performance improvements, especially in very large scenes with lots of actors.
-
New multithreaded AI and Lua scripts. Lua scripts now have extra callback functions
ThreadedUpdateAI(self),ThreadedUpdate(self)andSyncedUpdate(self).
TheThreadedcallback functions are run in a multithreaded fashion, whereasUpdateruns in a singlethreaded fashion (where it's safe to modify global state or affect other objects).
TheSyncedUpdatecallback is called in a single-threaded fashion, but only when an MO directly requests it by callingself:RequestSyncedUpdate(). This gives greater performance, as the script can avoid any single-threaded updates being called on it until it explicitly needs it. -
New generic Lua messaging system, to allow scripts on objects to communicate with other objects or scripts. Scripts on
MovableObjectnow have new callback functionsOnMessage(self, message, context)andOnGlobalMessage(self, message, context).
Script onActivityalso have similar functions:ActivityName:OnMessage(message, context)andActivityName:OnGlobalMessage(message, context).
TheOnMessagecallback will be triggered whenever theSendMessage(message, context)is called on an object, i.eObject:SendMessage("Hello World").
Thiscontextargument can be anything, like a table, string or number. It will be nil if left out of the SendMessage function call. TheOnGlobalMessagecallback works the exact same way, however global messages are sent to every object within the game, instead of a specific object.
To send a global message, useMovableMan:SendGlobalMessage(message, context). -
New
AEJetpacktype, which replaces the old technique ofACrab/AHumanusing anAEmitteras a jetpack. This type inherits fromAEmitter.
New INI and Lua (R/W) propertyJetpackType, which can be eitherAEJetpack.StandardorAEJetpack.JumpPack. Standard acts the same as the typical jetpack, whereas JumpPacks can only be activated when fully recharged, and fires all of it's fuel in one burst. Defaults to Standard.
New INI and Lua (R/W) propertyMinimumFuelRatio, which defines the ratio of current fuel to max fuel that has to be met to fire the jetpack. Defaults to 0 for Standard and 0.25 for JumpPacks.
New INI and Lua (R/W) propertyCanAdjustAngleWhileFiring, which defines whether the jet angle can change while the jetpack is active. Defaults to true.
New INI and Lua (R/W) propertyAdjustsThrottleForWeight, which defines whether the jetpack will adjust it's throttle (betweenNegativeThrottleMultiplierandPositiveThrottleMultiplier) to account for any extra inventory mass. Increased throttle will decrease jet time accordingly. Defaults to true. -
Multithreaded asynchronous pathfinding, which dramatically improves performance on large maps and improves AI responsiveness. New
ActorLua property (R)IsWaitingOnNewMovePath, which returns true while the actor is currently calculating a new path.
New LuaSceneManfunctionCalculatePathAsyncfor asynchronous pathfinding. This function has no return value, and is used as follows:SceneMan.Scene:CalculatePathAsync( function(pathRequest) -- Callback function that is run when the path has finished calculating, passing in the pathRequest object. pathRequest.Path; -- A list of Vectors that make up the calculated path. pathRequest.PathLength -- The number of points in the calculated path. pathRequest.Status; -- The enum status of the path, the options are PathRequest.Solved, PathRequest.NoSolution, and PathRequest.StartEndSame. pathRequest.TotalCost; -- The total cost of path. end, -- All other arguments are the same as Scene:CalculatePath(): startPos, -- The start position of the path to calculate. endPos, -- The end position of the path to calculate. movePathToGround, -- Whether or not to move the points in the calculated path to ground level. digStrength, -- The dig strength to use when calculating the path. team -- The team to use when calculating the path, allowing the path to ignore that team's doors. If not specified, it will default to `Activity.NOTEAM`, and no doors will be ignored. );
-
New FMOD and SoundContainer features:
The game is now divided into SFX, UI, and Music busses which all route into the Master bus.
The SFX bus has compression added for a better listening experience, and a safety volume limiter has been added to the Master bus.
Aside from volume being attenuated, sounds will now also be lowpass filtered as distance increases.
NewSoundContainerINI and Lua (R/W) propertyBusRouting, which denotes which bus the SoundContainer routes to. Available busses:SFX, UI, Music. Defaults toSFX.
Enumbinding forSoundContainer.BusRouting:SFX = 0, UI = 1, MUSIC = 2.
NewSoundContainerINI and Lua (R/W) propertyPanningStrengthMultiplier, which will multiply the strength of 3D panning. This can be used to achieve for example a psuedo-Immobile effect where attenuation effects are still applied but the sound does not move from the center. Recommended to keep between 0.0 and 1.0.
NewSoundContainerINI and Lua (R/W) propertyCustomPanValue, which hard-overrides the panning of a sound. Clamped between -1 and 1 for left and right panning. 0 disables the override and will re-enable default behavior. This should probably only be used on Immobile sounds, but it can be used on any sound. No guarantees. -
Tracy profiler integration.
You can now attach Tracy to builds of the game and see profiling information about various zones and how long they take.
This can also be used to profile specific lua scripts, with the following functions:
tracy.ZoneBegin(),tracy.ZoneEnd()to profile a block of code.
tracy.ZoneBeginN(text)to begin a custom named zone, andtracy.ZoneName(text)to dynamically set the current zone name on a per-call basis.
tracy.Message(text)to send a tracy message.
Lua scripts without any tracy documentation are still profiled by tracy, however only at a granularity of how long the entire script takes to execute. -
New
HeldDeviceLua functionIsBeingHeld, which returns whether or not theHeldDeviceis currently being held. -
New
HeldDeviceINI and Lua (R/W) propertyGetsHitByMOsWhenHeld, which defines whether thisHeldDevicecan be hit by MOs while equipped and held by an actor. Defaults to false. -
New
MovableObjectINI and Lua (R/W) propertyIgnoresActorHits, which defines whether thisMovableObjectshould ignore collisions with actors. Defaults to false. -
New
HeldDeviceINI and Lua (R/W) propertyVisualRecoilMultiplier, which defines how much the recoil animation should be scaled for this weapon (without affecting SharpAim). Defaults to 1.0. -
New
HeldDeviceINI and Lua (R/W) propertyUseSupportOffsetWhileReloading, which defines whether the off-hand should stay at the weapon's support offset when reloading. Defaults to false. -
New
HDFirearmINI and Lua (R/W) propertyReloadEndOffset, to define how many milliseconds prior to the reload being complete that theReloadEndSoundshould play. Defaults to -1, which means the game will automatically calculate so that the middle of the sound is aligned with the reload completing. -
New
ActorINI and Lua (R/W) propertyPainThreshold, which determines how much damage this actor must take in a frame to play theirPainSound. This can be set to 0 to never manually play the sound. Defaults to 15. -
New
AHumanINI and Lua (R/W) propertyMaxWalkPathCrouchShift, which determines how much the actor will automatically duck down to avoid low ceilings above them. This can be set to 0 to never duck. Defaults to 6. -
New
AHumanINI and Lua (R/W) propertyMaxCrouchRotation, which determines how much the actor will rotate when ducking to avoid low ceilings above them. This can be set to 0 to never duck. Defaults to a quarter of Pi * 1.25 (roughly 56 degrees). -
New
AHumanLua (R/W) propertyCrouchAmountOverride, which enforces that the actor crouch a certain amount, where 0 means fully standing and 1 is fully crouching. This override can be disabled by setting it to -1.0. -
New
AHumanLua (R) propertyCrouchAmount, which returns how much the actor is crouching, where 0 means fully standing and 1 is fully crouching. -
New
MOPixelINI and Lua (R/W) propertyStaininess, which defines how likely a pixel is to stain a surface when it collides with it. Staining a surface changes that surface'sColorto that of thisMOPixel, without changing the underlying material. Value can be between 0 and 1. Defaults to 0 (never stain). -
New
ActivityINI and Lua (R/W) propertyAllowsUserSaving, which can be used to enable/disable manual user saving/loading. This defaults to true for allGAScriptedwith anOnSave()function, but false otherwise. LuaActivityMan::SaveGame()function now forces a save even ifAllowsUserSavingis disabled. This allows mods and scripted gamemodes to handle saving in their own way (for example, only allowing saving at set points). -
New
AEmitterandPEmitterLua functions:
JustStartedEmitting(), which returns whether the emitter just started emitting this frame.
WasEmitting(), which returns whether the emitter was emitting last frame. -
New
AEmitterandPEmitterINI properties:
SustainBurstSound, which determines whether the burst sound should sustain and play until completion even when the emitter stops emitting, or if it cuts out with the emitter. Defaults to false.
BurstSoundFollowsEmitter, which determines whether the burst sound follows the emitter or keeps playing where the burst occurred. Defaults to true. -
New
SLTerrainINI propertyOrbitDirection, which defines which direction is considered to be orbit, for the sake of brain-path-to-orbit, dropship spawn/return location, etc. Can be any ofUp,Down,LeftorRight. Defaults toUp. -
New
ActorLua functionRemoveInventoryItemAtIndex, with removes theMovableObjectinventory item at a given index and returns. -
New
SceneLua functionsAddNavigatableArea(areaName)andClearNavigatableAreas(). This can be used to restrict pathfinding to only search a set of areas that have been added to the scene before viaScene:SetArea(area). -
New
ADoorLua functionResetSensorTimer(). Resets the sensor timer for that door, making it take the full SensorInterval again for it to detect actors. -
Exposed
SceneObjectpropertyBuyableModeto Lua (R). -
Enumbinding forSceneObject.BuyableMode:NORESTRICTIONS = 0, BUYMENUONLY = 1, OBJECTPICKERONLY = 2, SCRIPTONLY = 3. -
Exposed
UInputMan::AbsoluteMousePosto Lua -
New
GameActivity::LockControlledActorLua function to allow grab player input in the way menus (buy menu/full inventorymenu) do.
Changed
-
Unofficial modules (mods) now use Semantic Versioning to check which version of the game they target.
As such, theIndex.inipropertySupportedGameVersionmust now be a valid semantic version number. The game version has also been updated to match this standard.The
SupportedGameVersionversion number must be of the formX.Y.z, where:Xmatches the major version of the game,
Yis the minimum minor version of the game the mod requires,
zis the patch number, which is currently not enforced.Mods published for any development builds must match that development version exactly.
-
Pressing F2 to reload scripts now also reloads the scripts for all MOs currently in the scene.
-
Various optimizations to improve Lua performance.
-
Lua
Scene.ScenePathproperty has been changed to a functionScene:GetScenePath(). This was done for thread-safety with multithreading, but can be used in the same way. -
CameraMan::SetScrollTarget()function has had thetargetWrappedparameter removed, as it's not necessary. The camera will always focus taking the shortest path regardless now. The new full function signature isCameraMan::SetScrollTarget(target, speed, screenId), where speed defaults to 0.1 and screenId defaults to 0. -
Actors will now play their pain sound from any source of significant damage, instead of specifically when taking damage from colliding with terrain.
-
Gibbing objects will now inherit the velocity from the impulse that caused them to gib, meaning that gibs will be thrown away from the explosion or source of damage that caused it.
-
The
AHuman/ACrabpropertyJetpacknow takes anAEJetpack, instead of anAEmitter. -
The following properties have all been moved from
AHuman/ACrabtoAEJetpack:
JetTime
JetReplenishRate
JetAngleRange
JetTimeTotal
JetTimeLeft -
Improved loading times on large maps.
-
Script values, i.e
GetStringValue,RemoveStringValue,StringValueExistsand the associated functions forGetNumberValue/GetObjectValue, have been moved from MOSRotating to MovableObject, so now any object with script support can use these values. -
The
SceneObjectpropertyIsBuyablehas been renamed toBuyable.
Fixed
-
Fixed music resuming from incorrect position when unpausing.
-
Camera wrapping now works correctly on scenes which are both X and Y wrapped.
-
Fixed extreme lag in the Decision Day scenario.
-
Fixed Lua
UInputMan:MouseButtonPressed,UInputMan:MouseButtonHeld(mouseButton)andUInputMan:MouseButtonReleased(mouseButton)functions not working. Please note that this should take an enum of typeMouseButtons, i.eMouseButtons.MOUSE_LEFT, not a number. -
Fixed a rare crash bug that could occur when under extreme CPU load.
-
Fixed a bug where dropships that were non-empty would slowly drop down over time.
-
Fixed a bug where AI pathfinding would choose unoptimal routes.
-
Fixed a crash that could occur when scripted objects were deleted, particularly when switching scene.
Removed
- Removed RealToSimCap and OneSimUpdatePerFrame. Instead we try to always target 60fps, even if it slows the simulation down a little.
0.1.0 pre-release 5.0 - 2023/06/17
Added
-
New INI
HDFirearmpropertyLegacyCompatibilityRoundsAlwaysFireUnflipped. This is used to make guns fire their projectiles unflipped, like they used to in old game versions, and should only be turned on forHDFirearmsin old mods that need it. -
New INI and Lua (R)
HDFirearmpropertyInheritsFirerVelocity, which determines whether or not the particles in aRoundshould inherit their firer's velocity. Defaults to true to preserve normal behavior. -
New INI
BuyableModesettingBuyableMode = 3for script only items.
This makes the item unable to be bought by any player at all as if it wereBuyable = 0, but without removing the item from theCreateRandomLua functions that the AI and activities use.
That way players can still find these weapons used by activities and AI enemies, and modders can have big arsenals, without actually having big arsenals. -
New
DataModuleINI propertySupportedGameVersionto 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, andOnReload(self, hadMagazineBeforeReload)that triggers when the gun is reloaded. -
New
MOSRotatingINI and Lua (R/W)MOSRotatingpropertyGibAtEndOfLifetimethat, when set to true, will make theMOSRotatinggib if its age exceeds its lifetime, rather than deleting as it normally would. -
New
ActorINI propertiesOrganic = 0/1andMechanical = 0/1and supporting Lua functionsActor:IsOrganic()andActor: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 anActoris organic or mechanical, and treat them accordingly. -
New INI and Lua (R/W)
ACDropShippropertyHoverHeightModifier. This allows for modification of the height at which anACDropShipwill hover when unloading cargo, or staying at a location. -
New
SceneLua propertyBackgroundLayers(R/O) to access an iterator of theScene'sSLBackgroundlayers. -
SLBackgroundlayers can now be animated using the same INI and Lua animation controls as everything else (FrameCount,SpriteAnimMode, etc). (Issue #66)
The collection of theScene's background layers can be accessed viascene.BackgroundLayers. -
Added
SLBackgroundauto-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 = intValueslBackground:IsAutoScrolling()- (R/O) returns whether auto-scrolling is actually in effect on either axis (meaning eitherWrapXandCanAutoScrollXorWrapYandCanAutoScrollYare true).The collection of the
Scene's background layers can be accessed viascene.BackgroundLayers. -
New
Settings.inipropertySceneBackgroundAutoScaleMode = 0/1/2. (Issue #243)
Auto-scaling modes are: 0 = Off, 1 = Fit Screen, 2 = Always 2x.
This will auto-scale allScenebackground 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 theSLBackgroundINI propertyIgnoreAutoScaling, otherwise it may be excessively scaled up to 2x (maximum).
Note that anyScaleFactordefinitions 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
SLBackgroundINI propertyIgnoreAutoScaling = 0/1to ignore the global background layer auto-scaling setting and use theScaleFactordefined in the preset, if any. -
New
SLBackgroundINI propertyOriginPointOffsetto offset the layer from the top left corner of the screen. -
Added new
TerrainDebrisscattering 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
Materialbackground textures with INI propertyBGTextureFile. -
New
MovableObjectINI and Lua (R/W) propertySimUpdatesBetweenScriptedUpdates, that letsMovableObjects run their Lua update function less frequently, for performance benefits. -
Added faction themes.
Faction themes apply to theBuyMenuwhen 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'sIndex.ini(before anyIncludeFilelines) 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 = pathToLogoImageAll properties are optional, any combination works.
The skin and background color are also applied to theObjectPicker(scene object placer) for visual consistency. -
New
Settings.inipropertyDisableFactionBuyMenuThemes = 0/1which will cause custom faction theme definitions in all modules to be ignored and the default theme to be used instead. -
New
Settings.inipropertyDisableFactionBuyMenuThemeCursors = 0/1which will cause custom faction theme cursor definitions in all modules to be ignored and the default cursors to be used instead. -
New
Settings.iniandSceneManLua (R/W) propertyScrapCompactingHeightwhich determines the maximum height of a column of scrap terrain to collapse when the bottom pixel is knocked loose. 0 means no columns of terrain are ever collapsed, much like in old builds of CC. -
New
DataModuleINI and Lua (R/O) propertyIsMerchantwhich 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.iniShowForeignItems) gameplay setting is disabled.Note that this property takes priority over the
IsFactionproperty. A module that is set as bothIsFaction = 1andIsMerchant = 1will be treated asIsFaction = 0. -
Made
VectorpropertiesAbsRadAngleandAbsDegAnglewritable, so you can set aVector's direction directly, instead of rotating it by an angle viaRadRotateandDegRotate. -
New
HDFirearmLua functionGetNextMagazineName(), that gets the name of the nextMagazineto be loaded into theHDFirearm. -
New INI and Lua (R/W)
ActorpropertyPieMenu. This allows you to set anActor'sPieMenuvia INI and Lua. If no value is set for this, the defaultPieMenufor the type ofActorwill be used, these can be found inBase.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 likeCopyOfandPresetName, 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 owningActorfor thePieMenu, if there is one.
Controller(R) - Gets theControllercontrolling thePieMenu. If there's anActorowner, it'll be thatActor'sController, otherwise it's probably a generalControllerused for handling in-game menu inputs.
AffectedObject(R) - Gets the affectedMovableObjectfor thePieMenuif there is one. Support isn't fully here for it yet, butPieMenus can theoretically be made to affect objects that aren'tActors.
Pos(R) - Gets the position of the center of thePieMenu. Generally updated to move with itsOwnerorAffectedObject.
RotAngle(R/W) - Gets/sets the rotation of thePieMenu. Note that changing this may cause oddities and issues, especially if thePieMenuis currently visible.
FullInnerRadius(R/W) - Gets/sets the inner radius of thePieMenu, i.e. the radius distance before the inside of the ring.
PieSlices- Gets all of thePieSlices in thePieMenufor iterating over in a for loop.IsEnabled()- Gets whether or not thePieMenuis enabled or enabling.
IsEnabling()- Gets whether or not thePieMenuis currently enabling.
IsDisabling()- Gets whether or not thePieMenuis currently disabling.
IsEnablingOrDisabling()- Gets whether or not thePieMenuis currently enabling or disabling.
IsVisible()- Gets whether or not thePieMenuis currently visible (i.e. not disabled).
HasSubPieMenuOpen()- Gets whether thePieMenuhas a sub-PieMenuopen, and is thus transferring commands to that sub-PieMenu.
SetAnimationModeToNormal()- Sets thePieMenuback to normal animation mode, and disables it so it's ready for use.
DoDisableAnimation()- Makes thePieMenudo its disabling animation.
Wobble()- Makes thePieMenudo its wobbling animation.
FreezeAtRadius(radius)- Makes thePieMenufreeze open at the given radius.
GetPieCommand()- Gets the command given to thePieMenu, either by pressing aPieSlicebutton, or by selecting aPieSliceand closing thePieMenu.
GetFirstPieSliceByPresetName(presetName)- Searches through thePieSlices in thePieMenuand returns the first one with the givenPresetName.
GetFirstPieSliceByType(pieSliceType)- Searches through thePieSlices in thePieMenuand returns the first one with the givenPieSliceType.AddPieSlice(pieSliceToAdd, pieSliceOriginalSource, optional_onlyCheckPieSlicesWithSameOriginalSource, optional_allowQuadrantOverflow)- Adds the givenPieSliceto thePieMenu, returning whether or not thePieSlicewas added.
ThepieSliceOriginalSourceis the object that added thePieSliceto thePieMenu, and it's very important you set this properly (much of the time you'll want it to beselfif, say, you have a gun adding aPieSlice), otherwise you can end up with ghostPieSlices.
allowQuadrantOverflowis optional and defaults to false, it determines whether thePieSlicecan only be added in its specified direction (false), or if it can overflow if that direction is full ofPieSlices (true).AddPieSliceIfPresetNameIsUnique(pieSliceToAdd, pieSliceOriginalSource, optionalAllowQuadrantOverflow)- LikeAddPieSlice, this adds the givenPieSliceto thePieMenuand returns whether or not thePieSlicewas added, but only if thePieMenudoesn't contain aPieSlicewith thisPieSlice's preset name, optionally only checkingPieSlices with the same original source (by default it checks allPieSlices in thePieMenu).
PieSlices with no preset name will always be added by this.RemovePieSlice(pieSliceToRemove)- Removes the givenPieSlicefrom thePieMenu, and returns it to Lua so you can add it to anotherPieMenuif you want.
RemovePieSlicesByPresetName(presetNameToRemoveBy)- Removes anyPieSlices with the given preset name from thePieMenu. Note that, unlikeRemovePieSlice, thePieSliceis not returned, since multiplePieSlicescan be removed this way. Instead, this returns true if anyPieSlices were removed.
RemovePieSlicesByType(pieSliceTypeToRemoveBy)- Removes anyPieSlices with the givenPieSliceTypefrom thePieMenu. Note that, unlikeRemovePieSlice, thePieSliceis not returned, since multiplePieSlicescan be removed this way. Instead, this returns true if anyPieSlices were removed.
RemovePieSlicesByOriginalSource(originalSource)- Removes anyPieSlices with the original source from thePieMenu. Note that, unlikeRemovePieSlice, thePieSliceis not returned, since multiplePieSlicescan be removed this way. Instead, this returns true if anyPieSlices were removed.**
ReplacePieSlice(pieSliceToReplace, replacementPieSlice)** - Replaces the specifiedPieSliceto replace, if it exists in thePieMenu, with the replacementPieSliceand returns the replacedPieSlicefor use (e.g. for adding to a differentPieMenu). The replacementPieSlicetakes the replacedPieSlice`'s original source, direction, middle slice eligibility, angles and slot count, so it seamlessly replaces it. -
PieSlices have been modified to supportPieMenus being defined in INI. They have the following properties:Type(INI, Lua R/W) - Gets or sets thePieSlice's type, useful for invoking hardcoded game actions (e.g. pickup).
Direction(INI, Lua R/W) - Gets or sets thePieSlice's direction, i.e what direction thePieSliceshould be added in to aPieMenu. Defaults toAny, 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 thePieSlicefor it to take effect.
CanBeMiddleSlice(INI, Lua R/W) - Gets or sets whether or not thisPieSlicecan be the middle slice (i.e. a cardinal one like reload) in its direction, when added to aPieMenu. Defaults to true. Note that if you set this via Lua, you will need to remove and readd thePieSlicefor it to take effect.
Enabled(INI, Lua R/W) - Gets or sets whether or not thisPieSliceis enabled and usable.
ScriptPath(INI, Lua R/W) - Gets or sets the filepath to the script that should be run when thisPieSliceis 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 thisPieSliceis activated. A script path is also required for this to work.
SubPieMenu(INI Lua R/W) - Gets or sets the sub-PieMenuthat should be opened when thisPieSliceis activated. Note thatPieSlices with sub-PieMenus will not perform any other actions, though they will run scripts.
Icon(INI) - The icon for thisPieSliceto show in itsPieMenu.
OriginalSource(Lua R) - The object that added thisPieSliceto itsPieMenu. -
Added
Directionsenum with the following values:(-1) None (0) Up (1) Down (2) Left (3) Right (4) Any -
Added
GameActivityINI propertyBuyMenuEnabledto match the Lua property, and made the buy menuPieSlicedisappear ifBuyMenuEnabledis false.
Note that, if you toggle this from off to on in Lua for a runningGameActivity, you'll need to re-add the buy menuPieSlicemanually. -
Added
ControllerLua functionIsGamepadControlled(), that lets you tell if aControlleris being controlled by any of the gamepad inputs, much like the pre-existingIsMouseControlled()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. -
Added rotation option to Text primitives.
New bindings with argument for rotation are:
PrimitiveMan:DrawTextPrimitive(pos, text, bool useSmallFont, alignment, rotAngleInRadians)
PrimitiveMan:DrawTextPrimitive(player, pos, text, bool useSmallFont, alignment, rotAngleInRadians)
Original bindings with no rotation argument are untouched and can be called as they were. -
Added option to draw bitmap from file instead of from
MOSPritebased object to Bitmap primitives.
New bindings with argument for file path are:
PrimitiveMan:DrawBitmapPrimitive(pos, filePath, rotAngleInRadians)
PrimitiveMan:DrawBitmapPrimitive(pos, filePath, rotAngleInRadians, hFlipped, vFlipped)
PrimitiveMan:DrawBitmapPrimitive(player, pos, filePath, rotAngleInRadians)
PrimitiveMan:DrawBitmapPrimitive(player, pos, filePath, rotAngleInRadians, hFlipped, vFlipped)
Note that theframeargument does not exist in these bindings.
Original bindings with no filepath argument are untouched and can be called as they were. -
Added new primitive drawing functions to
PrimitiveMan:-- Polygon PrimitiveMan:DrawPolygonPrimitive(Vector startPos, color, { Vector vertexRelPos, ... }) PrimitiveMan:DrawPolygonPrimitive(player, Vector startPos, { Vector vertexRelPos, ... }) PrimitiveMan:DrawPolygonFillPrimitive(Vector startPos, color, { Vector vertexRelPos, ... }) PrimitiveMan:DrawPolygonFillPrimitive(player, Vector startPos, { Vector vertexRelPos, ... })
The vertices table contains
Vectors with the position of each vertex of the polygon RELATIVE to the starting position. The starting position will be automatically added to each vertex position, doing so manually will lead to unexpected results.
A minimum of 2 vertices (which would result in a line) are required to draw a polygon primitive. A console error will be printed and drawing will be skipped if less are provided.
There may be a limit for the number of vertices inPolygonFillPrimitivebecause it has different handling but it was not reached during testing.The order of vertices is of high importance. Bad ordering will lead to unexpected results.
For example:{ Vector(10, 0), Vector(10, 10), Vector(0, 10), Vector(0, 0) }will result in a square, while{ Vector(10, 0), Vector(0, 10), Vector(10, 10), Vector(0, 0) }will result in an hourglass shape.
Note that all vertices of the shape must be specified, as the last vertex will be connected to the first vertex and not to the starting position (whether it is used as center or as a corner) to complete the shape.
Omitting the lastVector(0, 0)in the above example would result in a right angle triangle.The
Vectors in the vertices table are single use! They will be deleted after being drawn, so they cannot be re-used!Usage example:
local myVertices = { Vector(10, 0), Vector(10, 10), Vector(0, 10), Vector(0, 0) }; PrimitiveMan:DrawPolygonPrimitive(self.Pos, 13, myVertices); -- myVertices no longer contains valid Vectors for this call, they were deleted after being drawn by the previous call. PrimitiveMan:DrawPolygonFillPrimitive(self.Pos, 13, { Vector(10, 0), Vector(10, 10), Vector(0, 10), Vector(0, 0) });
-
Added blended drawing functions to
PrimitiveMan:
There are 10 blending modes available to produce different color and transparency effects for both true primitives and bitmap based primitives.
Blended drawing effects are not the same as post-processing (glows), as they are all drawn in indexed color mode and will produce widely different results.Note that blended drawing is very expensive and chugs FPS like no tomorrow. It should not be abused!
There are 3 blended drawing function overloads:
-
PrimitiveMan:DrawPrimitives(blendMode, blendAmountR, blendAmountG, blendAmountB, blendAmountA, { primitiveObj, ... })
This is the fully fledged blended drawing function which allows individual control over each color channel blend amount.
Blend amounts are in percentages, where 0 means no blending and 100 means full blending (e.g.blendAmountA = 100will result in a fully transparent primitive, as if it was not drawn at all).
The blend mode and amounts will be applied to all the primitives in the primitive table.
Note that blend amounts are internally rounded to multiples of 5 (e.g. 32 will round to 30, 33 will round to 35) to reduce memory usage and because smaller steps are hardly noticeable. -
PrimitiveMan:DrawPrimitives(blendMode, blendAmountRGBA, { primitiveObj, ... })
This overload allows selecting a blend mode and applies the blend amount to all color channels at once.
This overload is for convenience when using certain modes (e.g.InvertandDissolve). See blend mode specifics further below. -
PrimitiveMan:DrawPrimitives(transBlendAmount, { primitiveObj, ... })
This overload uses the transparency blending mode and applies the blend amount to all color channels at once.
Transparency blending is likely to be the most commonly used mode so this exists for convenience.
The blending modes are defined in the new
DrawBlendModeenum as follows:(0) NoBlend (1) Burn (2) Color (3) Difference (4) Dissolve (5) Dodge (6) Invert (7) Luminance (8) Multiply (9) Saturation (10) Screen (11) Transparency (12) BlendModeCountThe blending modes are common and information on what the result of each is can be found with a quick search.
Some blend mode specifics:
InvertandDissolvemodes only use alpha channel blend amount. RGB channels blend amounts are ignored in these modes.Transparencymode ignores alpha channel blend amount. Only RGB channels blend amounts are used in this mode.- Some trial and error is expected to produce desired results in other modes.
The primitives table must be filled with
GraphicalPrimitiveobjects. For this the constructors for all the supported primitives have been exposed:LinePrimitive(player, startPos, endPos, color) ArcPrimitive(player, centerPos, startAngle, endAngle, radius, thickness, color) SplinePrimitive(player, startPos, guideA, guideB, endPos, color) BoxPrimitive(player, topLeftPos, bottomRightPos, color) BoxFillPrimitive(player, topLeftPos, bottomRightPos, color) RoundedBoxPrimitive(player, topLeftPos, bottomRightPos, cornerRadius, color) RoundedBoxFillPrimitive(player, topLeftPos, bottomRightPos, cornerRadius, color) CirclePrimitive(player, centerPos, radius, color) CircleFillPrimitive(player, centerPos, radius, color) EllipsePrimitive(player, centerPos, horizRadius, vertRadius, color) EllipseFillPrimitive(player, centerPos, horizRadius, vertRadius, color) TrianglePrimitive(player, pointA, pointB, pointC, color) TriangleFillPrimitive(player, pointA, pointB, pointC, color) TextPrimitive(player, pos, text, useSmallFont, alignment, rotAngle) BitmapPrimitive(player, centerPos, moSprite, rotAngle, frame, hFlipped, vFlipped) BitmapPrimitive(player, centerPos, filePath, rotAngle, hFlipped, vFlipped)
Note that
PolygonPrimitive,IconPrimitiveandLinePrimitivewith thickness do not support blended drawing.The
GraphicalPrimitives in the primitives table are single use! They will be deleted after being drawn, so they cannot be re-used!Usage example:
local myPrimitives = { CircleFillPrimitive(-1, self.Pos + Vector(-100, 0), 20, 13), BitmapPrimitive(-1, self.Pos + Vector(100, 0), "Base.rte/Craft/Rockets/MK2/RocketMK2000.png", 0, false, false) }; PrimitiveMan:DrawPrimitives(DrawBlendMode.Screen, 50, 0, 50, 0, myPrimitives); -- myPrimitives no longer contains valid primitives for this call, they were deleted after being drawn by the previous call. PrimitiveMan:DrawPrimitives(DrawBlendMode.Dissolve, 50, { CircleFillPrimitive(-1, self.Pos + Vector(-100, -100), 20, 13), BitmapPrimitive(-1, self.Pos + Vector(100, -100), "Base.rte/Craft/Rockets/MK2/RocketMK2000.png", 0, false, false) }); PrimitiveMan:DrawPrimitives(50, { CircleFillPrimitive(-1, self.Pos + Vector(-100, -200), 20, 13), BitmapPrimitive(-1, self.Pos + Vector(100, -200), "Base.rte/Craft/Rockets/MK2/RocketMK2000.png", 0, false, false) }); -- NoBlend will draw the primitives without any blending mode (solid mode). Any color channel blend amounts are ignored. PrimitiveMan:DrawPrimitives(DrawBlendMode.NoBlend, 0, 0, 0, 0, { CircleFillPrimitive(-1, self.Pos + Vector(-100, -300), 20, 13), BitmapPrimitive(-1, self.Pos + Vector(100, -300), "Base.rte/Craft/Rockets/MK2/RocketMK2000.png", 0, false, false) }); -- It is equivalent to calling the individual draw functions like so: -- PrimitiveMan:DrawCircleFillPrimitive(-1, self.Pos + Vector(-100, -200), 20, 13); -- PrimitiveMan:DrawBitmapPrimitive(-1, self.Pos + Vector(100, -200), "Base.rte/Craft/Rockets/MK2/RocketMK2000.png", 0, false, false);
-
-
New
VectorLua (R/O) propertySqrMagnitudewhich returns the squared magnitude of theVector.
Should be used for more efficient comparison withvector.SqrMagnitude > (floatValue * floatValue)overvector.Magnitude > floatValue. -
New
VectorLua 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
PresetManLua functionReloadEntityPreset(presetName, className, optionalDefinedInModule)that allows hot-reloadingEntityINI presets (along with all other entity presets referenced in the reloaded entity preset).
If theoptionalDefinedInModuleargument is not specified, the game will look through everyDataModuleto find anEntitypreset that matches the name and type.
Once anEntitypreset has been reloaded via the function, the key combinationCtrl + F2can be used to quickly reload it as many times as necessary.
Note that any changes made to theEntitypreset will not be reflected in existing copies of theEntity, 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
MOSRotatingINI propertyDetachAttachablesBeforeGibbingFromWoundsthat makesAttachablesfall off before theMOSRotatinggibs from having too many wounds, for nice visuals. Defaults to true. -
The game now supports saving and loading. The easiest way to do this is to quick-save with
F5, and quick-load withF9. Console clearing is now done withF10.ActivityMan:SaveGame(fileName) -- Saves the currently playing Scene and Activity. The save result will be printed to the console. ActivityMan:LoadGame(fileName) -- Loads and resumes a previously saved Scene and Activity.
The
Activitystart function now looks likefunction activityName:StartActivity(isNewGame). The newisNewGameparameter is true if a game is beingly newly started (or restarted), and false if it's being loaded.Scripts on
Activitiesnow have a new callback functionOnSave(in addition toCreate,Update, etc), which is called whenever a scene is saved.To support saving and loading,
Activitynow has several Lua convenience functions to for dealing with script variables:Activity:SaveNumber(stringKey, floatValue) -- Saves a float value which can later be retrieved using stringKey. Activity:LoadNumber(stringKey) -- Retrieves a previously saved float value with key stringKey. Activity:SaveString(stringKey, stringValue) -- Saves a string value which can later be retrieved using stringKey. Activity:LoadString(stringKey) -- Retrieves a previously saved string value with key stringKey.
A new
GlobalScripthas been added that will automatically save the game every three minutes. To turn it on, enable the AutosavingGlobalScriptin the main menu mod manager's Global Scripts section.
To load games saved by this script, open the console and enter the commandActivityMan:LoadGame("Autosave"), or use theCtrl + F9shortcut. -
New hardcoded
MovableObjectfunctionOnGameSave(self)that gets run for eachMovableObjectwith it when the game is saved. This can be used in tandem with custom values (forMOSRotatingsand child classes) to store data, which can be read duringCreatewhen the game is loaded. -
New Lua
AEmitterproperties:
TotalParticlesPerMinute (R/O) - The rate at which all of theEmissions of thisAEmittercombined, emit their particles.
TotalBurstSize (R/O) - The number of particles that will be emitted by all theEmissions of thisAEmittercombined, in one shot when a burst is triggered.
EmitCount (R/O) - The number of emissions emitted since emission was last enabled.
EmitOffset (R/W) - The offset (Vector) of the emission point from thisAEmitter's sprite center. -
New
PresetManLua functionReloadEntityPreset(presetName, className, optionalDefinedInModule)that allows hot-reloadingEntityINI presets (along with all other entity presets referenced in the reloaded entity preset).
If theoptionalDefinedInModuleargument is not specified, the game will look through everyDataModuleto find anEntitypreset that matches the name and type.
Once anEntitypreset has been reloaded via the function, the key combinationCtrl + F2can be used to quickly reload it as many times as necessary.
Note that any changes made to theEntitypreset will not be reflected in existing copies of theEntity, only in new ones created after the reload.
Also note that this will reload theEntity's sprites (and of all other referenced entity presets), which will be reflected immediately in all existing copies of theEntity. -
New INI and Lua (R/W)
ActorpropertyAIBaseDigStrength, used to determine the strength of the terrain theActorcan attempt to move through without digging tools. Normally used for moving through things like terrain debris and corpses. Defaults to 35. -
New optional parameter
ignoreMaterialfor Lua functionSceneMan:CastMaxStrengthRay(start, end, skip, ignoreMaterial), which allows specifying a material that the ray will ignore. Defaults to the door material, for legacy compatibility purposes. -
New
Settings.inipropertyPathFinderGridNodeSizeto define the size of the pathfinder's graph nodes, in pixels. -
New
Settings.inipropertyAIUpdateIntervalto define how often actor AI will update, in simulation updates. Higher values may give better performance with large actor counts, at a cost of AI capability and awareness.
This can be accessed via the new Lua (R/W)SettingsManpropertyAIUpdateInterval. -
New Lua (R)
TimerManpropertiesAIDeltaTimeMSandAIDeltaTimeSecsto get the time that has passed since the last AI update. -
Added
MOSRotatingINI propertyDetachAttachablesBeforeGibbingFromWoundsthat makesAttachablesfall off before theMOSRotatinggibs from having too many wounds, for nice visuals. Defaults to true. -
New
MOSRotatingLua propertyGibs(R/O) to access an iterator of theMOSRotating'sGibs. -
Expose
Gibto Lua.
You can read and write the following properties:gib.ParticlePreset = movableObject; gib.Offset = vector; gib.Count = intValue; gib.Spread = angleInRadians; gib.MinVelocity = floatValue; gib.MaxVelocity = floatValue; gib.LifeVariation = floatValue; gib.InheritsVel = bool; gib.IgnoresTeamHits = bool; gib.SpreadMode = SpreadMode;The
SpreadModeproperty accepts values from theSpreadModeenum:(0) Gib.SpreadRandom (1) Gib.SpreadEven (2) Gib.SpreadSpiralThe collection of a
MOSRotating'sGibs can be accessed viamosRotating.Gibs. -
New
Settings.inipropertyServerUseDeltaCompression = 0/1to enable delta compression in dedicated server mode which reduces bandwidth usage. Enabled by default. -
New
Settings.inipropertySubPieMenuHoverOpenDelaythat determines how long, in milliseconds,aPieSlicewith a sub-PieMenumust be hovered over for the sub-PieMenuto automatically open. Default is 1000 milliseconds. -
Added
PieSliceLua functionReloadScripts(). Works the same as theMovableObjectfunction, but forPieSlices. -
Added key combinations for resetting time scales to defaults while performance stats are visible.
Ctrl + 1to reset the time scale.
Ctrl + 3to reset theRealToSimCap.
Ctrl + 5to reset theDeltaTime. -
Added
Alt + Pkey combination for toggling advanced performance stats (graphs) visibility while performance stats are visible. -
Added new
UPS(Updates per second) measurement to the performance stats which is probably the most reliable performance indicator.
The sim update target is ~60 UPS (defined byDeltaTime).
When UPS dips due to load there will be noticeable FPS impact because more time is spent updating the sim and less time is left to draw frames before the next sim update.
When UPS dips to ~30 the FPS will be equal to UPS because there is only enough time to draw one frame before it is time for the next sim update.
When UPS is capped at the target, FPS will be greater than UPS because there is enough time to perform multiple draws before it is time for the next sim update.
Results will obviously vary depending on system performance. -
Added
LuaManLua functionsGetDirectoryList(pathToGetDirectoryNamesIn)andGetFileList(pathToGetFileNamesIn), that get the names of all directories or files at the specified file path. -
Added a new Lua scripted function for
Actors:OnControllerInputModeChange(self, previousControllerMode, previousControllingPlayer)that triggers when anActor'sController's input state changes (between AI/Player/Network control etc). This provides a script hook that fires when a player starts/stops controlling anActor. -
Added
ACrabINI properties for setting individual footAtomGroups, as opposed to setting the same footAtomGroups for bothLegson the left or right side.
These areLeftFGFootGroup,LeftBGFootGroup,RightFGFootGroupandRightBGFootGroup. -
Buy Menu Quality-of-Life improvements:
Shift-clicking an item (or Shift + Fire in keyboard-only) in the cart will now empty the entire cart.
Items in the cart will be indented to signify what actor's inventory they belong to.
Middle-clicking (or pressing the Pickup key) on an item will duplicate it. This also duplicates an actor's inventory.
You can now reorganize the cart by click-dragging. For kbd-only you can do this by holding the sharp aim key and pressing up/down. -
Added to Lua enum
ControlStatethe stateRELEASE_FACEBUTTON. -
Added screen-shake. The screen-shake strength can be tweaked or disabled in the options menu.
NewMOSRotatingINI propertyGibScreenShakeAmount, which determines how much this will shake the screen when gibbed. This defaults to automatically calculating a screen-shake amount based on the energy involved in the gib.
NewHDFirearmINI propertyRecoilScreenShakeAmount, which determines how much this weapon will shake the screen when fired. This defaults to automatically calculating a screen-shake amount based on the recoil energy.New
Settings.iniscreen-shake properties:
ScreenShakeStrength- a global multiplier applied to screen shaking strength.
ScreenShakeDecay- how quickly screen shake falls off.
MaxScreenShakeTime- the amount of screen shake time, i.e. the maximum number of seconds screen shake will happen until ScreenShakeDecay reduces it to zero.
DefaultShakePerUnitOfGibEnergy- how much the screen should shake per unit of energy from gibbing (i.e explosions), when the screen shake amount is auto-calculated.
DefaultShakePerUnitOfRecoilEnergy- how much the screen should shake per unit of energy for recoil, when the screen shake amount is auto-calculated.
DefaultShakeFromRecoilMaximum- the maximum amount of screen shake recoil can cause, when the screen shake amount is auto-calculated. This is ignored by per-firearm shake settings. -
Added new Lua manager
CameraMan, to handle camera movement. New Lua functions on CameraMan:AddScreenShake(screenShakeAmount, screen); -- Can be used to shake a particular screen. AddScreenShake(screenShakeAmount, position); -- Applies screenshake at a position in the game world. All screens looking near this position will have their screen shaken.
Several
SceneManLua functions have been moved into CameraMan. For the full list, see the Changed section below. -
Added
MovableManLua functionsGetMOsInRadius(position, radius, ignoreTeam, getsHitByMOsOnly)andGetMOsInBox(box, ignoreTeam, getsHitByMOsOnly)that'll return all of the MOs either within a circular radius of a position, or in an axis-aligned-bounding-box. TheignoreTeamparameter defaults toTeam.NOTEAM. ThegetsHitByMOsOnlydefaults to false, which will get everyMovableObject. -
SceneMansGetMOIDPixel(x, y, ignoreTeam)Lua function has a new optionalignoreTeamparameter. This defaults toTeam.NOTEAM. -
Added alternative
ActorLua functionRemoveInventoryItem(moduleName, presetName), that lets you specify the module and preset name of the inventory item, instead of just the preset name. -
Added alternative
AHumanLua functionEquipNamedDevice(moduleName, presetName, doEquip), that lets you specify the module and preset name of theHeldDeviceto equip, instead of just the preset name. -
Added Lua access (R/W) to
AttachablepropertyDeleteWhenRemovedFromParent, which determines whether the givenAttachableshould delete itself when it's removed from its current parent. -
Added Lua convenience function
RoundToNearestMultiple(num, multiple)which returns a number rounded to the nearest specified multiple.
Note that this operates on integers, so fractional parts will be truncated towards zero by type conversion. -
Added
ActorINI and Lua property (R/W)PlayerControllable, that determines whether theActorcan be swapped to by human players. Note that Lua can probably break this, by forcing theControllers ofActors that aren'tPlayerControllableto theCIM_PLAYERinput mode. -
Added alternative
MovableMan:GetClosestTeamActor(team, player, scenePoint, maxRadius, getDistance, onlyPlayerControllableActors, actorToExclude)that acts like the existing version, but allows you to specify whether or not to only getActorsthat arePlayerControllable. -
New
AttachableINI and Lua propertyIgnoresParticlesWhileAttached, which determines whether theAttachableshould ignore collisions (and penetrations) with single-atom particles. Useful for preventingHeldDevices from being destroyed by bullets while equipped. -
Added
AHumanINI and Lua (R/W) propertyDeviceArmSwayRate, that defines how muchHeldDeviceswill sway when walking. 0 is no sway, 1 directly couples sway with leg movement, >1 may be funny. Defaults to 0.75. -
Added
AHumanINI and Lua (R/W) propertyReloadOffset, that defines whereHandsshould move to when reloading, if they're not holding a supportedHeldDevice. -
Added
AHumanLua functionFirearmsAreReloading(onlyIfAllFirearmsAreReloading)which returns whether or not thisAHuman'sHeldDevicesare currently reloading. If the parameter is set to true and theAHumanis holding multipleHeldDevices, this will only return true if all of them are reloading. -
Added
AHumanLua functionReloadFirearms(onlyReloadEmptyFirearms). This behaves the same as the pre-existingReloadFirearmsfunction, but if the parameter is set to true, onlyHDFirearmsthat are empty will be reloaded. -
Added
AHumanLua property (R/W)UpperBodyState, that lets you get and set theAHuman'sUpperBodyState. If you don't know what this does, you probably don't need or want it. -
Added
AHumanLua property (R/W)MovementState, that lets you get and set theAHuman'sMovementState. If you don't know what this does, you probably don't need or want it. -
Added
AHumanLua property (R/W)ProneState, that lets you get and set theAHuman'sProneState. If you don't know what this does, you probably don't need or want it. -
Added
ActorLua property (R/W)LimbPushForcesAndCollisionsDisabled. If this is true, any of theActor'sArms andLegs won't do any movement or collide with terrain, and will just swing around with momentum. -
Added
HeldDeviceINI and Lua (R/W) propertyDualReloadable, that determines whether or not a one-handedHeldDevicecan be dual-reloaded (i.e. old reload behaviour). Note that for dual-reload to happen, both equippedHDFirearmsmust have this flag enabled. -
Added
HeldDeviceINI and Lua (R/W) propertyOneHandedReloadTimeMultiplier, that determines how much faster or slower anHeldDeviceis when reloading one-handed (i.e. if it's one-handed and the otherArmis missing, or is holding something). -
Added
HeldDeviceINI and Lua (R/W) propertySupportable, that determines whether or not aHeldDevicecan be supported by a backgroundArm. -
Added
TimerLua functionGetSimTimeLimitMS()that gets the sim time limit of theTimerin milliseconds. -
Added
TimerLua functionGetSimTimeLimitS()that gets the sim time limit of theTimerin seconds. -
Ground pressure calculations revamp. Ground pressure, by default, is now calculated using a pseudo-3d model which takes into account the depth of an object colliding with terrain. This means actors cause much less terrain deformation from walking, especially large actors walking on smooth ground.
New
AtomGroupINI propertyAreaDistributionType, with the following options:Linear // Legacy CC behaviour. This is best for long but flat objects, like guns. Circle // Calculates ground pressure assuming objects are cylindrical with a diameter equal to the object's width. This is best for roundish objects, like feet. Square // Similar to Circle, but instead assuming that the object is a cuboid with a depth equal to the object's width.New
AtomGroupINI properyAreaDistributionSurfaceAreaMultiplier. This is a multiplier to the calculated surface area, i.e how "blunt" an object is. Large values lead to objects having lower ground pressure, and so dig into the terrain less.The default values are
AreaDistributionType = CircleandAreaDistributionSurfaceAreaMultiplier = 0.5, meaning that an object is assumed to be an oval with a depth of half it's width. -
New
SceneManLua functionDislodgePixel(posX, posY)that removes a pixel of terrain at the passed in coordinates and turns it into aMOPixel. Returns the dislodged pixel as aMovableObject, ornilif no pixel terrain was found at the passed in position. -
New
HDFirearmLua propertyCanFirewhich accurately indicates whether the firearm is ready to fire off another round. -
New
HDFirearmLua propertyMSPerRoundwhich returns the minimum amount of MS in between shots, relative toRateOfFire. -
New
HDFirearmINI and Lua (R/W) propertiesReloadAngleandOneHandedReloadAnglewhich determine the width of the reload animation angle in radians, the latter being used when the device is held with no supportingArmavailable. 0 means the animation is disabled. -
New
HDFirearmLua (R) propertyCurrentReloadAnglewhich gets the reload angle being currently used. I.e. theReloadAnglewhen there's a supportingArmavailable, and theOneHandedReloadAnglewhen there isn't. -
New
HDFirearmLua propertyMSPerRoundwhich returns the minimum amount of MS in between shots, relative toRateOfFire. -
New
AttachableINI and Lua (R/W) propertyGibWhenRemovedFromParentwhich gibs theAttachablein question when it's removed from its parent.DeleteWhenRemovedFromParentwill always override this. -
New
Settings.inipropertyAutomaticGoldDepositwhich determines whether gold gathered by actors is automatically added into the team's funds. False means that gold needs to be manually transported into orbit via craft, the old school way. Enabled by default.
A noteworthy change in comparison to previous logic is that gold is no longer converted into objects, andGoldCarriedis now automatically transferred into craft upon entering them. This effectively allows the same actor to resume prospecting without having to return to orbit with the craft.
Regardless of the setting, this behavior is always disabled for AI-only teams for the time being, until the actor AI is accommodated accordingly. -
New
ActorLua functionAddGold(goldOz)which adds the passed-in amount of gold either to the team's funds, or theGoldCarriedof the actor in question, depending on whether automatic gold depositing is enabled. This effectively simulates the actor collecting gold. -
New
ActorLua functionDropAllGold()which converts all of the actor'sGoldCarriedinto particles and spews them on the ground. -
Added
Alt + F2key combination to reload all cached sprites. This allows you to see changes made to sprites immediately in-game. -
New
MovableObjectLua (R) propertyDistanceTravelledwhich returns the amount of pixels the object has travelled since its creation. -
Added
GameActivityINI propertyDefaultGoldMaxDifficulty, which lets you specify the default gold when the difficulty slider is maxed out. -
Added
HDFirearmLua (R/W) propertyBaseReloadTimethat lets you get and set theHDFirearm's base reload time (i.e. the reload time before it's adjusted for one-handed reloads where appropriate). -
Added
ActorINI and Lua property (R/W)PlayerControllable, that determines whether theActorcan be swapped to by human players. Note that Lua can probably break this, by forcing theControllers ofActors that aren'tPlayerControllableto theCIM_PLAYERinput mode. -
Added alternative
MovableMan:GetClosestTeamActor(team, player, scenePoint, maxRadius, getDistance, onlyPlayerControllableActors, actorToExclude)that acts like the existing version, but allows you to specify whether or not to only getActorsthat arePlayerControllable. -
Added new
Timerconstructorstimer = Timer(elapsedSimTimeMS)andtimer = Timer(elapsedSimTimeMS, simTimeLimitMS)that let you setupTimers more cleanly. -
Added
TimerLua (R) propertiesRealTimeLimitProgressandSimTimeLimitProgress, that get how much progress theTimerhas made towards itsRealTimeLimitorSimTimeLimit. 0 means no progress, 1.0 means the timer has reached or passed the time limit. -
New
Settings.inipropertyEnableVSyncto enable vertical synchronization. Enabled by default. -
New
Settings.inipropertyIgnoreMultiDisplaysto ignore all displays except the one the window is currently positioned at when changing resolution. -
Added Lua (R/W) properties for
ACrabAimRangeUpperLimitandAimRangeLowerLimit. INI bindings already existed and are mentioned in an earlier changelog entry. -
Added
TerrainObjectINI propertyClearChildObjectsthat lets you clear child objects when doing aCopyOfof anotherTerrainObject. -
Added
ActorLua (R) propertyMovePathEndthat gets you the last point in theActor's move path. -
Added
ActorLua (R) propertySceneWaypointsthat lets you iterate over theActor's scene waypoints. -
Added
MovableObjectLua (R) propertyHasEverBeenAddedToMovableManthat tells you whether or not theMovableObjecthas ever been added toMovableMan. -
Added alternate version of
SceneLua functionCalculatePath(startPos, endPos, movePathToGround, digStrength, team)that works as the previous one, but lets you specify the team to calculate the path for, allowing you to ignore doors on your team. -
Added
ControllerLua functionIsKeyboardOnlyControlledthat tells you whether theControlleris being controlled by keyboard only. Previously the only way to do this was to check that it's not mouse controlled and not gamepad controlled. -
Added
Controllercontrol statePIE_MENU_OPENEDthat is true for the first Update in which thePieMenuis opened. -
Added
ActivityLua functionGetPlayerController, which gets you theControllerused for GUI stuff and when there's noActorselected in anActivity. Be aware, it's very likely possible to cause problems by doing dumb things with this. -
Added
LegLua (R/W) propertyMoveSpeed, which lets you get and set theLeg'sMoveSpeedscalar, similar toArms. 1 means instant movement and 0 means no movement. -
Added
LuaManLua functionFileExists, which lets you check whether a specified file exists. Like withFileOpen, the file must be inside a folder ending in.rte. -
New
ActorLua (R) propertyDigStrength, that gets the calculated dig strength of the givenActor, based on whether or not they have any digging tools.
Changed
-
Codebase now uses the C++20 standard.
-
Dramatic performance enhancements, especially with high actor counts and large maps. FPS has been more-than-doubled.
-
Greatly reduce online multiplayer bandwidth usage.
-
Swapped MoonJIT to LuaJIT. Compiled from d0e88930ddde28ff662503f9f20facf34f7265aa.
-
Swapped to SDL2 for window management and input handling.
-
Settings.iniand player loadouts (BuyMenu presets) are now stored in theUserdatadirectory instead ofBase.rte. -
Lua scripts are now run in a more efficient way. As part of this change,
PieSlicescripts need to be reloaded likeMovableObjectscripts (i.e. usingpieSlice:ReloadScripts(), in order for their changes to be reflected in-game.
PresetMan:ReloadAllScripts()will reloadPieSlicepreset scripts, like it does forMovableObjects. -
The landing zone cursor will now show the width of the selected delivery craft.
-
Completely replaced
ScriptFilewithScriptPath. -
Changed the
VectorfunctionClampMagnitudeso its parameter order makes sense, it's nowVector:ClampMagnitude(lowerMagnitudeLimit, upperMagnitudeLimit). -
Changed the
MovableManfunctionAddItemso it now only acceptsHeldDevices and sub-classes (i.e.HDFirearm,ThrownDevice,TDExplosive), because it always expected that anyway, and it's good to enforce it. -
Scenebackground layer presets in INI are now defined asSLBackgroundrather thanSceneLayer. -
TerrainDebrisINI propertyOnlyOnSurface = 0/1replaced withDebrisPlacementMode = 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. -
MaterialINI propertyTextureFilerenamed toFGTextureFileto accommodate new background texture property. -
TerrainObjects no longer have a hard requirement forFGandMatlayer sprites. Any layer may be omitted as long as at least one is defined. -
Scenelayer 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:SetHeaderImagerenamed toSetBannerImage. -
Lua functions run by
PieSlices will now have the following signature:pieSliceFunction(pieMenuOwner, pieMenu, pieSlice). The details for these are as follows:
pieMenuOwner- TheActorowner of thisPieMenu, or theMovableObjectaffected object of it if it has no owner.pieMenu- ThePieMenuthat is being used, and is calling this function. Note that this may be a sub-PieMenu.
pieSlice- ThePieSlicethat has been activated to call this function. -
OnPieMenu(self)event function has been changed toWhilePieMenuOpen(self, openedPieMenu)and will run as long as thePieMenuis open. -
Any
Attachableon anActor(not justHeldDevices) can now have aWhilePieMenuOpen(self, openedPieMenu)function, and can addPieSlices and run functions when they're pressed. -
PieSliceIndexenum has been renamed toSliceTypeto 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 -
Major improvements to pathfinding performance and AI decision making.
-
Having the pie menu open no longer blocks user input when using mouse+keyboard or a controller.
-
MOSRotatingbased presets without anAtomGroupdefinition will now crash with error message during loading. -
Over-indentation in INI will crash with error message if detected during loading instead of skipping entire blocks or in some cases the rest of the file.
There is never a case where there should be a positive difference of more than one tab between lines, but this means that lines likeIncludeFilewhich would previously load fine even if over-indented will also crash, but you should never have those indented to begin with.Examples of structure that will cause a crash:
AddSomething = Something PresetName = Thing // Over-indented. Will crash. SomeProperty = Whatever AddSomething = Something PresetName = Thing SomeObjectProperty = Something CopyOf = Thing // Over-indented. Will crash.
-
Improve accuracy of the
MSPFmeasurement in performance stats, which also improves the accuracy of theFPSmeasurement.
TheMSPFmeasurement now displays 3 values:
Frame(previouslyMSPF) - The total frame time (game loop iteration), in milliseconds.
Update- The total time spent updating the sim during the frame (as the sim can be updated multiple times per frame), in milliseconds.
Draw- The time spend drawing during the frame, in milliseconds. -
Advanced performance stats (graphs) will now scale to
RealToSimCap. -
The keyboard shortcut for clearing the console is now
F10, sinceF5is used for quick-saving (F9quick-loads). -
BitmapPrimitivedrawing functions now acceptMOSpriteinstead ofEntityfor the object they get the bitmap to draw from.
This changes nothing regarding the bindings, but will now print an error to the console when attempting to draw a non-MOSpritebased object (e.g.MOPixel), instead of silently skipping it. -
Unless set to dual-reload, one-handed
HDFirearmswill now reload one-at-a-time. To maintain this behaviour in Lua scripts, it is recommend to useAHuman:ReloadFirearms()instead of reloadingHeldDevicesdirectly, as the latter will ignore restrictions. -
Made a lot of changes to
Arms- they can now only holdHeldDevices(and subclasses likeHDFirearmsandThrownDevices), andAHumanshave a lot ofArmanimations, including sway when walking and holding something, smootherArmmovement and reload animations.
They now have the following INI properties:MaxLength - The max length of the Arm in pixels. MoveSpeed - How quickly the Arm moves between targets. 0 means no movement, 1 means instant movement. HandIdleOffset - The idle offset this Arm's hand will move to if it has no targets, and nothing else affecting its idle offset (e.g. it's not holding or supporting a HeldDevice). IdleOffset is also allowed for compatibility. HandSprite - The sprite file for this Arm's hand. Hand is also allowed for compatibility. GripStrength - The Arm's grip strength when holding HeldDevices. Further described below, in the entry where it was added. ThrowStrength - The Arm's throw strength when throwing ThrownDevices. Further described below, in the entry where it was added. HeldDevice - Allows you to set the HeldDevice attached to this Arm.They now have the following Lua properties and functions:
MaxLength(R) - Allows getting theArm's maximum length.
MoveSpeed(R/W) - Allows getting and setting theArm's movement speed. 0 means no movement, 1 means instant movement.
HandIdleOffset(R/W) - Allows getting and setting theArm's default idle hand offset, i.e. where the hand will go when it has no targets and isn't holding or supporting anything.
HandPos(R/W) - Gets and sets the current position of the hand. Note that this will override any animations and move the hand to the position instantly, so it's generally not recommended.
HasAnyHandTargets(R) - Gets whether or not thisArmhas any hand targets, i.e. any positions theArmis supposed to try to move its hand to.
NumberOfHandTargets(R) - Gets the number of hand targets thisArmhas.
NextHandTargetDescription(R/W) - Gets the description of the next target thisArm's hand is moving to, or an empty string if there are no targets.
NextHandTargetPosition(R/W) - Gets the position of the next target thisArm's hand is moving to, orVector(0, 0)if there are no targets.
HandHasReachedCurrentTarget(R) - Gets whether or not thisArm's hand has reached its current target. This may not be reliably accessible from Lua since it can often get reset before being read from Lua, if the target has no delay. Note that this will be true if there are no targets but that hand has reached its appropriate idle offset.
GripStrength(R/W) - Gets and sets theArm's grip strength when holdingHeldDevices. Further described below, in the entry where it was added.
ThrowStrength(R/W) - Gets and sets theArm's throw strength when throwingThrownDevices. Further described below, in the entry where it was added.
HeldDevice(R/W) - Gets and sets theHeldDeviceheld by thisArm.
SupportedHeldDevice(R) - Gets theHeldDevicethisArmis supporting. For obvious reasons, this will be empty if this is not the BGArmor if it has aHeldDeviceof its own.
AddHandTarget(description, positionOnScene)- Adds a target for thisArm's hand to move to. The target goes to the back of the queue, allowing for multiple animations to be added in succession. The description is arbitrary, but useful for identification, and if the target being added has the same description as the target at the end of the queue, they will be merged to avoid duplication.
AddHandTarget(description, positionOnScene, delayAtTarget)- Adds a target for thisArm's hand to move to as above, but the hand will wait at the target for the specified amount of time.
RemoveNextHandTarget()- Removes the next hand target from the queue, if there are any.
ClearHandTargets()- Empties the queue of hand targets. Once the queue is empty, the hand will move towards its appropriate idle offset. -
The following
SceneManfunctions have been moved toCameraMan:SetOffset(offsetVector, screenId); GetScreenOcclusion(screenId); SetScreenOcclusion(occlusionVector, screenId); GetScrollTarget(screenId); SetScrollTarget(targetPosition, speed, screenId); TargetDistanceScalar(point); CheckOffset(screenId); SetScroll(center, screenId);
-
HDFirearmLua propertyReloadTimeis no longer writable. UseBaseReloadTimeinstead. INI propertyReloadTimehas been renamed toBaseReloadTime, thoughReloadTimestill works as well. -
GameActivitydefault gold INI properties have been renamed, so they all haveDifficultyat the end. The full set of properties is:
DefaultGoldCakeDifficulty,DefaultGoldEasyDifficulty,DefaultGoldMediumDifficulty,DefaultGoldHardDifficulty,DefaultGoldNutsDifficulty,DefaultGoldMaxDifficulty. -
UInputManLua functionsKeyPressed,KeyReleasedandKeyHeldnow takeSDL_Keycodevalues instead of Allegro scancodes.
Keycodes take keyboard layout into account and should be the preferred way of detecting input.If detecting by scancode (physical key location independent of layout) is absolutely necessary, the following functions have been added:
ScancodePressed,ScancodeReleased,ScancodeHeldInfo on the keycode and scancode Lua tables and how to access them be found here: SDL Keycode and Scancode enum values in Lua.
-
Replace
PrintScreenwithF12for dumping a single screenshot, asPrintScreenwas unreliable. -
AHuman,ACrabandACRocktwill now attempt to fallback to using eachLeg'sFootattachable'sAtomGroupas the appropriateFootGroup.
This allows using auto-generatedAtomGroups instead of manually defining eachAtomin aFootGroupwhen creating actors with larger or irregularly shaped feet simply by removing theFootGroupproperties from the actor preset. -
Failing to create actor
FootGroups during loading will now crash with error message instead of straight to desktop. -
GibpropertyInheritsVelnow works as afloatscalar from 0 to 1, defining the portion of velocity inherited from the parent object. -
Jetpack burst fuel consumption is now scaled according to the total burst size instead of always being tenfold.
Bursts during downtime from burst spacing are now less punishing, scaling according to half of the burst size. -
New
ActivityLua functionactivity:SetPlayerHadBrain(player, whetherOrNotPlayerHadBrain), which sets whether or not the given player had a brain. Probably mostly useful for dealing with loading a game with multiple players, where one player is dead and you have to sort out brain assignment. -
Changed
LuaMan:FileOpenaccess modes so it only allows"r", "r+", "w", "w+", "a", "a+", i.e. specifying type (text, binary) is not supported. See this reference page for details on the access modes. -
Moved
FlashWhitefunction fromActortoMOSRotating.
Fixed
-
Improved support for varied resolutions and aspect ratios. 1366x768 users rejoice.
-
Multi-display fullscreen now works regardless of window position or which screen in the arrangement is set as primary.
Still limited to horizontal arrangements that are top or bottom edge aligned (or anywhere in between for arrangements with different height displays). -
Controller hot-plug and disconnect is now properly detected at any point and will attempt to reconnect devices to the same gamepad slot.
-
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. -
Fix black striping in online multiplayer when client screen width isn't divisible by transmitted box width.
-
Fixed issue where actors refused to pathfind around enemy doors. (Issue #396)
-
Fix advanced performance stats (graphs) peak values stuck at 0.
-
Fix
MOSRotatingGetWounds()Lua function missing its implementation. -
Fixed
Entity.ModuleNamereturning an empty string forEntitiesdefined inBase.rte. They now return "Base.rte", as they should. -
Fixed
MOSRotatings registering all penetrations in one frame even when exceeding gibbing conditions. They now omit all collisions after being flagged for deletion, allowing particles like grenade fragments to penetrate other objects. -
Fixed immobile
SoundContainersnot pausing and resuming when you pause/resume anActivity.
Removed
-
Removed
SLTerrainandSLBackgroundINI propertyOffset. Internal and shouldn't have been exposed. -
Removed
SLTerrainINI alt propertyAddTerrainObject. UsePlaceTerrainObjectfor consistency with similar properties. -
Removed
TerrainObjectINI propertyDisplayAsTerrain. Wasn't implemented and did nothing. -
Removed
SceneManLua functionAddTerrainObject.SceneMan:AddSceneObjectshould be used instead. -
Removed
ActivityLua functionEnteredOrbit. This tells theActivityto consider anACraftas having entered orbit, and should never actually have been accessible to Lua. -
Removed
OnPieMenulisteners forActivitys andGlobalScripts, and removed theProvidesPieMenuContextconcept and everything around it. These things should no longer be necessary since you can modifyPieMenus on the fly at any time, and they made this already complex set of code even more complicated. -
Removed
SceneManLua functionsSetOffsetX(x, screenId)andSetOffsetY(y, screenId). UseCameraMan:SetOffset(offsetVector, screenId)instead. -
Removed
whichStickparameter for the followingUInputManLua functions:
JoyDirectionPressed,JoyDirectionReleased,JoyDirectionHeld,AnalogAxisValue
No longer used or meaningful. -
Removed
UInputManLua functionWhichKeyHeld. -
Dedicated fullscreen has been removed (again) along with the following
Settings.iniproperties:ForceVirtualFullScreenGfxDriver,ForceDedicatedFullScreenGfxDriver
0.1.0 pre-release 4.0 - 2022/02/28
Added
-
Executable can be compiled as 64bit.
-
New
Settings.inipropertyMeasureModuleLoadTime = 0/1to measure the duration of module loading (archived module extraction included). For benchmarking purposes. -
Colorobject's RGB values can now be set with index number.Color/TrailColor = Color Index = 0-255 // Corresponds with index in palette.bmp -
New
Settings.inipropertyForceDedicatedFullScreenGfxDriverto 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 anHDFirearmas something'sLeg) 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
MOSRotatingGibBlastStrengthINI and Lua (R/W) property. This lets you define how much force createdGibsand anyAttachableswill get launched with when theMOSRotatinggibs. -
New INI and Lua (R/W) properties for
Attachables:
ParentBreakWound = AEmitter...- allows you to optionally define differentBreakWoundsfor theAttachableand its parent. By default it matchesBreakWoundfor ease of use.BreakWoundis also now R/W accessible to Lua.
InheritsHFlipped = -1/0/1- allows you to define whether theAttachablewill inherit its parent's HFlipped value or not.
-1 means reversed inheritance (i.e. if the parent's HFlipped value is true, thisAttachable's HFlipped value will be false), 0 means no inheritance, 1 means normal inheritance. Defaults to 1 to preserve normal behavior.
InheritedRotAngleRadOffset = angle- andInheritedRotAngleDegOffset = angleallow you specify an offset to keep anAttachable's rotation at whenInheritsRotAngleis set to true. For example,InheritedRotAngleDegOffset = 90would make theAttachablealways face perpendicular to its parent. In Lua there's onlyInheritedRotAngleOffset, which takes/returns radians to avoid confusion. Note that this property does nothing if theAttachable'sInheritsRotAngleis set to false or theAttachablehas no parent.
GibWithParentChance = 0 - 1- allows you to specify whether thisAttachableshould 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 thisAttachablewill 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)
ArmpropertyGripStrength. This effectively replaces theJointStrengthof the heldHeldDevice, allowingArmsto control how tightly equipment is held. -
New INI and Lua (R/W)
HeldDevicepropertyGripStrengthMultiplier. This allowsHeldDevicesto multiply theGripStrengthof theirArmsto support them being more or less easy to hold. -
New Lua
MovableObjectfunctionGetWhichMOToNotHit. This provides access to the MO that has been set to not be hit bySetWhichMOToNotHit. -
Added
HeldDevicehandling to limit whichActor(s)can pick it up. Note that pickup limitations are all done by PresetName, so you can not use this to precisely specify individualActors.
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 = NoneThe 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
MOSRotatingLua (R) propertyIndividualMass. This provides access to theMOSRotating's actual mass value, not including anyAttachablesor inventory items. Note that the normalMassproperty is still used to set theMOSRotating's mass. -
Added
ActorLua (R) propertyInventoryMass. This provides access to the mass of theActor's inventory separate from theActor's actual mass. -
Added
LimbPathINI propertyEndSegCount, which allows you to specify a segment after which the owningActor's foot will not collide with terrain. This lets you add extra visual-only frames to yourLimbPaths. -
Added
AHumanINI propertyCrouchLimbPathBGto allow you to specify a differentLimbPathfor the background leg while crouching. -
Added
AHumanINI propertiesStandRotAngleTarget,WalkRotAngleTarget,CrouchRotAngleTargetandJumpRotAngleTargetthat let you define the rot angle the body should aim towards when in the correspondingMovementState. -
Added
AHumanLua methodsGetRotAngleTarget(movementState)andSetRotAngleTarget(movementState, newRotAngleTarget)that allow you to get and set rot angle targets forMovementStates. Note that only theMovementStatesmentioned above will actually work. -
LimbPathsare now Lua accessible forACrabsandAHumans. You can useGetLimbPath(Layer, MovementState)forAHumansandGetLimbPath(Side, Layer, MovementState)forACrabs.
LimbPathshave the following properties:
limbPath.StartOffset(R/W) - the start offset for theLimbPath. Also defines its position if it has no actual path.
limbPath.SegmentCount(R) - the number of segments in theLimbPath.
limbPath:GetSegment(segmentIndex)- Gets the segment Vector for the given segment index. You can use this to modifyLimbPaths. -
Added
OnStridespecial Lua function forAHumansthat is called whenever they stride (i.e. when theirStrideSoundis played). Like playingStrideSound, this does not happen when the AHuman is climbing. -
New
AHumanandACrabINI and Lua (R/W) propertyJetAngleRangewhich defines the rate at which the angle of theJetpack's thrust follows the aim angle of the actor (default being 0.25). -
New
AHumanINI propertyLookToAimRatioat which theHeadturns in the direction of aiming (default being 0.7). -
New
AHumanINI propertiesFGArmFlailScalarandBGArmFlailScalar. Used to change the rate at which eachArmfollows the rotation angle of theActor, regardless of aim angle. 0 means theArmwill always point in aiming direction. -
New
ActorINI and Lua (R/W) propertyCanRevealUnseenwhich can be used to disable the ability to reveal unseen areas. -
New
MOPixelLua (R/W) propertyTrailLengthwhich returns the trail length of theAtomaffiliated with thisMOPixel. -
New
HDFirearmINI propertyShellEjectAnglewhich lets you define the angle at whichShellparticles are ejected relative to theHDFirearm's rotation. -
New
GibINI propertyIgnoresTeamHits. -
New
AtomINI propertyTrailLengthVariation. Used to randomizeTrailLengthon every frame. 0 means no randomization (default), 1 means anything between full length and zero. -
New
ACraftINI and Lua (R/W) propertyHatchCloseSound. This is now required separately toHatchOpenSound. -
Exposed
MOSRotatingpropertyOrientToVelto Lua (R/W). -
Exposed
DataModulepropertiesAuthor,DescriptionandVersionto Lua (R). -
Exposed
ActorpropertiesHolsterOffsetandItemInReachto Lua (R/W). -
Exposed
ArmpropertyMaxLengthto 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, 3 for ceiled remainder with the last decimal place rounded to the nearest 0 or 5 (i.e. if option 2 gave 10.1, this would give 10.5, if it gave 10.369 this would give 10.370, etc.) -
The Lua console (and all text boxes) now support using
Ctrlto move the cursor around and select or delete text. -
Added
mosRotating:RemoveAttachable(attachableOrUniqueID, addToMovableMan, addBreakWounds)method that allows you to remove anAttachableand specify whether it should be added toMovableManor not, and whether breakwounds should be added (if defined) to theAttachableand parentMOSRotating. This method returns the removedAttachable, see theChangedsection for important details on that. -
Added
mosRotating:RemoveEmitter(attachableOrUniqueID, addToMovableMan, addBreakWounds)method that is identical to theRemoveAttachablefunction mentioned above. -
Added
attachable:RemoveFromParent()andattachable:RemoveFromParent(addToMovableMan, addBreakWounds)that allow you to removeAttachablesfrom their parents without having to useGetParentfirst. Their return value is the same asRemoveAttachableabove. -
Added
Settings.inidebug properties to allow modders to turn on some potentially useful information visualizations.
DrawAtomGroupVisualizations- anyMOSRotatingwill draw itsAtomGroupto the standard view.
DrawHandAndFootGroupVisualizations- anyActorsubclasses with will draw its hand and footAtomGroups to the standard view.
DrawLimbPathVisualizations- anyAHumansorACrabswill draw some of theirLimbPathsto the standard view.
DrawRayCastVisualizations- any rays cast bySceneManwill be drawn to the standard view.
DrawPixelCheckVisualizations- any pixel checks made bySceneMan:GetTerrMatterorSceneMan:GetMOIDPixelwill be drawn to the standard view. -
Added a fully featured inventory view for managing
AHumaninventories (to be expanded to other things in future). -
New
Settings.inipropertyCaseSensitiveFilePaths = 0/1to 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 theSettings.inipropertyMeasureModuleLoadTime. The result will be printed to the console. -
Added
MovableObjectLua functionEnableOrDisableAllScriptsthat allows you to enable or disable all scripts on aMovableObjectbased on the passed in value. -
Added
AEmitterandPEmitterLua (R/W) propertiesNegativeThrottleMultiplierandPositiveThrottleMultiplierthat affect the emission rate relative to throttle. -
Added
AttachableLua function and INI propertyInheritsFramewhich letsAttachablesinherit their parent's frame. It is set to false by default. -
Added
MovableObjectLua (R/W) and INI propertiesApplyWoundDamageOnCollisionandApplyWoundBurstDamageOnCollisionwhich allowMovableObjects to apply theEntryWounddamage/burst damage that would occur when they penetrate another object, without actually creating a wound. -
Turrets can now support an unlimited number of mountedHeldDevices. Properties have been added to Lua and INI to support this:
AddMountedDevice = ...(INI) andturret:AddMountedDevice(Lua) - this adds the specifiedHeldDeviceorHDFirearmas a mounted device on theTurret.
turret:GetMountedDevices(Lua) - this gives you access to all the mountedHeldDevices on theTurret. You can loop through them with a for loop, and remove or modify them as needed.
Note thatMountedDevice = ...(INI) andturret.MountedDevice(Lua R/W) deals with the first mountedHeldDevice, which is treated as the primary one for things like sharp-aiming. -
Added
TurretLua (R/W) and INI propertyMountedDeviceRotationOffsetthat lets you specify a standard rotation offset for all mountedHeldDeviceson 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 holdingBackspacekey. -
New
Settings.inipropertiesMuteMaster = 0/1,MuteMusic = 0/1andMuteSound = 0/1to control muting of master/music/sound channels without changing the volume property values. -
New
Settings.inipropertyTwoPlayerSplitscreenVertSplit = 0/1to 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.inipropertyConsoleUseMonospaceFont = 0/1or through the in-game settings. -
New
ThrownDeviceINI propertyStrikerLever, which is the same asShellforRoundinHDFirearm, but for grenades. Represents the lever/pin coming off when activated. -
New
ArmINI and Lua (R/W) propertyThrowStrengthwhich now calculates how farThrownDevices are thrown, which also takes to account the weight of the device.ThrownDevices can still defineMaxThrowVelandMinThrowVelto override this. -
New
Settings.inipropertyDisableLuaJIT = 0/1to disable LuaJIT (MoonJIT) to (potentially) improve performance on machines that seem to struggle with it. -
New
Settings.inipropertyShowEnemyHUDwhich allows disabling of enemy actor HUD in its entirety. -
New
DataModuleINI and Lua (R) propertyIsFactionwhich 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
MOSRotatingINI and Lua (R) propertyWoundCountAffectsImpulseLimitRatiowhich can be used to make objects more prone to gibbing from impulse when they have also received wounds. -
New
GibINI propertySpreadModewhich sports two new spread logic variants which alter the way velocity is applied to theGibParticles when they spawn. This can be used to create richer explosion effects.
SpreadMode = 0is the default, fully randomized spread according toMinVelocity,MaxVelocityandSpreadvalues. Think: a piece of grenade fragment, launching out in an arbitrary direction.
SpreadMode = 1is the same as the default, but with evenly spaced out angles. Think: an air blast shockwave, dispersing evenly outward from the explosion.
SpreadMode = 2has an entirely different behavior of its own, which utilizes the fermat spiral as means to evenly disperse the particles in a circular area, according toMaxVelocityandMinVelocity. Since this mode will always result in a full, 360-degree spread, theSpreadproperty can be used to add randomization to the gib particles. Think: a cloud of smoke. -
New
ActorINI and Lua (R/W) propertyStableRecoverDelaywhich determines how long it takes for an actor to regainSTABLEstatus after being renderedUNSTABLE. -
New
AHumanLua (R) propertyThrowProgresswhich returns the current throw chargeup progress as a scalar from 0 to 1. -
New
HDFirearmINI and Lua (R/W) propertyShellVelVariationwhich can be used to randomize the magnitude at which shells are ejected. -
New
HDFirearmLua (R) propertyReloadProgresswhich returns the current reload progress as a scalar from 0 to 1. -
New
HDFirearmINI and Lua (R/W) propertyReloadablewhich can be used to disable the ability to reload said device. -
New
HDFirearmLua (R) propertyRoundInMagCapacitywhich returns the maximum capacity of theMagazineor, if there's not currently aMagazine, the maximum capacity of the nextMagazine.
This means that the property will always return the maximum ammo capacity of the device, even when reloading. -
New
EntityLua (R) propertyModuleNamewhich returns the filename of the data module from which the entity originates from. -
Arms will now react to the recoil ofHeldDevices. This is affected by theArm'sGripStrengthand theHeldDevice'sRecoilTransmission, in the same way as recoil itself. -
HDFirearmreload progress now shows up as a HUD element. -
New
RoundINI propertyLifeVariationwhich can be used to randomize theLifetimeof shot particles. -
Exposed
MOSpritepropertyPrevRotAngleto Lua (R). -
New
ACraftINI and Lua (R/W) propertyScuttleOnDeathwhich can be used to disable the automatic self-destruct sequence when the craft's health drops down to zero. -
New
Settings.inipropertyUnheldItemsHUDDisplayRange = numPixelsthat 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 theActor'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
Actorto your shop list, so you can quickly select weapons, etc..
There is also a newSettings.iniproperty,SmartBuyMenuNavigation = 0/1, which allows you to turn off this smart buy menu navigation, in case you prefer not to have it. -
Exposed
ACraftpropertyHatchDelayto Lua (R/W). -
New
Settings.inipropertySimplifiedCollisionDetection = 0/1to enable more performant but less accurate MO collision detection (previouslyPreciseCollisions = 0). Disabled by default. -
New INI property
BuyableModeto specify in which buy lists aBuyable = 1item 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
MovableManLua functionKillAllTeamActors, which kills allActors on the givenTeam. -
New
ACRocketINI propertyMaxGimbalAngle, which enables automatic stabilization via tilting of the main engine. -
Added Lua bindings for
scene.Areasandarea.Boxesthat you can iterate through to get all theAreasin aSceneand all theBoxesin anArea. -
Added
AreaLua functionarea:RemoveBox(boxToRemove)which removes the givenBoxfrom theArea. Note that this removal is done by comparing theBox'sCorner,WidthandHeight, so you're actually removing the firstBoxthat matches the passed-in boxToRemove. -
Added
AreaLua propertyarea.FirstBoxthat returns the firstBoxin thisArea. Useful forAreasthat only have oneBox. -
Added
AreaLua properties forarea.Centerandarea.RandomPoint. They're exactly the same as the existingarea:GetCenterPoint()andarea:GetRandomPoint()functions, but a bit more convenient. -
Added
SceneManLua functionSceneMan:WrapBox(boxToWrap)which takes aBoxand, if it passes over the seam, splits it into multiple boxes and returns them. Useful for creatingBoxeswithout having to worry about the seam. -
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
ActorLua (R) propertySharpAimProgress, which returns the current sharp-aiming progress as a scalar from 0 to 1. -
New
HeldDeviceLua (R/W) propertySupported, which indicates whether or not the device is currently being supported by a background hand. -
New
HeldDeviceLua functionIsEmpty, which indicates whether the device is devoid of ammo. Can be used to skip an extra step to check for aMagazine. Will always returnfalsefor non-HDFirearmdevices. -
New
SoundContainerINI and Lua (R/W) propertyPitchVariation, which can be used to randomize the pitch of the sounds being played. -
New
AHumanandACrabINI and Lua (R/W) propertyJetReplenishRate, which determines how fast jump time (i.e. jetpack fuel) is replenished during downtime. -
Added
EntityLua functionentity:RemoveFromGroup(groupToRemoveFrom)which removes the given group from theEntity. The reverse ofAddToGroup. -
New
AHumanLua functionsGetWalkAngle(layer)andSetWalkAngle(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
AHumanINI and Lua (R/W) propertyArmSwingRate, which now controls the arms' walking animation, according to each arm'sIdleOffset.1is the default value,0means that the arms stay still. -
New
AttachableLua (R) propertyJointPos, which gets the position of the object's joint in scene coordinates. -
New
AHumanLua (R) propertyIsClimbing, which indicates whether the actor is currently climbing using either of the arms. -
New
AHumanLua functionsUnequipFGArm()andUnequipArms()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
MOSpriteINI propertyIconFile, which can be used to define a separate sprite to be displayed in GUI elements, such as the Buy Menu.
Defined similarly toSpriteFile, i.e.IconFile = ContentFilefollowed up by aFilePathto the sprite. -
New
MOSpriteLua functionsGetIconWidth()andGetIconHeight()which return the dimensions of its GUI representation. -
New
PrimitiveManLua functionsDrawIconPrimitive(player, pos, entity)andDrawIconPrimitive(pos, entity)which can be used to draw the GUI representation of the passed in entity. -
New
AEmitterandPEmitterLua (R) propertyThrottleFactor, which gets the throttle strength as a multiplier value that factors in either the positive or negative throttle multiplier according to throttle. -
New
AHumanLua (R) propertyEquippedMass, which returns the total mass of anyHeldDevices 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. -
New
FrameManLua functionSplitStringToFitWidth(stringToSplit, widthLimit, useSmallFont), which lets you split up a string so it fits within a given width limit for the specified font. Does not try to perfectly fit strings, and can be wonky if the width limit is small. Mostly used to ensure text fits on the screen!
Changed
-
ACrabactors will now default to showing theirTurretsprite as their GUI icon. If no turret is defined, theACrab's own sprite will be used.
In a similar fashion,AHumanwill now default to its torso sprite as its GUI representation if noHeadhas somehow been defined. -
ThrownDevices will now useStanceOffset,SharpStanceOffsetandSupportOffsetin the same way as any otherHeldDevice. In addition,EndThrowOffsetwill be used to set the BG hand position while sharp aiming or throwing. -
AHumanthrowing angle will no longer be affected by the rotation of the body. -
Exposed
MovableObjectpropertyRestThresholdto 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
MOSpritepropertySpriteAnimModeEnumLOOPWHENMOVINGtoLOOPWHENACTIVEas it also describes active devices. -
Changed
ActivityLua (R) propertiesRunning,PausedandActivityOvertoIsRunning,IsPausedandIsOverrespectively. (NOTE: correspondingActivityManfunctions remain unchanged) -
Exposed
ThrownDevicepropertiesStartThrowOffsetandEndThrowOffsetto Lua (R/W). -
HeldDevices can now show up as "Tools" in the buy menu, rather than just as "Shields". -
Keyboard-only controlled
AHumans andACrabs can now strafe while sharp-aiming. -
Lowered the default
AHumanHead damage multiplier from 5 to 4. -
"Fixed" grenades and other fast-moving objects bouncing violently off of doors and other stationary objects.
-
AEmitterandPEmitterthrottle logic has changed:
The propertiesMinThrottleRangeandMaxThrottleRangehave been changed toNegativeThrottleMultiplierandPositiveThrottleMultiplierrespectively.
The new logic uses the multipliers to multiply the emission rate relative to the absolute throttle value.NegativeThrottleMultiplieris used when throttle is negative, and vice versa. -
Doors in
Team = -1will now open up for all actors. -
MovableManfunctionKillAllActors(commonly found in activities) has been appropriately renamedKillAllEnemyActors. -
Wound limit gibbing logic has changed for
MOSRotating(and all its subclasses), where objects will now gib when they reach theirGibWoundLimitrather than when they surpass it. This allows for one-wound gibbing, which was previously infeasible. For objects with lowGibWoundLimits, 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 toHDFirearm. SetSpriteAnimModeto4if you wish to enable the looping active animation. -
AHumancan 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
SharpLengthto 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
MovableManfunctionsGetClosestActorandGetClosestTeamActorare now of typeVectorrather thanfloat. -
File paths in INIs are now case sensitive.
-
Hands will now draw in transparent drawing mode, i.e. editing menu.
-
AHumanbackgroundLegwill no longer draw in front of theAHuman. 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:
DamageMultiplieronAttachablesnow works as expected, allAttachablescan now transfer damage to their root parent.
This will travel up chains ofAttachables, as long as everyAttachablein 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 defaultDamageMultiplierforAttachablesis 0, so you have to set it if you want it. Also note that wounds will default this value to 1 instead of 0.
Attachableterrain collision has been reworked so that it can be changed simply by settingCollidesWithTerrainWhileAttached = true/falsein INI or Lua. Also,Attachablesattached to otherAttachableswill now collide with terrain properly.
BreakWoundsonAttachablesnow gets added to both theAttachableand the parent when theAttachableis broken off. IfParentBreakWoundis defined, the parent will use this instead of the regularBreakWound. -
Attachable.BreakWoundnow has R/W access in Lua. -
Attachable.DeleteWithParentis nowAttachable.DeleteWhenRemovedFromParent, since this more accurately describes what it does. -
Attachable.OnlyLinearForceshas been renamed toAttachable.ApplyTransferredForcesAtOffsetand its effect has been reversed, so something that checkedOnlyLinearForces == truewould now checkApplyTransferredForcesAtOffset == false, since this makes more sense to use. -
ArmsandLegsonAHumanswill no longer bleed out indefinitely. If you want this to happen, adjust theirBreakWoundorParentBreakWoundaccordingly. -
Reworked wound management:
Wound management is now always done withMOSRotatingfunctions, instead of requiring different ones forActors. This means TotalWoundCount and RemoveAnyRandomWounds no longer exist.
In place of these functions, you can get all wounds withGetWounds, you can get the wound count withGetWoundCount(or using the pre-existing WoundCount property), and remove wounds withRemoveWounds. You can also get the total gib wound limit withGetGibWoundLimit(or using the pre-existing GibWoundLimit property).
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:Attachableswith a positiveDamageMultiplier(i.e.Attachablesthat damage their parent),Attachableswith a negativeDamageMultiplier(i.e.Attachablesthat heal their parent) orAttachableswith noDamageMultiplier(i.e.Attachablesthat don't affect their parent).
Without any arguments,GetWoundCountandRemoveWoundswill only includeAttachableswith a positiveDamageMultiplierin their counting calculations, andGetGibWoundLimitwill not include anyAttachablesin 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 anAttachablethat satisfies the conditions hasAttachables that also satisfy the conditions, their wounds will be included in the results. -
Renamed
TurretINI propertyMountedMOtoMountedDeviceto better match the new reality thatTurretscan only mountHeldDevicesand their child classes. -
Renamed
ACrabLFGLeg,LBGLeg,RFGLegandRBGLegLua properties toLeftFGLeg,LeftBGLeg,RightFGLeg,RightBGLegrespectively, to be more consistent with other naming.
For the time being, the INI properties (as well as the ones for settingFootGroupsandLimbPaths) support both single letter and written out versions (i.e.LStandLimbPathandLeftStandLimbPathare both supported). This single letter versions will probably be deprecated over time. -
To better align with the other changes, hardcoded
AttachableINI definitions forACDropShipsandACRocketscan 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:AddMOwill now addHeldDevices(or any child class ofHeldDevice) to itsItemscollection, making it able to provide the functionality ofAddParticle,AddActorandAddItem. -
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. SeeAttachableproperties for more details.
As an added bonus,AttachablesonACDropShipsandACRocketscan 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).
-
Attachablesnow use theirGibImpulseLimitas well as theirJointStrengthwhen determining whether they should be detached by strong forces. To maintain backwards compatibility, if theGibImpulseLimitis less than theJointStrength, theJointStrengthwill be used instead for this purpose. -
The
FacingAnglefunction has been moved fromActortoMOSpriteso it can be used more widely. -
LifetimeandToDeletenow work on wounds, giving modders more control over them. -
Some functionality has been moved from
AudioMantoSoundContainerfor consistency. As such, the followingAudioManLua bindings have been replaced:
AudioMan:FadeOutSound(fadeOutTime);has been replaced withsoundContainer:FadeOut(fadeOutTime);
AudioMan:StopSound(soundContainer);andAudioMan:StopSound(soundContainer, player);have been replaced withsoundContainer:Stop();andsoundContainer:Stop(player); -
Pressing escape when a buy menu is open now closes it instead of pausing the game.
-
GetParentwill now return anMOSRotatinginstead of aMovableObjectso it doesn't need to be casted withToMOSRotating. Additionally, it will always return null for objects with no parents, instead of returning the self object for things that weren'tAttachables.
This makes things more consistent and reasonable throughout and will rarely, if ever, cause Lua problems. -
Previews generated by the
SceneEditorare now the same asScenePreviewDumps. Also, both are now saved as PNGs. -
Attachableterrain collisions will now propagate to any childAttachableson them. This means thatAttachableswill not collide with terrain, even if set to, if they're attached to a parent that doesn't collide with terrain.
This means that theattachable.CollidesWithTerrainWhileAttachedvalue may not represent the true state of things, you should instead useattachable.CanCollideWithTerrainto determine whether a givenAttachablecan collide with terrain. -
Actor selection keys can be used to cycle the selected
ObjectPickeritem while it's closed during building phase and in editors. -
The
ActorpropertyMaxMassnow no longer includes theMassof theActor, and has been renamed toMaxInventoryMassfor clarity. In mods, this is most important forACraft, which will now need their totalMasssubtracted from the old value. -
BuyMenutooltips now display item info as well as a description. This includesMaxInventoryMassandMaxPassengersforACraft,MassandPassengerSlotsrequired forActors, andMassfor otherMoveableObjects. -
Replaced the above-HUD pie menu inventory view with an animating inventory carousel.
-
AHuman:ReloadFirearmLua function has been changed toAHuman:ReloadFirearmsand will now reload offhand weapons as well, if appropriate. -
ACrab:ReloadFirearmLua function has been changed toACrab:ReloadFirearmsand will now reload all of theACrab's weapons. -
When using the Settings.ini flag
LaunchIntoActivity, you will start with some default amount of gold; either theActivity's medium difficulty gold amount, or its funds for Team 1, which default to 2000 when not set. -
AEmitters will now obeySpriteAnimModeset in Lua while they're emitting. When they stop emitting this will reset toNOANIM. -
AttachableLua methodIsDrawnAfterParenthas been changed to the propertyDrawnAfterParent, and is now R/W. -
All
mosRotating:RemoveAttachable,mosRotating:RemoveEmitterandattachable:RemoveFromParentfunctions will return the removedAttachableif it hasn't been added toMovableMan, or nil if it has. If theAttachableis 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.inipropertyMenuTransitionDurationrenamed toMenuTransitionDurationMultiplier. -
Settings.inipropertyDisableLoadingScreenrenamed toDisableLoadingScreenProgressReport. -
Scenario scene markers are now color coded to help distinguish them visually:
Base.rtescenes are yellow as always.
Missions.rtescenes are now green.
Scenes.rteor 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'sModuleNameno longer makes the module a playable faction (in MetaGame, etc.). TheIsFactionproperty 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
GetRadRotatedandGetDegRotatedtoGetRadRotatedCopyandGetDegRotatedCopyfor 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.
-
FrameManscreen text will now always try to fit on the screen, splitting into multiple lines if needed. If you want more control of this, split your screen text manually with the"\n"new line character.
Fixed
-
Fixed the logic for
GibandEmissionpropertyLifeVariationwhere it would round down to zero, giving particles infinite lifetime. -
Fixed legs going bonkers for one frame when turning around.
-
HFlippedis now properly assigned to emissions, gibs and particles that are shot from aHDFirearm'sRoundwhen the source object is also flipped. -
MovableObject:SetWhichMOToNotHitwill 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
Massof aMOSRotatinghas now been made more efficient. Additionally,AttachablesofAttachableswill now be properly included in Mass, so some things have gotten a lot heavier (e.g. Dummy Dreadnought). -
The moment of inertia of
AtomGroupsnow updates when the mass or Atoms change, meaning losingAttachablesor changing mass will properly affect how rotational forces apply to MOSRotatings. -
WoundDamageMultiplierson projectiles will now properly stack with wounds'DamageMultiplier. Prior to this, if you set theDamageMultiplierof a wound on some object, it'd be overwritten by the hitting projectile'sWoundDamageMultiplier. Now they multiply together properly. -
RadiusandDiameternow account forAttachableson objects that can have them. If you want just theRadiusorDiameterof the object, useIndividualRadiusandIndividualDiameter(only available forMOSRotatingand subclasses). This means thatRadiusandDiameterwill 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
DeactivationSoundofHDFirearmsnow respects itsSoundOverlapModeinstead 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
AttachableINI propertyCollidesWithTerrainWhenAttachedto more correct, consistentCollidesWithTerrainWhileAttached. -
You can now modify all hardcoded
AttachableCopyOfINI definitions without setting a newPresetName. This means you could, for example,CopyOfa predefinedLegand change it, without having to set a newPresetName. This is optional, and comes with the obvious limitation of not being able to find that modified copy in-game with Lua. -
OnCollideWithMOnow works forMOPixelsandMOSParticlesso you can use it to check if your bullets collide with things. -
OnCollideWithMOandOnCollideWithTerrain(and other special functions) will run more reliably right after the object is spawned. E.g.OnCollideWithTerrainon 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
PlayerandTeamnumbers 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.inipropertiesForceOverlayedWindowGfxDriverandForceNonOverlayedWindowGfxDriver. -
Removed
AttachableLua write capability forAtomSubGroupIDas changing this can cause all kinds of problems. -
Removed
MaxLengthproperty fromLeg, 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.RotTargetfrom Lua and INI. The property never worked and no longer exists. -
Removed
Attachable:CollectDamage,Attachable:TransferJointForcesandAttachable:TransferJointImpulsesLua function definitions. These are internal functions that should never have been exposed to Lua. -
Removed
MOSRotating:ApplyForcesandMOSRotating:ApplyImpulsesLua functions. These are both internal functions that should never have been exposed to Lua. -
Removed hardcoded INI constraint that forced
MassofMovableObjectsto not be 0. Previously, anytime aMassof 0 was read in from INI, it was changed to 0.0001, now 0Massis allowed and supported. -
Removed the quit confirmation dialog from the scenarios screen. Now pressing escape will return you to the main menu.
-
Removed
Settings.inipropertiesHSplitScreenandVSplitScreen. Superseded byTwoPlayerSplitscreenVertSplit.
0.1.0 pre-release 3.0 - 2020/12/25
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.inipropertyLoadingScreenReportPrecision = intValueto control how accurately the module loading progress reports what line is currently being read.
Only relevant whenDisableLoadingScreen = 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.inipropertyMenuTransitionDuration = floatValueto 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
ADoorsound 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.StableVelocityThresholdto lua. New bindings are: (Issue #101)
Actor:GetStableVelocityThreshold()returns aVectorwith 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 inVector. -
New
AttachableandAEmitterpropertyDeleteWithParent = 0/1. If enabled the attachable/emitter will be deleted along with the parent if parent is deleted/gibbed/destroyed. (Issue #97) -
New
Settings.inipropertyLaunchIntoActivity = 0/1. WithPlayIntrofunctionality 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.ThrowPrepTimeto lua and ini: (Issue #101)
ThrowPrepTime = valueInMSwill set how long it takes theAHumanto fully charge a throw. Default value is 1000.
AHuman.ThrowPrepTimeto get/set values via lua. -
Added new
SpriteAnimModemodes:SpriteAnimMode = 7 // OVERLIFETIMEThis mode handles exactly like (now removed)
MOSParticle.Framerate = 0and will complete the sprite's animation cycle over the course of its existence.SpriteAnimDurationis 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 hasLifeTime = 0(infinite) it will be overridden toSpriteAnimMode = 1(ALWAYSLOOP) otherwise it will never animate.SpriteAnimMode = 8 // ONCOLLIDEThis mode will drive the animation forward based on collisions this object has with other MOs or the terrain.
SpriteAnimDurationis inapplicable when using this mode and will do nothing.
This mode isMOSParticlespecific and used mainly for animating casings and small gibs. Using this mode on anything other thanMOSParticlewill do nothing. -
New
Settings.inipropertiesEnableCrabBombs = 0/1andCrabBombThreshold = intValue.
WhenEnableCrabBombsis enabled, releasing a number of crabs equal toCrabBombThresholdor 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 eitherADoor:OpenDoor()orADoor:CloseDoor()otherwise it will remain in the exact position it was stopped forever.
If eitherDrawMaterialLayerWhenOpenorDrawMaterialLayerWhenClosedproperties 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 theADoor.DoorStateenumeration.ADoor:GetDoorStatewill return this if the door was stopped by the user viaADoor:StopDoor. -
New shortcut
ALT + Wto generate a detailed 140x55px miniWorldDumpto be used for scene previews. No relying onSceneEditor, 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.TurretandLeg. 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
PEmitterto lua. Bindings are identical toAEmitterbindings, except that damage-related bindings don't exist forPEmitter. -
FLACaudio files can now be loaded through lua and ini. -
Added new lua
Vectorfunctions:GetRadRotated(angle)andGetDegRotated(angle). They return a rotated copy of the vector without modifying it. -
Added
Enumbinding forSoundSet.SoundSelectionCycleMode:RANDOM = 0, FORWARDS = 1, ALL = 2. -
Added
Enumbinding forSoundContainer.SoundOverlapMode:OVERLAP = 0, RESTART = 1, IGNORE_PLAY = 2. -
New
SoundContainerfunctionRestart, which allows you to restart a playingSoundContainer. Also anotherPlayfunction, that lets you just specify the player to play the sound for. -
New
HDFirearmINI propertyPreFireSound, 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 anActivationDelay. -
SoundSetshave been made a bit more fully featured, they can now have subSoundSetsand their ownSoundSelectionCycleModeand they now have a Lua binding so you can create them in Lua withlocal mySoundSet = SoundSet().
They have the following INI and Lua properties:SoundSelectionCycleMode(INI and Lua R/W) - Determines how sounds in thisSoundSetwill be selected each time it is played (or whenSelectNextSoundsis called).
Note that subSoundSetscan have differentSoundSelectionCycleModes.SoundSetswith subSoundSetsand sounds whoseSoundSelectionCycleModeisFORWARDSwill first go through their sounds, then each subSoundSet.soundSet.SubSoundSets(Lua R) - An iterator over the subSoundSetsof thisSoundSet, allowing you to manipulate them as you would anySoundSet.
soundSet:HasAnySounds(includeSubSoundSets)(Lua) - Whether or not thisSoundSethas any sounds, optionally including its subSoundSets.
soundSet:SelectNextSounds()(Lua) - Selects the next sounds for thisSoundSet. Note that playing aSoundContainerwill always also do this, so this is only really useful to allow you to skip sounds whenSoundSelectionCycleModeis set toFORWARDS.
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 givenSoundSetas a subSoundSetof thisSoundSet.
soundSet:RemoveSound("Path/to/sound.flac")(Lua) - Removes any sounds with the given filepath from theSoundSet, 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 theSoundSet, returning whether or not any where removed. Optionally removes matching sounds from any sub-SoundSets and their sub-SoundSets and so on.Additionally,
AddSoundandAddSoundSetINI properties work forSoundSets. They are exactly the same as they are forSoundContainers. -
You can get the top level
SoundSetof aSoundContainerwithsoundContainer:GetTopLevelSoundSetand manipulate it as described above. You can also set it to fully overwrite it withsoundContainer:SetTopLevelSoundSet. This allows you full interaction with all levels ofSoundSetsin aSoundContainer.
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
Managersfolder. -
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.iniwill 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
PreciseCollisionsfromSettings.inidue to bad things happening when disabled by user. -
Settings.inipropertyPlayIntrorenamed toSkipIntroand functionality changed to actually skip the intro and load user directly into main menu, rather than into the set default activity. -
Lua calls for
GetParentandGetRootParentcan now be called by anyMovableObjectrather than being limited toAttachableonly. (Issue #102)
In some cases a cast to the appropriate type (ToWhateverType, e.gToMOSRotating) will be needed when attempting to manipulate the object returned, because it will be returned asMovableObjectif 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
FrameManand now hardcoded inConstants. Lua bindings moved toRTEToolsand are now called without theFrameManprefix like so:
GetPPM(),GetMPP(),GetPPL(),GetLPP(). -
Removed hardcoded 10 second
LifeTimerestriction forMOPixelandMOSParticle. -
MOSParticleanimation can now be set withSpriteAnimModeandSpriteAnimDuration. If the property isn't defined it will default toSpriteAnimMode = 7(OVERLIFETIME). -
Reworked crab bombing behavior. When enabled through
Settings.iniand triggered will gib all living actors on scene except brains and doors. Devices and non-actor MOs will remain untouched. -
ADoorpropertiesDrawWhenOpenandDrawWhenClosedrenamed toDrawMaterialLayerWhenOpenandDrawMaterialLayerWhenClosedso they are more clear on what they actually do. -
Specially handled Lua function
OnScriptRemoveOrDisablehas been changed toOnScriptDisable, 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
UInputMantoConstantsand are no longer accessed with theUInputManagerprefix. These enums are now accessed with their own names as the prefix.
For example:UInputManager.DEVICE_KEYB_ONLYis nowInputDevice.DEVICE_KEYB_ONLY,UInputManager.INPUT_L_UPis nowInputElements.INPUT_L_UPand so on. -
CraftsOrbitAtTheEdgecorrected toCraftOrbitAtTheEdge. 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,AttachableorAEmitterpreset. -
ComboBoxes (dropdown lists) can now also be closed by clicking on their top part.
-
Activity:IsPlayerTeamrenamed toActivity:IsHumanTeam. -
Screenshot functionality changed: (Issue #162)
ThePrintScreenbutton will now take a single screenshot on key release and will not take more until the key is pressed and released again.
TheCtrl+Skey combination is unchanged and will take a single screenshot every frame while the keys are held.
TheCtrl+WandAlt+Wkey combinations will now take a single WorldDump/ScenePreview onWkey release (whileCtrl/Altare 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
_Screenshotsfolder (_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. -
ScreenDumpsandWorldDumpsare 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.HandPoswill 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 toFullscreenbutton - this will set the game window resolution to match the desktop resolution. When resolution matches the desktop, this button will change toWindowedand will allow setting the game window resolution back to default (960x540).
AddedUpscaled Fullscreenbutton - this will change the resolution to half of the desktop and the multiplier to 2. TheFullscreenbutton will change toWindowedin 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 inUpscaled Fullscreenmode will change resolution toFullscreen. 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
mt19937random 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 withSettings.inipropertyDisableMultiScreenResolutionValidation. Bad settings are likely to crash, use at own risk.
For setups with more than 3 screensDisableMultiScreenResolutionValidationmust be set true. -
Damage to
Actorsfrom impulses is now relative to their max health instead of being on a scale from 0 to 100. -
Sceneswith aPresetNamecontaining the strings "Test", "Editor" and "Tutorial" are no longer excluded from the scenarios screen and from the MetaGame. -
SoundContaineris now a concrete Lua entity. This means it can now be created withCreateSoundContainer("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 theSoundContaineris 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 theSoundContainer'sposition throughAudioMan, you should now use thePosproperty.
soundContainer.Volume- In addition to attenuation based volume changes, it is now possible to set aSoundContainer'soverall volume. This works together with volume changes caused by attenuation.
soundContainer.Pitch- Rather than updating theSoundContainer'spitch throughAudioMan, you should now use thePitchproperty. Also note that this now works properly with the game's global pitch so no complicated handling is necessary. -
AddSoundandSelectNextSoundSetLua bindings have been moved fromSoundContainertoSoundSet. 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 theAddedsection. -
Pressing escape at the options, mod manager, game editors and credits screens no longer quits the game.
Fixed
-
Fix crash when returning to
MetaGamescenario 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
EffectStartTimemaking 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
AHumanequipped items, and made it work forBGArmequipped items as well asFGArmones. -
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.
-
HDFirearmINI propertyDeactivationSoundnow 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.inipropertyPixelsPerMeter. Now hardcoded and cannot be changed by the user. -
Removed
MOSParticlepropertyFramerateand lua bindings.MOSParticleanimation is now handled withSpriteAnimModelike everything else. -
Removed
ConsoleMan.ForceVisibilityandConsoleMan.ScreenSizelua bindings. -
Removed
ActivityMan.PlayerCountandActivityMan.TeamCountsetters lua bindings (obsolete and did nothing). -
Removed
ActivitypropertiesTeamCountandPlayerCount. These are handled internally and do nothing when set in ini. -
Removed
ActivitypropertyFundsOfTeam#, useTeam#Fundsinstead. -
Some functionality has been moved from
AudioMantoSoundContainer. As such, the followingAudioManLua bindings are no longer available:
SetSoundPosition(soundContainer),SetSoundPitch(soundContainer,PlaySound(filePath, position, player, loops, priority, pitchOrAffectedByGlobalPitch,attenuationStartDistance, immobile)The lengthy
PlaySoundfunction should be replaced by making aSoundContainerin yourCreatefunction and setting properties appropriately.
This can be done by creating one defined INI withsoundContainer = CreateSoundContainer(...), or by making an empty one withsoundContainer = 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,AreaEditorandAssemblyEditor. -
Added handling for custom number and string values in INI.
AddCustomValue = NumberValue YourKeyName = YourNumberValue // Integer or floating point number. AddCustomValue = StringValue YourKeyName = YourStringValueYourKeyNameis a string value and is not limited to just numbers. -
New
Settings.inipropertyAdvancedPerformanceStats = 0/1to disable/enable the performance counter graphs (enabled by default). -
Added
PassengerSlotsINI 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
IsInsideXandIsInsideYtoArea. These act similarly to the pre-existingIsInside, but allow you to check for the X and Y axes individually. -
Added the concept of
SoundSets, which are collections of sounds inside aSoundContainer. This allows you to, for example, put multiple sounds for a given gunshot inside aSoundSetso they're played together. -
SoundContainershave 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.
-
SoundContainerLua 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.
-
MovableObjectscan now run multiple scripts by putting multipleAddScript = FilePath.lualines 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 sameself, so care must be taken when naming self variables.
Scripts can be checked for withmovableObject:HasScript(filePath);and added and removed withmovableObject:AddScript(filePath);andmovableObject:RemoveScript(filePath);. They can also be enabled and disabled in Lua (preserving their ordering) withmovableObject:EnableScript(filePath);andmovableObject:DisableScript(filePath);. -
Scripts on
MovableObjectsand anything that extends them (i.e. most things) now support the following new functions (in addition toCreate,Update,DestroyandOnPieMenu). 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
Attachablesnow 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
Systemfolder. -
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. -
Soundshave been renamed toSoundContainers, 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 usingAddSound = 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
DisableLoadingScreenis true. -
Box:WithinBoxlua bindings have been renamed:
Box:WithinBoxis nowBox:IsWithinBox.
Box:WithinBoxXis nowBox:IsWithinBoxX.
Box:WithinBoxYis nowBox:IsWithinBoxY. -
Made
AHumanshow 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 ... -
FrameManbroken down to 4 managers. New managers are:
PerformanceManto handle all performance stats and measurements.
PostProcessManto handle all post-processing (glows).
PrimitiveManto 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 nowPrimitiveMan:DrawLinePrimitive(). -
Resolution multiplier properties (
NxWindowedandNxFullscreen) in settings merged into a single propertyResolutionMultiplier. -
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 showUnavailable. -
PieMenuActorandOrbitedCrafthave now been removed. They are instead replaced with parameters in their respective functions, i.e.OnPieMenu(pieMenuActor);andCraftEnteredOrbit(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
ALWAYSPINGPONGnow works properly. Sprite animation has also been moved toMOSpriteinstead ofMOSRotating, they they'll be able to properly animate now. (Issue#77) -
Fixed
BG Armflailing 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
FrameManlua bindings:
FrameMan:ResetSplitScreens,FrameMan:PPMsetter,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.iniproperties:
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
-hto see help and-cto send ingame console input to cout. -
MOSpritenow has theFlipFactorproperty that returns -1 if the sprite is flipped and 1 if it's not.
Using anynugNumcalculations based onHFlippedis now considered criminal activity. -
TDExplosivenow has theIsAnimatedManuallyproperty that lets modders set its frames manually through lua. -
You can now add
AEmitterstoMOSRotatingand have them function similarly to attachables.
Addition:parent:AddEmitter(emitterToAdd)orparent:AddEmitter(emitterToAdd, parentOffsetVector)
Removal:parent:RemoveEmitter(emitterToRemove)orparent: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 toCollidesWithTerrainWhenAttached = 1in ini. -
Actor.DeathSoundis now accessible to lua usingActor.DeathSound = "string pathToNewFile"orActor.DeathSound = nilfor no DeathSound. -
AHumanFeet are now accessible to lua usingAHuman.FGFootandAHuman.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
-
ACrabaim limits now adjust to crab body rotation. -
ACrab.AimRangecan now be split intoAimRangeUpperLimitandAimRangeLowerLimit, allowing asymmetric ranges. -
Objective arrows and Delivery arrows are now color coordinated to match their teams, instead of being only green or red.
-
BuyMenu
Bombstab will now show allThrownDevicesinstead of justTDExplosives. -
The list of
MOSRotatingattachables (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)orparent:AddAttachable(attachableToAdd, parentOffsetVector)
Removal:parent:RemoveAttachable(attachableToRemove)orparent:RemoveAttachable(uniqueIdOfAttachableToRemove) -
Wounds have been separated internally from emitter attachables.
They can now be added withparent: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.ActivatesWhenReleasednow 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.ParticleNumberToAddproperty has been removed.
Note: For a log of changes made prior to the commencement of the open source community project, look here.