Skip to content

Commit

Permalink
#5127: Move the algorithm to create a speaker to the core module, add…
Browse files Browse the repository at this point in the history
… corresponding "CreateSpeaker" command.
  • Loading branch information
codereader committed Jan 24, 2021
1 parent f8ce09d commit 4518031
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 46 deletions.
56 changes: 12 additions & 44 deletions radiant/ui/ortho/OrthoContextMenu.cpp
Expand Up @@ -43,7 +43,6 @@ namespace {
const char* LIGHT_CLASSNAME = "light";
const char* MODEL_CLASSNAME_ANIMATED = "func_animate";
const char* MODEL_CLASSNAME_STATIC = "func_static";
const char* SPEAKER_CLASSNAME = "speaker";
const char* PLAYERSTART_CLASSNAME = "info_player_start";

// Angle key for the player start
Expand Down Expand Up @@ -343,58 +342,27 @@ void OrthoContextMenu::callbackAddPrefab()

void OrthoContextMenu::callbackAddSpeaker()
{
ISoundShaderPtr soundShader;

// If we have an active sound module, query the desired shader from the user
if (module::GlobalModuleRegistry().moduleExists(MODULE_SOUNDMANAGER))
if (!module::GlobalModuleRegistry().moduleExists(MODULE_SOUNDMANAGER))
{
IResourceChooser* chooser = GlobalDialogManager().createSoundShaderChooser();

// Use a SoundChooser dialog to get a selection from the user
std::string shaderPath = chooser->chooseResource();

chooser->destroyDialog();

if (shaderPath.empty())
{
return; // user cancelled the dialog, don't do anything
}

soundShader = GlobalSoundManager().getSoundShader(shaderPath);
return;
}

UndoableCommand command("addSpeaker");

// Cancel all selection
GlobalSelectionSystem().setSelectedAll(false);

try
{
// Create the speaker entity
auto spkNode = GlobalEntityModule().createEntityFromSelection(
SPEAKER_CLASSNAME, _lastPoint
);

if (soundShader)
{
// Set the shader keyvalue
Entity& entity = spkNode->getEntity();
IResourceChooser* chooser = GlobalDialogManager().createSoundShaderChooser();

entity.setKeyValue("s_shader", soundShader->getName());
// Use a SoundChooser dialog to get a selection from the user
std::string shaderPath = chooser->chooseResource();

// Initialise the speaker with suitable distance values
SoundRadii radii = soundShader->getRadii();
chooser->destroyDialog();

entity.setKeyValue("s_mindistance", string::to_string(radii.getMin(true)));
entity.setKeyValue("s_maxdistance",
(radii.getMax(true) > 0 ? string::to_string(radii.getMax(true)) : "10")
);
}
}
catch (cmd::ExecutionFailure& e)
if (shaderPath.empty())
{
wxutil::Messagebox::ShowError(fmt::format(_("Unable to create speaker: {0}"), e.what()));
return; // user cancelled the dialog, don't do anything
}

GlobalCommandSystem().executeCommand("CreateSpeaker", {
cmd::Argument(shaderPath), cmd::Argument(_lastPoint)
});
}

void OrthoContextMenu::callbackAddModel()
Expand Down
10 changes: 8 additions & 2 deletions radiantcore/entity/EntityModule.cpp
@@ -1,6 +1,7 @@
#include "EntityModule.h"

#include "itextstream.h"
#include "icommandsystem.h"
#include "imap.h"
#include "iselection.h"
#include "i18n.h"
Expand All @@ -27,6 +28,7 @@
#include "selection/algorithm/Shader.h"
#include "command/ExecutionFailure.h"
#include "eclass.h"
#include "algorithm/Speaker.h"

namespace entity
{
Expand Down Expand Up @@ -279,16 +281,20 @@ const StringSet& Doom3EntityModule::getDependencies() const
_dependencies.insert(MODULE_XMLREGISTRY);
_dependencies.insert(MODULE_MAP);
_dependencies.insert(MODULE_GAMEMANAGER);
_dependencies.insert(MODULE_COMMANDSYSTEM);
}

return _dependencies;
}

void Doom3EntityModule::initialiseModule(const IApplicationContext& ctx)
{
rMessage() << getName() << "::initialiseModule called." << std::endl;
rMessage() << getName() << "::initialiseModule called." << std::endl;

LightShader::m_defaultShader = game::current::getValue<std::string>("/defaults/lightShader");
LightShader::m_defaultShader = game::current::getValue<std::string>("/defaults/lightShader");

GlobalCommandSystem().addCommand("CreateSpeaker", std::bind(&algorithm::CreateSpeaker, std::placeholders::_1),
{ cmd::ARGTYPE_STRING, cmd::ARGTYPE_VECTOR3 });
}

void Doom3EntityModule::shutdownModule()
Expand Down
66 changes: 66 additions & 0 deletions radiantcore/entity/algorithm/Speaker.h
@@ -0,0 +1,66 @@
#pragma once

#include "icommandsystem.h"
#include "itextstream.h"
#include "iundo.h"
#include "iselection.h"
#include "isound.h"
#include "fmt/format.h"
#include "command/ExecutionFailure.h"
#include "string/convert.h"

namespace entity
{

namespace algorithm
{

inline void CreateSpeaker(const cmd::ArgumentList& args)
{
constexpr const char* SPEAKER_CLASSNAME = "speaker";

if (args.size() != 2)
{
rWarning() << "Usage: CreateSpeaker <soundShader:string> <position:Vector3>" << std::endl;
return;
}

UndoableCommand command("addSpeaker");

// Cancel all selection
GlobalSelectionSystem().setSelectedAll(false);

// Create the speaker entity (exceptions are allowed to leak)
auto spkNode = GlobalEntityModule().createEntityFromSelection(
SPEAKER_CLASSNAME, args[1].getVector3()
);

auto shader = args[0].getString();

if (shader.empty() || !module::GlobalModuleRegistry().moduleExists(MODULE_SOUNDMANAGER))
{
return; // done here
}

auto soundShader = GlobalSoundManager().getSoundShader(shader);

if (!soundShader)
{
throw cmd::ExecutionFailure(fmt::format(_("Cannot find sound shader: {0}"), shader));
}

// Set the shader keyvalue
auto& entity = spkNode->getEntity();

entity.setKeyValue("s_shader", soundShader->getName());

// Initialise the speaker with suitable distance values
auto radii = soundShader->getRadii();

entity.setKeyValue("s_mindistance", string::to_string(radii.getMin(true)));
entity.setKeyValue("s_maxdistance", radii.getMax(true) > 0 ? string::to_string(radii.getMax(true)) : "10");
}

}

}
1 change: 1 addition & 0 deletions tools/msvc/DarkRadiantCore.vcxproj
Expand Up @@ -725,6 +725,7 @@
<ClInclude Include="..\..\radiantcore\eclass\Doom3ModelDef.h" />
<ClInclude Include="..\..\radiantcore\eclass\EClassColourManager.h" />
<ClInclude Include="..\..\radiantcore\eclass\EClassManager.h" />
<ClInclude Include="..\..\radiantcore\entity\algorithm\Speaker.h" />
<ClInclude Include="..\..\radiantcore\entity\AngleKey.h" />
<ClInclude Include="..\..\radiantcore\entity\ColourKey.h" />
<ClInclude Include="..\..\radiantcore\entity\curve\Curve.h" />
Expand Down
6 changes: 6 additions & 0 deletions tools/msvc/DarkRadiantCore.vcxproj.filters
Expand Up @@ -194,6 +194,9 @@
<Filter Include="src\decl">
<UniqueIdentifier>{90b48fa3-7e87-4565-8475-083668a5ad90}</UniqueIdentifier>
</Filter>
<Filter Include="src\entity\algorithm">
<UniqueIdentifier>{b7afddd6-8c82-4975-a947-00999bd70fec}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\radiantcore\modulesystem\ModuleLoader.cpp">
Expand Down Expand Up @@ -2073,5 +2076,8 @@
<ClInclude Include="..\..\radiantcore\decl\FavouriteSet.h">
<Filter>src\decl</Filter>
</ClInclude>
<ClInclude Include="..\..\radiantcore\entity\algorithm\Speaker.h">
<Filter>src\entity\algorithm</Filter>
</ClInclude>
</ItemGroup>
</Project>

0 comments on commit 4518031

Please sign in to comment.