224 lines
8.1 KiB
C++
Executable File
224 lines
8.1 KiB
C++
Executable File
/**
|
|
* Handler for player data
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by hjl, SLSE, 2017-02-20
|
|
*/
|
|
|
|
#include "handler_artillerie_sound.h"
|
|
#include "settings.h"
|
|
|
|
#include <LtsUtilsSettings/settings.h>
|
|
|
|
#include <QNetworkReply>
|
|
#include <qmath.h>
|
|
#include <math.h>
|
|
|
|
namespace CesArtillerySound
|
|
{
|
|
|
|
HandlerArtillerieSound::HandlerArtillerieSound(const std::shared_ptr<CentralEffectSimulation::DdsHandler> &ddsHandler,
|
|
const std::shared_ptr<CentralEffectSimulation::HandlerBuildingData> &buildingDataHandler,
|
|
QObject *parent)
|
|
: QObject(parent)
|
|
, m_ddsHandler(ddsHandler)
|
|
, m_handlerBuildingData(buildingDataHandler)
|
|
, m_logger(CentralEffectSimulation::getLogger("Plugin.ArtillerySound.HandlerArtillerieSound"))
|
|
{
|
|
}
|
|
|
|
HandlerArtillerieSound::~HandlerArtillerieSound()
|
|
{
|
|
} // end of dtor()
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool HandlerArtillerieSound::init()
|
|
{
|
|
|
|
if (Settings::cesPlayArtillerieSounds())
|
|
{
|
|
DEBUG_LOG(m_logger) << "init with Artillerie-Sounds";
|
|
auto dtcAes = m_ddsHandler->dtcAes();
|
|
|
|
dtcAes->enableExplosionSingle();
|
|
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::explosionSingleChanged,
|
|
this, &HandlerArtillerieSound::onExplosionSingleChanged);
|
|
|
|
dtcAes->enableTechnicalArea();
|
|
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::technicalAreaChanged,
|
|
this, &HandlerArtillerieSound::onTechnicalAreaChanged);
|
|
}
|
|
else
|
|
DEBUG_LOG(m_logger) << "init without Artillerie-Sounds";
|
|
return true;
|
|
} // end of init()
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
void HandlerArtillerieSound::onExplosionSingleChanged(const AreaEffectSimulation::ExplosionSingle &data, DataModification modType)
|
|
{
|
|
bool handleExplosion = false;
|
|
if (modType != DataModification::eAdded &&
|
|
modType != DataModification::eModified)
|
|
{
|
|
m_explosionSingleState.remove(data.id());
|
|
return;
|
|
}
|
|
|
|
if (data.effectStateId() == AreaEffectSimulation::AesEffectState_def::EsRemoved)
|
|
{
|
|
DEBUG_LOG(m_logger) << "Remove SingleExplosion";
|
|
m_explosionSingleState.remove(data.id());
|
|
return;
|
|
}
|
|
// Only handle transitions from prepared or fired to activated
|
|
if ((m_explosionSingleState.value(data.id()) == AreaEffectSimulation::AesEffectState_def::EsPrepared ||
|
|
m_explosionSingleState.value(data.id()) == AreaEffectSimulation::AesEffectState_def::EsFired) &&
|
|
data.effectStateId() == AreaEffectSimulation::AesEffectState_def::EsActivated)
|
|
{
|
|
DEBUG_LOG(m_logger) << "Handle SingleExplosion";
|
|
handleExplosion = true;
|
|
}
|
|
m_explosionSingleState.insert(data.id(), data.effectStateId());
|
|
|
|
|
|
DEBUG_LOG(m_logger) << "Got ExplosionSingle State=" << data.effectStateId()
|
|
<< " id=" << data.id();
|
|
if (handleExplosion)
|
|
{
|
|
DEBUG_LOG(m_logger) << "Handle ExplosionSingle (EsActivated) HandlerArtillerieSound";
|
|
|
|
auto assetPositions = m_handlerBuildingData->getAssetPositions();
|
|
///////////////////////////////////////////////////////////////////
|
|
/// Play Sound to each EGCU and OSGU volume depends on distance
|
|
///////////////////////////////////////////////////////////////////
|
|
INFO_LOG(m_logger) << "printAssetPositions: ";
|
|
QHashIterator<int, CentralEffectSimulation::HandlerBuildingData::AssetPosition> i(assetPositions);
|
|
while (i.hasNext())
|
|
{
|
|
i.next();
|
|
INFO_LOG(m_logger) << "printAssetPositions: "
|
|
<< i.key() << ": " << i.value().structureElementId
|
|
<< " type = " << i.value().mountingPointType
|
|
<< " hostname =" << i.value().hostname
|
|
<< " pos=" << i.value().geoPosition
|
|
<< " posUtm=" << i.value().positionUtm.x()
|
|
<< "/" << i.value().positionUtm.y()
|
|
<< " zone=" << i.value().zone;
|
|
// Calculate the distance between the speaker and the explosion
|
|
const QPointF posExplosionUtm = CentralEffectSimulation::geographic2Utm(data.impactPosition(), i.value().zone);
|
|
const qreal distance = qSqrt(qPow(posExplosionUtm.x() - i.value().positionUtm.x(), 2) + qPow(posExplosionUtm.y() - i.value().positionUtm.y(), 2));
|
|
int sound = Settings::cesSoundId();
|
|
const qreal distanceThreshold = Settings::cesDistanceThreshold(); // [m]
|
|
const qreal factor = Settings::cesFactor();
|
|
const qreal cesReduceFactor = Settings::cesReduceFactor();
|
|
INFO_LOG(m_logger) << "Distance to Explosion =" << distance
|
|
<< " hostname =" << i.value().hostname
|
|
<< " distanceThreshold=" << distanceThreshold
|
|
<< " factor=" << factor;
|
|
qreal volumePercent = 100;
|
|
if (distance > distanceThreshold)
|
|
volumePercent = factor * log10(distance) * cesReduceFactor;
|
|
QString user = Settings::cesUser();
|
|
QString passwd = Settings::cesPasswd();
|
|
playSound(user, passwd, i.value().hostname, sound, volumePercent);
|
|
}
|
|
}
|
|
|
|
} // onExplosionSingleChanged
|
|
|
|
void HandlerArtillerieSound::playSound(QString &user, QString &passwd, const QString &host, int &sound, qreal &volume)
|
|
{
|
|
QUrl url;
|
|
QString request = QStringLiteral("http://%1/hitsound.php?sound=%2&vol=%3")
|
|
.arg(host)
|
|
.arg(sound)
|
|
.arg(volume);
|
|
url.setUrl(request);
|
|
url.setUserName(user);
|
|
url.setPassword(passwd);
|
|
DEBUG_LOG(m_logger) << "startRequest: " << url.toString();
|
|
startRequest(url);
|
|
}
|
|
|
|
void HandlerArtillerieSound::startRequest(const QUrl &requestedUrl)
|
|
{
|
|
DEBUG_LOG(m_logger) << "startRequest: " << requestedUrl.toString();
|
|
m_httpRequestAborted = false;
|
|
auto reply = m_qnam.get(QNetworkRequest(requestedUrl));
|
|
connect(reply, &QNetworkReply::finished, this, &HandlerArtillerieSound::httpFinished);
|
|
}
|
|
|
|
|
|
void HandlerArtillerieSound::httpFinished()
|
|
{
|
|
DEBUG_LOG(m_logger) << "httpFinished";
|
|
auto reply = qobject_cast<QNetworkReply *>(sender());
|
|
if (!reply)
|
|
return;
|
|
|
|
if (m_httpRequestAborted)
|
|
{
|
|
ERROR_LOG(m_logger) << "httpRequestAborted";
|
|
reply->deleteLater();
|
|
return;
|
|
}
|
|
|
|
if (reply->error())
|
|
{
|
|
QNetworkRequest request = reply->request();
|
|
QUrl url = request.url();
|
|
ERROR_LOG(m_logger) << "reply->error: " << reply->errorString()
|
|
<< " host=" << url.host()
|
|
<< " query='" << url.query()
|
|
<< "' '" << qUtf8Printable(url.toString()) << "'";
|
|
reply->deleteLater();
|
|
return;
|
|
}
|
|
|
|
|
|
// Sucess
|
|
|
|
//parse the reply JSON and display result in the UI
|
|
const QByteArray json(reply->readAll());
|
|
DEBUG_LOG(m_logger) << "Sucess " << json;
|
|
|
|
reply->deleteLater();
|
|
}
|
|
|
|
|
|
void HandlerArtillerieSound::onTechnicalAreaChanged(const AreaEffectSimulation::TechnicalArea &data, DataModification modType)
|
|
{
|
|
if (modType != DataModification::eAdded &&
|
|
modType != DataModification::eModified)
|
|
{
|
|
m_technicalAreas.remove(data.id());
|
|
return;
|
|
}
|
|
|
|
if (data.effectStateId() == AreaEffectSimulation::AesEffectState_def::EsRemoved)
|
|
{
|
|
DEBUG_LOG(m_logger) << "Remove TechnicalArea";
|
|
m_technicalAreas.remove(data.id());
|
|
return;
|
|
}
|
|
if (data.type() == AreaEffectSimulation::AesTechnicalAreaType_def::TatSoundZone)
|
|
{
|
|
int zone = -1;
|
|
m_technicalAreas.insert(data.id(), data);
|
|
DEBUG_LOG(m_logger) << "Handle TechnicalArea HandlerArtillerieSound id=" << data.id();
|
|
QPointF cornerButtomLeft = CentralEffectSimulation::geographic2Utm(data.area().cornerBottomLeft(), &zone);
|
|
qreal x = cornerButtomLeft.x() + data.area().width() / 2;
|
|
qreal y = cornerButtomLeft.y() + data.area().height() / 2;
|
|
QPointF center(x, y);
|
|
DEBUG_LOG(m_logger) << "Handle TechnicalArea HandlerArtillerieSound cornerButtomLeft = " << cornerButtomLeft.x() << "/" << cornerButtomLeft.y()
|
|
<< " zone=" << zone;
|
|
DEBUG_LOG(m_logger) << "Handle TechnicalArea HandlerArtillerieSound center = " << center.x() << "/" << center.y()
|
|
<< " zone=" << zone;
|
|
}
|
|
} // onTechnicalAreaChanged
|
|
|
|
|
|
} // namespace CesArtillerySound
|