Skip to content

Commit f96a916

Browse files
authored
Merge pull request #561 from cortex-command-community/pathfinding-nav-optimizations
Game System Optimizations
2 parents 403fcb4 + 18d05ae commit f96a916

38 files changed

+912
-501
lines changed

Activities/GAScripted.cpp

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ int GAScripted::Create() {
7676
// Scan the script file for any mentions/uses of Areas.
7777
CollectRequiredAreas();
7878

79+
7980
// If the GAScripted has a OnSave() function, we assume it can be saved by default
81+
ReloadScripts();
8082
m_AllowsUserSaving = HasSaveFunction();
8183

8284
return 0;
@@ -195,24 +197,15 @@ int GAScripted::ReloadScripts() {
195197
if (!g_LuaMan.GetMasterScriptState().GlobalIsDefined(m_LuaClassName)) {
196198
// Temporarily store this Activity so the Lua state can access it
197199
g_LuaMan.GetMasterScriptState().SetTempEntity(this);
198-
200+
199201
// Define the var that will hold the script file definitions
200202
if ((error = g_LuaMan.GetMasterScriptState().RunScriptString(m_LuaClassName + " = ToGameActivity(LuaMan.TempEntity);")) < 0) {
201203
return error;
202204
}
203205
}
204206

205-
std::string luaClearSupportedFunctionsString;
206-
for (const std::string& functionName : GetSupportedScriptFunctionNames()) {
207-
luaClearSupportedFunctionsString += m_LuaClassName + "." + functionName + " = nil; ";
208-
}
209-
210-
if ((error = g_LuaMan.GetMasterScriptState().RunScriptString(luaClearSupportedFunctionsString)) < 0) {
211-
return error;
212-
}
213-
214207
std::unordered_map<std::string, LuabindObjectWrapper*> scriptFileFunctions;
215-
if ((error = g_LuaMan.GetMasterScriptState().RunScriptFileAndRetrieveFunctions(m_ScriptPath, m_LuaClassName, GetSupportedScriptFunctionNames(), scriptFileFunctions)) < 0) {
208+
if ((error = g_LuaMan.GetMasterScriptState().RunScriptFileAndRetrieveFunctions(m_ScriptPath, m_LuaClassName, GetSupportedScriptFunctionNames(), scriptFileFunctions, true)) < 0) {
216209
return error;
217210
}
218211

@@ -310,8 +303,11 @@ int GAScripted::Start() {
310303
return error;
311304
}
312305

313-
// Create the Lua variable which will hold the class representation that we'll add some definitions to
314-
if ((error = g_LuaMan.GetMasterScriptState().RunScriptString(m_LuaClassName + " = ToGameActivity(ActivityMan:GetActivity());")) < 0) {
306+
// Temporarily store this Activity so the Lua state can access it
307+
g_LuaMan.GetMasterScriptState().SetTempEntity(this);
308+
309+
// Define the var that will hold the script file definitions
310+
if ((error = g_LuaMan.GetMasterScriptState().RunScriptString(m_LuaClassName + " = ToGameActivity(LuaMan.TempEntity);")) < 0) {
315311
return error;
316312
}
317313

@@ -563,12 +559,12 @@ void GAScripted::AddPieSlicesToActiveActorPieMenus() {
563559
PieMenu *controlledActorPieMenu = m_ControlledActor[player]->GetPieMenu();
564560
if (controlledActorPieMenu && m_ControlledActor[player]->GetController()->IsState(PIE_MENU_ACTIVE) && controlledActorPieMenu->IsEnabling()) {
565561
for (const std::unique_ptr<PieSlice> &pieSlice : m_PieSlicesToAdd) {
566-
controlledActorPieMenu->AddPieSliceIfPresetNameIsUnique(dynamic_cast<PieSlice *>(pieSlice->Clone()), this, true);
562+
controlledActorPieMenu->AddPieSliceIfPresetNameIsUnique(pieSlice.get(), this, true);
567563
}
568564
for (const GlobalScript *globalScript : m_GlobalScriptsList) {
569565
if (globalScript->IsActive()) {
570566
for (const std::unique_ptr<PieSlice> &pieSlice : globalScript->GetPieSlicesToAdd()) {
571-
controlledActorPieMenu->AddPieSliceIfPresetNameIsUnique(dynamic_cast<PieSlice *>(pieSlice->Clone()), globalScript, true);
567+
controlledActorPieMenu->AddPieSliceIfPresetNameIsUnique(pieSlice.get(), globalScript, true);
572568
}
573569
}
574570
}

Activities/GameActivity.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1347,7 +1347,7 @@ void GameActivity::Update()
13471347
// Assure that Controlled Actor is a safe pointer
13481348

13491349
// Only allow this if player's brain is intact
1350-
if (g_MovableMan.IsActor(m_Brain[player]))
1350+
if (m_Brain[player] && !m_Brain[player]->IsDead() )
13511351
{
13521352
// Note that we have now had a brain
13531353
m_HadBrain[player] = true;

CHANGELOG.md

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
2222
The `OnGlobalMessage` callback works the exact same way, however global messages are sent to every object within the game, instead of a specific object.
2323
To send a global message, use `MovableMan:SendGlobalMessage(message, context)`.
2424

25+
- New `AEJetpack` type, which replaces the old technique of `ACrab`/`AHuman` using an `AEmitter` as a jetpack. This type inherits from `AEmitter`.
26+
New INI and Lua (R/W) property `JetpackType`, which can be either `AEJetpack.Standard` or `AEJetpack.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.
27+
New INI and Lua (R/W) property `MinimumFuelRatio`, 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.
28+
New INI and Lua (R/W) property `CanAdjustAngleWhileFiring`, which defines whether the jet angle can change while the jetpack is active. Defaults to true.
29+
New INI and Lua (R/W) property `AdjustsThrottleForWeight`, which defines whether the jetpack will adjust it's throttle (between `NegativeThrottleMultiplier` and `PositiveThrottleMultiplier`) to account for any extra inventory mass. Increased throttle will decrease jet time accordingly. Defaults to true.
30+
2531
- New Lua event function `SyncedUpdate()`, which will be called in a thread-safe synchronized manner and allows multithreaded scripts to modify game state in a safe and consistent way.
2632

2733
- Multithreaded asynchronous pathfinding, which dramatically improves performance on large maps and improves AI responsiveness.
@@ -44,13 +50,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
4450
);
4551
```
4652

47-
- New `AEJetpack` type, which replaces the old technique of `ACrab`/`AHuman` using an `AEmitter` as a jetpack. This type inherits from `AEmitter`.
48-
New INI and Lua (R/W) property `JetpackType`, which can be either `AEJetpack.Standard` or `AEJetpack.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.
49-
New INI and Lua (R/W) property `MinimumFuelRatio`, 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.
50-
New INI and Lua (R/W) property `CanAdjustAngleWhileFiring`, which defines whether the jet angle can change while the jetpack is active. Defaults to true.
51-
New INI and Lua (R/W) property `AdjustsThrottleForWeight`, which defines whether the jetpack will adjust it's throttle (between `NegativeThrottleMultiplier` and `PositiveThrottleMultiplier`) to account for any extra inventory mass. Increased throttle will decrease jet time accordingly. Defaults to true.
53+
- New FMOD and SoundContainer features:
54+
The game is now divided into SFX, UI, and Music busses which all route into the Master bus.
55+
The SFX bus has compression added for a better listening experience, and a safety volume limiter has been added to the Master bus.
56+
Aside from volume being attenuated, sounds will now also be lowpass filtered as distance increases.
57+
New `SoundContainer` INI and Lua (R/W) property `BusRouting`, which denotes which bus the SoundContainer routes to. Available busses: `SFX, UI, Music`. Defaults to `SFX`.
58+
`Enum` binding for `SoundContainer.BusRouting`: `SFX = 0, UI = 1, MUSIC = 2`.
59+
New `SoundContainer` INI and Lua (R/W) property `PanningStrengthMultiplier`, 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.
60+
61+
- Tracy profiler integration.
62+
You can now attach Tracy to builds of the game and see profiling information about various zones and how long they take.
63+
This can also be used to profile specific lua scripts, with the following functions:
64+
`tracy.ZoneBegin()`, `tracy.ZoneEnd()` to profile a block of code.
65+
`tracy.ZoneBeginN(text)` to begin a custom named zone, and `tracy.ZoneName(text)` to dynamically set the current zone name on a per-call basis.
66+
`tracy.Message(text)` to send a tracy message.
67+
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.
5268

53-
- New `HeldDevice` Lua (R) function `IsBeingHeld`, which returns whether or not the `HeldDevice` is currently being held.
69+
- New `HeldDevice` Lua function `IsBeingHeld`, which returns whether or not the `HeldDevice` is currently being held.
5470

5571
- New `HeldDevice` INI and Lua (R/W) property `GetsHitByMOsWhenHeld`, which defines whether this `HeldDevice` can be hit by MOs while equipped and held by an actor. Defaults to true.
5672

@@ -78,13 +94,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
7894

7995
- New `SLTerrain` INI property `OrbitDirection`, 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 of `Up`, `Down`, `Left` or `Right`. Defaults to `Up`.
8096

81-
- New FMOD and SoundContainer features:
82-
The game is now divided into SFX, UI, and Music busses which all route into the Master bus.
83-
The SFX bus has compression added for a better listening experience, and a safety volume limiter has been added to the Master bus.
84-
Aside from volume being attenuated, sounds will now also be lowpass filtered as distance increases.
85-
New `SoundContainer` INI and Lua (R/W) property `BusRouting`, which denotes which bus the SoundContainer routes to. Available busses: `SFX, UI, Music`. Defaults to `SFX`.
86-
`Enum` binding for `SoundContainer.BusRouting`: `SFX = 0, UI = 1, MUSIC = 2`.
87-
New `SoundContainer` INI and Lua (R/W) property `PanningStrengthMultiplier`, 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.
97+
- New `Actor` Lua function `RemoveInventoryItemAtIndex`, with removes the `MovableObject` inventory item at a given index and returns.
98+
99+
- New `Scene` Lua functions `AddNavigatableArea(areaName)` and `ClearNavigatableAreas()`. This can be used to restrict pathfinding to only search a set of areas that have been added to the scene before via `Scene:SetArea(area)`.
88100

89101
</details>
90102

@@ -101,6 +113,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
101113

102114
Mods published for any development builds must match that development version exactly.
103115

116+
- Pressing F2 to reload scripts now also reloads the scripts for all MOs currently in the scene.
117+
118+
- Various optimizations to improve Lua performance.
119+
104120
- Lua `Scene.ScenePath` property has been changed to a function `Scene:GetScenePath()`. This was done for thread-safety with multithreading, but can be used in the same way.
105121

106122
- `CameraMan::SetScrollTarget()` function has had the `targetWrapped` parameter removed, as it's not necessary. The camera will always focus taking the shortest path regardless now. The new full function signature is `CameraMan::SetScrollTarget(target, speed, screenId)`, where speed defaults to 0.1 and screenId defaults to 0.

Entities/Activity.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ void Activity::Clear() {
6464
m_TeamFunds[team] = 2000;
6565
m_FundsChanged[team] = false;
6666
}
67+
68+
m_SavedValues.Reset();
6769
}
6870

6971
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Entities/Actor.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ void Actor::Clear() {
125125
m_MoveVector.Reset();
126126
m_MovePath.clear();
127127
m_UpdateMovePath = true;
128-
m_MoveProximityLimit = 75.0F;
128+
m_MoveProximityLimit = 20.0F;
129129
m_AIBaseDigStrength = c_PathFindingDefaultDigStrength;
130130
m_BaseMass = std::numeric_limits<float>::infinity();
131131

@@ -811,7 +811,7 @@ void Actor::RemoveInventoryItem(const std::string &moduleName, const std::string
811811

812812
MovableObject * Actor::RemoveInventoryItemAtIndex(int inventoryIndex) {
813813
if (inventoryIndex >= 0 && inventoryIndex < m_Inventory.size()) {
814-
MovableObject *itemAtIndex = m_Inventory.at(inventoryIndex);
814+
MovableObject *itemAtIndex = m_Inventory[inventoryIndex];
815815
m_Inventory.erase(m_Inventory.begin() + inventoryIndex);
816816
return itemAtIndex;
817817
}

Entities/Actor.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,6 +1368,18 @@ ClassInfoGetters;
13681368
/// <param name="newRecoverDelay">The recovery delay, in MS.</param>
13691369
void SetStableRecoverDelay(int newRecoverDelay) { m_StableRecoverDelay = newRecoverDelay; }
13701370

1371+
/// <summary>
1372+
/// Gets the distance in which the Actor will have considered itself to have reached it's waypoint.
1373+
/// </summary>
1374+
/// <returns>The move proximity limit.</returns>
1375+
float GetMoveProximityLimit() const { return m_MoveProximityLimit; }
1376+
1377+
/// <summary>
1378+
/// Sets the distance in which the Actor will have considered itself to have reached it's waypoint.
1379+
/// </summary>
1380+
/// <param name="newProximityLimit">The move proximity limit.</param>
1381+
void SetMoveProximityLimit(float newProximityLimit) { m_MoveProximityLimit = newProximityLimit; }
1382+
13711383
/// <summary>
13721384
/// Gets whether or not this Actor has the organic flag set and should be considered as organic.
13731385
/// </summary>

Entities/MOSRotating.cpp

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1881,13 +1881,20 @@ void MOSRotating::Draw(BITMAP *pTargetBitmap, const Vector &targetPos, DrawMode
18811881
}
18821882
}
18831883

1884+
#ifdef DRAW_MOID_LAYER
1885+
bool needsWrap = true;
1886+
#else
1887+
bool needsWrap = mode != g_DrawMOID;
1888+
#endif
1889+
1890+
18841891
// Take care of wrapping situations
18851892
Vector aDrawPos[4];
18861893
int passes = 1;
18871894

18881895
aDrawPos[0] = spritePos;
18891896

1890-
if (g_SceneMan.SceneWrapsX()) {
1897+
if (needsWrap && g_SceneMan.SceneWrapsX()) {
18911898
// See if need to double draw this across the scene seam if we're being drawn onto a scenewide bitmap
18921899
if (targetPos.IsZero() && m_WrapDoubleDraw) {
18931900
if (spritePos.m_X < m_SpriteDiameter) {
@@ -1915,16 +1922,24 @@ void MOSRotating::Draw(BITMAP *pTargetBitmap, const Vector &targetPos, DrawMode
19151922
}
19161923

19171924
if (m_HFlipped && pFlipBitmap) {
1918-
// Don't size the intermediate bitmaps to the m_Scale, because the scaling happens after they are done
1919-
clear_to_color(pFlipBitmap, keyColor);
1925+
#ifdef DRAW_MOID_LAYER
1926+
bool drawIntermediate = true;
1927+
#else
1928+
bool drawIntermediate = mode != g_DrawMOID;
1929+
#endif
19201930

1921-
// Draw either the source color bitmap or the intermediate material bitmap onto the intermediate flipping bitmap
1922-
if (mode == g_DrawColor || mode == g_DrawTrans) {
1923-
draw_sprite_h_flip(pFlipBitmap, m_aSprite[m_Frame], 0, 0);
1924-
} else {
1925-
// If using the temp bitmap (which is always larger than the sprite) make sure the flipped image ends up in the upper right corner as if it was just as small as the sprite bitmap
1926-
draw_sprite_h_flip(pFlipBitmap, pTempBitmap, -(pTempBitmap->w - m_aSprite[m_Frame]->w), 0);
1927-
}
1931+
if (drawIntermediate) {
1932+
// Don't size the intermediate bitmaps to the m_Scale, because the scaling happens after they are done
1933+
clear_to_color(pFlipBitmap, keyColor);
1934+
1935+
// Draw either the source color bitmap or the intermediate material bitmap onto the intermediate flipping bitmap
1936+
if (mode == g_DrawColor || mode == g_DrawTrans) {
1937+
draw_sprite_h_flip(pFlipBitmap, m_aSprite[m_Frame], 0, 0);
1938+
} else {
1939+
// If using the temp bitmap (which is always larger than the sprite) make sure the flipped image ends up in the upper right corner as if it was just as small as the sprite bitmap
1940+
draw_sprite_h_flip(pFlipBitmap, pTempBitmap, -(pTempBitmap->w - m_aSprite[m_Frame]->w), 0);
1941+
}
1942+
}
19281943

19291944
if (mode == g_DrawTrans) {
19301945
clear_to_color(pTempBitmap, keyColor);
@@ -2051,14 +2066,14 @@ void MOSRotating::CorrectAttachableAndWoundPositionsAndRotations() const {
20512066

20522067
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
20532068

2054-
void MOSRotating::OnGameSave() {
2055-
MovableObject::OnGameSave();
2069+
void MOSRotating::OnSave() {
20562070
for (AEmitter *wound : m_Wounds) {
2057-
wound->OnGameSave();
2071+
wound->OnSave();
20582072
}
20592073
for (Attachable *attachable : m_Attachables) {
2060-
attachable->OnGameSave();
2074+
attachable->OnSave();
20612075
}
2076+
MovableObject::OnSave();
20622077
}
20632078

20642079
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Entities/MOSRotating.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -832,7 +832,7 @@ ClassInfoGetters;
832832
/// <summary>
833833
/// Method to be run when the game is saved via ActivityMan::SaveCurrentGame. Not currently used in metagame or editor saving.
834834
/// </summary>
835-
void OnGameSave() override;
835+
void OnSave() override;
836836

837837

838838
//////////////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)