From f79e493f68d9a87d42f4e8038507f2ea3dab208b Mon Sep 17 00:00:00 2001 From: codereader Date: Tue, 6 Sep 2022 12:32:36 +0200 Subject: [PATCH] #6092: Action parsing code and unit tests --- include/ifx.h | 15 +++++ radiantcore/fx/FxAction.cpp | 93 ++++++++++++++++------------- radiantcore/fx/FxAction.h | 10 ++++ test/Fx.cpp | 29 +++++++++ test/resources/tdm/fx/parsertest.fx | 20 +++++++ 5 files changed, 124 insertions(+), 43 deletions(-) diff --git a/include/ifx.h b/include/ifx.h index 324be080d5..9adc4a2aa1 100644 --- a/include/ifx.h +++ b/include/ifx.h @@ -91,11 +91,26 @@ class IFxAction // Returns the name of the action containing the light which should be used virtual const std::string& getUseLight() = 0; + // Modify the model in a named sibling action. Can be used to fade out a particle in a sibling. + virtual const std::string& getUseModel() = 0; + // Attach to external light (a light not defined in the effect) for fading. virtual const std::string& getAttachLight() = 0; // Attach to an external entity virtual const std::string& getAttachEntity() = 0; + + // Launches a projectile of the given entityDef + virtual const std::string& getLaunchProjectileDef() = 0; + + // If not empty, this action spawns a light with this material + virtual const std::string& getLightMaterialName() = 0; + + // For Type::Light actions, this defines the RGB colour components + virtual const Vector3& getLightRgbColour() = 0; + + // For Type::Light actions, this defines the radius of the spawned light + virtual float getLightRadius() = 0; }; class IFxDeclaration : diff --git a/radiantcore/fx/FxAction.cpp b/radiantcore/fx/FxAction.cpp index c01d52137a..6bd37297ad 100644 --- a/radiantcore/fx/FxAction.cpp +++ b/radiantcore/fx/FxAction.cpp @@ -28,7 +28,9 @@ FxAction::FxAction(FxDeclaration& fx) : _decalSize(0), _offset(0,0,0), _axis(0,0,0), - _angle(0,0,0) + _angle(0,0,0), + _lightRgbColour(0, 0, 0), + _lightRadius(0) {} FxAction::Type FxAction::getType() @@ -146,6 +148,11 @@ const std::string& FxAction::getUseLight() return _useLightAction; } +const std::string& FxAction::getUseModel() +{ + return _useModelAction; +} + const std::string& FxAction::getAttachLight() { return _attachLightName; @@ -156,6 +163,26 @@ const std::string& FxAction::getAttachEntity() return _attachEntityName; } +const std::string& FxAction::getLaunchProjectileDef() +{ + return _launchProjectileDefName; +} + +const std::string& FxAction::getLightMaterialName() +{ + return _lightMaterialName; +} + +const Vector3& FxAction::getLightRgbColour() +{ + return _lightRgbColour; +} + +float FxAction::getLightRadius() +{ + return _lightRadius; +} + void FxAction::parseFromTokens(parser::DefTokeniser& tokeniser) { while (tokeniser.hasMoreTokens()) @@ -263,6 +290,11 @@ void FxAction::parseFromTokens(parser::DefTokeniser& tokeniser) _useLightAction = tokeniser.nextToken(); _type = Type::Light; } + else if (token == "usemodel") + { + _useModelAction = tokeniser.nextToken(); + _type = Type::Model; + } else if (token == "attachlight") { _attachLightName = tokeniser.nextToken(); @@ -273,50 +305,25 @@ void FxAction::parseFromTokens(parser::DefTokeniser& tokeniser) _attachEntityName = tokeniser.nextToken(); _type = Type::AttachEntity; } -#if 0 - if (!token.Icmp("launch")) { - src.ReadToken(&token); - FXAction.data = token; - FXAction.type = FX_LAUNCH; - - // precache the entity def - declManager->FindType(DECL_ENTITYDEF, FXAction.data); - continue; - } - - if (!token.Icmp("useModel")) { - src.ReadToken(&token); - FXAction.data = token; - for (int i = 0; i < events.Num(); i++) { - if (events[i].name.Icmp(FXAction.data) == 0) { - FXAction.sibling = i; - } - } - FXAction.type = FX_MODEL; - - // precache the model - renderModelManager->FindModel(FXAction.data); - continue; + else if (token == "launch") + { + _launchProjectileDefName = tokeniser.nextToken(); + _type = Type::Launch; } - - if (!token.Icmp("light")) { - src.ReadToken(&token); - FXAction.data = token; - src.ExpectTokenString(","); - FXAction.lightColor[0] = src.ParseFloat(); - src.ExpectTokenString(","); - FXAction.lightColor[1] = src.ParseFloat(); - src.ExpectTokenString(","); - FXAction.lightColor[2] = src.ParseFloat(); - src.ExpectTokenString(","); - FXAction.lightRadius = src.ParseFloat(); - FXAction.type = FX_LIGHT; - - // precache the light material - declManager->FindMaterial(FXAction.data); - continue; + else if (token == "light") + { + _type = Type::Light; + _lightMaterialName = tokeniser.nextToken(); + tokeniser.assertNextToken(","); + _lightRgbColour.x() = string::convert(tokeniser.nextToken()); + tokeniser.assertNextToken(","); + _lightRgbColour.y() = string::convert(tokeniser.nextToken()); + tokeniser.assertNextToken(","); + _lightRgbColour.z() = string::convert(tokeniser.nextToken()); + tokeniser.assertNextToken(","); + _lightRadius = string::convert(tokeniser.nextToken()); } - +#if 0 if (!token.Icmp("model")) { src.ReadToken(&token); FXAction.data = token; diff --git a/radiantcore/fx/FxAction.h b/radiantcore/fx/FxAction.h index 32e775012a..1446b43473 100644 --- a/radiantcore/fx/FxAction.h +++ b/radiantcore/fx/FxAction.h @@ -37,8 +37,13 @@ class FxAction : Vector3 _axis; Vector3 _angle; std::string _useLightAction; + std::string _useModelAction; std::string _attachLightName; std::string _attachEntityName; + std::string _launchProjectileDefName; + std::string _lightMaterialName; + Vector3 _lightRgbColour; + float _lightRadius; public: using Ptr = std::shared_ptr; @@ -68,8 +73,13 @@ class FxAction : const Vector3& getAxis() override; const Vector3& getAngle() override; const std::string& getUseLight() override; + const std::string& getUseModel() override; const std::string& getAttachLight() override; const std::string& getAttachEntity() override; + const std::string& getLaunchProjectileDef() override; + const std::string& getLightMaterialName() override; + const Vector3& getLightRgbColour() override; + float getLightRadius() override; // Parses the action from the given tokens. // The opening brace { will already have been been consumed by the calling code diff --git a/test/Fx.cpp b/test/Fx.cpp index a115ace911..4c437220e3 100644 --- a/test/Fx.cpp +++ b/test/Fx.cpp @@ -165,6 +165,15 @@ TEST_F(FxTest, ParseActionUseLight) EXPECT_EQ(getFxByName("fx/parserTest/useLight")->getAction(1)->getType(), fx::IFxAction::Type::Light); } +TEST_F(FxTest, ParseActionUseModel) +{ + EXPECT_EQ(getFxByName("fx/sparks")->getAction(0)->getUseModel(), ""); + + EXPECT_EQ(getFxByName("fx/parserTest/useModel")->getAction(1)->getUseModel(), "ModelOwner"); + // UseModel implies that the action is of type Model + EXPECT_EQ(getFxByName("fx/parserTest/useModel")->getAction(1)->getType(), fx::IFxAction::Type::Model); +} + TEST_F(FxTest, ParseActionAttachLight) { EXPECT_EQ(getFxByName("fx/sparks")->getAction(0)->getAttachLight(), ""); @@ -181,4 +190,24 @@ TEST_F(FxTest, ParseActionAttachEntity) EXPECT_EQ(getFxByName("fx/parserTest/attach")->getAction(1)->getType(), fx::IFxAction::Type::AttachEntity); } +TEST_F(FxTest, ParseActionLaunchProjectile) +{ + EXPECT_EQ(getFxByName("fx/sparks")->getAction(0)->getLaunchProjectileDef(), ""); + + EXPECT_EQ(getFxByName("fx/parserTest/projectile")->getAction(0)->getLaunchProjectileDef(), "atdm:projectile_broadhead"); + EXPECT_EQ(getFxByName("fx/parserTest/projectile")->getAction(0)->getType(), fx::IFxAction::Type::Launch); +} + +TEST_F(FxTest, ParseActionLight) +{ + EXPECT_EQ(getFxByName("fx/parserTest/shake")->getAction(0)->getLightMaterialName(), ""); + EXPECT_EQ(getFxByName("fx/parserTest/shake")->getAction(0)->getLightRadius(), 0.0f); + EXPECT_EQ(getFxByName("fx/parserTest/shake")->getAction(0)->getLightRgbColour(), Vector3(0,0,0)); + + EXPECT_EQ(getFxByName("fx/parserTest/useLight")->getAction(0)->getType(), fx::IFxAction::Type::Light); + EXPECT_EQ(getFxByName("fx/parserTest/useLight")->getAction(0)->getLightMaterialName(), "lights/biground"); + EXPECT_EQ(getFxByName("fx/parserTest/useLight")->getAction(0)->getLightRadius(), 550.3f); + EXPECT_TRUE(math::isNear(getFxByName("fx/parserTest/useLight")->getAction(0)->getLightRgbColour(), Vector3(0.5, 1, 0.7), 0.001f)); +} + } diff --git a/test/resources/tdm/fx/parsertest.fx b/test/resources/tdm/fx/parsertest.fx index 1114d5fd03..7effffa80a 100644 --- a/test/resources/tdm/fx/parsertest.fx +++ b/test/resources/tdm/fx/parsertest.fx @@ -136,6 +136,18 @@ fx fx/parserTest/useLight } } +fx fx/parserTest/useModel +{ + { + delay 1.5 + name "ModelOwner" + } + { + useModel "ModelOwner" + fadeOut 0.5 + } +} + fx fx/parserTest/attach { { @@ -147,3 +159,11 @@ fx fx/parserTest/attach attachEntity "func_static_1" } } + +fx fx/parserTest/projectile +{ + { + delay 1.5 + launch "atdm:projectile_broadhead" + } +}