1493 lines
63 KiB
C++
Executable File
1493 lines
63 KiB
C++
Executable File
/**
|
|
* Handler for player data
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by gr, SLSE, 2017-02-20
|
|
*/
|
|
|
|
#include "handler_nbc.h"
|
|
|
|
#include <QtCore/QTimer>
|
|
#include <QtCore/QDateTime>
|
|
|
|
#include <LtsUtilsCore/dds_bitarray.h>
|
|
#include <LtsCoordTrans/lts_coord_trans.h>
|
|
#include <ProjectDataManagement/pdm_enums.hpp>
|
|
#include <cmath>
|
|
|
|
namespace dds
|
|
{
|
|
namespace core
|
|
{
|
|
inline uint qHash(ProjectDataManagement::PdmEventType et)
|
|
{
|
|
return ::qHash(et.underlying());
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace CES_NBC
|
|
{
|
|
inline uint qHash(EffectType et)
|
|
{
|
|
return ::qHash(int(et));
|
|
}
|
|
|
|
QString toString(EffectType et)
|
|
{
|
|
switch (et)
|
|
{
|
|
case EffectType::Unknown: return QStringLiteral("Unknown");
|
|
case EffectType::EffectiveMineRangeEnter: return QStringLiteral("EffectiveMineRangeEnter");
|
|
case EffectType::EffectiveMineRangeLeave: return QStringLiteral("EffectiveMineRangeLeave");
|
|
case EffectType::NContaminationLeave: return QStringLiteral("NContaminationLeave");
|
|
case EffectType::NContaminationEnterArea1: return QStringLiteral("NContaminationEnterArea1");
|
|
case EffectType::NContaminationEnterArea2: return QStringLiteral("NContaminationEnterArea2");
|
|
case EffectType::NContaminationDetonation: return QStringLiteral("NContaminationDetonation");
|
|
case EffectType::FunctionalAreaLeave: return QStringLiteral("FunctionalAreaLeave");
|
|
case EffectType::FunctionalAreaEnter: return QStringLiteral("FunctionalAreaEnter");
|
|
case EffectType::ExplosionArea: return QStringLiteral("ExplosionArea");
|
|
case EffectType::ExplosionSingle: return QStringLiteral("ExplosionSingle");
|
|
case EffectType::BCContaminationLeave: return QStringLiteral("BCContaminationLeave");
|
|
case EffectType::BCContaminationEnterFloating: return QStringLiteral("BCContaminationEnterFloating");
|
|
case EffectType::BCContaminationEnterResident: return QStringLiteral("BCContaminationEnterResident");
|
|
case EffectType::BCContaminationEnterFloatingArea: return QStringLiteral("BCContaminationEnterFloatingArea");
|
|
case EffectType::BeStillWarning: return QStringLiteral("BeStillWarning");
|
|
}
|
|
return QStringLiteral("Unknown (%1)").arg(int(et));
|
|
}
|
|
|
|
|
|
HandlerNBC::HandlerNBC(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_logger(CentralEffectSimulation::getLogger("Plugin.NBC.HandlerNBC"))
|
|
{
|
|
} // end of ctor()
|
|
//-----------------------------------------------------------------------------
|
|
|
|
HandlerNBC::~HandlerNBC()
|
|
{
|
|
} // end of dtor()
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool HandlerNBC::init()
|
|
{
|
|
auto dtcAes = m_ddsHandler->dtcAes();
|
|
|
|
dtcAes->waitForHistoricalDataBCContamination(2000);
|
|
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::bCContaminationChanged,
|
|
this, &HandlerNBC::onBCContaminationChanged);
|
|
|
|
dtcAes->waitForHistoricalDataNContamination(2000);
|
|
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::nContaminationChanged,
|
|
this, &HandlerNBC::onNContaminationChanged);
|
|
|
|
dtcAes->waitForHistoricalDataAesItemView(2000);
|
|
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::aesItemViewChanged,
|
|
this, &HandlerNBC::onAesItemViewChanged);
|
|
|
|
|
|
connect(m_handlerParticipant.get(), &CentralEffectSimulation::HandlerParticipant::newIndoorPosition,
|
|
this, &HandlerNBC::onNewIndoorParticipantPosition);
|
|
connect(m_handlerParticipant.get(), &CentralEffectSimulation::HandlerParticipant::newOutdoorPosition,
|
|
this, &HandlerNBC::onNewOutdoorParticipantPosition);
|
|
connect(m_handlerParticipant.get(), &CentralEffectSimulation::HandlerParticipant::participantDecontaminated,
|
|
this, &HandlerNBC::onParticipantDecontaminated);
|
|
connect(m_handlerParticipant.get(), &CentralEffectSimulation::HandlerParticipant::restoreRadioReadinessChanged,
|
|
this, &HandlerNBC::onRestoreRadioReadinessChanged);
|
|
|
|
|
|
// Get 'static' data for all bcContaminations
|
|
{
|
|
auto cb = [this](const AreaEffectSimulation::BCContamination & bc)
|
|
{
|
|
onBCContaminationChanged(bc, DataModification::eAdded);
|
|
};
|
|
if (!dtcAes->bCContaminations(cb))
|
|
return false;
|
|
}
|
|
// Get 'static' data for all NContaminations
|
|
{
|
|
auto cb = [this](const AreaEffectSimulation::NContamination & nc)
|
|
{
|
|
onNContaminationChanged(nc, DataModification::eAdded);
|
|
};
|
|
if (!dtcAes->nContaminations(cb))
|
|
return false;
|
|
}
|
|
|
|
|
|
// 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) << "HandlerParticipantArea::init() finished.";
|
|
return true;
|
|
} // end of init()
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void HandlerNBC::onSendCesHitReply(const Core::FunctionReplyObject &replyObject)
|
|
{
|
|
DEBUG_LOG(m_logger) << "onSendCesHitReply for id " << replyObject.id() << " success= " << replyObject.error();
|
|
|
|
if (replyObject.error())
|
|
WARNING_LOG(m_logger) << "Can not send enter/leave Area to participant in training area: " << replyObject();
|
|
|
|
// Send next Request, if available
|
|
if (!m_sendCesHitRequestQueue.isEmpty())
|
|
{
|
|
DEBUG_LOG(m_logger) << "m_sendCesAreaActionRequestQueue.size()=" << m_sendCesHitRequestQueue.size();
|
|
m_sendCesHitRequestQueue.dequeue();
|
|
// Send next Message
|
|
if (!m_sendCesHitRequestQueue.isEmpty())
|
|
{
|
|
const auto &hr = m_sendCesHitRequestQueue.head();
|
|
DEBUG_LOG(m_logger) << "sendCesHitRequest: " << hr;
|
|
m_ddsHandler->ftcTab()->sendCesHitRequest(hr, this);
|
|
}
|
|
}
|
|
}
|
|
// ///////////////////////////////////
|
|
// A E S (AreaEffectSimulation)
|
|
// ///////////////////////////////////
|
|
void HandlerNBC::onAesItemViewChanged(const AreaEffectSimulation::AesItemView &data, DataModification modType)
|
|
{
|
|
const bool isSupplyTruck = false;
|
|
const double hazardDistance = 0.0;
|
|
|
|
double upperOffset = 0;
|
|
double lowerOffset = 0;
|
|
bool offsetIsSet = false;
|
|
TRACE_LOG(m_logger) << "onAesItemViewChanged"
|
|
<< " aesItemId=" << data.aesItemId();
|
|
|
|
|
|
AreaEffectSimulation::BCContamination bCContamination = m_ddsHandler->dtcAes()->bCContamination(data.aesItemId());
|
|
|
|
|
|
|
|
const int aesItemId = data.aesItemId();
|
|
const AreaEffectSimulation::AesEffectState &effectState = data.effectStateId();
|
|
if ((data.aesTypeId().underlying() != AreaEffectSimulation::AesType_def::AtDangerArea)
|
|
&& (data.aesTypeId().underlying() != AreaEffectSimulation::AesType_def::AtBCContamination)
|
|
&& (data.aesTypeId().underlying() != AreaEffectSimulation::AesType_def::AtNContamination))
|
|
return;
|
|
|
|
if (data.aesTypeId().underlying() == AreaEffectSimulation::AesType_def::AtBCContamination)
|
|
{
|
|
const AreaEffectSimulation::BCContamination &bc = m_ddsHandler->dtcAes()->bCContamination(data.aesItemId());
|
|
if (!bc.isCentral())
|
|
{
|
|
DEBUG_LOG(m_logger) << "!Central BCContamination id: " << aesItemId;
|
|
return;
|
|
}
|
|
offsetIsSet = true;
|
|
upperOffset = bCContamination.upperOffset();
|
|
lowerOffset = bCContamination.lowerOffset();
|
|
}
|
|
else if (data.aesTypeId().underlying() == AreaEffectSimulation::AesType_def::AtDangerArea)
|
|
{
|
|
const AreaEffectSimulation::DangerArea &da = m_ddsHandler->dtcAes()->dangerArea(data.aesItemId());
|
|
if (!da.isCentral())
|
|
{
|
|
DEBUG_LOG(m_logger) << "!Central DangerArea id: " << aesItemId;
|
|
return;
|
|
}
|
|
}
|
|
else if (data.aesTypeId().underlying() == AreaEffectSimulation::AesType_def::AtNContamination)
|
|
{
|
|
const AreaEffectSimulation::NContamination &nc = m_ddsHandler->dtcAes()->nContamination(data.aesItemId());
|
|
if (!nc.isCentral())
|
|
{
|
|
DEBUG_LOG(m_logger) << "!Central NContamination id: " << aesItemId;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
TRACE_LOG(m_logger) << "Got AesItemView id: " << aesItemId
|
|
<< ", type: " << data.aesTypeId()
|
|
<< ", effectState: " << data.effectStateId()
|
|
<< ", modType: " << modType;
|
|
|
|
|
|
const double impactRadius = m_ddsHandler->chargeTypeRadius(data.chargeStruct());
|
|
DEBUG_LOG(m_logger) << "impactRadius=" << impactRadius;
|
|
switch (effectState.underlying())
|
|
{
|
|
case AreaEffectSimulation::AesEffectState_def::EsPrepared:
|
|
{
|
|
const auto &aesItemViewUtm = CentralEffectSimulation::AesItemViewUtm::create(data,
|
|
m_aesItemViews[data.aesItemId()],
|
|
impactRadius,
|
|
isSupplyTruck,
|
|
hazardDistance,
|
|
offsetIsSet,
|
|
upperOffset,
|
|
lowerOffset);
|
|
m_aesItemViews.insert(data.aesItemId(), aesItemViewUtm);
|
|
}
|
|
break;
|
|
case AreaEffectSimulation::AesEffectState_def::EsActivated:
|
|
{
|
|
|
|
CentralEffectSimulation::AesItemViewUtm aesItemViewUtm =
|
|
CentralEffectSimulation::AesItemViewUtm::create(data,
|
|
m_aesItemViews[data.aesItemId()],
|
|
impactRadius,
|
|
isSupplyTruck,
|
|
hazardDistance,
|
|
offsetIsSet,
|
|
upperOffset,
|
|
lowerOffset);
|
|
const Core::GeoPosition2D &pointGeo = bCContamination.impactPosition();
|
|
int zone = aesItemViewUtm.zone;
|
|
|
|
//aesItemViewUtm.center = CentralEffectSimulation::geographic2Utm(pointGeo, &zone);
|
|
|
|
auto utm = LtsCoordTrans::UtmCoordinate::fromGeographic(pointGeo.lon(), pointGeo.lat(), zone);
|
|
QPointF impactPositionUtm = QPointF(utm.x, utm.y);
|
|
aesItemViewUtm.center = impactPositionUtm;
|
|
|
|
switch (data.aesTypeId().underlying())
|
|
{
|
|
case AreaEffectSimulation::AesType_def::AtBCContamination:
|
|
case AreaEffectSimulation::AesType_def::AtNContamination:
|
|
// for each participant:
|
|
// Bounding-Box Check,
|
|
// form-Check
|
|
// if new field for this participant send sendCesHitRequest
|
|
calculateBcContamination(aesItemViewUtm);
|
|
m_aesItemViews.insert(data.aesItemId(), aesItemViewUtm);
|
|
// DEBUG_LOG(m_logger) << "insert AtBCContamination oder AtNContamination AesItemView id: " << aesItemId
|
|
// << ", type: " << data.aesTypeId();
|
|
break;
|
|
case AreaEffectSimulation::AesType_def::AtDangerArea:
|
|
calculateDangerArea(aesItemViewUtm);
|
|
m_aesItemViews.insert(data.aesItemId(), aesItemViewUtm);
|
|
DEBUG_LOG(m_logger) << "insert AtDangerArea AesItemView id: " << aesItemId
|
|
<< ", type: " << data.aesTypeId();
|
|
break;
|
|
default:
|
|
break;
|
|
} // switch aesTypeId
|
|
break;
|
|
} // case EsActivated
|
|
case AreaEffectSimulation::AesEffectState_def::EsRemoved:
|
|
case AreaEffectSimulation::AesEffectState_def::EsExpired:
|
|
{
|
|
aesItemViewRemoved(aesItemId);
|
|
break;
|
|
}
|
|
default:
|
|
// do nothing
|
|
break;
|
|
} // switch effectStateId
|
|
} // onAesItemViewChanged
|
|
|
|
|
|
|
|
void HandlerNBC::onBCContaminationChanged(const AreaEffectSimulation::BCContamination &data, DataModification modType)
|
|
{
|
|
if (!data.isCentral())
|
|
{
|
|
aesItemViewRemoved(data.id());
|
|
return;
|
|
}
|
|
|
|
switch (modType)
|
|
{
|
|
case DataModification::eRemoved:
|
|
break;
|
|
case DataModification::eAdded:
|
|
case DataModification::eModified:
|
|
switch (data.effectStateId().underlying())
|
|
{
|
|
case AreaEffectSimulation::AesEffectState_def::EsActivated:
|
|
{
|
|
CentralEffectSimulation::AesItemViewUtm &ref = m_aesItemViews[data.id()];
|
|
if (m_ddsHandler->volatilityTypeId(data.chargeStruct()) == ProjectDataManagement::VolatilityType_def::Resident)
|
|
{
|
|
ref.radials = {data.impactRadius()};
|
|
ref.center = CentralEffectSimulation::geographic2Utm(data.impactPosition(), &ref.zone);
|
|
}
|
|
else
|
|
ref.radials.clear();
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandlerNBC::onNContaminationChanged(const AreaEffectSimulation::NContamination &data, DataModification modType)
|
|
{
|
|
|
|
DEBUG_LOG(m_logger) << "onNContaminationChanged"
|
|
<< " id=" << data.id();
|
|
switch (modType)
|
|
{
|
|
case DataModification::eRemoved:
|
|
break;
|
|
case DataModification::eAdded:
|
|
case DataModification::eModified:
|
|
switch (data.effectStateId().underlying())
|
|
{
|
|
case AreaEffectSimulation::AesEffectState_def::EsActivated:
|
|
{
|
|
CentralEffectSimulation::AesItemViewUtm &ref = m_aesItemViews[data.id()];
|
|
ref.radials = {data.impactRadius(),
|
|
data.borderLengthInner(),
|
|
data.borderLengthInner() + data.borderLengthOuter()
|
|
};
|
|
ref.center = CentralEffectSimulation::geographic2Utm(data.impactPosition(), &ref.zone);
|
|
const QHash<int, CentralEffectSimulation::HandlerParticipant::CesParticipantData> participantsMap = m_handlerParticipant->positions();
|
|
for (const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPos : participantsMap)
|
|
{
|
|
if (m_handlerParticipant->isOutdated(participantPos))
|
|
continue;
|
|
DEBUG_LOG(m_logger) << "onNContaminationChanged participantId=" << participantPos.participantId()
|
|
<< " insideBuilding=" << participantPos.insideBuilding()
|
|
<< " buildingId=" << participantPos.buildingId();
|
|
|
|
const QPointF posUtm = CentralEffectSimulation::geographic2Utm(participantPos.pos(), &ref.zone);
|
|
const bool isInCircle = inCircle(ref.center, data.impactRadius(), posUtm);
|
|
|
|
const EffectType effectType = CES_NBC::EffectType::NContaminationDetonation;
|
|
const int ctasEffectType = static_cast<int>(effectType) & 0xffff;
|
|
DEBUG_LOG(m_logger) << "onNContaminationChanged isInCircle=" << isInCircle
|
|
<< " aesItemId=" << data.id();
|
|
if ( isInCircle)
|
|
{
|
|
QHash<int, bool> aesIds = m_participantAes.value(participantPos.participantId());
|
|
aesIds.insert(data.id(), true);
|
|
|
|
m_participantAes.insert( participantPos.participantId(), aesIds);
|
|
|
|
QHash<int, QSet<EffectType>> effectTypeStatesFromAesItem = m_effectTypeStates.value(data.id());
|
|
|
|
|
|
QSet<EffectType> effectSet = effectTypeStatesFromAesItem.value(participantPos.participantId());
|
|
|
|
effectSet.insert(EffectType::NContaminationDetonation);
|
|
|
|
effectTypeStatesFromAesItem.insert(participantPos.participantId(), effectSet);
|
|
|
|
m_effectTypeStates.insert(data.id(), effectTypeStatesFromAesItem);
|
|
|
|
|
|
DEBUG_LOG(m_logger) << "m_participantAes.insert participantId=" << participantPos.participantId()
|
|
<< " aesId=" << data.id();
|
|
sendCesHitRequest(ref,
|
|
participantPos,
|
|
//effectTime >= 0 ? effectTime : participantPosition.sampleTime(),
|
|
QDateTime::currentMSecsSinceEpoch(),
|
|
ctasEffectType,
|
|
0);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandlerNBC::calculateBcContamination(const CentralEffectSimulation::AesItemViewUtm &itemView)
|
|
{
|
|
TRACE_LOG(m_logger) << "HandlerParticipantArea::calculateBcContamination aesItemId =" << itemView.aesItemId;
|
|
const auto participantsMap = m_handlerParticipant->positions();
|
|
for (const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPos : participantsMap)
|
|
{
|
|
if (m_handlerParticipant->isOutdated(participantPos))
|
|
continue;
|
|
DEBUG_LOG(m_logger) << "participantId=" << participantPos.participantId()
|
|
<< " insideBuilding=" << participantPos.insideBuilding()
|
|
<< " buildingId=" << participantPos.buildingId()
|
|
<< " roomId=" << participantPos.roomId();
|
|
inFormCheck(itemView, participantPos);
|
|
}
|
|
// for
|
|
} // calculateBcContamination
|
|
|
|
void HandlerNBC::calculateDangerArea(const CentralEffectSimulation::AesItemViewUtm &itemView)
|
|
{
|
|
DEBUG_LOG(m_logger) << "HandlerParticipantArea::calculateDangerArea aesItemId =" << itemView.aesItemId;
|
|
const auto partPosMap = m_handlerParticipant->positions();
|
|
for (const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPos : partPosMap)
|
|
inFormCheck(itemView, participantPos);
|
|
} // calculateDangerArea
|
|
|
|
void HandlerNBC::deleteDangerArea(const int aesItemId)
|
|
{
|
|
CentralEffectSimulation::AesItemViewUtm itemView = m_aesItemViews.value(aesItemId);
|
|
DEBUG_LOG(m_logger) << "delete " << itemView.aesItemId << ", aesItemId: " << aesItemId;
|
|
|
|
const auto partPosMap = m_handlerParticipant->positions();
|
|
for (const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPos : partPosMap)
|
|
{
|
|
sendParticipantEvent(aesItemId, participantPos, ProjectDataManagement::PdmEventType_def::LeaveDangerArea);
|
|
DEBUG_LOG(m_logger) << "Participant inside id=" << participantPos.participantId();
|
|
}// for all Participants
|
|
} // deleteDangerArea
|
|
|
|
void HandlerNBC::onNewOutdoorParticipantPosition(const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantData)
|
|
{
|
|
bool leave = false;
|
|
DEBUG_LOG(m_logger) << "++++++++ onNewOutdoorParticipantPosition participantId=" << participantData.participantId()
|
|
<< " buildingId=" << participantData.buildingId()
|
|
<< " roomId=" << participantData.roomId()
|
|
<< " reportingSource=" << participantData.reportingSource()
|
|
<< " m_aesItemViews.size=" << m_aesItemViews.size();
|
|
|
|
if (m_handlerParticipant->isOutdated(participantData))
|
|
return;
|
|
|
|
if (m_handlerParticipant->getEquipmentNumber(participantData.participantId()) == 0)
|
|
{
|
|
DEBUG_LOG(m_logger) << "Not handle position: participant has no equipment number";
|
|
return;
|
|
}
|
|
|
|
if (m_lastRoomId.value(participantData.participantId()) > 0)
|
|
{
|
|
DEBUG_LOG(m_logger) << "Leave Building m_isInContaminatedRoom.contains participantId=" << participantData.participantId()
|
|
<< " m_isInContaminatedRoom.\nremove!!!";
|
|
|
|
|
|
AreaEffectSimulation::AesItemView aesItemView;
|
|
bool aesIsAvailable = m_ddsHandler->dtcAes()->aesItemViewFromEntityId(m_isInContaminatedRoom.value(participantData.participantId()),AreaEffectSimulation::AesType::AtUnknown, aesItemView );
|
|
|
|
if (aesIsAvailable
|
|
&& (aesItemView.effectStateId() == AreaEffectSimulation::AesEffectState_def::EsActivated))
|
|
{
|
|
DEBUG_LOG(m_logger) << "Feld ist nicht mehr da. id=" << aesItemView.aesItemId();
|
|
m_isInContaminatedRoom.remove(participantData.participantId());
|
|
|
|
}
|
|
else
|
|
{
|
|
DEBUG_LOG(m_logger) << "Feld ist nicht mehr da. id=" << aesItemView.aesItemId();
|
|
sendLeaveEvent(aesItemView.aesItemId(),participantData );
|
|
}
|
|
leave = true;
|
|
}
|
|
else
|
|
{
|
|
DEBUG_LOG(m_logger) << "m_lastRoomId.contains(" << m_lastRoomId.contains(participantData.participantId())
|
|
<< " roomId=" << m_lastRoomId.value(participantData.participantId());
|
|
}
|
|
|
|
m_lastRoomId.insert(participantData.participantId(), 0);
|
|
|
|
|
|
DEBUG_LOG(m_logger) << "HandlerParticipantArea::calculateAesParticipant paricipantId: " << participantData.participantId()
|
|
<< " m_aesItemViews.size()=" << m_aesItemViews.size();
|
|
for (const CentralEffectSimulation::AesItemViewUtm &itemView : qAsConst(m_aesItemViews))
|
|
{
|
|
DEBUG_LOG(m_logger) << " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
|
DEBUG_LOG(m_logger) << " itemView: " << itemView.aesItemId << ", " << itemView.aesTypeId;
|
|
if (leave)
|
|
{
|
|
QHash<int, QSet<EffectType>> effectTypeHash = m_effectTypeStates.value(itemView.aesItemId);
|
|
if ( effectTypeHash.contains(participantData.participantId()))
|
|
{
|
|
effectTypeHash.remove(participantData.participantId());
|
|
}
|
|
m_effectTypeStates.insert(itemView.aesItemId, effectTypeHash);
|
|
}
|
|
switch (itemView.aesTypeId.underlying())
|
|
{
|
|
case AreaEffectSimulation::AesType_def::AtBCContamination:
|
|
case AreaEffectSimulation::AesType_def::AtNContamination:
|
|
case AreaEffectSimulation::AesType_def::AtDangerArea:
|
|
inFormCheck(itemView, participantData);
|
|
break;
|
|
default:
|
|
// nothing
|
|
break;
|
|
} // switch
|
|
} // for
|
|
} // onNewOutdoorParticipantPosition
|
|
|
|
void HandlerNBC::onParticipantDecontaminated(const int participantId)
|
|
{
|
|
DEBUG_LOG(m_logger) << "onParticipantDecontaminated participantId=" << participantId;
|
|
m_participantAes.remove(participantId);
|
|
|
|
for (auto i = m_effectTypeStates.cbegin(), end = m_effectTypeStates.cend(); i != end; ++i)
|
|
{
|
|
DEBUG_LOG(m_logger) << "aesItemId=" << i.key();
|
|
QHash<int, QSet<EffectType>> value = i.value();
|
|
value.remove(participantId);
|
|
m_effectTypeStates.insert(i.key(), value);
|
|
}
|
|
}
|
|
|
|
void HandlerNBC::onRestoreRadioReadinessChanged(const int participantId)
|
|
{
|
|
DEBUG_LOG(m_logger) << "HandlerNBC::onRestoreRadioReadinessChanged participantId=" << participantId
|
|
<< " m_participantAes.size=" << m_participantAes.size();
|
|
|
|
if (!m_participantAes.contains(participantId) )
|
|
{
|
|
DEBUG_LOG(m_logger) << "HandlerNBC::onRestoreRadioReadinessChanged !m_participantAes.contains( participantId=" << participantId << ")";
|
|
return;
|
|
}
|
|
|
|
QHash<int, bool> aesIds = m_participantAes.value(participantId);
|
|
|
|
QHashIterator<int, bool> i(aesIds);
|
|
while (i.hasNext())
|
|
{
|
|
i.next();
|
|
DEBUG_LOG(m_logger) << "HandlerNBC::onRestoreRadioReadinessChanged remove aesId=" << i.key();
|
|
m_participantAes.remove(i.key());
|
|
m_eventStates.remove(i.key());
|
|
m_effectTypeStates.remove(i.key());
|
|
}
|
|
|
|
m_participantAes.remove(participantId);
|
|
}
|
|
|
|
|
|
// return true, if participant is inside of the bounding Box
|
|
bool HandlerNBC::inBoundingBoxCheck(const CentralEffectSimulation::AesItemViewUtm &itemView,
|
|
const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantData)
|
|
{
|
|
if (itemView.effectStateId != AreaEffectSimulation::AesEffectState_def::EsActivated)
|
|
return false;
|
|
|
|
// QRectF(topLeft, bottomRight) -> no need to mormalize, QRectF:contains() handles it correct
|
|
|
|
const QRectF boundingBoxImpact(itemView.boundingBoxBottomLeft,
|
|
itemView.boundingBoxTopRight);
|
|
|
|
const QPointF participantPosUtmPoint = CentralEffectSimulation::geographic2Utm(participantData.pos(), itemView.zone);
|
|
if (boundingBoxImpact.contains(participantPosUtmPoint))
|
|
{
|
|
DEBUG_LOG(m_logger) << "inBoundingBoxCheck Paricipant " << participantData.participantId()
|
|
<< " inside AesItemView:" << itemView.aesItemId;
|
|
return true;
|
|
}
|
|
TRACE_LOG(m_logger) << "inBoundingBoxCheck Paricipant " << participantData.participantId()
|
|
<< " outside AesItemView:" << itemView.aesItemId;
|
|
return false;
|
|
}
|
|
|
|
void HandlerNBC::sendEnterEvent(const int aesItemId, const AreaEffectSimulation::AesType aesTypeId, const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantData, bool isIndoor)
|
|
{
|
|
|
|
AreaEffectSimulation::AesItemView aesItemView;
|
|
m_ddsHandler->dtcAes()->aesItemViewFromEntityId(aesItemId,AreaEffectSimulation::AesType::AtUnknown, aesItemView );
|
|
|
|
|
|
DEBUG_LOG(m_logger) << "sendEnterEvent, paricipantId: " << participantData.participantId()
|
|
<< ", aesItemId: " << aesItemId
|
|
<< ", aesType=" << aesTypeId
|
|
<< ", isIndoor=" << isIndoor;
|
|
|
|
QHash<int, bool> aesIds = m_participantAes.value(participantData.participantId());
|
|
aesIds.insert(aesItemId, true);
|
|
m_participantAes.insert(participantData.participantId(), aesIds);
|
|
int zone = -1;
|
|
|
|
if ( m_aesItemViews.contains(aesItemId))
|
|
zone = m_aesItemViews.value(aesItemId).zone;
|
|
else
|
|
{
|
|
ERROR_LOG(m_logger) << "No m_aesItemViews.contains aesItemId=" << aesItemId;
|
|
}
|
|
|
|
const QPointF participantPosUtmPoint = CentralEffectSimulation::geographic2Utm(participantData.pos(), zone);
|
|
switch (aesTypeId.underlying())
|
|
{
|
|
case AreaEffectSimulation::AesType_def::AtBCContamination:
|
|
{
|
|
// since buildings can only be contaminated by resident bccontaminations
|
|
// effectType is EffectType::BCContaminationEnterResident if isIndoor
|
|
EffectType effectType = isIndoor ? EffectType::BCContaminationEnterResident : effectTypeForBCContaminationArea(m_aesItemViews.value(aesItemId), participantPosUtmPoint);
|
|
|
|
// The Hit Event comes later from the participant
|
|
sendEffectTypeEvent(aesItemId, participantData, effectType);
|
|
break;
|
|
}
|
|
case AreaEffectSimulation::AesType_def::AtDangerArea:
|
|
sendParticipantEvent(aesItemId, participantData, ProjectDataManagement::PdmEventType_def::EnterDangerArea);
|
|
break;
|
|
case AreaEffectSimulation::AesType_def::AtNContamination:
|
|
sendParticipantEvent(aesItemId, participantData, ProjectDataManagement::PdmEventType_def::EnterNuclear);
|
|
sendEffectTypeEvent(aesItemId, participantData, effectTypeForNContaminationArea(m_aesItemViews.value(aesItemId), participantPosUtmPoint, participantData.sampleTime(), participantData.insideBuilding()));
|
|
break;
|
|
case AreaEffectSimulation::AesType_def::AtExplosionArea:
|
|
case AreaEffectSimulation::AesType_def::AtFunctionalArea:
|
|
case AreaEffectSimulation::AesType_def::AtMineArea:
|
|
default:
|
|
INFO_LOG(m_logger) << "sendEvent Unhandled AES-Type" << aesTypeId;
|
|
break;
|
|
}
|
|
} // END sendEvent
|
|
|
|
void HandlerNBC::sendLeaveEvent(const int aesItemId, const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantData)
|
|
{
|
|
|
|
AreaEffectSimulation::AesItemView aesItemView;
|
|
m_ddsHandler->dtcAes()->aesItemViewFromEntityId(aesItemId, AreaEffectSimulation::AesType_def::AtUnknown, aesItemView);
|
|
|
|
DEBUG_LOG(m_logger) << "sendLeaveEvent"
|
|
<< " aesId=" << aesItemId
|
|
<< " participantId=" << participantData.participantId()
|
|
<< " aesTypeId=" << aesItemView.aesTypeId();
|
|
|
|
|
|
switch (aesItemView.aesTypeId().underlying())
|
|
{
|
|
case AreaEffectSimulation::AesType_def::AtBCContamination:
|
|
sendEffectTypeEvent(aesItemId, participantData, EffectType::BCContaminationLeave);
|
|
break;
|
|
case AreaEffectSimulation::AesType_def::AtDangerArea:
|
|
sendParticipantEvent(aesItemId, participantData, ProjectDataManagement::PdmEventType_def::LeaveDangerArea);
|
|
break;
|
|
case AreaEffectSimulation::AesType_def::AtMineArea:
|
|
sendParticipantEvent(aesItemId, participantData, ProjectDataManagement::PdmEventType_def::LeaveMineArea);
|
|
break;
|
|
case AreaEffectSimulation::AesType_def::AtNContamination:
|
|
sendParticipantEvent(aesItemId, participantData, ProjectDataManagement::PdmEventType_def::LeaveNuclear);
|
|
sendEffectTypeEvent(aesItemId, participantData, EffectType::NContaminationLeave);
|
|
break;
|
|
case AreaEffectSimulation::AesType_def::AtExplosionArea:
|
|
case AreaEffectSimulation::AesType_def::AtFunctionalArea:
|
|
default:
|
|
break;
|
|
} // end switch
|
|
}
|
|
|
|
|
|
// return true, if participant is inside of the form of AesItemView
|
|
bool HandlerNBC::inFormCheck(const CentralEffectSimulation::AesItemViewUtm &itemView,
|
|
const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantData)
|
|
{
|
|
if (itemView.effectStateId != AreaEffectSimulation::AesEffectState_def::EsActivated)
|
|
return false;
|
|
|
|
const QRectF boundingBoxImpact(itemView.boundingBoxBottomLeft,
|
|
itemView.boundingBoxTopRight);
|
|
const QPointF participantPosUtmPoint = CentralEffectSimulation::geographic2Utm(participantData.pos(), itemView.zone);
|
|
const QString participantPosMgrs = CentralEffectSimulation::geographic2mgrs(participantData.pos(), itemView.zone);
|
|
TRACE_LOG(m_logger) << "inFormCheck start, paricipantId: " << participantData.participantId()
|
|
<< ", aesItemId: " << itemView.aesItemId
|
|
<< ", aesTypeId: " << itemView.aesTypeId
|
|
<< ", form.size: " << itemView.form.size()
|
|
<< ", Mgrs:" << participantPosMgrs
|
|
<< ", effectStateId: " << itemView.effectStateId;
|
|
|
|
if (boundingBoxImpact.contains(participantPosUtmPoint) &&
|
|
itemView.form.containsPoint(participantPosUtmPoint, Qt::FillRule::OddEvenFill))
|
|
{
|
|
DEBUG_LOG(m_logger) << "Participant id=" << participantData.participantId()
|
|
<< " inside Area"
|
|
<< " inside Building:" << participantData.insideBuilding()
|
|
<< " roomId=" << participantData.roomId();
|
|
if ( participantData.roomId() > 0 )
|
|
{
|
|
|
|
InfrastructureManagement::StructureElement structureElement;
|
|
bool roomFound = m_ddsHandler->dtcIsm()->getStructureElementById(participantData.roomId(), structureElement);
|
|
|
|
DEBUG_LOG (m_logger) << "Participant id=" << participantData.participantId()
|
|
<< " pos.z=" << participantData.pos().z()
|
|
<< " upperOffset =" << itemView.upperOffset
|
|
<< " lowerOffset=" << itemView.lowerOffset
|
|
<< " roomFound=" << roomFound
|
|
<< " offsetZ=" << structureElement.relPosition().offsetZ();
|
|
|
|
if ( (itemView.aesTypeId.underlying() != AreaEffectSimulation::AesType_def::AtNContamination)
|
|
&& itemView.offsetIsSet
|
|
&& ( ( structureElement.relPosition().offsetZ() + 1.5 > itemView.upperOffset )
|
|
|| ( structureElement.relPosition().offsetZ() + 1.5 < itemView.lowerOffset)))
|
|
{
|
|
DEBUG_LOG (m_logger) << "Participant id=" << participantData.participantId()
|
|
<< " pos.z=" << participantData.pos().z()
|
|
<< " not between upperOffset =" << itemView.upperOffset
|
|
<< " and lowerOffset=" << itemView.lowerOffset
|
|
<< "\nreturn false";
|
|
|
|
sendLeaveEvent(itemView.aesItemId, participantData);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
sendEnterEvent(itemView.aesItemId, itemView.aesTypeId, participantData);
|
|
return true;
|
|
} // if inside
|
|
|
|
|
|
sendLeaveEvent(itemView.aesItemId, participantData);
|
|
#if 0
|
|
if (m_logger.isDebugEnabled())
|
|
{
|
|
DEBUG_LOG(m_logger) << "inFormCheck: Paricipant " << participantPosition.participantId << " outside AesItemView " << itemView.aesItemId;
|
|
DEBUG_LOG(m_logger) << "ParticipantPos = " << debug(participantPosUtmPoint);
|
|
for (const auto &itPos : itemView.form)
|
|
DEBUG_LOG(m_logger) << "itemView =" << debug(itPos);
|
|
}
|
|
#endif
|
|
return false;
|
|
} // END inFormCheck
|
|
|
|
// Send via TAB-Proxy to battlefield
|
|
void HandlerNBC::sendCesHitRequest(const CentralEffectSimulation::AesItemViewUtm &itemView,
|
|
const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantData,
|
|
qint64 effectTime,
|
|
int remaining,
|
|
int mineFieldBitIndex)
|
|
{
|
|
if (remaining < 0)
|
|
return;
|
|
|
|
DEBUG_LOG(m_logger) << "sendCesHitRequest Settings::calculateCentralAes="
|
|
<< " insideWlsArea=" << std::boolalpha << participantData.insideWlsArea()
|
|
<< " isSmartChargeType=" << std::boolalpha << m_ddsHandler->isSmartChargeType(itemView.chargeStruct)
|
|
<< " participantId=" << participantData.participantId();
|
|
|
|
const int equipNo = m_ddsHandler->participantId2EquipNo(participantData.participantId());
|
|
DEBUG_LOG(m_logger) << " ftc sendCESHit to Participant participantId = " << participantData.participantId()
|
|
<< " equipNo = " << equipNo
|
|
<< " aesItemId =" << itemView.aesItemId;
|
|
|
|
// participantPosition.participantPosition == 0 -> send to all
|
|
if (participantData.participantId() != 0 && equipNo <= 0)
|
|
{
|
|
DEBUG_LOG(m_logger) << "participantPosition.participantId != 0 && equipNo <= 0" ;
|
|
return;
|
|
}
|
|
|
|
int32_t originatorParticipantId = m_aesItemId2partIdMap.value(itemView.aesItemId, 0);
|
|
|
|
const TrainingAreaBase::TabPosition pos(participantData.pos(),
|
|
Core::PositionReportingSource_def::Gps, // irrelevant
|
|
participantData.buildingId(),
|
|
participantData.roomId());
|
|
const int originatorEquipNo = m_ddsHandler->participantId2EquipNo(originatorParticipantId);
|
|
|
|
const ProjectDataManagement::PdmEventType eventType = ProjectDataManagement::PdmEventType_def::Unknown;
|
|
TrainingAreaBase::SendCesHitRequest requestTab(
|
|
equipNo, // equipmentNumber
|
|
participantData.participantId(), // participantId
|
|
itemView.chargeStruct.chargeTypeId(), // chargeTypeId
|
|
itemView.aesItemId, // aesId
|
|
originatorEquipNo, // originatorEquipmentNumber
|
|
remaining, // remainEffectPercent ( no protection outside Building )
|
|
pos,
|
|
effectTime, // effectTime
|
|
eventType,
|
|
itemView.partyId, // originPartyId
|
|
mineFieldBitIndex
|
|
);
|
|
DEBUG_LOG(m_logger) << " participantId=" << participantData.participantId()
|
|
<< " chargeTypeId=" << itemView.chargeStruct.chargeTypeId();
|
|
|
|
|
|
m_sendCesHitRequestQueue.enqueue(requestTab);
|
|
if (m_sendCesHitRequestQueue.size() == 1)
|
|
{
|
|
DEBUG_LOG(m_logger) << "SendCesHitRequest: " << requestTab;
|
|
m_ddsHandler->ftcTab()->sendCesHitRequest(requestTab, this);
|
|
}
|
|
}
|
|
|
|
void HandlerNBC::sendCesHitRequest(const int aesItemId,
|
|
const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantData,
|
|
qint64 effectTime,
|
|
int remaining,
|
|
int mineFieldBitIndex,
|
|
EffectType effectType)
|
|
{
|
|
if (remaining < 0)
|
|
return;
|
|
|
|
AreaEffectSimulation::AesItem aesItem;
|
|
m_ddsHandler->dtcAes()->aesItemFromId(aesItemId, aesItem);
|
|
|
|
int32_t legacyChargeTypeId = 0;
|
|
int32_t partyId = 0;
|
|
if ( aesItem.partyId.is_set())
|
|
partyId = aesItem.partyId.get();
|
|
legacyChargeTypeId = m_ddsHandler->getLegacyIdFromChargeTypeId(aesItem.chargeStruct());
|
|
DEBUG_LOG(m_logger) << "sendCesHitRequest Settings::calculateCentralAes="
|
|
<< " insideWlsArea=" << std::boolalpha << participantData.insideWlsArea()
|
|
<< " isSmartChargeType=" << std::boolalpha << m_ddsHandler->isSmartChargeType(aesItem.chargeStruct())
|
|
<< " participantId=" << participantData.participantId()
|
|
<< " partyId=" << partyId
|
|
<< " effectType=" << static_cast<int>(effectType)
|
|
<< " remaining=" << remaining;
|
|
|
|
const int equipmentNumber = m_ddsHandler->participantId2EquipNo(participantData.participantId());
|
|
DEBUG_LOG(m_logger) << " ftc sendCESHit to Participant participantId = " << participantData.participantId()
|
|
<< " equipNo = " << equipmentNumber << " aesItemId =" << aesItemId;
|
|
|
|
// participantPosition.participantPosition == 0 -> send to all
|
|
if (participantData.participantId() != 0 && equipmentNumber <= 0)
|
|
{
|
|
DEBUG_LOG(m_logger) << "participantPosition.participantId != 0 && equipNo <= 0" ;
|
|
return;
|
|
} // if
|
|
|
|
// Check Protection by buildings
|
|
else if (effectType == CES_NBC::EffectType::NContaminationEnterArea1)
|
|
{
|
|
DEBUG_LOG(m_logger) << "NContaminationEnterArea1";
|
|
if (participantData.buildingId() > 0)
|
|
{
|
|
DEBUG_LOG(m_logger) << "NContaminationEnterArea1 Protection by buildings"
|
|
<< " remaining vorher=" << remaining
|
|
<< " remaining nachher=2";
|
|
remaining = 2;
|
|
}
|
|
else
|
|
{
|
|
DEBUG_LOG(m_logger) << "NContaminationEnterArea1 NO Protection by buildings"
|
|
<< " remaining vorher="<< remaining
|
|
<< " remaining nachher=1";
|
|
remaining = 1;
|
|
}
|
|
}
|
|
else if (effectType == CES_NBC::EffectType::NContaminationEnterArea2)
|
|
{
|
|
DEBUG_LOG(m_logger) << "NContaminationEnterArea2 NO Protection by buildings"
|
|
<< " remaining vorher="<< remaining
|
|
<< " remaining nachher=2";
|
|
DEBUG_LOG(m_logger) << "NContaminationEnterArea2";
|
|
remaining = 2;
|
|
}
|
|
|
|
int32_t originatorParticipantId = m_aesItemId2partIdMap.value(aesItemId, 0);
|
|
const int originatorEquipmentNumber = m_ddsHandler->participantId2EquipNo(originatorParticipantId);
|
|
const TrainingAreaBase::TabPosition pos(
|
|
participantData.pos(), Core::PositionReportingSource_def::Gps, participantData.buildingId(),
|
|
participantData.roomId()
|
|
);
|
|
const ProjectDataManagement::PdmEventType eventType = ProjectDataManagement::PdmEventType_def::Unknown;
|
|
TrainingAreaBase::SendCesHitRequest requestTab(
|
|
equipmentNumber, participantData.participantId(), legacyChargeTypeId, aesItemId, originatorEquipmentNumber,
|
|
remaining, pos, effectTime, eventType, partyId, mineFieldBitIndex
|
|
);
|
|
DEBUG_LOG(m_logger) << " participantId=" << participantData.participantId() << " chargeTypeId=" << aesItem.chargeStruct().chargeTypeId()
|
|
<< " legacyChargeTypeId=" << legacyChargeTypeId;
|
|
|
|
m_sendCesHitRequestQueue.enqueue(requestTab);
|
|
if (m_sendCesHitRequestQueue.size() == 1)
|
|
{
|
|
DEBUG_LOG(m_logger) << "SendCesHitRequest: " << requestTab;
|
|
m_ddsHandler->ftcTab()->sendCesHitRequest(requestTab, this);
|
|
} // if
|
|
}
|
|
|
|
void HandlerNBC::sendParticipantEvent(const int aesItemId,
|
|
const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantData,
|
|
const ProjectDataManagement::PdmEventType eventType)
|
|
{
|
|
ParticipantManagement::TypeClass typeClass = m_handlerParticipant->typeClassFromTypeId(participantData.participantTypeId());
|
|
// can happen since the positions are collected for all participants (no check if it is a SupportEntity or similar)
|
|
if (typeClass == ParticipantManagement::TypeClass_def::Unit ||
|
|
typeClass == ParticipantManagement::TypeClass_def::SupportUnit ||
|
|
typeClass == ParticipantManagement::TypeClass_def::SupportEntity ||
|
|
typeClass == ParticipantManagement::TypeClass_def::Aircraft ||
|
|
typeClass == ParticipantManagement::TypeClass_def::Vessel ||
|
|
typeClass == ParticipantManagement::TypeClass_def::Unknown)
|
|
{
|
|
DEBUG_LOG(m_logger) << "Participant with id " << participantData.participantId()
|
|
<< " has invalid typeClass: " << typeClass
|
|
<< " eventType: " << eventType;
|
|
return;
|
|
}
|
|
|
|
if (!eventMustBeSend(aesItemId, participantData.participantId(), eventType))
|
|
{
|
|
if ( m_isInContaminatedRoom.contains(participantData.participantId()) && participantData.roomId() == 0) // Tln leaves Building
|
|
{
|
|
DEBUG_LOG(m_logger) << "Sending Event because Participant leaves Building";
|
|
}
|
|
else
|
|
{
|
|
DEBUG_LOG(m_logger) << "Not sending Event " << eventType << " for participant " << participantData.participantId()
|
|
<< " and aes " << aesItemId << " - already sent";
|
|
return;
|
|
}
|
|
}
|
|
|
|
// send hit events only with central AES Simulation
|
|
if (eventType == ProjectDataManagement::PdmEventType_def::HitB
|
|
|| eventType == ProjectDataManagement::PdmEventType_def::HitC
|
|
|| eventType == ProjectDataManagement::PdmEventType_def::Hit
|
|
|| eventType == ProjectDataManagement::PdmEventType_def::HitEffectSimulation
|
|
|| eventType == ProjectDataManagement::PdmEventType_def::HitMine
|
|
|| eventType == ProjectDataManagement::PdmEventType_def::HitN)
|
|
{
|
|
DEBUG_LOG(m_logger) << "send hit events only with central AES Simulation participant=" << participantData.participantId();
|
|
return;
|
|
}
|
|
|
|
int equipmentNumber = m_ddsHandler->participantId2EquipNo(participantData.participantId());
|
|
if (equipmentNumber <= 0)
|
|
{
|
|
WARNING_LOG(m_logger) << "Not sending Event " << eventType << " for participant " << participantData.participantId()
|
|
<< " - participant has no equipment number";
|
|
return;
|
|
}
|
|
|
|
DEBUG_LOG(m_logger) << "sendParticipantEvent" << eventType
|
|
<< " participantId=" << participantData.participantId()
|
|
<< " AesItemId=" << aesItemId;
|
|
|
|
CentralEffectSimulation::ParticipantEvent pe;
|
|
pe.id(m_ddsHandler->getParticipantEventId());
|
|
|
|
pe.eventTypeId(eventType.underlying());
|
|
pe.participantId(participantData.participantId());
|
|
pe.eventTime(participantData.sampleTime());
|
|
pe.aesItemId(aesItemId);
|
|
pe.partyId(participantData.partyId());
|
|
|
|
if (eventType == ProjectDataManagement::PdmEventType_def::BCContamination)
|
|
{
|
|
const AreaEffectSimulation::BCContamination &bc = m_ddsHandler->dtcAes()->bCContamination(aesItemId);
|
|
pe.aesName(bc.name());
|
|
}
|
|
else if (eventType == ProjectDataManagement::PdmEventType_def::DangerArea)
|
|
{
|
|
const AreaEffectSimulation::DangerArea &da = m_ddsHandler->dtcAes()->dangerArea(aesItemId);
|
|
pe.aesName(da.name());
|
|
}
|
|
else if (eventType == ProjectDataManagement::PdmEventType_def::NContamination)
|
|
{
|
|
const AreaEffectSimulation::NContamination &nc = m_ddsHandler->dtcAes()->nContamination(aesItemId);
|
|
pe.aesName(nc.name());
|
|
}
|
|
|
|
pe.equipmentNumber(equipmentNumber);
|
|
pe.vulnerability(participantData.vulnerabilityState.underlying());
|
|
pe.position(participantData.pos());
|
|
|
|
AreaEffectSimulation::AesItem aesItem;
|
|
m_ddsHandler->dtcAes()->aesItemFromId(aesItemId, aesItem);
|
|
|
|
// Criterion for friendly Fire:
|
|
if (aesItem.partyId() != -1
|
|
&& ((eventType == ProjectDataManagement::PdmEventType_def::EnterMineArea
|
|
|| eventType == ProjectDataManagement::PdmEventType_def::EnterNuclear
|
|
|| eventType == ProjectDataManagement::PdmEventType_def::HitB
|
|
|| eventType == ProjectDataManagement::PdmEventType_def::HitC
|
|
|| eventType == ProjectDataManagement::PdmEventType_def::Hit
|
|
|| eventType == ProjectDataManagement::PdmEventType_def::HitEffectSimulation
|
|
|| eventType == ProjectDataManagement::PdmEventType_def::HitMine
|
|
|| eventType == ProjectDataManagement::PdmEventType_def::HitN)
|
|
&& aesItem.partyId() == participantData.partyId()))
|
|
pe.friendlyFire(true);
|
|
else
|
|
pe.friendlyFire(false);
|
|
|
|
INFO_LOG(m_logger) << "sendParticipantEvent: " << pe
|
|
<< ", currentMSecsSinceEpoch = " << QDateTime::currentMSecsSinceEpoch()
|
|
<< ", time difference = " << QDateTime::currentMSecsSinceEpoch() - pe.eventTime();
|
|
m_ddsHandler->dtsCes()->publish(pe);
|
|
|
|
const auto id = pe.id();
|
|
QTimer::singleShot(1 * 60 * 1000, this, [id, this]() { m_ddsHandler->dtsCes()->removeParticipantEventByKey(id); });
|
|
}
|
|
|
|
void HandlerNBC::sendEffectTypeEvent(const int aesItemId,
|
|
const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantData,
|
|
EffectType effectType)
|
|
{
|
|
// Trefferereignis Sekundaerwirkung
|
|
int mineFieldBitIndex = 0;
|
|
|
|
if (!effectTypeMustBeSend(aesItemId,
|
|
participantData.participantId(),
|
|
effectType))
|
|
{
|
|
DEBUG_LOG(m_logger) << "Not sending EffectType event " << toString(effectType)
|
|
<< ", participant: " << participantData.participantId()
|
|
<< ", aesItemId: " << aesItemId
|
|
<< " - already sent";
|
|
return;
|
|
}
|
|
const int ctasEffectType = static_cast<int>(effectType) & 0xffff;
|
|
DEBUG_LOG(m_logger) << "Sending EffectType event " << toString(effectType)
|
|
<< ", participant: " << participantData.participantId()
|
|
<< ", aesItemId: " << aesItemId
|
|
<< ", ctasEffectType: " << ctasEffectType;
|
|
sendCesHitRequest(aesItemId,
|
|
participantData,
|
|
//effectTime >= 0 ? effectTime : participantPosition.sampleTime(),
|
|
QDateTime::currentMSecsSinceEpoch(),
|
|
ctasEffectType,
|
|
mineFieldBitIndex,
|
|
effectType);
|
|
}
|
|
|
|
bool HandlerNBC::eventMustBeSend(int aesItemId,
|
|
int participantId,
|
|
const ProjectDataManagement::PdmEventType eventType)
|
|
{
|
|
// end enter-leave only once
|
|
QSet<ProjectDataManagement::PdmEventType> &activeEvents = m_eventStates[aesItemId][participantId]; // reference!
|
|
// - only send event if it was not already sent
|
|
if (activeEvents.contains(eventType))
|
|
{
|
|
DEBUG_LOG(m_logger) << "activeEvents=" << eventType
|
|
<< " return false";
|
|
return false;
|
|
}
|
|
|
|
activeEvents.insert(eventType);
|
|
|
|
// - remove opposite events (e.g remove Enter event when we leave the area)
|
|
switch (eventType.underlying())
|
|
{
|
|
case ProjectDataManagement::PdmEventType_def::EnterDangerArea:
|
|
activeEvents.remove(ProjectDataManagement::PdmEventType_def::LeaveDangerArea);
|
|
break;
|
|
case ProjectDataManagement::PdmEventType_def::LeaveDangerArea:
|
|
activeEvents.remove(ProjectDataManagement::PdmEventType_def::EnterDangerArea);
|
|
break;
|
|
case ProjectDataManagement::PdmEventType_def::EnterMineArea:
|
|
activeEvents.remove(ProjectDataManagement::PdmEventType_def::LeaveMineArea);
|
|
break;
|
|
case ProjectDataManagement::PdmEventType_def::LeaveMineArea:
|
|
activeEvents.remove(ProjectDataManagement::PdmEventType_def::EnterMineArea);
|
|
break;
|
|
case ProjectDataManagement::PdmEventType_def::EnterNuclear:
|
|
activeEvents.remove(ProjectDataManagement::PdmEventType_def::LeaveNuclear);
|
|
break;
|
|
case ProjectDataManagement::PdmEventType_def::LeaveNuclear:
|
|
activeEvents.remove(ProjectDataManagement::PdmEventType_def::EnterNuclear);
|
|
break;
|
|
case ProjectDataManagement::PdmEventType_def::EnterFunctionalArea:
|
|
case ProjectDataManagement::PdmEventType_def::LeaveFunctionalArea:
|
|
default:
|
|
break;
|
|
}
|
|
DEBUG_LOG(m_logger) << "eventMustBeSend=true";
|
|
return true;
|
|
}
|
|
|
|
bool HandlerNBC::effectTypeMustBeSend(int aesItemId,
|
|
int participantId,
|
|
EffectType effectType)
|
|
{
|
|
DEBUG_LOG(m_logger) << "effectTypeMustBeSend"
|
|
<< " aesItemId= " << aesItemId
|
|
<< " participantId=" << participantId
|
|
<< " effectType=" << CES_NBC::toString(effectType);
|
|
|
|
// end enter-leave only once
|
|
QSet<EffectType> &activeEffects = m_effectTypeStates[aesItemId][participantId]; // reference!
|
|
// - only send event if it was not already sent
|
|
if (activeEffects.contains(effectType))
|
|
{
|
|
//DEBUG_LOG(m_logger) << "effectTypeStates already contains aesItemId " << aesItemId;
|
|
return false;
|
|
}
|
|
if ( (effectType == EffectType::NContaminationEnterArea1)
|
|
|| (effectType == EffectType::NContaminationEnterArea2))
|
|
{
|
|
if (activeEffects.contains(EffectType::NContaminationDetonation))
|
|
{
|
|
DEBUG_LOG(m_logger) << "effectTypeStates.contains(NContaminationDetonation) " << aesItemId
|
|
<< " return false";
|
|
return false;
|
|
}
|
|
}
|
|
activeEffects += effectType;
|
|
|
|
bool bMustBeSend = true;
|
|
switch (effectType)
|
|
{
|
|
case EffectType::NContaminationLeave:
|
|
bMustBeSend = false;
|
|
bMustBeSend |= activeEffects.remove(EffectType::NContaminationEnterArea1);
|
|
bMustBeSend |= activeEffects.remove(EffectType::NContaminationEnterArea2);
|
|
bMustBeSend |= activeEffects.remove(EffectType::NContaminationDetonation);
|
|
break;
|
|
case EffectType::NContaminationEnterArea1:
|
|
bMustBeSend = true;
|
|
activeEffects.remove(EffectType::NContaminationLeave);
|
|
activeEffects.remove(EffectType::NContaminationEnterArea2);
|
|
activeEffects.remove(EffectType::NContaminationDetonation);
|
|
break;
|
|
case EffectType::NContaminationEnterArea2:
|
|
bMustBeSend = true;
|
|
activeEffects.remove(EffectType::NContaminationLeave);
|
|
activeEffects.remove(EffectType::NContaminationEnterArea1);
|
|
activeEffects.remove(EffectType::NContaminationDetonation);
|
|
break;
|
|
case EffectType::NContaminationDetonation:
|
|
bMustBeSend = true;
|
|
activeEffects.remove(EffectType::NContaminationLeave);
|
|
activeEffects.remove(EffectType::NContaminationEnterArea1);
|
|
activeEffects.remove(EffectType::NContaminationEnterArea2);
|
|
break;
|
|
case EffectType::BCContaminationLeave:
|
|
bMustBeSend = false;
|
|
bMustBeSend |= activeEffects.remove(EffectType::BCContaminationEnterFloating);
|
|
bMustBeSend |= activeEffects.remove(EffectType::BCContaminationEnterResident);
|
|
bMustBeSend |= activeEffects.remove(EffectType::BCContaminationEnterFloatingArea);
|
|
break;
|
|
case EffectType::BCContaminationEnterFloating:
|
|
bMustBeSend = true;
|
|
activeEffects.remove(EffectType::BCContaminationLeave);
|
|
activeEffects.remove(EffectType::BCContaminationEnterResident);
|
|
activeEffects.remove(EffectType::BCContaminationEnterFloatingArea);
|
|
break;
|
|
case EffectType::BCContaminationEnterResident:
|
|
bMustBeSend = true;
|
|
activeEffects.remove(EffectType::BCContaminationLeave);
|
|
activeEffects.remove(EffectType::BCContaminationEnterFloating);
|
|
activeEffects.remove(EffectType::BCContaminationEnterFloatingArea);
|
|
break;
|
|
case EffectType::BCContaminationEnterFloatingArea:
|
|
bMustBeSend = true;
|
|
activeEffects.remove(EffectType::BCContaminationLeave);
|
|
activeEffects.remove(EffectType::BCContaminationEnterFloating);
|
|
activeEffects.remove(EffectType::BCContaminationEnterResident);
|
|
break;
|
|
case EffectType::EffectiveMineRangeEnter:
|
|
case EffectType::EffectiveMineRangeLeave:
|
|
case EffectType::FunctionalAreaLeave:
|
|
case EffectType::FunctionalAreaEnter:
|
|
case EffectType::ExplosionArea:
|
|
case EffectType::ExplosionSingle:
|
|
case EffectType::BeStillWarning:
|
|
case EffectType::Unknown:
|
|
break;
|
|
}
|
|
|
|
return bMustBeSend;
|
|
}
|
|
|
|
|
|
// Anmerkung: Im SFM werden Quadrate und keine Kreise genommen. ( Wird hier nach Absprache mit Manfred nicht gemacht)
|
|
bool HandlerNBC::inCircle(const QPointF ¢erUtm, const double radius, const QPointF &pointUtm)
|
|
{
|
|
double squareDist = CentralEffectSimulation::getSquareDistance(centerUtm, pointUtm);
|
|
double squareRadius = radius * radius;
|
|
DEBUG_LOG(m_logger) << "squareDist: " << squareDist << ", squareRadius: " << squareRadius
|
|
<< " centerUtm=" << centerUtm.x() << "/" << centerUtm.y()
|
|
<< " pointUtm=" << pointUtm.x() << "/" << pointUtm.y()
|
|
<< " radius = " << radius
|
|
<< " dist=" << sqrt(squareDist);
|
|
return (squareDist < squareRadius);
|
|
} // inCircle
|
|
|
|
|
|
ProjectDataManagement::PdmEventType HandlerNBC::leaveEventTypeForAesType(AreaEffectSimulation::AesType aesTypeId)
|
|
{
|
|
switch (aesTypeId.underlying())
|
|
{
|
|
case AreaEffectSimulation::AesType_def::AtDangerArea:
|
|
return ProjectDataManagement::PdmEventType::LeaveDangerArea;
|
|
case AreaEffectSimulation::AesType_def::AtMineArea:
|
|
return ProjectDataManagement::PdmEventType::LeaveMineArea;
|
|
case AreaEffectSimulation::AesType_def::AtNContamination:
|
|
return ProjectDataManagement::PdmEventType::LeaveNuclear;
|
|
default:
|
|
break;
|
|
}
|
|
return ProjectDataManagement::PdmEventType::Unknown;
|
|
}
|
|
|
|
EffectType HandlerNBC::leaveEffectTypeForAesType(AreaEffectSimulation::AesType aesTypeId)
|
|
{
|
|
switch (aesTypeId.underlying())
|
|
{
|
|
case AreaEffectSimulation::AesType_def::AtBCContamination:
|
|
return EffectType::BCContaminationLeave;
|
|
case AreaEffectSimulation::AesType_def::AtNContamination:
|
|
return EffectType::NContaminationLeave;
|
|
default:
|
|
break;
|
|
}
|
|
return EffectType::Unknown;
|
|
}
|
|
|
|
EffectType HandlerNBC::effectTypeForNContaminationArea(const CentralEffectSimulation::AesItemViewUtm &itemView,
|
|
const QPointF &participantPosUtmPoint,
|
|
qint64 partPosSampleTime,
|
|
const bool isIndoor)
|
|
{
|
|
const AreaEffectSimulation::NContamination &nc = m_ddsHandler->dtcAes()->nContamination(itemView.aesItemId);
|
|
auto utm = LtsCoordTrans::UtmCoordinate::fromGeographic(nc.impactPosition().lon(), nc.impactPosition().lat(), itemView.zone);
|
|
QPointF impactPositionUtm = QPointF(utm.x, utm.y);
|
|
DEBUG_LOG(m_logger) << "HandlerNBC::effectTypeForNContaminationArea itemView.radials.size()=" << itemView.radials.size();
|
|
if (itemView.radials.size() != 3)
|
|
return EffectType::NContaminationEnterArea2; // not yet known, we only know we're inside the area
|
|
|
|
DEBUG_LOG(m_logger) << "impactPositionUtm=" << impactPositionUtm.x() << "/" << impactPositionUtm.y()
|
|
<< " participantPosUtmPoint=" << participantPosUtmPoint.x() << "/" << participantPosUtmPoint.y();
|
|
|
|
const double squareDist = CentralEffectSimulation::getSquareDistance(impactPositionUtm, participantPosUtmPoint);
|
|
if (squareDist <= pow(itemView.radials.at(0), 2))
|
|
{
|
|
// 5s delay
|
|
DEBUG_LOG(m_logger) << "partPosSampleTime: " << partPosSampleTime
|
|
<< ", itemView.effectStart: " << itemView.effectStart;
|
|
if (partPosSampleTime < itemView.effectStart + 5000)
|
|
{
|
|
DEBUG_LOG(m_logger) << "return EffectType::NContaminationDetonation";
|
|
return EffectType::NContaminationDetonation;
|
|
}
|
|
DEBUG_LOG(m_logger) << "return EffectType::NContaminationEnterArea2";
|
|
return EffectType::NContaminationEnterArea2;
|
|
}
|
|
DEBUG_LOG(m_logger) << "squareDist=" << squareDist
|
|
<< " pow(itemView.radials.at(1), 2)=" << pow(itemView.radials.at(1), 2)
|
|
<< " itemView.radials.at(1)=" << itemView.radials.at(1);
|
|
// Bereich 1
|
|
if (squareDist <= pow(itemView.radials.at(1), 2))
|
|
{
|
|
DEBUG_LOG(m_logger) << "-------------- NContamination Bereich 1 ---------------------";
|
|
if ( isIndoor)
|
|
{
|
|
DEBUG_LOG(m_logger) << "NContaminationEnterArea1 indoor => NContaminationEnterArea2";
|
|
return EffectType::NContaminationEnterArea2;
|
|
}
|
|
DEBUG_LOG(m_logger) << "NContaminationEnterArea1";
|
|
return EffectType::NContaminationEnterArea1;
|
|
}
|
|
DEBUG_LOG(m_logger) << "squareDist=" << squareDist
|
|
<< " Dist=" << sqrt (squareDist )
|
|
<< " pow(itemView.radials.at(2), 2)=" << pow(itemView.radials.at(2), 2)
|
|
<< " itemView.radials.at(2)=" << itemView.radials.at(2);
|
|
// Bereich 2
|
|
if (squareDist <= pow(itemView.radials.at(2), 2))
|
|
{
|
|
DEBUG_LOG(m_logger) << "-------------- NContamination Bereich 2 ---------------------";
|
|
if ( isIndoor)
|
|
{
|
|
DEBUG_LOG(m_logger) << "NContaminationEnterArea2 indoor => NContaminationLeave";
|
|
return EffectType::NContaminationLeave;
|
|
}
|
|
DEBUG_LOG(m_logger) << "NContaminationEnterArea2";
|
|
return EffectType::NContaminationEnterArea2;
|
|
}
|
|
DEBUG_LOG(m_logger) << "NContaminationLeave";
|
|
return EffectType::NContaminationLeave;
|
|
}
|
|
|
|
EffectType HandlerNBC::effectTypeForBCContaminationArea(const CentralEffectSimulation::AesItemViewUtm &itemView,
|
|
const QPointF &participantPosUtmPoint)
|
|
{
|
|
if (itemView.radials.size() != 1)
|
|
return EffectType::BCContaminationEnterFloating;
|
|
// use real start point for non floating!
|
|
const auto &bcItem = m_ddsHandler->dtcAes()->bCContamination(itemView.aesItemId);
|
|
const auto utmImpcat = CentralEffectSimulation::geographic2Utm(bcItem.impactPosition(), itemView.zone);
|
|
const double squareDist = CentralEffectSimulation::getSquareDistance(utmImpcat, participantPosUtmPoint);
|
|
if (squareDist <= pow(itemView.radials.at(0), 2))
|
|
{
|
|
return EffectType::BCContaminationEnterResident; // first circle of resident contamination
|
|
}
|
|
return EffectType::BCContaminationEnterFloatingArea;
|
|
|
|
//return EffectType::BCContaminationEnterFloatingArea; // expanding/moving part of the contamination
|
|
}
|
|
|
|
|
|
void HandlerNBC::aesItemViewRemoved(int aesItemId)
|
|
{
|
|
const CentralEffectSimulation::AesItemViewUtm aiv = m_aesItemViews.value(aesItemId);
|
|
if (aiv.aesItemId == aesItemId)
|
|
{
|
|
const auto effectTypLeave = leaveEffectTypeForAesType(aiv.aesTypeId);
|
|
if (effectTypLeave != EffectType::Unknown)
|
|
{
|
|
DEBUG_LOG(m_logger) << "aesItemViewRemoved, leaveEffectType: " << toString(effectTypLeave);
|
|
auto it = m_effectTypeStates.find(aesItemId);
|
|
if (it != m_effectTypeStates.end())
|
|
{
|
|
const QHash<int, QSet<EffectType>> &participants = it.value();
|
|
DEBUG_LOG(m_logger) << "aesItemViewRemoved, sending leave events to " << participants.size()
|
|
<< " participants";
|
|
for (auto itP = participants.begin(); itP != participants.end(); ++ itP)
|
|
sendEffectTypeEvent(aesItemId, m_handlerParticipant->position(itP.key()), effectTypLeave);
|
|
}
|
|
}
|
|
const auto eventTypeLeave = leaveEventTypeForAesType(aiv.aesTypeId);
|
|
if (eventTypeLeave != ProjectDataManagement::PdmEventType::Unknown)
|
|
{
|
|
DEBUG_LOG(m_logger) << "aesItemViewRemoved, leaveEventType: " << eventTypeLeave;
|
|
auto it = m_eventStates.find(aesItemId);
|
|
if (it != m_eventStates.end())
|
|
{
|
|
const QHash<int, QSet<ProjectDataManagement::PdmEventType>> &participants = it.value();
|
|
DEBUG_LOG(m_logger) << "aesItemViewRemoved, sending leave events to " << participants.size()
|
|
<< " participants";
|
|
for (auto itP = participants.begin(); itP != participants.end(); ++ itP)
|
|
sendParticipantEvent(aiv.aesItemId, m_handlerParticipant->position(itP.key()), eventTypeLeave);
|
|
}
|
|
}
|
|
}
|
|
|
|
m_effectTypeStates.remove(aesItemId);
|
|
m_aesItemViews.remove(aesItemId);
|
|
m_explosionSingleStates.remove(aesItemId);
|
|
m_eventStates.remove(aesItemId);
|
|
} // END aesItemViewRemoved
|
|
|
|
// ///////////////////////////////////
|
|
// B L D (Buildings)
|
|
// ///////////////////////////////////
|
|
|
|
int HandlerNBC::getContaminationFromBuildingRoom(const int buildingId, const int roomId) const
|
|
{
|
|
DEBUG_LOG(m_logger) << "getContaminationFromBuildingRoom buildingId=" << buildingId
|
|
<< " roomId=" << roomId;
|
|
|
|
Buildings::BuildingState buildingState = m_ddsHandler->dtcBld()->buildingState(buildingId);
|
|
if (buildingState.contaminationStates().size() == 0 )
|
|
return 0;
|
|
|
|
|
|
if (buildingState.contaminationStates().size() == 0)
|
|
return 0;
|
|
|
|
for (unsigned int i = 0; i < buildingState.contaminationStates().size(); i++)
|
|
{
|
|
for (unsigned int j = 0; j < buildingState.contaminationStates()[i].rooms().size(); j++)
|
|
{
|
|
if (buildingState.contaminationStates()[i].rooms()[j] == roomId)
|
|
return buildingState.contaminationStates()[i].aesId();
|
|
}
|
|
}
|
|
return 0;
|
|
} // end of getContaminationFromBuildingRoom()
|
|
|
|
void HandlerNBC::onBuildingStateChanged(const Buildings::BuildingState &data, DataModification modType)
|
|
{
|
|
if (modType == DataModification::eRemoved)
|
|
{
|
|
return;
|
|
}
|
|
|
|
DEBUG_LOG(m_logger) << "Got BuildingState originatorParticipantId=" << data.originatorParticipantId()
|
|
<< ", aesId = " << data.aesId()
|
|
<< ", data.contaminationStates().size()=" << data.contaminationStates().size();
|
|
// Check each participant
|
|
const QHash<int, CentralEffectSimulation::HandlerParticipant::CesParticipantData> participantsMap = m_handlerParticipant->positions();
|
|
|
|
for (const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPos : participantsMap)
|
|
{
|
|
if (m_handlerParticipant->isOutdated(participantPos))
|
|
continue;
|
|
|
|
if (participantPos.buildingId() == 0)
|
|
continue;
|
|
|
|
int aesId = getContaminationFromBuildingRoom(participantPos.buildingId(), participantPos.roomId());
|
|
const CentralEffectSimulation::AesItemViewUtm itemView = m_aesItemViews.value(aesId);
|
|
QHash<int, bool> aesIds = m_participantAes.value(participantPos.participantId());
|
|
aesIds.insert(aesId, true);
|
|
m_participantAes.insert(participantPos.participantId(), aesIds);
|
|
onNewIndoorParticipantPosition(participantPos);
|
|
}
|
|
|
|
} // END onBuildingStateChanged
|
|
|
|
void HandlerNBC::onNewIndoorParticipantPosition(const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantData)
|
|
{
|
|
bool enterBuilding = false;
|
|
if ( m_lastRoomId.value(participantData.participantId()) == 0)
|
|
{
|
|
DEBUG_LOG(m_logger) << "m_lastRoomId Enter Building m_isInContaminatedRoom.contains participantId=" << participantData.participantId()
|
|
<< " roomId=" << participantData.roomId()
|
|
<< " m_isInContaminatedRoom. \nremove!!!!";
|
|
m_isInContaminatedRoom.remove(participantData.participantId());
|
|
m_lastRoomId.insert(participantData.participantId(), participantData.roomId());
|
|
enterBuilding = true;
|
|
}
|
|
else
|
|
{
|
|
DEBUG_LOG(m_logger) << "m_lastRoomId.contains(" << m_lastRoomId.contains(participantData.participantId())
|
|
<< " roomId=" << m_lastRoomId.value(participantData.participantId());
|
|
}
|
|
|
|
int aesId = getContaminationFromBuildingRoom(participantData.buildingId(), participantData.roomId());
|
|
DEBUG_LOG(m_logger) << "++++++++ onNewIndoorParticipantPosition participantId=" << participantData.participantId()
|
|
<< " buildingId=" << participantData.buildingId()
|
|
<< " roomId=" << participantData.roomId()
|
|
<< " reportingSource=" << participantData.reportingSource()
|
|
<< " Raum ist Kontaminiert: aesId=" << aesId;
|
|
if ( aesId == 0)
|
|
{
|
|
onNewOutdoorParticipantPosition(participantData);
|
|
return;
|
|
}
|
|
|
|
|
|
if (enterBuilding)
|
|
{
|
|
QHash<int, QSet<EffectType>> effectTypeHash = m_effectTypeStates.value(aesId);
|
|
if ( effectTypeHash.contains(participantData.participantId()))
|
|
{
|
|
effectTypeHash.remove(participantData.participantId());
|
|
}
|
|
m_effectTypeStates.insert(aesId, effectTypeHash);
|
|
}
|
|
|
|
|
|
DEBUG_LOG(m_logger) << "aesId=" << aesId;
|
|
|
|
if (aesId > 0 && !m_aesItemViews.contains(aesId))
|
|
{
|
|
DEBUG_LOG(m_logger) << "m_isInContaminatedRoom insert participantId=" << participantData.participantId()
|
|
<< " aesId=" << aesId;
|
|
m_isInContaminatedRoom.insert(participantData.participantId(), aesId);
|
|
}
|
|
|
|
if (aesId > 0)
|
|
{
|
|
AreaEffectSimulation::AesItemView aesItemView;
|
|
m_ddsHandler->dtcAes()->aesItemViewFromEntityId(aesId,AreaEffectSimulation::AesType::AtUnknown, aesItemView );
|
|
|
|
AreaEffectSimulation::AesType aesTypeId = aesItemView.aesTypeId();
|
|
|
|
DEBUG_LOG(m_logger) << "onNewIndoorParticipantPosition sendEnterEvent aesTypeId=" << aesTypeId;
|
|
sendEnterEvent(aesId,aesTypeId, participantData, true);
|
|
}
|
|
else
|
|
{
|
|
if (m_participantAes.contains(participantData.participantId()))
|
|
{
|
|
QHash<int, bool> aesIds = m_participantAes.value(participantData.participantId());
|
|
// leave aesArea
|
|
QHashIterator<int, bool> i(aesIds);
|
|
while (i.hasNext())
|
|
{
|
|
i.next();
|
|
CentralEffectSimulation::AesItemViewUtm itemView;
|
|
itemView = m_aesItemViews.value(i.key());
|
|
if (itemView.aesItemId > 0)
|
|
sendLeaveEvent(itemView.aesItemId, participantData);
|
|
}
|
|
}
|
|
}
|
|
} // onNewIndoorParticipantPosition
|
|
|
|
} // namespace CES_NBC
|