/** * Handler for player data * $Id$ * $HeadURL$ * $Author$ * Created by gr, SLSE, 2017-02-20 */ #include "handler_participant_booby_trap.h" #include #include #include namespace CesVirtualMines { HandlerParticipantBoobyTrap::HandlerParticipantBoobyTrap(const std::shared_ptr &ddsHandler, const std::shared_ptr &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 &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 &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