Files
qt5-legatus-legacy/Lts/Services/CentralEffectSimulation/Plugins/VirtualMines/handler_participant_booby_trap.cpp
T
2026-08-13 18:33:10 +02:00

686 lines
30 KiB
C++
Executable File

/**
* Handler for player data
* $Id$
* $HeadURL$
* $Author$
* Created by gr, SLSE, 2017-02-20
*/
#include "handler_participant_booby_trap.h"
#include <LtsCoordTrans/lts_coord_trans.h>
#include <QLineF>
#include <QTimer>
namespace CesVirtualMines
{
HandlerParticipantBoobyTrap::HandlerParticipantBoobyTrap(const std::shared_ptr<CentralEffectSimulation::DdsHandler> &ddsHandler,
const std::shared_ptr<CentralEffectSimulation::HandlerParticipant> &participantHandler,
QObject *parent)
: QObject(parent)
, m_ddsHandler(ddsHandler)
, m_handlerParticipant(participantHandler)
, m_boobyTrapItems()
, m_requestMap()
, m_timer(new QTimer(this))
, m_logger(CentralEffectSimulation::getLogger("Plugin.VirtualMines.HandlerParticipantBoobyTrap"))
{
INFO_LOG(m_logger) << "HandlerParticipantBoobyTrap::HandlerParticipantBoobyTrap";
m_timer->setSingleShot(true);
connect(m_timer, &QTimer::timeout, this, &HandlerParticipantBoobyTrap::sendFtcCesHitRequestTimeout);
} // end of ctor()
//-----------------------------------------------------------------------------
HandlerParticipantBoobyTrap::~HandlerParticipantBoobyTrap()
{
INFO_LOG(m_logger) << "HandlerParticipantBoobyTrap::~HandlerParticipantBoobyTrap";
} // end of dtor()
//-----------------------------------------------------------------------------
bool HandlerParticipantBoobyTrap::init()
{
INFO_LOG(m_logger) << "HandlerParticipantBoobyTrap::init";
auto dtcAes = m_ddsHandler->dtcAes();
auto ftcAes = m_ddsHandler->ftcAes();
auto dtcCes = m_ddsHandler->dtsCes();
dtcAes->waitForHistoricalDataBoobyTrap(2000);
dtcAes->waitForHistoricalDataAesItemView(2000);
dtcAes->enableBoobyTrap();
ftcAes->enableBoobyTrapTrigger();
dtcCes->enableParticipantEvent();
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::boobyTrapChanged,
this, &HandlerParticipantBoobyTrap::onBoobyTrapChanged);
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::aesItemViewChanged,
this, &HandlerParticipantBoobyTrap::onAesItemViewChanged);
connect(m_handlerParticipant.get(), &CentralEffectSimulation::HandlerParticipant::newOutdoorPosition,
this, &HandlerParticipantBoobyTrap::onParticipantPositionChanged);
// Get 'static' data for all onAesItemView
{
auto cb = [this](const AreaEffectSimulation::AesItemView & aiv)
{
onAesItemViewChanged(aiv, DataModification::eAdded);
};
if (!dtcAes->aesItemViews(cb))
return false;
}
INFO_LOG(m_logger) << "HandlerParticipantBoobyTrap::init() finished. ";
return true;
} // end of init()
//-----------------------------------------------------------------------------
// ///////////////////////////////////
// A E S (AreaEffectSimulation)
// ///////////////////////////////////
void HandlerParticipantBoobyTrap::onBoobyTrapChanged(const AreaEffectSimulation::BoobyTrap &data, DataModification modType)
{
if (data.isDeleted()
|| data.effectStateId() == AreaEffectSimulation::AesEffectState::EsRemoved
|| (data.effectStateId() == AreaEffectSimulation::AesEffectState::EsExpired && !data.triggered())
|| !data.isCentral()
|| modType == DataModification::eRemoved)
{
m_boobyTraps.remove(data.id());
m_boobyTrapItems.remove(data.id());
m_boobyTrapItemsSecondary.remove(data.id());
return;
}
INFO_LOG(m_logger) << "HandlerParticipantBoobyTrap::onBoobyTrapChanged"
<< " data.sampleTime=" << data.sampleTime()
<< " m_ddsHandler->currentPartitionTime=" << m_ddsHandler->currentPartitionTime()
<< " diff=" << m_ddsHandler->currentPartitionTime() - data.sampleTime();
if ((m_ddsHandler->currentPartitionTime() - data.sampleTime()) > 2000)
{
INFO_LOG(m_logger) << "onBoobyTrap outdated";
return;
}
m_boobyTraps.insert(data.id(), data);
if (!data.triggered())
return;
// CentralEffectSimulation::AesItemViewUtm prevData;
// const double impactRadius = 0;
// prevData.aesItemId = 0;
// const CentralEffectSimulation::AesItemViewUtm boobyTrapUtm = CentralEffectSimulation::AesItemViewUtm::create(data, prevData, impactRadius);
// if (data.aesTypeId() == AreaEffectSimulation::AesType_def::AtBoobyTrap)
// m_boobyTrapItems.insert(data.aesItemId(), boobyTrapUtm);
// if (data.aesTypeId() == AreaEffectSimulation::AesType_def::AtBoobyTrapSecondary)
// m_boobyTrapItemsSecondary.insert(data.aesItemId(), boobyTrapUtm);
// DEBUG_LOG(m_logger) << "Check each participant"
// << " aesTypeId=" << data.aesTypeId();
// Check each participant
const auto partPosMap = m_handlerParticipant->positions();
for (const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPos : partPosMap)
{
if (m_handlerParticipant->isOutdated(participantPos))
{
TRACE_LOG(m_logger) << "isOutdated participantId=" << participantPos.participantId() << " continue";
continue;
}
DEBUG_LOG(m_logger) << "Check each actuell participant participantId=" << participantPos.participantId();
if (participantPos.insideBuilding())
{
DEBUG_LOG(m_logger) << "inside Building participantId=" << participantPos.participantId() << " continue";
continue;
}
if (participantPos.vulnerabilityState == ProjectDataManagement::VulnerabilityState::inner_enum::CatastrophicKill)
{
DEBUG_LOG(m_logger) << "CatastrophicKill participantId=" << participantPos.participantId() << " continue";
continue;
}
DEBUG_LOG(m_logger) << "pos participantId=" << participantPos.participantId()
<< " buildingId=" << participantPos.buildingId()
<< " insideBuilding=" << participantPos.insideBuilding()
<< " positionValid=" << participantPos.positionValid;
const CentralEffectSimulation::AesItemViewUtm aesItemView = m_boobyTrapItemsSecondary.value(data.id());
calculateBoobyTrapParticipant(aesItemView, participantPos);
}
m_boobyTraps.remove(data.id());
m_boobyTrapItems.remove(data.id());
m_boobyTrapItemsSecondary.remove(data.id());
}
void HandlerParticipantBoobyTrap::onAesItemViewChanged(const AreaEffectSimulation::AesItemView &data, DataModification modType)
{
INFO_LOG(m_logger) << "---------------------------------------------------------------------------";
INFO_LOG(m_logger) << "HandlerParticipantBoobyTrap::onAesItemViewChanged"
<< " aesTypeId=" << data.aesTypeId()
<< " data.effectStateId()=" << data.effectStateId();
if (data.effectStateId() == AreaEffectSimulation::AesEffectState::EsExpired
|| data.effectStateId() == AreaEffectSimulation::AesEffectState::EsRemoved
|| modType == DataModification::eRemoved)
{
if (data.aesTypeId() == AreaEffectSimulation::AesType_def::AtBoobyTrapSecondary)
{
m_boobyTraps.remove(data.id());
m_boobyTrapItems.remove(data.id());
m_boobyTrapItemsSecondary.remove(data.id());
m_triggeredMineParticipant.remove(data.id());
DEBUG_LOG(m_logger) << "onBoobyTrapChanged remove aesId=" << data.id()
<< " m_triggeredMineParticipant.remove(" << data.id() ;
}
return;
}
//
if (data.aesTypeId() != AreaEffectSimulation::AesType_def::AtBoobyTrap
&& data.aesTypeId() != AreaEffectSimulation::AesType_def::AtBoobyTrapSecondary)
return;
const int aesItemId = data.aesItemId();
DEBUG_LOG(m_logger) << "Got AesItemView id: " << aesItemId
<< ", type: " << data.aesTypeId()
<< ", effectState: " << data.effectStateId()
<< ", modType: " << modType;
if (modType == DataModification::eAdded
|| modType == DataModification::eModified)
{
const AreaEffectSimulation::AesEffectState &effectState = data.effectStateId();
switch (effectState.underlying())
{
case AreaEffectSimulation::AesEffectState_def::EsActivated:
{
CentralEffectSimulation::AesItemViewUtm prevData;
const double impactRadius = 0;
prevData.aesItemId = 0;
const CentralEffectSimulation::AesItemViewUtm boobyTrapUtm = CentralEffectSimulation::AesItemViewUtm::create(data, prevData, impactRadius);
if (data.aesTypeId() == AreaEffectSimulation::AesType_def::AtBoobyTrap)
m_boobyTrapItems.insert(data.aesItemId(), boobyTrapUtm);
if (data.aesTypeId() == AreaEffectSimulation::AesType_def::AtBoobyTrapSecondary)
m_boobyTrapItemsSecondary.insert(data.aesItemId(), boobyTrapUtm);
DEBUG_LOG(m_logger) << "Check each participant"
<< " aesTypeId=" << data.aesTypeId();
// Check each participant
// const auto partPosMap = m_handlerParticipant->positions();
// for (const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPos : partPosMap)
// {
// if (m_handlerParticipant->isOutdated(participantPos))
// {
// TRACE_LOG(m_logger) << "isOutdated participantId=" << participantPos.participantId() << " continue";
// continue;
// }
// DEBUG_LOG(m_logger) << "Check each actuell participant participantId=" << participantPos.participantId();
// if (participantPos.insideBuilding())
// {
// DEBUG_LOG(m_logger) << "inside Building participantId=" << participantPos.participantId() << " continue";
// continue;
// }
// if (participantPos.vulnerabilityState == ProjectDataManagement::VulnerabilityState::inner_enum::CatastrophicKill)
// {
// DEBUG_LOG(m_logger) << "CatastrophicKill participantId=" << participantPos.participantId() << " continue";
// continue;
// }
// // Nur Positionsmeldungen, die neuer sind als die Mine koennen sie ausloesen!
// if ((participantPos.sampleTime() < data.sampleTime())
// && (data.aesTypeId() == AreaEffectSimulation::AesType_def::AtBoobyTrap))
// {
// DEBUG_LOG(m_logger) << " the time of the participant is older than the BoobyTrap participantId=" << participantPos.participantId()
// << " participantPos.sampleTime()=" << participantPos.sampleTime()
// << " data.sampleTime()=" << data.sampleTime()
// << " diff =" << participantPos.sampleTime() - data.sampleTime();
// continue;
// }
// DEBUG_LOG(m_logger) << "pos participantId=" << participantPos.participantId()
// << " buildingId=" << participantPos.buildingId()
// << " insideBuilding=" << participantPos.insideBuilding()
// << " positionValid=" << participantPos.positionValid
// << " aesTypeId=" << data.aesTypeId();
// const CentralEffectSimulation::AesItemViewUtm aesItemView = m_boobyTrapItems.value(data.aesItemId());
// calculateBoobyTrapParticipant(aesItemView, participantPos);
// }
break;
}
default:
{
DEBUG_LOG(m_logger) << "default";
}
}
return;
}
} // onAesItemViewChanged
void HandlerParticipantBoobyTrap::calculateBoobyTrapParticipantsSecondary(int aesItemId, int participantId)
{
DEBUG_LOG(m_logger) << "calculateBoobyTrapParticipantsSecondary : aesItemId=" << aesItemId;
const auto partPosMap = m_handlerParticipant->positions();
for (const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPos : partPosMap)
{
if (participantPos.participantId() == participantId)
{
DEBUG_LOG(m_logger) << "is already handled participantId=" << participantId;
continue;
}
if (m_handlerParticipant->isOutdated(participantPos))
{
// DEBUG_LOG(m_logger) << "isOutdated participantId=" << participantPos.participantId();
continue;
}
if (participantPos.insideBuilding())
{
DEBUG_LOG(m_logger) << "inside Building participantId=" << participantPos.participantId() << " continue";
continue;
}
if (participantPos.vulnerabilityState == ProjectDataManagement::VulnerabilityState::inner_enum::CatastrophicKill)
{
DEBUG_LOG(m_logger) << "CatastrophicKill participantId=" << participantPos.participantId() << " continue";
continue;
}
const CentralEffectSimulation::AesItemViewUtm aesItemView = m_boobyTrapItemsSecondary.value(aesItemId);
calculateBoobyTrapParticipantSecondary(aesItemView, participantPos);
}
}
bool HandlerParticipantBoobyTrap::insideSecondaryArea(const QPolygonF &polygonf, const QPointF &participantPos) const
{
DEBUG_LOG(m_logger) << "pos to check: " << CentralEffectSimulation::debug(participantPos) ;
return polygonf.containsPoint(participantPos, Qt::OddEvenFill);
}
bool HandlerParticipantBoobyTrap::enteredOrCrossedArea(const QPolygonF &polygonf, const QPolygonF &participantStep) const
{
#if QT_VERSION < QT_VERSION_CHECK(5,10,0)
bool result = polygonf.intersected(participantStep).size() > 0;
#else
bool result = polygonf.intersects(participantStep);
#endif
DEBUG_LOG(m_logger) << "enteredOrCrossedArea : " << CentralEffectSimulation::debug(participantStep[0])
<< " to " << CentralEffectSimulation::debug(participantStep[1])
<< " result = " << result;
for (int i = 0; i < polygonf.size(); i++)
{
const QPointF point = polygonf[i];
DEBUG_LOG(m_logger) << "polygonf[" << i << "]="
<< point.x() << "/" << point.y();
}
for (int i = 0; i < participantStep.size(); i++)
{
const QPointF point = participantStep[i];
DEBUG_LOG(m_logger) << "participantStep[" << i << "]="
<< point.x() << "/" << point.y();
}
//return polygonf.containsPoint(participantStep, Qt::OddEvenFill);
return result;
}
void HandlerParticipantBoobyTrap::calculateBoobyTrapParticipantSecondary(const CentralEffectSimulation::AesItemViewUtm &aesItemView,
const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPos)
{
bool result;
const AreaEffectSimulation::BoobyTrap boobyTrap = m_ddsHandler->dtcAes()->boobyTrap(aesItemView.aesItemId);
const QPointF partPosGeo = QPointF(participantPos.pos().lon(), participantPos.pos().lat());
const QPointF impactPosGeo = QPointF(boobyTrap.impactPosition().lon(), boobyTrap.impactPosition().lat());
DEBUG_LOG(m_logger) << "calculateBoobyTrapParticipantSecondary itemView.id=" << aesItemView.aesItemId
<< " participantId=" << participantPos.participantId();
DEBUG_LOG(m_logger) << "BoobyTrap id = " << aesItemView.aesItemId
<< ", Box bottomLeft = " << CentralEffectSimulation::debug(aesItemView.boundingBoxBottomLeft)
<< ", topRight = " << CentralEffectSimulation::debug(aesItemView.boundingBoxTopRight);
bool completeEnclosed = false;
bool isGroundLevel = true;
int exerciseId = m_ddsHandler->getExerciseId();
QPolygonF polygonGeo;
polygonGeo.append(partPosGeo);
polygonGeo.append(impactPosGeo);
const QVector<int> &buildingIds = m_ddsHandler->dtcIsm()->getBuildingByPolygon(exerciseId, polygonGeo, completeEnclosed, isGroundLevel);
//dtcIsm.get()->getBuildingByPolygon(exerciseId, polygonGeo, completeEnclosed, isGroundLevel);
if ( buildingIds.size() > 0)
{
DEBUG_LOG(m_logger) << "Gebaeude verdeckt den Minentreffer participantId=" << participantPos.participantId();
return;
}
if (!aesItemView.boundingBox.containsPoint(partPosGeo, Qt::OddEvenFill))
DEBUG_LOG(m_logger) << "not in boundingBox " << participantPos.participantId();
else
DEBUG_LOG(m_logger) << "in boundingBox" << participantPos.participantId();
// const QPolygonF utmStepPoly = m_handlerParticipant->getParticipantStep(participantPos.participantId(), aesItemView.zone);
result = insideSecondaryArea(aesItemView.form, partPosGeo);
DEBUG_LOG(m_logger) << "insideSecondaryArea : "
<< " participantId=" << participantPos.participantId()
<< " aesItemId=" << aesItemView.aesItemId
<< " result=" << result;
// const bool result = enteredOrCrossedArea(aesItemView.form, partPosGeo);
DEBUG_LOG(m_logger) << "result BoobyTrap Explosion = " << result;
if (result)
{
DEBUG_LOG(m_logger) << "sendParticipantEvent";
sendParticipantEvent(aesItemView, participantPos, ProjectDataManagement::EventType_def::HitMine);
DEBUG_LOG(m_logger) << "sendParticipantHit";
sendParticipantHit(aesItemView, participantPos, ProjectDataManagement::EventType_def::HitMine);
}
} // calculateBoobyTrapParticipantSecondary
// return true, if participant is inside of the bounding Box
bool HandlerParticipantBoobyTrap::intersectsBoundingBoxCheck(const CentralEffectSimulation::AesItemViewUtm &itemView,
const int participantId)
{
bool result = false;
DEBUG_LOG(m_logger) << "intersectsBoundingBoxCheck participantId=" << participantId
<< " itemViewId=" << itemView.aesItemId
<< " m_zone=" << itemView.zone;
const QPolygonF stepPoly = m_handlerParticipant->getParticipantStep(participantId, itemView.zone);
if (stepPoly.size() < 2)
return false;
DEBUG_LOG(m_logger) << "stepPoly von=" << stepPoly.at(0).x() << "/" << stepPoly.at(0).y()
<< " bis=" << stepPoly.at(1).x() << "/" << stepPoly.at(1).y()
<< " m_zone=" << itemView.zone;
DEBUG_LOG(m_logger) << "ItemView Bounding Box BottomLeft=" << itemView.boundingBoxBottomLeft.x() << "/" << itemView.boundingBoxBottomLeft.y()
<< " boundingBoxTopRight=" << itemView.boundingBoxTopRight.x() << "/" << itemView.boundingBoxTopRight.y();
#if QT_VERSION < QT_VERSION_CHECK(5,10,0)
result = itemView.boundingBox.intersected(stepPoly).size() > 0;
#else
result = itemView.boundingBox.intersects(stepPoly);
#endif
DEBUG_LOG(m_logger) << "HandlerMineAreas::intersectsBoundingBoxCheck result =" << result;
return result;
}
bool HandlerParticipantBoobyTrap::calculateBoobyTrapParticipant(const CentralEffectSimulation::AesItemViewUtm &aesItemView,
const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPos)
{
DEBUG_LOG(m_logger) << "calculateBoobyTrapParticipant itemView.id=" << aesItemView.aesItemId
<< " participantId=" << participantPos.participantId();
// Check coverage by a building
const AreaEffectSimulation::BoobyTrap boobyTrap = m_ddsHandler->dtcAes()->boobyTrap(aesItemView.aesItemId);
//const QPointF partPosGeo = CentralEffectSimulation::geographic2Utm(participantPos.pos(), aesItemView.zone);
//const QPointF impactPosGeo = CentralEffectSimulation::geographic2Utm(boobyTrap.impactPosition(), aesItemView.zone);
const QPointF partPosGeo = QPointF(participantPos.pos().lon(), participantPos.pos().lat());
const QPointF impactPosGeo = QPointF(boobyTrap.impactPosition().lon(), boobyTrap.impactPosition().lat());
bool completeEnclosed = false;
bool isGroundLevel = true;
int exerciseId = m_ddsHandler->getExerciseId();
QPolygonF polygonGeo;
polygonGeo.append(partPosGeo);
polygonGeo.append(impactPosGeo);
const QVector<int> &buildingIds = m_ddsHandler->dtcIsm()->getBuildingByPolygon(exerciseId, polygonGeo, completeEnclosed, isGroundLevel);
if (buildingIds.size() > 0)
{
DEBUG_LOG(m_logger) << "coverage by building id =" << buildingIds[0];
return false;
}
const QPointF partPosUtm = CentralEffectSimulation::geographic2Utm(participantPos.pos(), -1);
DEBUG_LOG(m_logger) << "BoobyTrap id = " << aesItemView.aesItemId
<< ", Box bottomLeft = " << CentralEffectSimulation::debug(aesItemView.boundingBoxBottomLeft)
<< ", topRight = " << CentralEffectSimulation::debug(aesItemView.boundingBoxTopRight)
<< " participantPos=" << partPosUtm.x() << "/" << partPosUtm.y();
if (!aesItemView.boundingBox.containsPoint(partPosUtm, Qt::OddEvenFill))
{
DEBUG_LOG(m_logger) << "not in boundingBox " << participantPos.participantId();
bool intersectsBoundingBox = intersectsBoundingBoxCheck(aesItemView, participantPos.participantId());
if (!intersectsBoundingBox)
{
DEBUG_LOG(m_logger) << "Continue nach Bounding BoxCheck itemView: " << aesItemView.aesItemId << ", "
<< " paricipantId=" << participantPos.participantId();
return false;
}
}
else
DEBUG_LOG(m_logger) << "in boundingBox participantId=" << participantPos.participantId();
const QPolygonF posStepPoly = m_handlerParticipant->getParticipantStep(participantPos.participantId(), aesItemView.zone);
if (posStepPoly.size() < 2)
return false;
const bool result = enteredOrCrossedArea(aesItemView.form, posStepPoly);
DEBUG_LOG(m_logger) << "enteredOrCrossedArea : "
<< " participantId=" << participantPos.participantId()
<< " aesItemId=" << aesItemView.aesItemId
<< " result=" << result;
// const bool result = enteredOrCrossedArea(aesItemView.form, partPosGeo);
DEBUG_LOG(m_logger) << "result BoobyTrap Explosion = " << result;
if (result)
{
DEBUG_LOG(m_logger) << "sendFtcBoobyTrapTrigger id=" << aesItemView.aesItemId;
sendFtcBoobyTrapTrigger(aesItemView.aesItemId);
DEBUG_LOG(m_logger) << "sendParticipantEvent";
sendParticipantEvent(aesItemView, participantPos, ProjectDataManagement::EventType_def::HitMine);
DEBUG_LOG(m_logger) << "sendParticipantHit";
sendParticipantHit(aesItemView, participantPos, ProjectDataManagement::EventType_def::HitMine);
//calculateBoobyTrapParticipantsSecondary(aesItemView.aesItemId, participantPos.participantId() );
}
return true;
} // calculateBoobyTrapParticipant
void HandlerParticipantBoobyTrap::onParticipantPositionChanged(const CentralEffectSimulation::HandlerParticipant::CesParticipantData &partPos)
{
// Bounding Box von der Linie
DEBUG_LOG(m_logger) << "ParicipantPos "
<< " participantId=" << partPos.participantId()
<< " participantTypeId=" << partPos.participantTypeId()
<< " participantPos: lat=" << partPos.pos().lat()
<< " lon=" << partPos.pos().lon()
<< " Anzahl BoobyTraps=" << m_boobyTrapItems.size();
if (partPos.vulnerabilityState == ProjectDataManagement::VulnerabilityState::inner_enum::CatastrophicKill)
{
DEBUG_LOG(m_logger) << "Not handle position: participant has vulnerability state CatastrophicKill";
return;
}
if (m_handlerParticipant->getEquipmentNumber(partPos.participantId()) == 0)
{
DEBUG_LOG(m_logger) << "Not handle position: participant has no equipment number";
return;
}
for (const CentralEffectSimulation::AesItemViewUtm &boobyTrap : qAsConst(m_boobyTrapItems))
{
if (!calculateBoobyTrapParticipant(boobyTrap, partPos))
continue;
DEBUG_LOG(m_logger) << "boobyTrap id = " << boobyTrap.aesItemId
<< ", Box bottomLeft = " << CentralEffectSimulation::debug(boobyTrap.boundingBoxBottomLeft)
<< ", topRight = " << CentralEffectSimulation::debug(boobyTrap.boundingBoxTopRight);
const QPolygonF posStepPoly = m_handlerParticipant->getParticipantStep(partPos.participantId(), boobyTrap.zone);
if (posStepPoly.size() < 2)
return;
const bool result = enteredOrCrossedArea(boobyTrap.form, posStepPoly);
DEBUG_LOG(m_logger) << "result BoobyTrap Explosion = " << result;
if (result)
sendParticipantEvent(boobyTrap, partPos, ProjectDataManagement::EventType_def::HitMine);
}
} // end of onParticipantPositionChanged()
//-----------------------------------------------------------------------------
// ///////////////////////////////////
// P D M (ProjectDataManagement)
// ///////////////////////////////////
// Search for corresponding aesItemView
// Check for all participants wheter he is in the explosion area
void HandlerParticipantBoobyTrap::sendParticipantEvent(const CentralEffectSimulation::AesItemViewUtm &boobyTrapItem,
const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPosition,
const ProjectDataManagement::EventType eventType)
{
DEBUG_LOG(m_logger) << "sendParticipantEvent aesItemId=" << boobyTrapItem.aesItemId
<< " participantId=" << participantPosition.participantId();
if ((m_triggeredMineParticipant.contains(boobyTrapItem.aesItemId))
&& (m_triggeredMineParticipant.value(boobyTrapItem.aesItemId) == participantPosition.participantId()))
{
DEBUG_LOG(m_logger) << "m_triggeredMineParticipant already sent "
<< " aesItemId=" << boobyTrapItem.aesItemId
<< " participantId=" << participantPosition.participantId();
return;
}
m_triggeredMineParticipant.insert(boobyTrapItem.aesItemId, participantPosition.participantId());
ParticipantManagement::TypeClass typeClass = m_handlerParticipant->typeClassFromTypeId(participantPosition.participantTypeId());
if (typeClass == ParticipantManagement::TypeClass_def::Unit ||
typeClass == ParticipantManagement::TypeClass_def::SupportUnit ||
typeClass == ParticipantManagement::TypeClass_def::SupportEntity ||
typeClass == ParticipantManagement::TypeClass_def::Unknown)
return;
int equipmentNumber = m_ddsHandler->participantId2EquipNo(participantPosition.participantId());
if (equipmentNumber <= 0)
return;
CentralEffectSimulation::ParticipantEvent pe;
if (m_boobyTraps.contains(boobyTrapItem.aesItemId))
{
INFO_LOG(m_logger) << "BoobyTrap Position found";
AreaEffectSimulation::BoobyTrap boobyTrap = m_boobyTraps.value(boobyTrapItem.aesItemId);
pe.position().lat(boobyTrap.impactPosition().lat());
pe.position().lon(boobyTrap.impactPosition().lon());
}
else
{
INFO_LOG(m_logger) << "No BoobyTrap Position found";
pe.position(participantPosition.pos());
}
const AreaEffectSimulation::BoobyTrap &bt = m_ddsHandler->dtcAes()->boobyTrap(boobyTrapItem.aesItemId);
DEBUG_LOG(m_logger) << "sendParticipantEvent participantId=" << participantPosition.participantId()
<< " lat= " << participantPosition.pos().lat()
<< " lon= " << participantPosition.pos().lon()
<< " equipmentNumber=" << equipmentNumber
<< " eventType=" << eventType;
pe.id(m_ddsHandler->getParticipantEventId());
pe.eventTypeId(eventType);
pe.participantId(participantPosition.participantId());
pe.eventTime(participantPosition.sampleTime());
pe.aesItemId(boobyTrapItem.aesItemId);
pe.partyId(participantPosition.partyId());
pe.aesName(bt.name());
pe.equipmentNumber(equipmentNumber);
pe.friendlyFire(boobyTrapItem.partyId == participantPosition.partyId());
m_ddsHandler->dtsCes()->publish(pe);
qint64 id = pe.id();
QTimer::singleShot(1 * 60 * 1000, this, [id, this]() { m_ddsHandler->dtsCes()->removeParticipantEventByKey(id); });
}
void HandlerParticipantBoobyTrap::sendParticipantHit(const CentralEffectSimulation::AesItemViewUtm &boobyTrap,
const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPosition,
const ProjectDataManagement::EventType eventType)
{
// Q_UNUSED(eventType); // not used - no alarm for this
const int equipNo = m_ddsHandler->participantId2EquipNo(participantPosition.participantId());
const int participantId = participantPosition.participantId();
const int originatorEquipNo = 0;
if ( equipNo == 0)
return;
Core::GeoPosition position;
// TODO: Hier wird die Mitte der Bounding-Box genommen und nicht die Position vom Participant
position.lat(participantPosition.pos().lat());
position.lon(participantPosition.pos().lon());
const TrainingAreaBase::TabPosition pos(position, participantPosition.reportingSource(), 0, 0);
int remainTasCodeIndirect = m_ddsHandler->remainingTasCode(boobyTrap.chargeStruct);
//pos.position(position);
//pos.reportingSource(participantPosition.reportingSource());
DEBUG_LOG(m_logger) << "sendParticipantHit participantId=" << participantId
<< " equipmentNumber=" << equipNo
<< " chargeTypeId=" << boobyTrap.chargeStruct.chargeTypeId()
<< " eventType=" << eventType
<< " remainTasCodeIndirect=" << remainTasCodeIndirect;
TrainingAreaBase::SendCesHitRequest requestTab(
equipNo, // equipmentNumber
participantId, // participantId
boobyTrap.chargeStruct.chargeTypeId(), // chargeTypeId
boobyTrap.aesItemId, // aesId
originatorEquipNo, // originatorEquipmentNumber
remainTasCodeIndirect, // IED heavy
pos,
boobyTrap.effectStart, // effectTime
eventType,
boobyTrap.partyId, // originPartyId
0
);
m_requestMap.insert(equipNo, requestTab);
if (!m_timer->isActive() && !m_requestMap.isEmpty())
m_timer->start(1000);
}
void HandlerParticipantBoobyTrap::onSendCesHitReply(const Core::FunctionReplyObject &replyObject)
{
//if (replyObject.error())
// WARNING_LOG(m_logger) << "Can not send hit on participant to training area: " << replyObject();
//else
DEBUG_LOG(m_logger) << "onSendCesHitReply for id " << replyObject.id() << " success";
}
void HandlerParticipantBoobyTrap::onBoobyTrapTriggerReply(const Core::FunctionReplyObject &replyObject)
{
if (replyObject.error())
ERROR_LOG(m_logger) << "Can not send BoobyTrapTriggerReply: " << replyObject();
else
DEBUG_LOG(m_logger) << "onBoobyTrapTriggerReply for id " << replyObject.id() << " success";
}
void HandlerParticipantBoobyTrap::sendFtcBoobyTrapTrigger(int aesItemId)
{
auto ftcAes = m_ddsHandler->ftcAes();
AreaEffectSimulation::BoobyTrapTriggerRequest hr;
hr.id(aesItemId);
hr.triggered(true);
DEBUG_LOG(m_logger) << "sendFtcAesRemoveBoobyTrap: id=" << hr;
ftcAes->boobyTrapTriggerRequest(hr, this);
}
void HandlerParticipantBoobyTrap::sendFtcCesHitRequestTimeout()
{
auto ftcTab = m_ddsHandler->ftcTab();
for (const TrainingAreaBase::SendCesHitRequest &hr : qAsConst(m_requestMap))
{
DEBUG_LOG(m_logger) << "sendFtcCesHitRequestTimeout: " << hr;
ftcTab->sendCesHitRequest(hr, this);
}
m_requestMap.clear();
}
} // namespace CesVirtualMines