/** * @RDE_HEADER@ * PDM Custom functions (extends pdmm_dtc_impl.cpp/.h) * $Id$ * $HeadURL$ * $Author$ * Created by Iuliana Ojog, SLSE, 2016-11-26 */ #include "pdm_dtc_impl_custom.h" #include "NGLLogger/INGLLogger.h" #include "pdm_translation.h" #include #include #include #include #include #include #include #include #include namespace ProjectDataManagement { namespace Interface { DtcImplCustom::DtcImplCustom(const std::shared_ptr &ddsConnector) : DtcImpl(ddsConnector) { waitForHistoricalDataChargeType(2000); waitForHistoricalDataIgniterFunction(2000); waitForHistoricalDataIgniterType(2000); waitForHistoricalDataChargeType(2000); waitForHistoricalDataChargeTypeIgniterTypeIgniterFunction(2000); waitForHistoricalDataLoadType(2000); waitForHistoricalDataChargeTypeLoadType(2000); fillChargeTypeIgniterTypeIgniterFunctionProps(); fillChargeTypeLoadTypeProps(); // Disable updates as merge does some funny things /* connect(this, &DtcImplCustom::chargeTypeChanged, this, &DtcImplCustom::onChargeTypeChanged); connect(this, &DtcImplCustom::igniterTypeChanged, this, &DtcImplCustom::onIgniterTypeChanged); connect(this, &DtcImplCustom::igniterFunctionChanged, this, &DtcImplCustom::onIgniterFunctionChanged); connect(this, &DtcImplCustom::chargeTypeIgniterTypeIgniterFunctionChanged, this, &DtcImplCustom::onChargeTypeIgniterTypeIgniterFunctionChanged); */ } void DtcImplCustom::fillChargeTypeIgniterTypeIgniterFunctionProps() { if (!isChargeTypeIgniterTypeIgniterFunctionEnabled()) waitForHistoricalDataChargeTypeIgniterTypeIgniterFunction(2000); auto ctItIfMap = chargeTypeIgniterTypeIgniterFunctions(); for (auto it = ctItIfMap.constBegin(); it != ctItIfMap.constEnd(); ++it) { ChargeTypeIgniterTypeIgniterFunctionProps props; ChargeTypeIgniterTypeIgniterFunction ctitif = it.value(); props.chargeTypeId = ctitif.chargeTypeId(); props.igniterTypeId = ctitif.igniterTypeId(); props.igniterFunctionId = ctitif.igniterFunctionId(); props.igniterFunctionBase = ctitif.igniterFunctionBaseId(); props.impactRadius = ctitif.impactRadius(); props.hazardDistance = ctitif.hazardDistance(); props.chargeLegacyId = ctitif.chargeLegacyId(); QJsonObject ctProps = propertiesToJson(chargeType(props.chargeTypeId).properties()); QJsonObject itProps = propertiesToJson(igniterType(props.igniterTypeId).properties()); QJsonObject ifProps = propertiesToJson(igniterFunction(props.igniterFunctionId).properties()); QJsonObject ctitifProps = propertiesToJson(ctitif.properties()); // Combine JsonObjects to Map -> one big JsonObject QVariantMap map = ctProps.toVariantMap(); #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) map.insert(itProps.toVariantMap()); map.insert(ifProps.toVariantMap()); map.insert(ctitifProps.toVariantMap()); #else map.unite(itProps.toVariantMap()); map.unite(ifProps.toVariantMap()); map.unite(ctitifProps.toVariantMap()); #endif QJsonObject obj = QJsonObject::fromVariantMap(map); setProps(props, obj); m_ctItIfProps.insert(it.key(), props); } for (auto it = m_ctItIfProps.constBegin(); it != m_ctItIfProps.constEnd(); ++it) { if (it.value().chargeTypeId > 2000 || it.value().chargeTypeId < 100) continue; INFO_LOG(m_logger) << "chargeTypeId: " << it.value().chargeTypeId; INFO_LOG(m_logger) << "ChargeTypeName:" << it.value().adlerChargeTypeName; INFO_LOG(m_logger) << "igniterTypeId: " << it.value().igniterTypeId; INFO_LOG(m_logger) << "igniterTypeName: " << it.value().adlerIgniterTypeName; INFO_LOG(m_logger) << "igniterFunctionId: " << it.value().igniterFunctionId; INFO_LOG(m_logger) << "igniterFunctionName: " << it.value().adlerIgniterFunctionName; INFO_LOG(m_logger) << "igniterFunctionBase: " << it.value().igniterFunctionBase; INFO_LOG(m_logger) << "impactRadius: " << it.value().impactRadius; INFO_LOG(m_logger) << "chargeLegacyId: " << it.value().chargeLegacyId; INFO_LOG(m_logger) << "isSmart: " << it.value().isSmart; INFO_LOG(m_logger) << "isSmoke: " << it.value().isSmoke; INFO_LOG(m_logger) << "isDus: " << it.value().isDus; INFO_LOG(m_logger) << "isConcrete: " << it.value().isConcrete; INFO_LOG(m_logger) << "volatilityTypeId: " << it.value().volatilityTypeId; } } void DtcImplCustom::fillChargeTypeLoadTypeProps() { if (!isChargeTypeLoadTypeEnabled()) waitForHistoricalDataChargeTypeLoadType(2000); for (const auto &ctlt : chargeTypeLoadTypes()) { ChargeTypeLoadTypeProps props; props.chargeTypeId = ctlt.chargeTypeId(); props.loadTypeId = ctlt.loadTypeId(); QJsonObject ltProps = propertiesToJson(loadType(props.loadTypeId).properties()); QJsonObject ctltProps = propertiesToJson(ctlt.properties()); // Combine JsonObjects to Map -> one big JsonObject QVariantMap map = ltProps.toVariantMap(); #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) map.insert(ctltProps.toVariantMap()); #else map.unite(ctltProps.toVariantMap()); #endif QJsonObject obj = QJsonObject::fromVariantMap(map); setProps(props, obj); m_ctLtProps.insert(ctlt.id(), props); } } void DtcImplCustom::onIgniterTypeChanged(const IgniterType &ignType) { if (ignType.id() <= 0) return; for (auto it = m_ctItIfProps.begin(); it != m_ctItIfProps.end(); ++it) { if (it.value().igniterTypeId != ignType.id()) continue; QJsonObject ctProps = propertiesToJson(chargeType(it.value().chargeTypeId).properties()); QJsonObject itProps = propertiesToJson(ignType.properties()); QJsonObject ifProps = propertiesToJson(igniterFunction(it.value().igniterFunctionId).properties()); QJsonObject ctitifProps = propertiesToJson(chargeTypeIgniterTypeIgniterFunction(it.key()).properties()); // Combine JsonObjects to Map -> one big JsonObject mergeProperties(it, ifProps, ctProps, ctitifProps, itProps); } } void DtcImplCustom::onIgniterFunctionChanged(const IgniterFunction &ignFunc) { if (ignFunc.id() <= 0) return; for (auto it = m_ctItIfProps.begin(); it != m_ctItIfProps.end(); ++it) { if (it.value().igniterFunctionId != ignFunc.id()) continue; QJsonObject ctProps = propertiesToJson(chargeType(it.value().chargeTypeId).properties()); QJsonObject itProps = propertiesToJson(igniterType(it.value().igniterFunctionId).properties()); QJsonObject ifProps = propertiesToJson(ignFunc.properties()); QJsonObject ctitifProps = propertiesToJson(chargeTypeIgniterTypeIgniterFunction(it.key()).properties()); // Combine JsonObjects to Map -> one big JsonObject mergeProperties(it, ifProps, ctProps, ctitifProps, itProps); } } void DtcImplCustom::mergeProperties(QHash::iterator &it, const QJsonObject &ifProps, const QJsonObject &ctProps, const QJsonObject &ctitifProps, const QJsonObject &itProps) { QVariantMap map = ctProps.toVariantMap(); #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) map.insert(itProps.toVariantMap()); map.insert(ifProps.toVariantMap()); map.insert(ctitifProps.toVariantMap()); #else map.unite(itProps.toVariantMap()); map.unite(ifProps.toVariantMap()); map.unite(ctitifProps.toVariantMap()); #endif QJsonObject obj = QJsonObject::fromVariantMap(map); setProps(it.value(), obj); m_ctItIfProps.insert(it.key(), it.value()); } void DtcImplCustom::onChargeTypeChanged(const ChargeType &ct) { if (ct.id() <= 0) return; QHash::iterator it; for (it = m_ctItIfProps.begin(); it != m_ctItIfProps.end(); ++it) { if (it.value().chargeTypeId != ct.id()) continue; QJsonObject ctProps = propertiesToJson(ct.properties()); QJsonObject itProps = propertiesToJson(igniterType(it.value().igniterFunctionId).properties()); QJsonObject ifProps = propertiesToJson(igniterFunction(it.value().igniterFunctionId).properties()); QJsonObject ctitifProps = propertiesToJson(chargeTypeIgniterTypeIgniterFunction(it.key()).properties()); // Combine JsonObjects to Map -> one big JsonObject mergeProperties(it, ifProps, ctProps, ctitifProps, itProps); } } void DtcImplCustom::onChargeTypeIgniterTypeIgniterFunctionChanged(const ChargeTypeIgniterTypeIgniterFunction &ctitif) { if (ctitif.id() <= 0) return; for (auto it = m_ctItIfProps.begin(); it != m_ctItIfProps.end(); ++it) { if (it.key() != ctitif.id()) continue; it.value().chargeTypeId = ctitif.chargeTypeId(); it.value().igniterTypeId = ctitif.igniterTypeId(); it.value().igniterFunctionId = ctitif.igniterFunctionId(); it.value().igniterFunctionBase = ctitif.igniterFunctionBaseId(); it.value().impactRadius = ctitif.impactRadius(); it.value().hazardDistance = ctitif.hazardDistance(); it.value().chargeLegacyId = ctitif.chargeLegacyId(); QJsonObject ctProps = propertiesToJson(chargeType(it.value().chargeTypeId).properties()); QJsonObject itProps = propertiesToJson(igniterType(it.value().igniterFunctionId).properties()); QJsonObject ifProps = propertiesToJson(igniterFunction(it.value().igniterFunctionId).properties()); QJsonObject ctitifProps = propertiesToJson(ctitif.properties()); // Combine JsonObjects to Map -> one big JsonObject mergeProperties(it, ifProps, ctProps, ctitifProps, itProps); } } QVector DtcImplCustom::chargesForGearClass(GearClass gearClass) { QVector ret; if (!isGearTypeEnabled()) { enableGearType(); waitForHistoricalDataGearType(2000); } if (!isGearTypeChargeTypeEnabled()) { enableGearTypeChargeType(); waitForHistoricalDataGearTypeChargeType(2000); } const auto gear2ChargeMap = gearTypeChargeTypes(); const auto chargeMap = chargeTypes(); for (const rti::sub::LoanedSample &sample : m_dtcGearType->readAlive()) { if (sample.data().gearClassId() != gearClass) continue; const int gearTypeId = sample.data().id(); for (auto gIt = gear2ChargeMap.begin(); gIt != gear2ChargeMap.end(); ++gIt) { if (gIt.value().gearTypeId() == gearTypeId) ret += chargeMap.value(gIt.value().chargeTypeId()); } } return ret; } QVector DtcImplCustom::ignitersForChargeType(int chargeTypeId) { QVector ret; if (!isIgniterTypeEnabled()) { enableIgniterType(); waitForHistoricalDataIgniterType(2000); } if (!isChargeTypeIgniterTypeIgniterFunctionEnabled()) { enableChargeTypeIgniterTypeIgniterFunction(); waitForHistoricalDataChargeTypeIgniterTypeIgniterFunction(2000); } const auto chargeType2IgniterMap = chargeTypeIgniterTypeIgniterFunctions(); const auto igniterTypeMap = igniterTypes(); for (auto it = chargeType2IgniterMap.begin(); it != chargeType2IgniterMap.end(); ++it) { if (it.value().chargeTypeId() == chargeTypeId) { ProjectDataManagement::IgniterType igType = igniterTypeMap.value(it.value().igniterTypeId()); if (!ret.contains(igType)) ret += igType; } } return ret; } QVector DtcImplCustom::igniterFunctionsForChargeTypeIgniterType(int chargeTypeId, int igniterTypeId) { QVector ret; if (!isIgniterFunctionEnabled()) { enableIgniterFunction(); waitForHistoricalDataIgniterFunction(2000); } if (!isChargeTypeIgniterTypeIgniterFunctionEnabled()) { enableChargeTypeIgniterTypeIgniterFunction(); waitForHistoricalDataChargeTypeIgniterTypeIgniterFunction(2000); } const auto chargeType2IgniterMap = chargeTypeIgniterTypeIgniterFunctions(); for (auto it = chargeType2IgniterMap.constBegin(); it != chargeType2IgniterMap.constEnd(); ++it) { if (it.value().chargeTypeId() == chargeTypeId && it.value().igniterTypeId() == igniterTypeId) ret += it.value(); } return ret; } QVector DtcImplCustom::loadsForChargeType(int chargeTypeId) { QVector ret; if (!isLoadTypeEnabled()) { enableLoadType(); waitForHistoricalDataLoadType(2000); } if (!isChargeTypeLoadTypeEnabled()) { enableChargeTypeLoadType(); waitForHistoricalDataChargeTypeLoadType(2000); } const auto chargeType2IgniterMap = chargeTypeLoadTypes(); const auto loadTypeMap = loadTypes(); for (auto it = chargeType2IgniterMap.begin(); it != chargeType2IgniterMap.end(); ++it) { if (it.value().chargeTypeId() == chargeTypeId) { ProjectDataManagement::LoadType igType = loadTypeMap.value(it.value().loadTypeId()); if (!ret.contains(igType)) ret += igType; } } return ret; } int DtcImplCustom::getTargetTypeIdFromAdlerTargetType(const QString &typ) { if (typ.isEmpty()) return 0; if (!isTargetTypeEnabled()) { enableTargetType(); waitForHistoricalDataTargetType(2000); } const auto targetTypeMap = targetTypes(); for (const auto &targetType : targetTypeMap) { if (adlerTargetTypeName(targetType.id()) != typ) continue; DEBUG_LOG(m_logger) << LOGFUNCTION << " - adlerTargetTypeName: " << typ << ", targetTypeId:" << targetType.id(); return targetType.id(); } return 0; } int DtcImplCustom::getTargetSubTypeIdFromAdlerTargetSubType(const QString &subTyp) { if (subTyp.isEmpty()) return 0; if (!isTargetSubTypeEnabled()) { enableTargetSubType(); waitForHistoricalDataTargetSubType(2000); } const auto targetSubTypeMap = targetSubTypes(); for (const auto &targetSubType : targetSubTypeMap) { if (adlerTargetSubTypeName(targetSubType.id()) != subTyp) continue; DEBUG_LOG(m_logger) << LOGFUNCTION << " - adlerTargetSubTypName: " << subTyp << ", targetSubTypeId:" << targetSubType.id(); return targetSubType.id(); } return 0; } int DtcImplCustom::getChargeTypeIdFromAdlerCharges(const QString &geschosssorte) { if (geschosssorte.isEmpty()) return 0; if (!isChargeTypeEnabled()) { enableChargeType(); waitForHistoricalDataChargeType(2000); } const auto chargeMap = chargeTypes(); for (const auto &charge : chargeMap) { if (adlerChargeTypeName(charge.id()) != geschosssorte) continue; INFO_LOG(m_logger) << "---- geschosssorte: " << geschosssorte << ", chargeId:" << charge.id(); return charge.id(); } return 0; } int DtcImplCustom::getIgniterTypeIdFromAdlerIgniter(const QString &zuender) { int igniterTypeId = 0; if (!isIgniterTypeEnabled()) { enableIgniterType(); waitForHistoricalDataIgniterType(2000); } const auto ignTypeMap = igniterTypes(); for (const auto &ignType : ignTypeMap) { if (adlerIgniterTypeName(ignType.id()) != zuender) continue; INFO_LOG(m_logger) << "---- zuender: " << zuender << ", igniterTypeId:" << ignType.id(); igniterTypeId = ignType.id(); break; } return igniterTypeId; } int DtcImplCustom::getIgniterFunctionIdFromAdlerIgniterFunction(const QString &zuenderFunktion) { int igniterFunctionId = 0; if (!isIgniterFunctionEnabled()) { enableIgniterFunction(); waitForHistoricalDataIgniterFunction(2000); } const auto ignFunctionMap = igniterFunctions(); for (const auto &ignFunc : ignFunctionMap) { if (adlerIgniterFunctionName(ignFunc.id()) != zuenderFunktion) continue; INFO_LOG(m_logger) << "---- zuender: " << zuenderFunktion << ", igniterFunctionId:" << ignFunc.id(); igniterFunctionId = ignFunc.id(); break; } return igniterFunctionId; } int DtcImplCustom::getLoadTypeIdFromAdlerLoad(const QString &ladung) { int loadTypeId = 0; if (!isLoadTypeEnabled()) { enableLoadType(); waitForHistoricalDataLoadType(2000); } for (const auto < : loadTypes()) { if (adlerLoadTypeName(lt.id()) != ladung) continue; INFO_LOG(m_logger) << "---- zuender: " << ladung << ", loadTypeId:" << lt.id(); loadTypeId = lt.id(); break; } return loadTypeId; } double DtcImplCustom::expansionFactor(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { // no igniterType/igniterFunction for Chemicals return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).expansionFactor; } double DtcImplCustom::impactRadius(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).impactRadius; } double DtcImplCustom::impactEdgeLength(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { // no igniterType/igniterFunction return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).impactEdgeLength; } bool DtcImplCustom::isDryFire(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { // no igniterType/igniterFunction return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).isDryFire; } int DtcImplCustom::mineClass(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).mineClass; } bool DtcImplCustom::canBeThrown(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).canBeThrown; } bool DtcImplCustom::canBeCreated(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).canBeCreated; } bool DtcImplCustom::isIed(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).isIed; } bool DtcImplCustom::isReactivatable(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { auto props = chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId); return props.isDus && props.isReactivatable; } bool DtcImplCustom::isSmart(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).isSmart; } bool DtcImplCustom::isSmoke(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).isSmoke; } int DtcImplCustom::maxEffectShows(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).maxEffectShows; } bool DtcImplCustom::isVisible(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).isVisible; } int DtcImplCustom::searchRadius(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).searchRadius; } bool DtcImplCustom::showHitline(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).showHitline && !isIndirect(chargeTypeId); } int DtcImplCustom::remainingTasCode(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).remainingTasCode; } int DtcImplCustom::segments(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).segments; } bool DtcImplCustom::isLine(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).isLine; } bool DtcImplCustom::isFromMineLayer(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).isFromMineLayer; } bool DtcImplCustom::isMineLaying(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).isMineLaying; } QJsonObject DtcImplCustom::mineLayingPattern(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).mineLayingPattern; } QVector DtcImplCustom::spacing(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).spacing; } int DtcImplCustom::height(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).height; } int DtcImplCustom::secondaryRemainingTasCode(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).secondaryRemainingTasCode; } bool DtcImplCustom::isLaserGuidable(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).isLaserGuidable; } bool DtcImplCustom::isUasDroppable(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).isUasDroppable; } bool DtcImplCustom::isJamming(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).isJamming; } ChargeTypeProperty DtcImplCustom::getChargeTypeSpecialProperty(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { if (chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).isLRF) return ChargeTypeProperty::LRF; if (chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).isLTD) return ChargeTypeProperty::LTD; return ChargeTypeProperty::None; } VolatilityType DtcImplCustom::volatilityTypeId(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).volatilityTypeId; } int DtcImplCustom::hazardDistance(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).hazardDistance; } QVector DtcImplCustom::casEffects(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).casEffects; } bool DtcImplCustom::canRestock(int gearTypeId) { return gearTypeProps(gearTypeId).canRestock; } bool DtcImplCustom::canSetDefaults(int gearTypeId) { return gearTypeProps(gearTypeId).canSetDefaults; } int DtcImplCustom::maxCharges(int gearTypeId) { return gearTypeProps(gearTypeId).maxCharges; } int DtcImplCustom::cadence(int gearTypeId) { return gearTypeProps(gearTypeId).cadence; } int DtcImplCustom::getAdlerWeaponSystemId(int gearTypeId) { return gearTypeProps(gearTypeId).adlerWeaponSystemId; } int DtcImplCustom::maxCharge(int gearTypeId, int chargeTypeId) { const auto gear2ChargeMap = gearTypeChargeTypes(); for (auto gIt = gear2ChargeMap.begin(); gIt != gear2ChargeMap.end(); ++gIt) { if (gIt.value().gearTypeId() == gearTypeId && gIt.value().chargeTypeId() == chargeTypeId) return gearTypeChargeTypeProps(gIt.value().id()).maxCharge; } return 0; } int DtcImplCustom::factoryDefault(int gearTypeId, int chargeTypeId) { const auto gear2ChargeMap = gearTypeChargeTypes(); for (auto gIt = gear2ChargeMap.begin(); gIt != gear2ChargeMap.end(); ++gIt) { if (gIt.value().gearTypeId() == gearTypeId && gIt.value().chargeTypeId() == chargeTypeId) return gearTypeChargeTypeProps(gIt.value().id()).factoryDefault; } return 0; } QVector DtcImplCustom::targetSubTypesForTargetType(int targetTypeId) { QVector ret; const auto &targetTypeTargetSubtypeMap = targetTypeTargetSubTypes(); const auto &targetSubtypesMap = targetSubTypes(); for (const auto &targeTypeTargetSubtype : targetTypeTargetSubtypeMap) { if (targeTypeTargetSubtype.targetTypeId() == targetTypeId) { ProjectDataManagement::TargetSubType targetSubType = targetSubtypesMap.value(targeTypeTargetSubtype.targetSubTypeId()); if (!ret.contains(targetSubType)) ret += targetSubType; } } return ret; } QVector DtcImplCustom::gearTypeIdFromChargeTypeId(int chargeTypeId) { // 27-05-2026: implement cache; // valid, since charges do not change during exercise: static QHash> s_gearTypeChargeTypeCache; const auto &it = s_gearTypeChargeTypeCache.constFind(chargeTypeId); if (it != s_gearTypeChargeTypeCache.constEnd()) return *it; QVector ret; for (const auto >ct : gearTypeChargeTypes()) { if (gtct.chargeTypeId() == chargeTypeId) ret << gtct.gearTypeId(); } s_gearTypeChargeTypeCache[chargeTypeId] = ret; return ret; } GearClass DtcImplCustom::gearClassFromChargeTypeId(int chargeTypeId) { // 20.11.2024: implement cache; // valid, since charges do not change during exercise: // 20.11.2024: Cache modifications reviewed be Hanna :-) static QHash s_gearClassChargeTypeCache; const auto &it = s_gearClassChargeTypeCache.constFind(chargeTypeId); if (it != s_gearClassChargeTypeCache.constEnd()) return *it; const int requestedCTID = chargeTypeId; // !!! pay attention: chargeTypeId may change in following line chargeTypeId = getAvailableChargeTypeId(chargeTypeId); if (chargeTypeId <= 0) { // update cache: s_gearClassChargeTypeCache[requestedCTID] = ProjectDataManagement::GearClass::Unknown; return ProjectDataManagement::GearClass::Unknown; } const auto &gear2ChargeMap = gearTypeChargeTypes(); const auto &gearTypesMap = gearTypes(); for (const auto &gearType2ChargeType : gear2ChargeMap) // gear2ChargeMap is already const :-) { if (gearType2ChargeType.chargeTypeId() == chargeTypeId) { const auto &gearType = gearTypesMap.value(gearType2ChargeType.gearTypeId()); // update cache: s_gearClassChargeTypeCache[requestedCTID] = gearType.gearClassId(); return gearType.gearClassId(); } } // update cache: s_gearClassChargeTypeCache[requestedCTID] = ProjectDataManagement::GearClass::Unknown; return ProjectDataManagement::GearClass::Unknown; } QVector DtcImplCustom::getSanitationProcedures(qint64 procedures) { QVector ret; const auto procs = sanitationProcedures(); if (procedures == 0) { ret.append(procs.value(0)); return ret; } for (const auto &proc : procs) { if (procedures & proc.dataCode()) ret.append(proc); } /* unsigned long long check = 1ULL; //Treatment Category X if (procedures & (check << 63) || procedures & (check << 62) || procedures & (check << 61)) ret.append(ProjectDataManagement::SanitationProcedures::Unknown); if (procedures & (check << 60)) ret.append(ProjectDataManagement::SanitationProcedures::Tamponade); if (procedures & (check << 59)) ret.append(ProjectDataManagement::SanitationProcedures::ManCompression); if (procedures & (check << 58)) ret.append(ProjectDataManagement::SanitationProcedures::Hemostyptics); if (procedures & (check << 57)) ret.append(ProjectDataManagement::SanitationProcedures::PressureDress); if (procedures & (check << 56)) ret.append(ProjectDataManagement::SanitationProcedures::ApplTourniquet); //Treatment Category A if (procedures & (check << 55)) ret.append(ProjectDataManagement::SanitationProcedures::TrachealTube); if (procedures & (check << 54)) ret.append(ProjectDataManagement::SanitationProcedures::EmergencyCric); if (procedures & (check << 53)) ret.append(ProjectDataManagement::SanitationProcedures::LarynxTube); if (procedures & (check << 52)) ret.append(ProjectDataManagement::SanitationProcedures::GuedelTube); if (procedures & (check << 51)) ret.append(ProjectDataManagement::SanitationProcedures::HeadOfBedEle); if (procedures & (check << 50)) ret.append(ProjectDataManagement::SanitationProcedures::RecPosition); if (procedures & (check << 49)) ret.append(ProjectDataManagement::SanitationProcedures::WendlTube); if (procedures & (check << 48)) ret.append(ProjectDataManagement::SanitationProcedures::JawThrustMan); //Treatment Category B if (procedures & (check << 47) || procedures & (check << 46) || procedures & (check << 45) || procedures & (check << 44)) ret.append(ProjectDataManagement::SanitationProcedures::Unknown); if (procedures & (check << 43)) ret.append(ProjectDataManagement::SanitationProcedures::AsVentilation); if (procedures & (check << 42)) ret.append(ProjectDataManagement::SanitationProcedures::ChestTube); if (procedures & (check << 41)) ret.append(ProjectDataManagement::SanitationProcedures::OxygenDelivery); if (procedures & (check << 40)) ret.append(ProjectDataManagement::SanitationProcedures::ChestSeal); //Treatment Category C if (procedures & (check << 39) || procedures & (check << 38) || procedures & (check << 37) || procedures & (check << 36)) ret.append(ProjectDataManagement::SanitationProcedures::Unknown); //if (procedures & (check << 35)) //ret.append(ProjectDataManagement::SanitationProcedures::FluidSubstitut); if (procedures & (check << 34)) ret.append(ProjectDataManagement::SanitationProcedures::IOAccess); if (procedures & (check << 33)) ret.append(ProjectDataManagement::SanitationProcedures::IVAccess); if (procedures & (check << 32)) ret.append(ProjectDataManagement::SanitationProcedures::ShockPosition); //Treatment Category D if (procedures & (check << 31) || procedures & (check << 30) || procedures & (check << 29) || procedures & (check << 28)) ret.append(ProjectDataManagement::SanitationProcedures::Unknown); if (procedures & (check << 27)) ret.append(ProjectDataManagement::SanitationProcedures::Positioning); if (procedures & (check << 26)) ret.append(ProjectDataManagement::SanitationProcedures::RecovPosition); if (procedures & (check << 25)) ret.append(ProjectDataManagement::SanitationProcedures::DeterminCGS); if (procedures & (check << 24)) ret.append(ProjectDataManagement::SanitationProcedures::AssessmAwaren); //Treatment Category E if (procedures & (check << 23)) ret.append(ProjectDataManagement::SanitationProcedures::Unknown); if (procedures & (check << 22)) ret.append(ProjectDataManagement::SanitationProcedures::GenWoundCare); if (procedures & (check << 21)) ret.append(ProjectDataManagement::SanitationProcedures::TreatmBurnings); if (procedures & (check << 20)) ret.append(ProjectDataManagement::SanitationProcedures::Blizzard); if (procedures & (check << 19)) ret.append(ProjectDataManagement::SanitationProcedures::RescueBlanket); if (procedures & (check << 18)) ret.append(ProjectDataManagement::SanitationProcedures::BleedingControl); if (procedures & (check << 17)) ret.append(ProjectDataManagement::SanitationProcedures::UniversalRail); if (procedures & (check << 16)) ret.append(ProjectDataManagement::SanitationProcedures::VitSignsCheck); //Treatment Category M if (procedures & (check << 15) || procedures & (check << 14)) ret.append(ProjectDataManagement::SanitationProcedures::Unknown); if (procedures & (check << 13)) ret.append(ProjectDataManagement::SanitationProcedures::MuscleRelaxant); if (procedures & (check << 12)) ret.append(ProjectDataManagement::SanitationProcedures::RingersSolution); if (procedures & (check << 11)) ret.append(ProjectDataManagement::SanitationProcedures::Hypnotics); if (procedures & (check << 10)) ret.append(ProjectDataManagement::SanitationProcedures::TranesamicAcid); if (procedures & (check << 9)) ret.append(ProjectDataManagement::SanitationProcedures::Antibiotics); if (procedures & (check << 8)) ret.append(ProjectDataManagement::SanitationProcedures::Analgesics); //Treatment Category 00 Not used */ return ret; } QStringList DtcImplCustom::sanitationProceduresList(qint64 procedures) { QStringList ret; const QVector proc = getSanitationProcedures(procedures); if (!proc.isEmpty()) { // No Procedure Taken so it's a connect/disconnect telegram missused.... later check for qualification for DISconnect if (proc.size() == 1 && proc.at(0).id() == 0) return ret << tr("DCU Connected"); ret.reserve(proc.size()); for (const auto &s : proc) ret << trSanitationProcedureName(s.name()); } return ret; } int DtcImplCustom::chargeTypeIdFromLegacyId(GearClass gearClass, int legacyId) { if (legacyId <= 0) return 0; // Check chargeType const auto chargeMap = chargesForGearClass(gearClass); for (const auto &charge : chargeMap) { // igniterType/igniterFunction default 0 auto chargeIgniterFunction = getChargeTypeIgniterTypeIgniterFunction(charge.id(), 0, 0); if (chargeIgniterFunction.chargeLegacyId() == legacyId) return charge.id(); } return 0; } bool DtcImplCustom::isGmlrs(int chargeTypeId) { return adlerChargeTypeName(chargeTypeId) == QStringLiteral("Unitary M31"); } bool DtcImplCustom::isDm72(int chargeTypeId) { return adlerChargeTypeName(chargeTypeId) == QStringLiteral("Mine DM72"); } bool DtcImplCustom::isRocket(int chargeTypeId) { const GearClass gearClass = gearClassFromChargeTypeId(chargeTypeId); return gearClass.underlying() == GearClass::Rocket; } ChargeTypeIgniterTypeIgniterFunction DtcImplCustom::getChargeTypeIgniterTypeIgniterFunction(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { if (chargeTypeId <= 0) return {}; const auto chargeTIgnTFunctVec = igniterFunctionsForChargeTypeIgniterType(chargeTypeId, igniterTypeId); for (const ChargeTypeIgniterTypeIgniterFunction &ctigtf : chargeTIgnTFunctVec) { if (ctigtf.igniterFunctionId() == igniterFunctionId) return ctigtf; } if (!chargeTIgnTFunctVec.isEmpty()) return chargeTIgnTFunctVec.first(); return {}; } ChargeTypeLoadType DtcImplCustom::getChargeTypeLoadType(int chargeTypeId, int loadTypeId) { if (chargeTypeId <= 0) return {}; for (const ChargeTypeLoadType &ctlt : chargeTypeLoadTypes()) { if (ctlt.chargeTypeId() == chargeTypeId && ctlt.loadTypeId() == loadTypeId) return ctlt; } return {}; } QString DtcImplCustom::indirectString(bool isIndirect) const { if (!isIndirect) return {}; return QLatin1String(", ") + tr("indirect"); } // Neither static nor const as this is a EA auto-created method. bool DtcImplCustom::isIndirect(int chargeTypeId) { return (chargeTypeId >= 1000 && chargeTypeId <= 2000) ? (chargeTypeId % 1000) < 500 : (chargeTypeId % 1000 > 500); } QString DtcImplCustom::suffix(int chargeTypeId, bool omitBaseSuffix) { if (chargeTypeId <= 0) return {}; bool bIsIndirect = isIndirect(chargeTypeId); if (bIsIndirect) { if (chargeTypeId >= 1000 && chargeTypeId <= 2000) chargeTypeId += 500; else chargeTypeId -= 500; } if (chargeTypeId < 4000) // 2xxx and 3xxx get DF as well as TAS xx { switch (chargeTypeId / 100) { case 15: case 16: case 17: case 18: case 19: return QLatin1String(" (") + offsetName(static_cast(chargeTypeId / 100 * 100)) + indirectString(bIsIndirect) + QLatin1String(")"); default: { if (!omitBaseSuffix && (chargeTypeId <= 80 || chargeTypeId > 2000)) return QLatin1String(" (") + offsetName(UleisClassOffset::None) + indirectString(bIsIndirect) + QLatin1String(")"); // TAS (xx) and ULEIS(2xxx): Direct Fire if (bIsIndirect) return QLatin1String(" (") + tr("indirect") + QLatin1String(")"); return {}; } } } const auto chargeMap = chargeTypes(); // If Map contains value, it should be named correctly. if (chargeMap.contains(chargeTypeId)) return {}; return QLatin1String(" (") + offsetName(static_cast(chargeTypeId / 1000 * 1000)) + indirectString(bIsIndirect) + QLatin1String(")"); } QString DtcImplCustom::offsetName(UleisClassOffset o) { switch (o) { // TAS: case UleisClassOffset::None: return tr("DF"); case UleisClassOffset::ShortTimeChild1: return tr("ST1"); case UleisClassOffset::ShortTimeChild2: return tr("ST2"); case UleisClassOffset::ShortTimeChild3: return tr("ST3"); case UleisClassOffset::ShortTimeChild4: return tr("ST4"); case UleisClassOffset::ShortTimeChild5: return tr("ST5"); // ULEIS: case UleisClassOffset::DirectImpactGrandparent: case UleisClassOffset::DirectImpactChild: return tr("DF"); case UleisClassOffset::BurstOfFireParent: case UleisClassOffset::BurstOfFireChild: return tr("BoF"); case UleisClassOffset::AirBurstParent: case UleisClassOffset::AirBurstChild: return tr("AB"); case UleisClassOffset::UnarmedParent: case UleisClassOffset::UnarmedChild: return tr("UnA"); case UleisClassOffset::FireAndForgetParent: case UleisClassOffset::FireAndForgetChild: return tr("FF"); case UleisClassOffset::ShortTimeScanningParent: case UleisClassOffset::ShortTimeScanningChild: return tr("STS"); default: return {}; } } QStringList DtcImplCustom::chargeNames(std::vector &chargeIds) { QStringList retVal; QMap> charges; for (int chargeId : chargeIds) { int base; if (chargeId < 1000) base = chargeId; else if (chargeId < 2000) base = chargeId % 100; else if (chargeId < 3000) base = chargeId; else base = 2000 + (chargeId % 1000); UleisClassOffset alteration; if (chargeId < 1000) alteration = UleisClassOffset::None; else if (chargeId < 2000) alteration = static_cast(chargeId / 100 * 100); else { int val = chargeId / 1000; if (val % 2 == 1) --val; alteration = static_cast(val * 1000); } charges[base] << alteration; } for (auto it = charges.cbegin(); it != charges.cend(); ++it) { QString chargeName = translate(&DtcImpl::chargeType, &ProjectDataManagement::trChargeTypeName, it.key()); QStringList sl; auto uleisClassOffsets = it.value(); sl.reserve(uleisClassOffsets.size()); for (UleisClassOffset o : qAsConst(uleisClassOffsets)) sl << offsetName(o); if (sl.size() == 6) chargeName += tr(" (all)"); else if (sl.size() == 1 && (it.value().contains(UleisClassOffset::DirectImpactGrandparent) || it.value().contains(UleisClassOffset::None))) { // Noop } else chargeName += QLatin1String(" (") + sl.join(QLatin1String(", ")) + QLatin1String(")"); retVal << chargeName; } return retVal; } QString DtcImplCustom::translate(const std::function &getItem, const std::function &pdmTranslate, qint32 id) { const auto item = getItem(*this, id); if (item.id() != id) return tr("[invalid:%1]").arg(id); return pdmTranslate(item.name()); } QString DtcImplCustom::translateShortChargeType(const std::function &pdmTranslate, qint32 id) { const auto item = chargeType(id); if (item.id() != id) return tr("[invalid:%1]").arg(id); return pdmTranslate(item.shortName()); } QString DtcImplCustom::translateShortIgniterType(const std::function &pdmTranslate, qint32 id) { const auto item = igniterType(id); if (item.id() != id) return tr("[invalid:%1]").arg(id); return pdmTranslate(item.shortName()); } QString DtcImplCustom::translateShortIgniterFunction(const std::function &pdmTranslate, qint32 id) { const auto item = igniterFunction(id); if (item.id() != id) return tr("[invalid:%1]").arg(id); return pdmTranslate(item.shortName()); } QString DtcImplCustom::translateShortLoadType(const std::function &pdmTranslate, qint32 id) { const auto item = loadType(id); if (item.id() != id) return tr("[invalid:%1]").arg(id); return pdmTranslate(item.shortName()); } QString DtcImplCustom::trBiteComponentTextName(int biteComponentId) { return translate(&DtcImpl::biteComponentText, &ProjectDataManagement::trBiteComponentTextName, biteComponentId); } QString DtcImplCustom::trCanComponentStringName(int canComponentId) { return translate(&DtcImpl::canComponentString, &ProjectDataManagement::trCanComponentStringName, canComponentId); } QString DtcImplCustom::trChargeTypeShortName(int chargeTypeId, bool omitBaseSuffix) { return translateShortChargeType(&ProjectDataManagement::trChargeTypeShortName, getAvailableChargeTypeId(chargeTypeId)) + suffix(chargeTypeId, omitBaseSuffix); } QString DtcImplCustom::trChargeTypeName(int chargeTypeId, bool omitBaseSuffix) { return translate(&DtcImpl::chargeType, &ProjectDataManagement::trChargeTypeName, getAvailableChargeTypeId(chargeTypeId)) + suffix(chargeTypeId, omitBaseSuffix); } QString DtcImplCustom::trFirePurposeName(int firePurposeId) { return translate(&DtcImpl::firePurpose, &ProjectDataManagement::trFirePurposeName, firePurposeId); } QString DtcImplCustom::trGearTypeName(int gearTypeId) { return translate(&DtcImpl::gearType, &ProjectDataManagement::trGearTypeName, gearTypeId); } QString DtcImplCustom::trIgniterTypeName(int igniterTypeId) { return translate(&DtcImpl::igniterType, &ProjectDataManagement::trIgniterTypeName, igniterTypeId); } QString DtcImplCustom::trIgniterTypeShortName(int igniterTypeId) { return translateShortIgniterType(&ProjectDataManagement::trIgniterTypeShortName, igniterTypeId); } QString DtcImplCustom::trIgniterFunctionName(int igniterFunctionId) { return translate(&DtcImpl::igniterFunction, &ProjectDataManagement::trIgniterFunctionName, igniterFunctionId); } QString DtcImplCustom::trIgniterFunctionShortName(int igniterFunctionId) { return translateShortIgniterFunction(&ProjectDataManagement::trIgniterFunctionShortName, igniterFunctionId); } QString DtcImplCustom::trLoadTypeName(int loadTypeId) { return translate(&DtcImpl::loadType, &ProjectDataManagement::trLoadTypeName, loadTypeId); } QString DtcImplCustom::trLoadTypeShortName(int loadTypeId) { return translateShortLoadType(&ProjectDataManagement::trLoadTypeShortName, loadTypeId); } QString DtcImplCustom::trTargetTypeName(int targetTypeId) { return translate(&DtcImpl::targetType, &ProjectDataManagement::trTargetTypeName, targetTypeId); } QString DtcImplCustom::trTargetSubTypeName(int targetSubTypeId) { return translate(&DtcImpl::targetSubType, &ProjectDataManagement::trTargetSubTypeName, targetSubTypeId); } QString DtcImplCustom::trLanguageHmiName(int languageHmiId) { return translate(&DtcImpl::languageHmi, &ProjectDataManagement::trLanguageHmiName, languageHmiId); } QString DtcImplCustom::trLanguageXduName(int languageXduId) { return translate(&DtcImpl::languageXdu, &ProjectDataManagement::trLanguageXduName, languageXduId); } QString DtcImplCustom::trNuclearPresetName(int nucularPresetId) { return translate(&DtcImpl::nuclearPreset, &ProjectDataManagement::trNuclearPresetName, nucularPresetId); } QString DtcImplCustom::trRadioGroupName(int radioGroupId) { return translate(&DtcImpl::radioGroup, &ProjectDataManagement::trRadioGroupName, radioGroupId); } QString DtcImplCustom::trVulnerabilityKindName(int vulnerabilityKindId, VulnerabilityClass vulnerabilityClassId) { ProjectDataManagement::VulnerabilityKind vk = DtcImpl::vulnerabilityKind(vulnerabilityKindId); if (vk.vulnerabilityClassId() == vulnerabilityClassId) return translate(&DtcImpl::vulnerabilityKind, &ProjectDataManagement::trVulnerabilityKindName, vulnerabilityKindId); else { WARNING_LOG(m_logger) << "Cannot translate VulnerabilityKindId " << vulnerabilityKindId << " for Vulnerability Class " << vulnerabilityClassId; return QString(); } } QString DtcImplCustom::trSanitationMaterialName(int sanitationMaterialId) { return translate(&DtcImpl::sanitationMaterial, &ProjectDataManagement::trSanitationMaterialName, sanitationMaterialId); } QJsonObject DtcImplCustom::propertiesToJson(const std::string &properties) { QJsonParseError parserError; const QByteArray props(QByteArray::fromRawData(properties.c_str(), properties.size())); const QJsonDocument doc(QJsonDocument::fromJson(props, &parserError)); if (parserError.error != QJsonParseError::NoError) { ERROR_LOG(m_logger) << "Cannot parse properties: no valid json:" << properties; return {}; } return doc.object(); } void DtcImplCustom::setProps(ChargeTypeIgniterTypeIgniterFunctionProps &props, QJsonObject obj) { props.expansionFactor = obj.value(QStringLiteral("expansionFactor")).toDouble(0.0); const int tmp = obj.value(QStringLiteral("volatilityTypeId")).toInt(0); switch (tmp) { case VolatilityType_def::Floating: props.volatilityTypeId = VolatilityType::Floating; break; case VolatilityType_def::Resident: props.volatilityTypeId = VolatilityType::Resident; break; default: props.volatilityTypeId = VolatilityType::Unknown; break; } props.isSmart = obj.value(QStringLiteral("isSmart")).toBool(false); props.isDryFire = obj.value(QStringLiteral("isDryFire")).toBool(false); props.isDus = obj.value(QStringLiteral("isDus")).toBool(false); props.mineClass = obj.value(QStringLiteral("mineClass")).toInt(0); props.canBeThrown = obj.value(QStringLiteral("canBeThrown")).toBool(false); props.canBeCreated = obj.value(QStringLiteral("canBeCreated")).toBool(true); props.isIed = obj.value(QStringLiteral("isIED")).toBool(false); props.isReactivatable = obj.value(QStringLiteral("isReactivatable")).toBool(false); props.isSmoke = obj.value(QStringLiteral("isSmoke")).toBool(false); props.maxEffectShows = obj.value(QStringLiteral("maxEffectShows")).toInt(1); props.isLRF = obj.value(QStringLiteral("isLRF")).toBool(false); props.isLTD = obj.value(QStringLiteral("isLTD")).toBool(false); props.isAP = obj.value(QStringLiteral("isAP")).toBool(false); props.isAT = obj.value(QStringLiteral("isAT")).toBool(false); props.remainingTasCode = obj.value(QStringLiteral("remainingTasCode")).toInt(); props.secondaryRemainingTasCode = obj.value(QStringLiteral("secondaryRemainingTasCode")).toInt(); props.segments = obj.value(QStringLiteral("segments")).toInt(); props.isLine = obj.value(QStringLiteral("isLine")).toBool(false); props.isConcrete = obj.value(QStringLiteral("isConcrete")).toBool(false); props.isFromMineLayer = obj.value(QStringLiteral("isFromMineLayer")).toBool(false); props.isMineLaying = obj.contains(QStringLiteral("mineLaying")); props.mineLayingPattern = obj.value(QStringLiteral("mineLaying")).toObject(); props.height = obj.value(QStringLiteral("height")).toInt(); props.hazardDistance = obj.value(QStringLiteral("hazardDistance")).toInt(); props.isVirtuallyFireable = obj.value(QStringLiteral("isVirtuallyFireable")).toBool(false); props.isAdlerChargeType = obj.value(QStringLiteral("isAdlerChargeType")).toBool(false); props.adlerChargeTypeName = obj.value(QStringLiteral("adlerChargeTypeName")).toString(); props.adlerIgniterTypeName = obj.value(QStringLiteral("AdlerL11String")).toString(); props.adlerIgniterFunctionName = obj.value(QStringLiteral("AdlerL41String")).toString(); QJsonArray jsonArray = obj.value(QLatin1String("spacing")).toArray(); for (auto it = jsonArray.constBegin(); it != jsonArray.constEnd(); ++it) props.spacing.append(it->toInt()); jsonArray = obj.value(QLatin1String("casEffects")).toArray(); for (auto it = jsonArray.constBegin(); it != jsonArray.constEnd(); ++it) { QJsonObject objFt = it->toObject(); CasEffect ce; ce.severityType(static_cast(objFt.value(QStringLiteral("severityType")).toInt())); ce.iedClass(objFt.value(QStringLiteral("iedClass")).toInt()); ce.impactRadius(objFt.value(QStringLiteral("impactRadius")).toInt()); props.casEffects.append(ce); } std::sort(props.casEffects.begin(), props.casEffects.end(), [](const CasEffect &a, const CasEffect &b) { return a.severityType() < b.severityType(); }); // Caution: Negate as suppressVisibility is negation of isVisible! props.isVisible = !obj.value(QStringLiteral("suppressVisibility")).toBool(false); props.searchRadius = obj.value(QStringLiteral("searchRadius")).toInt(0); props.showHitline = obj.value(QStringLiteral("showHitline")).toBool(true); props.isLaserGuidable = obj.value(QStringLiteral("isLaserGuidable")).toBool(false); props.isUasDroppable = obj.value(QStringLiteral("isUasDroppable")).toBool(false); props.isJamming = obj.value(QStringLiteral("isJamming")).toBool(false); props.isLaserGuidable = obj.value(QStringLiteral("isLaserGuidable")).toBool(false); // Malte: primary: most severe CasEffect const QVector &casEffectsCopy = props.casEffects; if (!casEffectsCopy.empty()) props.impactRadius = casEffectsCopy.first().impactRadius(); props.impactEdgeLength = props.impactRadius * 2.0; // : impactRadius by most severe CasEffect) } void DtcImplCustom::setProps(ChargeTypeLoadTypeProps &props, QJsonObject obj) { props.adlerLoadTypeName = obj.value(QStringLiteral("AdlerL10String")).toString(); } DtcImplCustom::ChargeTypeIgniterTypeIgniterFunctionProps DtcImplCustom::chargeTypeIgniterTypeIgniterFunctionProps(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { chargeTypeId = getAvailableChargeTypeId(chargeTypeId); for (auto it = m_ctItIfProps.constBegin(); it != m_ctItIfProps.constEnd(); ++it) { if (it.value().chargeTypeId == chargeTypeId && it.value().igniterTypeId == igniterTypeId && it.value().igniterFunctionId == igniterFunctionId) return it.value(); } // if no entry, find first entry for chargeTypeId & igniterTypeId for (auto it = m_ctItIfProps.constBegin(); it != m_ctItIfProps.constEnd(); ++it) { if (it.value().chargeTypeId == chargeTypeId && it.value().igniterTypeId == igniterTypeId) return it.value(); } // if no entry, find first entry for chargeTypeId for (auto it = m_ctItIfProps.constBegin(); it != m_ctItIfProps.constEnd(); ++it) { if (it.value().chargeTypeId == chargeTypeId) return it.value(); } return {}; } DtcImplCustom::ChargeTypeLoadTypeProps DtcImplCustom::chargeTypeLoadTypeProps(int chargeTypeId, int loadTypeId) { chargeTypeId = getAvailableChargeTypeId(chargeTypeId); for (auto it = m_ctLtProps.constBegin(); it != m_ctLtProps.constEnd(); ++it) { if (it.value().chargeTypeId == chargeTypeId && it.value().loadTypeId == loadTypeId) return it.value(); } return {}; } void DtcImplCustom::onGearTypeChanged(const GearType >) { if (gt.id() <= 0) return; QJsonParseError parserError; const QByteArray props(QByteArray::fromRawData(gt.properties().c_str(), gt.properties().size())); const QJsonDocument doc(QJsonDocument::fromJson(props, &parserError)); if (parserError.error != QJsonParseError::NoError) { m_gtProps.remove(gt.id()); return; } const QJsonObject obj(doc.object()); GearTypeProps gtp; gtp.canRestock = obj.value(QStringLiteral("canRestock")).toBool(false); gtp.canSetDefaults = obj.value(QStringLiteral("canSetDefaults")).toBool(false); gtp.maxCharges = obj.value(QStringLiteral("maxCharges")).toInt(12); gtp.adlerWeaponSystemId = obj.value(QStringLiteral("AdlerWeaponSystemId")).toInt(); gtp.cadence = obj.value(QStringLiteral("cadence")).toInt(-1); m_gtProps.insert(gt.id(), gtp); } DtcImplCustom::GearTypeProps DtcImplCustom::gearTypeProps(int gearTypeId) { auto it = m_gtProps.constFind(gearTypeId); if (it == m_gtProps.constEnd()) { onGearTypeChanged(gearType(gearTypeId)); it = m_gtProps.constFind(gearTypeId); } if (it != m_gtProps.constEnd()) return it.value(); return GearTypeProps(); } void DtcImplCustom::onGearTypeChargeTypeChanged(const GearTypeChargeType >ct) { if (gtct.id() <= 0) return; QJsonParseError parserError; const QByteArray props(QByteArray::fromRawData(gtct.properties().c_str(), gtct.properties().size())); const QJsonDocument doc(QJsonDocument::fromJson(props, &parserError)); if (parserError.error != QJsonParseError::NoError) { m_gtctProps.remove(gtct.id()); return; } const QJsonObject obj(doc.object()); GearTypeChargeTypeProps gtctp; gtctp.factoryDefault = obj.value(QStringLiteral("factoryDefault")).toInt(0); gtctp.maxCharge = obj.value(QStringLiteral("maxCharge")).toInt(0); m_gtctProps.insert(gtct.id(), gtctp); } DtcImplCustom::GearTypeChargeTypeProps DtcImplCustom::gearTypeChargeTypeProps(int gearTypeChargeTypeId) { auto it = m_gtctProps.constFind(gearTypeChargeTypeId); if (it == m_gtctProps.constEnd()) { onGearTypeChargeTypeChanged(gearTypeChargeType(gearTypeChargeTypeId)); it = m_gtctProps.constFind(gearTypeChargeTypeId); } if (it != m_gtctProps.constEnd()) return it.value(); return GearTypeChargeTypeProps(); } int DtcImplCustom::getAvailableChargeTypeId(int chargeTypeId /*, bool *bOk*/) { // if (bOk) // *bOk = true; if (isIndirect(chargeTypeId)) { if (chargeTypeId >= 1000 && chargeTypeId < 2000) chargeTypeId += 500; else chargeTypeId -= 500; } if (chargeTypeId <= 0) return 0; const auto chargeMap = chargeTypes(); if (chargeMap.contains(chargeTypeId)) return chargeTypeId; if (chargeTypeId > 1500 && chargeTypeId < 2000) { int copy = chargeTypeId % 100; if (chargeMap.contains(copy)) return copy; // if (bOk) // *bOk = false; return chargeTypeId; } if (chargeTypeId < 2000) { // if (bOk) // *bOk = false; return 0; } // Odd thousands? Check the even thousands below: 5xxx -> 4xxx if ((chargeTypeId / 1000) % 2 == 1) { int copy = chargeTypeId - 1000; if (chargeMap.contains(copy)) return copy; } // Not even an even thousand found? Check the 2xxx charge then: int copy = (chargeTypeId % 1000) + 2000; if (chargeMap.contains(copy)) return copy; // if (bOk) // *bOk = false; return chargeTypeId; } bool DtcImplCustom::isAtMine(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).isAT; } bool DtcImplCustom::isApMine(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, igniterTypeId, igniterFunctionId).isAP; } double DtcImplCustom::getLethalRadius(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { const auto &vec = casEffects(chargeTypeId, igniterTypeId, igniterFunctionId); for (const ProjectDataManagement::CasEffect &casEffect : vec) { if (casEffect.severityType() == SeverityType_def::lethal) return casEffect.impactRadius(); } return 0.0; } double DtcImplCustom::getNonLethalRadius(int chargeTypeId, int igniterTypeId, int igniterFunctionId) { const auto &vec = casEffects(chargeTypeId, igniterTypeId, igniterFunctionId); for (const ProjectDataManagement::CasEffect &casEffect : vec) { if (casEffect.severityType() == SeverityType_def::medium) return casEffect.impactRadius(); } return 0.0; } double DtcImplCustom::getMaxRange(int chargeTypeId, int gearTypeId) { const auto gear2ChargeMap = gearTypeChargeTypes(); for (auto gIt = gear2ChargeMap.begin(); gIt != gear2ChargeMap.end(); ++gIt) { if (gIt.value().gearTypeId() == gearTypeId && gIt.value().chargeTypeId() == chargeTypeId) return gIt.value().maxRange(); } return 0; } ProjectDataManagement::BuildingChargeEffect DtcImplCustom::getBuildingChargeEffectByChargeTypeId(int chargeTypeId) { if (!isBuildingChargeEffectEnabled()) { enableBuildingChargeEffect(); waitForHistoricalDataBuildingChargeEffect(2000); } for (const ProjectDataManagement::BuildingChargeEffect &bcEffect : qAsConst(m_buildingChargeEffectCont)) { if (bcEffect.chargeTypeId() == chargeTypeId) { DEBUG_LOG(m_logger) << "getBuildingChargeEffectByChargeTypeId: chargeTypeId '" << chargeTypeId << "' found" << ", bcEffect=" << bcEffect; return bcEffect; } } return {}; } bool DtcImplCustom::isVirtuallyFireable(int chargeTypeId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, 0, 0).isVirtuallyFireable; } bool DtcImplCustom::isAdlerChargeType(int chargeTypeId) { return chargeTypeIgniterTypeIgniterFunctionProps(chargeTypeId, 0, 0).isAdlerChargeType; } QString DtcImplCustom::adlerChargeTypeName(int chargeTypeId) { // if no entry, find first entry for chargeTypeId for (auto it = m_ctItIfProps.constBegin(); it != m_ctItIfProps.constEnd(); ++it) { if (it.value().chargeTypeId == chargeTypeId) return it.value().adlerChargeTypeName; } return {}; } QString DtcImplCustom::adlerIgniterTypeName(int igniterTypeId) { for (auto it = m_ctItIfProps.constBegin(); it != m_ctItIfProps.constEnd(); ++it) { if (it.value().igniterTypeId == igniterTypeId) return it.value().adlerIgniterTypeName; } return {}; } QString DtcImplCustom::adlerIgniterFunctionName(int igniterFunctionId) { for (auto it = m_ctItIfProps.constBegin(); it != m_ctItIfProps.constEnd(); ++it) { if (it.value().igniterFunctionId == igniterFunctionId) return it.value().adlerIgniterFunctionName; } return {}; } QString DtcImplCustom::adlerLoadTypeName(int loadTypeId) { for (auto it = m_ctLtProps.constBegin(); it != m_ctLtProps.constEnd(); ++it) { if (it.value().loadTypeId == loadTypeId) return it.value().adlerLoadTypeName; } return {}; } QString DtcImplCustom::adlerTargetTypeName(int targetTypeId) { for (const ProjectDataManagement::TargetType &targetTyp : qAsConst(m_targetTypeCont)) { const QJsonObject obj = QJsonDocument::fromJson(QByteArray::fromRawData(targetTyp.properties().c_str(), targetTyp.properties().size())).object(); if (targetTyp.id() == targetTypeId) return obj[QStringLiteral("AdlerL20String")].toString(); } return {}; } QString DtcImplCustom::adlerTargetSubTypeName(int targetSubTypeId) { for (const ProjectDataManagement::TargetSubType &targetSubTyp : qAsConst(m_targetSubTypeCont)) { const QJsonObject obj = QJsonDocument::fromJson(QByteArray::fromRawData(targetSubTyp.properties().c_str(), targetSubTyp.properties().size())).object(); if (targetSubTyp.id() == targetSubTypeId) return obj[QStringLiteral("AdlerL21String")].toString(); } return {}; } int DtcImplCustom::getAmountFireMarkers(int firePurposeId) { const ProjectDataManagement::FirePurpose &fp = firePurpose(firePurposeId); QJsonObject obj = propertiesToJson(fp.properties()); return obj.value(QStringLiteral("FireMarkers")).toInt(); } bool DtcImplCustom::getWithDurationFirePurpose(int firePurposeId) { const ProjectDataManagement::FirePurpose &fp = firePurpose(firePurposeId); QJsonObject obj = propertiesToJson(fp.properties()); return obj.value(QStringLiteral("withDuration")).toBool(); } } // namespace Interface } // namespace ProjectDataManagement