18
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-11-14 16:50:53 +01:00
Files
maszyna/tests/unit/test_gauge_duplicates.cpp
jerrrrycho d259251373 feat: cab controls can animate duplicate submodels (eu07/maszyna#527)
A control defined again in the same cab section of the .mmd with the
block key "duplicate: yes" no longer replaces the control: the first
definition stays the control (sounds, type, command feedback), and the
duplicate adds a copy with its own submodel, animation type and scale /
offset, following the control's value and active state. The duplicate's
sound keys are ignored so the control is not heard twice, and clicking
any copy works the control. This lets e.g. the ASF cab move its second
master controller and reverser with the first ones.

Without the key a repeated definition still replaces the earlier one,
as some of the game's .mmd files repeat controls with other submodels.
A duplicate with no definition of the control loaded from the current
cab's models before it is just the control.

clear_cab_controls() now also clears ggCompressorListButton, which kept
the previous cab's submodel.

The rule is in vehicle/gaugeduplicates.h, covered by
tests/unit/test_gauge_duplicates.cpp.

(eu07/maszyna#527)
2026-11-07 23:19:53 +01:00

54 lines
2.1 KiB
C++

#include "stdafx.h"
#include "doctest.h"
#include "vehicle/gaugeduplicates.h"
// cab controls with more than one submodel (eu07/maszyna#527): a definition of a control in the .mmd marked
// "duplicate: yes" adds a copy of the control already defined in the cab, instead of replacing it. TGauge itself
// (3d models, sounds) is not part of the core library, the rule which decides it is
namespace {
// stand-ins for the 3d models of the cab
struct model {};
} // namespace
TEST_CASE("gauge duplicates: the values of the duplicate key which mark a duplicate") {
CHECK(gauge_duplicates::is_duplicate("yes"));
CHECK(gauge_duplicates::is_duplicate("true"));
CHECK(gauge_duplicates::is_duplicate("1"));
CHECK_FALSE(gauge_duplicates::is_duplicate("no"));
CHECK_FALSE(gauge_duplicates::is_duplicate("false"));
CHECK_FALSE(gauge_duplicates::is_duplicate("0"));
CHECK_FALSE(gauge_duplicates::is_duplicate(""));
}
TEST_CASE("gauge duplicates: a duplicate adds a copy to the control loaded from either model of the cab") {
model cab;
model lowpoly;
CHECK(gauge_duplicates::adds_copy<model>(true, &cab, &cab, &lowpoly));
CHECK(gauge_duplicates::adds_copy<model>(true, &lowpoly, &cab, &lowpoly));
// a cab without a low poly interior
CHECK(gauge_duplicates::adds_copy<model>(true, &cab, &cab, nullptr));
}
TEST_CASE("gauge duplicates: a definition not marked as a duplicate replaces the control, as before") {
model cab;
model lowpoly;
CHECK_FALSE(gauge_duplicates::adds_copy<model>(false, &cab, &cab, &lowpoly));
CHECK_FALSE(gauge_duplicates::adds_copy<model>(false, nullptr, &cab, &lowpoly));
}
TEST_CASE("gauge duplicates: with nothing loaded in this cab a duplicate is the control itself") {
model cab;
model lowpoly;
model previouscab;
// the control isn't defined before it
CHECK_FALSE(gauge_duplicates::adds_copy<model>(true, nullptr, &cab, &lowpoly));
CHECK_FALSE(gauge_duplicates::adds_copy<model>(true, nullptr, &cab, nullptr));
// the control is left over from the cab loaded before
CHECK_FALSE(gauge_duplicates::adds_copy<model>(true, &previouscab, &cab, &lowpoly));
CHECK_FALSE(gauge_duplicates::adds_copy<model>(true, &previouscab, &cab, nullptr));
}