Skip to content

Commit

Permalink
#6092: Action parsing code and unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Sep 6, 2022
1 parent dcac59a commit f79e493
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 43 deletions.
15 changes: 15 additions & 0 deletions include/ifx.h
Expand Up @@ -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 :
Expand Down
93 changes: 50 additions & 43 deletions radiantcore/fx/FxAction.cpp
Expand Up @@ -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()
Expand Down Expand Up @@ -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;
Expand All @@ -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())
Expand Down Expand Up @@ -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();
Expand All @@ -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<float>(tokeniser.nextToken());
tokeniser.assertNextToken(",");
_lightRgbColour.y() = string::convert<float>(tokeniser.nextToken());
tokeniser.assertNextToken(",");
_lightRgbColour.z() = string::convert<float>(tokeniser.nextToken());
tokeniser.assertNextToken(",");
_lightRadius = string::convert<float>(tokeniser.nextToken());
}

#if 0
if (!token.Icmp("model")) {
src.ReadToken(&token);
FXAction.data = token;
Expand Down
10 changes: 10 additions & 0 deletions radiantcore/fx/FxAction.h
Expand Up @@ -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<FxAction>;
Expand Down Expand Up @@ -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
Expand Down
29 changes: 29 additions & 0 deletions test/Fx.cpp
Expand Up @@ -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(), "");
Expand All @@ -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));
}

}
20 changes: 20 additions & 0 deletions test/resources/tdm/fx/parsertest.fx
Expand Up @@ -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
{
{
Expand All @@ -147,3 +159,11 @@ fx fx/parserTest/attach
attachEntity "func_static_1"
}
}

fx fx/parserTest/projectile
{
{
delay 1.5
launch "atdm:projectile_broadhead"
}
}

0 comments on commit f79e493

Please sign in to comment.