Skip to content

Commit 0c39a47

Browse files
committed
Merge branch 'development' into cf/468-add-proper-semantic-version-comparison-to-check-mod-compatibility
2 parents f655759 + 4906192 commit 0c39a47

36 files changed

+1399
-275
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ compile_commands.json
1313

1414
/build*
1515

16+
/enc_temp_folder
17+
1618
/_Bin
1719
/NATPunchServer/Server/NATCompleteServer/Debug
1820
/NATPunchServer/Server/NATCompleteServer/Release

Activities/GibEditor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ void GibEditor::DrawGUI(BITMAP *pTargetBitmap, const Vector &targetPos, int whic
685685
// Draw ghost outline of edited object to place gibs upon
686686
if (m_pEditedObject)
687687
{
688-
g_FrameMan.SetTransTable(MoreTrans);
688+
g_FrameMan.SetTransTableFromPreset(TransparencyPreset::MoreTrans);
689689
// Draw only the MOSRotating since that's all we are adding gibs for; any attachables have to be edited separately
690690
m_pEditedObject->MOSRotating::Draw(pTargetBitmap, targetPos, g_DrawTrans, true);
691691
}

CHANGELOG.md

Lines changed: 160 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,157 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
208208
`PrimitiveMan:DrawLinePrimitive(player, startPos, endPos, color, thickness)`
209209
Original bindings with no thickness argument are untouched and can be called as they were.
210210

211+
- Added rotation option to Text primitives.
212+
New bindings with argument for rotation are:
213+
`PrimitiveMan:DrawTextPrimitive(pos, text, bool useSmallFont, alignment, rotAngleInRadians)`
214+
`PrimitiveMan:DrawTextPrimitive(player, pos, text, bool useSmallFont, alignment, rotAngleInRadians)`
215+
Original bindings with no rotation argument are untouched and can be called as they were.
216+
217+
- Added option to draw bitmap from file instead of from `MOSPrite` based object to Bitmap primitives.
218+
New bindings with argument for file path are:
219+
`PrimitiveMan:DrawBitmapPrimitive(pos, filePath, rotAngleInRadians)`
220+
`PrimitiveMan:DrawBitmapPrimitive(pos, filePath, rotAngleInRadians, hFlipped, vFlipped)`
221+
`PrimitiveMan:DrawBitmapPrimitive(player, pos, filePath, rotAngleInRadians)`
222+
`PrimitiveMan:DrawBitmapPrimitive(player, pos, filePath, rotAngleInRadians, hFlipped, vFlipped)`
223+
Note that the `frame` argument does not exist in these bindings.
224+
Original bindings with no filepath argument are untouched and can be called as they were.
225+
226+
- Added new primitive drawing functions to `PrimitiveMan`:
227+
```lua
228+
-- Polygon
229+
PrimitiveMan:DrawPolygonPrimitive(Vector startPos, color, { Vector vertexRelPos, ... })
230+
PrimitiveMan:DrawPolygonPrimitive(player, Vector startPos, { Vector vertexRelPos, ... })
231+
232+
PrimitiveMan:DrawPolygonFillPrimitive(Vector startPos, color, { Vector vertexRelPos, ... })
233+
PrimitiveMan:DrawPolygonFillPrimitive(player, Vector startPos, { Vector vertexRelPos, ... })
234+
```
235+
The vertices table contains `Vector`s 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.
236+
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.
237+
There may be a limit for the number of vertices in `PolygonFillPrimitive` because it has different handling but it was not reached during testing.
238+
239+
The order of vertices is of high importance. Bad ordering will lead to unexpected results.
240+
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.
241+
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.
242+
Omitting the last `Vector(0, 0)` in the above example would result in a right angle triangle.
243+
244+
**The `Vector`s in the vertices table are single use! They will be deleted after being drawn, so they cannot be re-used!**
245+
246+
Usage example:
247+
```lua
248+
local myVertices = {
249+
Vector(10, 0),
250+
Vector(10, 10),
251+
Vector(0, 10),
252+
Vector(0, 0)
253+
};
254+
PrimitiveMan:DrawPolygonPrimitive(self.Pos, 13, myVertices);
255+
256+
-- myVertices no longer contains valid Vectors for this call, they were deleted after being drawn by the previous call.
257+
PrimitiveMan:DrawPolygonFillPrimitive(self.Pos, 13, {
258+
Vector(10, 0),
259+
Vector(10, 10),
260+
Vector(0, 10),
261+
Vector(0, 0)
262+
});
263+
```
264+
265+
- Added blended drawing functions to `PrimitiveMan`:
266+
There are 10 blending modes available to produce different color and transparency effects for both true primitives and bitmap based primitives.
267+
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.
268+
269+
**Note that blended drawing is very expensive and chugs FPS like no tomorrow. It should not be abused!**
270+
271+
There are 3 blended drawing function overloads:
272+
273+
* `PrimitiveMan:DrawPrimitives(blendMode, blendAmountR, blendAmountG, blendAmountB, blendAmountA, { primitiveObj, ... })`
274+
This is the fully fledged blended drawing function which allows individual control over each color channel blend amount.
275+
Blend amounts are in percentages, where 0 means no blending and 100 means full blending (e.g. `blendAmountA = 100` will result in a fully transparent primitive, as if it was not drawn at all).
276+
The blend mode and amounts will be applied to all the primitives in the primitive table.
277+
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.
278+
279+
* `PrimitiveMan:DrawPrimitives(blendMode, blendAmountRGBA, { primitiveObj, ... })`
280+
This overload allows selecting a blend mode and applies the blend amount to all color channels at once.
281+
This overload is for convenience when using certain modes (e.g. `Invert` and `Dissolve`). See blend mode specifics further below.
282+
283+
* `PrimitiveMan:DrawPrimitives(transBlendAmount, { primitiveObj, ... })`
284+
This overload uses the transparency blending mode and applies the blend amount to all color channels at once.
285+
Transparency blending is likely to be the most commonly used mode so this exists for convenience.
286+
287+
The blending modes are defined in the new `DrawBlendMode` enum as follows:
288+
```
289+
(0) NoBlend
290+
(1) Burn
291+
(2) Color
292+
(3) Difference
293+
(4) Dissolve
294+
(5) Dodge
295+
(6) Invert
296+
(7) Luminance
297+
(8) Multiply
298+
(9) Saturation
299+
(10) Screen
300+
(11) Transparency
301+
(12) BlendModeCount
302+
```
303+
The blending modes are common and information on what the result of each is can be found with a quick search.
304+
305+
Some blend mode specifics:
306+
* `Invert` and `Dissolve` modes only use alpha channel blend amount. RGB channels blend amounts are ignored in these modes.
307+
* `Transparency` mode ignores alpha channel blend amount. Only RGB channels blend amounts are used in this mode.
308+
* Some trial and error is expected to produce desired results in other modes.
309+
310+
The primitives table must be filled with `GraphicalPrimitive` objects. For this the constructors for all the supported primitives have been exposed:
311+
```lua
312+
LinePrimitive(player, startPos, endPos, color)
313+
ArcPrimitive(player, centerPos, startAngle, endAngle, radius, thickness, color)
314+
SplinePrimitive(player, startPos, guideA, guideB, endPos, color)
315+
BoxPrimitive(player, topLeftPos, bottomRightPos, color)
316+
BoxFillPrimitive(player, topLeftPos, bottomRightPos, color)
317+
RoundedBoxPrimitive(player, topLeftPos, bottomRightPos, cornerRadius, color)
318+
RoundedBoxFillPrimitive(player, topLeftPos, bottomRightPos, cornerRadius, color)
319+
CirclePrimitive(player, centerPos, radius, color)
320+
CircleFillPrimitive(player, centerPos, radius, color)
321+
EllipsePrimitive(player, centerPos, horizRadius, vertRadius, color)
322+
EllipseFillPrimitive(player, centerPos, horizRadius, vertRadius, color)
323+
TrianglePrimitive(player, pointA, pointB, pointC, color)
324+
TriangleFillPrimitive(player, pointA, pointB, pointC, color)
325+
TextPrimitive(player, pos, text, useSmallFont, alignment, rotAngle)
326+
BitmapPrimitive(player, centerPos, moSprite, rotAngle, frame, hFlipped, vFlipped)
327+
BitmapPrimitive(player, centerPos, filePath, rotAngle, hFlipped, vFlipped)
328+
```
329+
Note that `PolygonPrimitive`, `IconPrimitive` and `LinePrimitive` with thickness do not support blended drawing.
330+
331+
**The `GraphicalPrimitive`s in the primitives table are single use! They will be deleted after being drawn, so they cannot be re-used!**
332+
333+
Usage example:
334+
```lua
335+
local myPrimitives = {
336+
CircleFillPrimitive(-1, self.Pos + Vector(-100, 0), 20, 13),
337+
BitmapPrimitive(-1, self.Pos + Vector(100, 0), "Base.rte/Craft/Rockets/MK2/RocketMK2000.png", 0, false, false)
338+
};
339+
PrimitiveMan:DrawPrimitives(DrawBlendMode.Screen, 50, 0, 50, 0, myPrimitives);
340+
341+
-- myPrimitives no longer contains valid primitives for this call, they were deleted after being drawn by the previous call.
342+
PrimitiveMan:DrawPrimitives(DrawBlendMode.Dissolve, 50, {
343+
CircleFillPrimitive(-1, self.Pos + Vector(-100, -100), 20, 13),
344+
BitmapPrimitive(-1, self.Pos + Vector(100, -100), "Base.rte/Craft/Rockets/MK2/RocketMK2000.png", 0, false, false)
345+
});
346+
347+
PrimitiveMan:DrawPrimitives(50, {
348+
CircleFillPrimitive(-1, self.Pos + Vector(-100, -200), 20, 13),
349+
BitmapPrimitive(-1, self.Pos + Vector(100, -200), "Base.rte/Craft/Rockets/MK2/RocketMK2000.png", 0, false, false)
350+
});
351+
352+
-- NoBlend will draw the primitives without any blending mode (solid mode). Any color channel blend amounts are ignored.
353+
PrimitiveMan:DrawPrimitives(DrawBlendMode.NoBlend, 0, 0, 0, 0, {
354+
CircleFillPrimitive(-1, self.Pos + Vector(-100, -300), 20, 13),
355+
BitmapPrimitive(-1, self.Pos + Vector(100, -300), "Base.rte/Craft/Rockets/MK2/RocketMK2000.png", 0, false, false)
356+
});
357+
-- It is equivalent to calling the individual draw functions like so:
358+
-- PrimitiveMan:DrawCircleFillPrimitive(-1, self.Pos + Vector(-100, -200), 20, 13);
359+
-- PrimitiveMan:DrawBitmapPrimitive(-1, self.Pos + Vector(100, -200), "Base.rte/Craft/Rockets/MK2/RocketMK2000.png", 0, false, false);
360+
```
361+
211362
- New `Vector` Lua (R/O) property `SqrMagnitude` which returns the squared magnitude of the `Vector`.
212363
Should be used for more efficient comparison with `vector.SqrMagnitude > (floatValue * floatValue)` over `vector.Magnitude > floatValue`.
213364

@@ -308,7 +459,9 @@ This can be accessed via the new Lua (R/W) `SettingsMan` property `AIUpdateInter
308459
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.
309460
Results will obviously vary depending on system performance.
310461

311-
- Added `LuaMan` Lua functions `GetDirectoryList(pathToGetDirectoryNamesIn)` and `GetFileList(pathToGetFileNamesIn)`, that get the names of all directories or files at the specified file path.
462+
- Added `LuaMan` Lua functions `GetDirectoryList(pathToGetDirectoryNamesIn)` and `GetFileList(pathToGetFileNamesIn)`, that get the names of all directories or files at the specified file path.
463+
464+
- Added a new Lua scripted function for `Actor`s: `OnControllerInputModeChange(self, previousControllerMode, previousControllingPlayer)` that triggers when an `Actor`'s `Controller`'s input state changes (between AI/Player/Network control etc). This provides a script hook that fires when a player starts/stops controlling an `Actor`.
312465

313466
- Added `ACrab` INI properties for setting individual foot `AtomGroup`s, as opposed to setting the same foot `AtomGroup`s for both `Legs` on the left or right side.
314467
These are `LeftFGFootGroup`, `LeftBGFootGroup`, `RightFGFootGroup` and `RightBGFootGroup`.
@@ -319,6 +472,9 @@ This can be accessed via the new Lua (R/W) `SettingsMan` property `AIUpdateInter
319472

320473
- Added Lua access (R/W) to `Attachable` property `DeleteWhenRemovedFromParent`, which determines whether the given `Attachable` should delete itself when it's removed from its current parent.
321474

475+
- Added Lua convenience function `RoundToNearestMultiple(num, multiple)` which returns a number rounded to the nearest specified multiple.
476+
Note that this operates on integers, so fractional parts will be truncated towards zero by type conversion.
477+
322478
</details>
323479

324480
<details><summary><b>Changed</b></summary>
@@ -470,6 +626,9 @@ As such, the `Index.ini` property `SupportedGameVersion` must now be a valid sem
470626

471627
Mods published for any development builds must match that development version exactly.
472628

629+
- `BitmapPrimitive` drawing functions now accept `MOSprite` instead of `Entity` for the object they get the bitmap to draw from.
630+
This changes nothing regarding the bindings, but will now print an error to the console when attempting to draw a non-`MOSprite` based object (e.g. `MOPixel`), instead of silently skipping it.
631+
473632
</details>
474633

475634
<details><summary><b>Fixed</b></summary>

Entities/Actor.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -616,9 +616,16 @@ void Actor::SetTeam(int team)
616616

617617
void Actor::SetControllerMode(Controller::InputMode newMode, int newPlayer)
618618
{
619+
620+
Controller::InputMode previousControllerMode = m_Controller.GetInputMode();
621+
int previousControllingPlayer = m_Controller.GetPlayer();
622+
619623
m_Controller.SetInputMode(newMode);
620624
m_Controller.SetPlayer(newPlayer);
621625

626+
RunScriptedFunctionInAppropriateScripts("OnControllerInputModeChange", false, false, {}, {std::to_string(previousControllerMode), std::to_string(previousControllingPlayer) });
627+
628+
622629
// So the AI doesn't jerk around
623630
m_StuckTimer.Reset();
624631

@@ -635,13 +642,7 @@ void Actor::SetControllerMode(Controller::InputMode newMode, int newPlayer)
635642
Controller::InputMode Actor::SwapControllerModes(Controller::InputMode newMode, int newPlayer)
636643
{
637644
Controller::InputMode returnMode = m_Controller.GetInputMode();
638-
m_Controller.SetInputMode(newMode);
639-
m_Controller.SetPlayer(newPlayer);
640-
641-
// So the AI doesn't jerk around
642-
m_StuckTimer.Reset();
643-
644-
m_NewControlTmr.Reset();
645+
SetControllerMode(newMode, newPlayer);
645646
return returnMode;
646647
}
647648

Entities/Actor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class Actor : public MOSRotating {
7575

7676
// Concrete allocation and cloning definitions
7777
EntityAllocation(Actor);
78-
AddScriptFunctionNames(MOSRotating, "UpdateAI");
78+
AddScriptFunctionNames(MOSRotating, "UpdateAI", "OnControllerInputModeChange");
7979
SerializableOverrideMethods;
8080
ClassInfoGetters;
8181

Entities/PieMenu.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ namespace RTE {
589589

590590
if (m_EnabledState != EnabledState::Disabled) {
591591
if (m_DrawBackgroundTransparent && !g_FrameMan.IsInMultiplayerMode()) {
592-
g_FrameMan.SetTransTable(MoreTrans);
592+
g_FrameMan.SetTransTableFromPreset(TransparencyPreset::MoreTrans);
593593
draw_trans_sprite(targetBitmap, m_BGBitmap, drawPos.GetFloorIntX() - m_BGBitmap->w / 2, drawPos.GetFloorIntY() - m_BGBitmap->h / 2);
594594
} else {
595595
draw_sprite(targetBitmap, m_BGBitmap, drawPos.GetFloorIntX() - m_BGBitmap->w / 2, drawPos.GetFloorIntY() - m_BGBitmap->h / 2);

Entities/PieSlice.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,11 @@ namespace RTE {
8181
m_Direction = c_DirectionNameToDirectionsMap.find(directionString)->second;
8282
} else {
8383
try {
84-
m_Direction = static_cast<Directions>(std::stoi(directionString));
84+
int direction = std::stoi(directionString);
85+
if (direction < Directions::None || direction > Directions::Any) {
86+
reader.ReportError("Direction " + directionString + " is invalid (Out of Bounds).");
87+
}
88+
m_Direction = static_cast<Directions>(direction);
8589
} catch (const std::invalid_argument &) {
8690
reader.ReportError("Direction " + directionString + " is invalid.");
8791
}

0 commit comments

Comments
 (0)