diff --git a/src/libs/sea_ai/include/ai_flow_graph.h b/src/libs/sea_ai/include/ai_flow_graph.h index c53e284ef..93cd0f7fb 100644 --- a/src/libs/sea_ai/include/ai_flow_graph.h +++ b/src/libs/sea_ai/include/ai_flow_graph.h @@ -121,9 +121,9 @@ class AIFlowGraph float GetDistance(uint32_t dwPnt) { float fDist = 0.0f; - for (uint32_t i = 0; i < aPoints.size(); i++) + for (auto &aPoint : aPoints) { - point_t *pP = &aPoints[i]; + point_t *pP = &aPoint; fDist += pP->fDistance; if (dwPnt == pP->dwPnt) return fDist; @@ -462,8 +462,8 @@ inline AIFlowGraph::VectorPath *AIFlowGraph::GetVectorPath(size_t dwP1, size_t d Path *pPath = GetPath(dwP1, dwP2); if (pPath) { - for (uint32_t i = 0; i < pPath->aPoints.size(); i++) - pVPath->AddPoint(GetPointPos(pPath->aPoints[i].dwPnt)); + for (auto &aPoint : pPath->aPoints) + pVPath->AddPoint(GetPointPos(aPoint.dwPnt)); } STORM_DELETE(pPath); return pVPath; diff --git a/src/libs/sea_ai/src/ai_balls.cpp b/src/libs/sea_ai/src/ai_balls.cpp index a3660dbae..a80126ea6 100644 --- a/src/libs/sea_ai/src/ai_balls.cpp +++ b/src/libs/sea_ai/src/ai_balls.cpp @@ -337,13 +337,13 @@ uint32_t AIBalls::AttributeChanged(ATTRIBUTES *pAttributeChanged) { if (*pAttributeChanged == "clear") { - for (uint32_t i = 0; i < aBallTypes.size(); i++) + for (auto &aBallType : aBallTypes) { - BALL_TYPE *pBallsType = &aBallTypes[i]; + BALL_TYPE *pBallsType = &aBallType; - for (uint32_t j = 0; j < pBallsType->Balls.size(); j++) + for (auto &Ball : pBallsType->Balls) { - BALL_PARAMS *pBall = &pBallsType->Balls[j]; + BALL_PARAMS *pBall = &Ball; pBall->sBallEvent.clear(); @@ -413,10 +413,10 @@ uint64_t AIBalls::ProcessMessage(MESSAGE &message) { if (message.Long() == MSG_MODEL_RELEASE) { - for (uint32_t i = 0; i < aBallTypes.size(); i++) - for (uint32_t j = 0; j < aBallTypes[i].Balls.size(); j++) + for (auto &aBallType : aBallTypes) + for (uint32_t j = 0; j < aBallType.Balls.size(); j++) { - BALL_PARAMS *pBall = &aBallTypes[i].Balls[j]; + BALL_PARAMS *pBall = &aBallType.Balls[j]; if (pBall->pParticle) { @@ -451,13 +451,13 @@ void BALL_PARAMS::Save(CSaveLoad *pSL) void AIBalls::Save(CSaveLoad *pSL) { - for (uint32_t i = 0; i < aBallTypes.size(); i++) + for (auto &aBallType : aBallTypes) { - pSL->SaveDword(aBallTypes[i].Balls.size()); + pSL->SaveDword(aBallType.Balls.size()); - for (uint32_t j = 0; j < aBallTypes[i].Balls.size(); j++) + for (uint32_t j = 0; j < aBallType.Balls.size(); j++) { - aBallTypes[i].Balls[j].Save(pSL); + aBallType.Balls[j].Save(pSL); } } } @@ -485,16 +485,16 @@ void BALL_PARAMS::Load(CSaveLoad *pSL) void AIBalls::Load(CSaveLoad *pSL) { - for (uint32_t i = 0; i < aBallTypes.size(); i++) + for (auto &aBallType : aBallTypes) { const uint32_t dwNum = pSL->LoadDword(); - auto balls_size = std::size(aBallTypes[i].Balls); - aBallTypes[i].Balls.resize(balls_size + dwNum); + auto balls_size = std::size(aBallType.Balls); + aBallType.Balls.resize(balls_size + dwNum); for (uint32_t j = 0; j < dwNum; j++) { // BALL_PARAMS * pB = &aBallTypes[i].Balls[aBallTypes[i].Balls.Add()]; - BALL_PARAMS &pB = aBallTypes[i].Balls[balls_size + j]; + BALL_PARAMS &pB = aBallType.Balls[balls_size + j]; pB.Load(pSL); if (pB.pParticle) { @@ -502,7 +502,7 @@ void AIBalls::Load(CSaveLoad *pSL) if (auto eidParticle = EntityManager::GetEntityId("particles")) { pB.pParticle = (VPARTICLE_SYSTEM *)core.Send_Message( - eidParticle, "lsffffffl", PS_CREATE_RIC, (char *)aBallTypes[i].sParticleName.c_str(), pB.vPos.x, + eidParticle, "lsffffffl", PS_CREATE_RIC, (char *)aBallType.sParticleName.c_str(), pB.vPos.x, pB.vPos.y, pB.vPos.z, 0.0f, 1.0f, 0.0f, 100000); } } diff --git a/src/libs/sea_ai/src/ai_fort.cpp b/src/libs/sea_ai/src/ai_fort.cpp index 423b025e1..d084156f8 100644 --- a/src/libs/sea_ai/src/ai_fort.cpp +++ b/src/libs/sea_ai/src/ai_fort.cpp @@ -14,8 +14,8 @@ AIFort::AIFort() AIFort::~AIFort() { pAIFort = nullptr; - for (uint32_t i = 0; i < aForts.size(); i++) - STORM_DELETE(aForts[i]); + for (auto &aFort : aForts) + STORM_DELETE(aFort); } bool AIFort::Init() @@ -90,17 +90,17 @@ void AIFort::Execute(uint32_t Delta_Time) auto fMinDistance = 1e10f; auto vCPos = pC->GetPos(); const auto fMaxFireDistance = AICannon::CalcMaxFireDistance(vCPos.y, fSpeedV0, 0.35f); // FIX-ME - for (uint32_t j = 0; j < AIShip::AIShips.size(); j++) - if (!AIShip::AIShips[j]->isDead() && - Helper.isEnemy(pF->GetACharacter(), AIShip::AIShips[j]->GetACharacter())) + for (auto &j : AIShip::AIShips) + if (!j->isDead() && + Helper.isEnemy(pF->GetACharacter(), j->GetACharacter())) { - const auto fDistance = AIShip::AIShips[j]->GetDistance(vCPos); + const auto fDistance = j->GetDistance(vCPos); if (fDistance > fMaxFireDistance) continue; if (fDistance < fMinDistance) { fMinDistance = fDistance; - pFireAIShip = AIShip::AIShips[j]; + pFireAIShip = j; } } if (pFireAIShip) @@ -265,10 +265,10 @@ void AIFort::AddFortHit(int32_t iCharacterIndex, CVECTOR &vHitPos) AIFort::AI_FORT *AIFort::FindFort(entid_t eidModel) { - for (int32_t i = 0; i < aForts.size(); i++) + for (auto &aFort : aForts) { - if (EntityManager::GetEntityPointer(aForts[i]->GetModelEID()) == EntityManager::GetEntityPointer(eidModel)) - return aForts[i]; + if (EntityManager::GetEntityPointer(aFort->GetModelEID()) == EntityManager::GetEntityPointer(eidModel)) + return aFort; } return nullptr; } @@ -491,15 +491,15 @@ CVECTOR AIFort::AI_FORT::GetAttackPoint(VAI_INNEROBJ *pObj) void AIFort::Save(CSaveLoad *pSL) { pSL->SaveFloat(fMinCannonDamageDistance); - for (uint32_t i = 0; i < aForts.size(); i++) - aForts[i]->Save(pSL); + for (auto &aFort : aForts) + aFort->Save(pSL); } void AIFort::Load(CSaveLoad *pSL) { fMinCannonDamageDistance = pSL->LoadFloat(); - for (uint32_t i = 0; i < aForts.size(); i++) - aForts[i]->Load(pSL, GetId()); + for (auto &aFort : aForts) + aFort->Load(pSL, GetId()); } void AIFort::AI_FORT::Save(CSaveLoad *pSL) @@ -553,6 +553,6 @@ void AIFort::AI_FORT::Load(CSaveLoad *pSL, entid_t eid) void AIFort::Fire(const CVECTOR &vPos) { - for (int32_t i = 0; i < aForts.size(); i++) - pShipsLights->AddDynamicLights(&aForts[i]->tmpObject, vPos); + for (auto &aFort : aForts) + pShipsLights->AddDynamicLights(&aFort->tmpObject, vPos); } diff --git a/src/libs/sea_ai/src/ai_group.cpp b/src/libs/sea_ai/src/ai_group.cpp index bc359e7a9..a68ea3e42 100644 --- a/src/libs/sea_ai/src/ai_group.cpp +++ b/src/libs/sea_ai/src/ai_group.cpp @@ -91,8 +91,8 @@ void AIGroup::AddShip(entid_t eidShip, ATTRIBUTES *pACharacter, ATTRIBUTES *pASh bool AIGroup::isMainGroup() { - for (uint32_t i = 0; i < aGroupShips.size(); i++) - if (aGroupShips[i]->isMainCharacter()) + for (auto &aGroupShip : aGroupShips) + if (aGroupShip->isMainCharacter()) return true; return false; @@ -124,20 +124,20 @@ void AIGroup::Execute(float fDeltaTime) auto vNewGroupPos = pG->vInitGroupPos + ((100.0f + FRAND(200.0f)) * CVECTOR(sinf(fNewAng), 0.0f, cosf(fNewAng))); - for (uint32_t i = 0; i < aGroupShips.size(); i++) + for (auto &aGroupShip : aGroupShips) { - aGroupShips[i]->SetPos(vNewGroupPos); - aGroupShips[i]->CheckStartPosition(); + aGroupShip->SetPos(vNewGroupPos); + aGroupShip->CheckStartPosition(); } } } if (isMainGroup()) { - for (uint32_t i = 0; i < aGroupShips.size(); i++) - if (!aGroupShips[i]->isMainCharacter()) - aGroupShips[i]->GetTaskController()->SetNewTask(PRIMARY_TASK, AITASK_DEFEND, - GetCommanderACharacter()); + for (auto &aGroupShip : aGroupShips) + if (!aGroupShip->isMainCharacter()) + aGroupShip->GetTaskController()->SetNewTask(PRIMARY_TASK, AITASK_DEFEND, + GetCommanderACharacter()); } bFirstExecute = false; @@ -165,21 +165,21 @@ void AIGroup::Execute(float fDeltaTime) if (!isMainGroup()) { auto fMinimalSpeed = 1e+10f; - for (uint32_t i = 0; i < aGroupShips.size(); i++) + for (auto &aGroupShip : aGroupShips) { - const auto fCurSpeed = aGroupShips[i]->GetShipBasePointer()->GetCurrentSpeed(); + const auto fCurSpeed = aGroupShip->GetShipBasePointer()->GetCurrentSpeed(); if (fCurSpeed < fMinimalSpeed) fMinimalSpeed = fCurSpeed; } const auto bSetFixedSpeed = sCommand == "move"; - for (uint32_t i = 0; i < aGroupShips.size(); i++) - aGroupShips[i]->GetShipBasePointer()->SetFixedSpeed(bSetFixedSpeed, fMinimalSpeed); + for (auto &aGroupShip : aGroupShips) + aGroupShip->GetShipBasePointer()->SetFixedSpeed(bSetFixedSpeed, fMinimalSpeed); } - for (uint32_t i = 0; i < aGroupShips.size(); i++) - aGroupShips[i]->Execute(fDeltaTime); + for (auto &aGroupShip : aGroupShips) + aGroupShip->Execute(fDeltaTime); } void AIGroup::Realize(float fDeltaTime) @@ -193,8 +193,8 @@ void AIGroup::Realize(float fDeltaTime) bool AIGroup::isDead() { - for (uint32_t i = 0; i < aGroupShips.size(); i++) - if (!aGroupShips[i]->isDead()) + for (auto &aGroupShip : aGroupShips) + if (!aGroupShip->isDead()) return false; return true; } @@ -202,8 +202,8 @@ bool AIGroup::isDead() float AIGroup::GetPower() { auto fPower = 0.0f; - for (uint32_t i = 0; i < aGroupShips.size(); i++) - fPower += aGroupShips[i]->GetPower(); + for (auto &aGroupShip : aGroupShips) + fPower += aGroupShip->GetPower(); return fPower; } @@ -220,9 +220,8 @@ AIGroup *AIGroup::FindGroup(ATTRIBUTES *pACharacter) { if (!pACharacter) return nullptr; - for (uint32_t i = 0; i < AIGroups.size(); i++) + for (auto pGroup : AIGroups) { - AIGroup *pGroup = AIGroups[i]; for (uint32_t j = 0; j < pGroup->aGroupShips.size(); j++) if (*pGroup->aGroupShips[j] == pACharacter) return pGroup; @@ -232,17 +231,17 @@ AIGroup *AIGroup::FindGroup(ATTRIBUTES *pACharacter) AIGroup *AIGroup::FindGroup(const char *pGroupName) { - for (uint32_t i = 0; i < AIGroups.size(); i++) - if (AIGroups[i]->GetName() == pGroupName) - return AIGroups[i]; + for (auto &AIGroup : AIGroups) + if (AIGroup->GetName() == pGroupName) + return AIGroup; return nullptr; } AIGroup *AIGroup::FindMainGroup() { - for (uint32_t i = 0; i < AIGroups.size(); i++) - if (AIGroups[i]->isMainGroup()) - return AIGroups[i]; + for (auto &AIGroup : AIGroups) + if (AIGroup->isMainGroup()) + return AIGroup; return nullptr; } @@ -254,10 +253,8 @@ void AIGroup::SailMainGroup(CVECTOR vPos, float fAngle, ATTRIBUTES *pACharacter) const auto eidSea = EntityManager::GetEntityId("sea"); - for (uint32_t i = 0; i < pMG->aGroupShips.size(); i++) + for (auto pAIShip : pMG->aGroupShips) { - AIShip *pAIShip = pMG->aGroupShips[i]; - if (pAIShip->isDead()) continue; @@ -452,8 +449,8 @@ void AIGroup::Save(CSaveLoad *pSL) pSL->SaveDword(bFirstExecute); pSL->SaveDword(aGroupShips.size()); - for (uint32_t i = 0; i < aGroupShips.size(); i++) - aGroupShips[i]->Save(pSL); + for (auto &aGroupShip : aGroupShips) + aGroupShip->Save(pSL); } void AIGroup::Load(CSaveLoad *pSL) diff --git a/src/libs/sea_ai/src/ai_helper.cpp b/src/libs/sea_ai/src/ai_helper.cpp index 3de7a16b2..31d18ee86 100644 --- a/src/libs/sea_ai/src/ai_helper.cpp +++ b/src/libs/sea_ai/src/ai_helper.cpp @@ -213,12 +213,12 @@ void AIHelper::Save(CSaveLoad *pSL) pSL->SaveAPointer("seacameras", pASeaCameras); pSL->SaveDword(aCharacters.size()); - for (uint32_t i = 0; i < aCharacters.size(); i++) - pSL->SaveAPointer("character", aCharacters[i]); + for (auto &aCharacter : aCharacters) + pSL->SaveAPointer("character", aCharacter); pSL->SaveDword(aMainCharacters.size()); - for (uint32_t i = 0; i < aMainCharacters.size(); i++) - pSL->SaveAPointer("character", aMainCharacters[i]); + for (auto &aMainCharacter : aMainCharacters) + pSL->SaveAPointer("character", aMainCharacter); } void AIHelper::Load(CSaveLoad *pSL) diff --git a/src/libs/sea_ai/src/ai_sea_goods.cpp b/src/libs/sea_ai/src/ai_sea_goods.cpp index 2e378e1d0..11c2dc86f 100644 --- a/src/libs/sea_ai/src/ai_sea_goods.cpp +++ b/src/libs/sea_ai/src/ai_sea_goods.cpp @@ -16,13 +16,13 @@ AISeaGoods::AISeaGoods() AISeaGoods::~AISeaGoods() { - for (uint32_t i = 0; i < aGoods.size(); i++) + for (auto &aGood : aGoods) { - if (aGoods[i]->pGeo) - pGeoService->DeleteGeometry(aGoods[i]->pGeo); - aGoods[i]->sModel.clear(); - aGoods[i]->aItems.clear(); - STORM_DELETE(aGoods[i]); + if (aGood->pGeo) + pGeoService->DeleteGeometry(aGood->pGeo); + aGood->sModel.clear(); + aGood->aItems.clear(); + STORM_DELETE(aGood); } aGoods.clear(); } @@ -49,10 +49,10 @@ void AISeaGoods::Execute(uint32_t dwDeltaTime) if (!pSea) return; - for (uint32_t i = 0; i < aGoods.size(); i++) - for (uint32_t j = 0; j < aGoods[i]->aItems.size(); j++) + for (auto &aGood : aGoods) + for (uint32_t j = 0; j < aGood->aItems.size(); j++) { - auto *pI = &aGoods[i]->aItems[j]; + auto *pI = &aGood->aItems[j]; pI->fTime -= fDeltaTime; pI->vPos.y = pSea->WaveXZ(pI->vPos.x, pI->vPos.z, &pI->vNormal); @@ -63,8 +63,8 @@ void AISeaGoods::Execute(uint32_t dwDeltaTime) if (pI->fTime < -20.0f) { // aGoods[i]->aItems.ExtractNoShift(j); - aGoods[i]->aItems[j] = aGoods[i]->aItems.back(); - aGoods[i]->aItems.pop_back(); + aGood->aItems[j] = aGood->aItems.back(); + aGood->aItems.pop_back(); j--; continue; } @@ -82,9 +82,8 @@ void AISeaGoods::Execute(uint32_t dwDeltaTime) } // check ships - for (uint32_t k = 0; k < aShips.size(); k++) + for (auto pS : aShips) { - auto pS = aShips[k]; auto *pACharacter = pS->GetACharacter(); const int iCharacterIndex = GetIndex(pS->GetACharacter()); const auto fDistance = sqrtf(~(pS->State.vPos - pI->vPos)); @@ -95,8 +94,8 @@ void AISeaGoods::Execute(uint32_t dwDeltaTime) if (pVData->GetInt() || bDeleteGoodAnyway) { // aGoods[i]->aItems.ExtractNoShift(j); - aGoods[i]->aItems[j] = aGoods[i]->aItems.back(); - aGoods[i]->aItems.pop_back(); + aGood->aItems[j] = aGood->aItems.back(); + aGood->aItems.pop_back(); j--; break; } @@ -113,18 +112,18 @@ void AISeaGoods::Realize(uint32_t dwDeltaTime) AIHelper::pRS->SetRenderState(D3DRS_LIGHTING, true); - for (uint32_t i = 0; i < aGoods.size(); i++) - if (aGoods[i]->pGeo) - for (uint32_t j = 0; j < aGoods[i]->aItems.size(); j++) + for (auto &aGood : aGoods) + if (aGood->pGeo) + for (uint32_t j = 0; j < aGood->aItems.size(); j++) { - auto *const pI = &aGoods[i]->aItems[j]; + auto *const pI = &aGood->aItems[j]; // set world matrix for item CMatrix m; m.BuildPosition(pI->vPos.x, pI->vPos.y, pI->vPos.z); AIHelper::pRS->SetTransform(D3DTS_WORLD, m); - aGoods[i]->pGeo->Draw((GEOS::PLANE *)AIHelper::pRS->GetPlanes(), 0, nullptr); + aGood->pGeo->Draw((GEOS::PLANE *)AIHelper::pRS->GetPlanes(), 0, nullptr); } AIHelper::pRS->SetRenderState(D3DRS_LIGHTING, false); @@ -136,10 +135,10 @@ uint32_t AISeaGoods::AttributeChanged(ATTRIBUTES *pAttribute) if (*pAttribute == "Add") { - for (uint32_t i = 0; i < aGoods.size(); i++) - if (aGoods[i]->sModel == sTmpModel) + for (auto &aGood : aGoods) + if (aGood->sModel == sTmpModel) { - aGoods[i]->aItems.push_back(TmpItem); + aGood->aItems.push_back(TmpItem); return 0; } auto *pG = new goods_t; diff --git a/src/libs/sea_ai/src/ai_ship.cpp b/src/libs/sea_ai/src/ai_ship.cpp index 68c6914cb..b9dd1e8ee 100644 --- a/src/libs/sea_ai/src/ai_ship.cpp +++ b/src/libs/sea_ai/src/ai_ship.cpp @@ -188,11 +188,11 @@ void AIShip::CheckSituation() // if (isMainCharacter()) return; auto fMinEnemyDist = 1e9f; - for (uint32_t i = 0; i < AIShips.size(); i++) - if (AIShips[i] != this) + for (auto &AIShip : AIShips) + if (AIShip != this) { - const auto fDist = GetDistance(*AIShips[i]); - if (Helper.isEnemy(GetACharacter(), AIShips[i]->GetACharacter())) + const auto fDist = GetDistance(*AIShip); + if (Helper.isEnemy(GetACharacter(), AIShip->GetACharacter())) { if (fDist < fMinEnemyDist) { @@ -270,11 +270,11 @@ bool AIShip::isCanPlace(CVECTOR vNewPos) const auto vBoxSize = GetBoxsize(); vBoxSize.x += 30.0f; vBoxSize.z += 30.0f; - for (uint32_t i = 0; i < AIShips.size(); i++) - if (this != AIShips[i]) + for (auto &AIShip : AIShips) + if (this != AIShip) { - const auto fMinDist = (vBoxSize.z + AIShips[i]->GetBoxsize().z) / 2.0f; - if (AIShips[i]->GetDistance(vNewPos) < fMinDist) + const auto fMinDist = (vBoxSize.z + AIShip->GetBoxsize().z) / 2.0f; + if (AIShip->GetDistance(vNewPos) < fMinDist) return false; } if (AIHelper::pIsland && AIHelper::pIsland->Check2DBoxDepth(vNewPos, vBoxSize, 0.0f, -14.0f)) @@ -548,14 +548,14 @@ float AIShip::GetDefendHP() float AIShip::GetAttackHP(float fAttackDistance) { auto fHP = 0.0f; - for (uint32_t i = 0; i < AIShips.size(); i++) - if (AIShips[i] != this) + for (auto &AIShip : AIShips) + if (AIShip != this) { auto fHP1 = 0.0f; - if (fAttackDistance <= 0.0f && AIShips[i]->isAttack(GetACharacter())) - fHP1 = AIShips[i]->GetShipHP(); - if (isEnemy(*AIShips[i]) && AIShips[i]->GetDistance(*AIShips[i]) <= fAttackDistance) - fHP1 = AIShips[i]->GetShipHP(); + if (fAttackDistance <= 0.0f && AIShip->isAttack(GetACharacter())) + fHP1 = AIShip->GetShipHP(); + if (isEnemy(*AIShip) && AIShip->GetDistance(*AIShip) <= fAttackDistance) + fHP1 = AIShip->GetShipHP(); fHP += fHP1; } return fHP; @@ -611,9 +611,9 @@ void AIShip::SwapShips(AIShip *pOtherShip) // static members AIShip *AIShip::FindShip(ATTRIBUTES *pACharacter) { - for (uint32_t i = 0; i < AIShips.size(); i++) - if (*AIShips[i] == pACharacter) - return AIShips[i]; + for (auto &AIShip : AIShips) + if (*AIShip == pACharacter) + return AIShip; return nullptr; } diff --git a/src/libs/sea_ai/src/ai_ship_cannon_controller.cpp b/src/libs/sea_ai/src/ai_ship_cannon_controller.cpp index c14ddc547..82ed49306 100644 --- a/src/libs/sea_ai/src/ai_ship_cannon_controller.cpp +++ b/src/libs/sea_ai/src/ai_ship_cannon_controller.cpp @@ -4,38 +4,19 @@ float AIShipCannonController::fMaxCannonDamageDistance = 1.0f; float AIShipCannonController::fMaxCannonDamageRadiusPoint = 1.0f; -AIShipCannonController::AIShipCannonController(AIShip *_pShip) +AIShipCannonController::AIShipCannonController(AIShip *_pShip) : bReload(false), bNotEnoughBalls(false) { SetAIShip(_pShip); - bReload = false; - bTempFlag = false; - bNotEnoughBalls = false; - - rs.dwColor = 0xFFFFFF; - rs.vPos = CVECTOR(10000.0f, 0.0f, 0.0f); - rs.dwSubTexture = -1; - rs.fAngle = 0.0f; - rs.fSize = 1.0f; -} - -AIShipCannonController::~AIShipCannonController() -{ } -bool AIShipCannonController::Fire2Position(uint32_t dwBort, const CVECTOR &vFirePos, float fFireHeight) +bool AIShipCannonController::Fire2Position(AISHIP_BORT &bort, const CVECTOR &vFirePos, float fFireHeight) { - Assert(dwBort < aShipBorts.size()); - auto *pBort = &aShipBorts[dwBort]; - - const auto bEnoughBalls = isHaveEnoughtBallsForBort(dwBort); + const auto bEnoughBalls = isHaveEnoughBallsForBort(bort); if (!bEnoughBalls) bNotEnoughBalls = true; - if (!pBort->isCharged() || !pBort->aCannons.size() || pBort->isBortDamaged()) + if (!bort.isCharged() || bort.aCannons.empty() || bort.isBortDamaged()) return false; - - auto vFireDir = !(vFirePos - pOurAIShip->GetPos()); - auto fFireDist = sqrtf(~(vFirePos - pOurAIShip->GetPos())); - + auto vTempFirePos = vFirePos + CVECTOR(0.0f, fFireHeight, 0.0f); auto *pVData = core.Event(SHIP_GET_BORT_FIRE_DELTA, "afff", GetAIShip()->GetACharacter(), vTempFirePos.x, @@ -47,18 +28,24 @@ bool AIShipCannonController::Fire2Position(uint32_t dwBort, const CVECTOR &vFire const auto vTempFireDir = !(vTempFirePos - pOurAIShip->GetPos()); core.Event(SHIP_BORT_FIRE, "lisffffff", GetIndex(GetAIShip()->GetACharacter()), GetAIShip()->GetShipEID(), - (char *)aShipBorts[dwBort].sName.c_str(), vTempFirePos.x, vTempFirePos.y, vTempFirePos.z, vTempFireDir.x, + const_cast(bort.sName.c_str()), vTempFirePos.x, vTempFirePos.y, vTempFirePos.z, vTempFireDir.x, vTempFireDir.y, vTempFireDir.z); - for (uint32_t j = 0; j < pBort->aCannons.size(); j++) + for (auto& cannon : bort.aCannons) { - auto *pCannon = &pBort->aCannons[j]; - if (pCannon->isDamaged()) - continue; - pCannon->SetRechargeEnable(bEnoughBalls); - pCannon->Fire(pBort->fSpeedV0, vTempFirePos); + if (!cannon.isDamaged()) + { + cannon.SetRechargeEnable(bEnoughBalls); + + if (debugDrawToggle) + { + debugFirePositions.emplace_back(vTempFirePos, ARGB(0xFF, 0xFF, 0xFF, 0x00), float{}); + } + + cannon.Fire(bort.fSpeedV0, vTempFirePos); + } } - pBort->ClearCharge(); // FIX-ME + bort.ClearCharge(); // FIX-ME return true; } @@ -76,30 +63,30 @@ bool AIShipCannonController::Fire(const CVECTOR &vFireCamPos, const CVECTOR &vFi CVECTOR vTempFirePos = vOurPos + !vTempDir; vTempFirePos.y = 0.0f; - uint32_t dwBort = GetFirstFireBort(vTempFirePos); - if (dwBort != INVALID_BORT_INDEX) - do - { - const float fMaxDist = - AICannon::CalcMaxFireDistance(aShipBorts[dwBort].fOurBortFireHeight + vOurPos.y, fSpeedV0, fAngle); + auto bortIt = GetFirstFireBort(vTempFirePos); + while (IsValid(bortIt)) + { + const float fMaxDist = AICannon::CalcMaxFireDistance(bortIt->fOurBortFireHeight + vOurPos.y, fSpeedV0, fAngle); - CVECTOR vFirePos = vFireCamPos + fMaxDist * !vFireDir; - vFirePos.y = 0.0f; + CVECTOR vFirePos = vFireCamPos + fMaxDist * !vFireDir; + vFirePos.y = 0.0f; - Fire2Position(dwBort, vFirePos, 0.0f); - } while ((dwBort = GetNextFireBort(dwBort, vTempFirePos)) != INVALID_BORT_INDEX); + Fire2Position(*bortIt, vFirePos, 0.0f); + + bortIt = GetNextFireBort(bortIt, vTempFirePos); + } return true; } bool AIShipCannonController::Fire(const CVECTOR &vFirePos) { - uint32_t dwBort = GetFirstFireBort(vFirePos); - if (dwBort != INVALID_BORT_INDEX) - do - { - Fire2Position(dwBort, vFirePos, -1.0f); - } while ((dwBort = GetNextFireBort(dwBort, vFirePos)) != INVALID_BORT_INDEX); + auto bortIt = GetFirstFireBort(vFirePos); + while (IsValid(bortIt)) + { + Fire2Position(*bortIt, vFirePos, -1.0f); + bortIt = GetNextFireBort(bortIt, vFirePos); + } return true; } @@ -107,33 +94,36 @@ bool AIShipCannonController::Fire(AIShip *pEnemy) { Assert(pEnemy); - float fFireHeight; - VDATA *pVData = core.Event(CANNON_GET_FIRE_HEIGHT, "aa", pOurAIShip->GetACharacter(), pEnemy->GetACharacter()); Assert(pVData); - fFireHeight = pVData->GetFloat(); + const float fFireHeight = pVData->GetFloat(); const float fDistance = GetAIShip()->GetDistance(*pEnemy); const float fSpeedZ = pEnemy->GetShipBasePointer()->GetCurrentSpeed(); const float fAng = pEnemy->GetShipBasePointer()->GetAng().y; - CVECTOR vFirePos = (fSpeedZ * fDistance / GetSpeedV0()) * CVECTOR(sinf(fAng), 0.0f, cosf(fAng)); - vFirePos += pEnemy->GetPos(); - rs.vPos = vFirePos; + const auto vEnemyPos = pEnemy->GetPos(); - uint32_t dwBort = GetFirstFireBort(vFirePos); - if (dwBort != INVALID_BORT_INDEX) - do + // rough estimation + auto vFirePos = (fSpeedZ * fDistance / GetSpeedV0()) * CVECTOR(sinf(fAng), 0.0f, cosf(fAng)) + vEnemyPos; + + auto bortIt = GetFirstFireBort(vFirePos); + while (IsValid(bortIt)) + { + if (debugDrawToggle) { - Fire2Position(dwBort, vFirePos, fFireHeight); - } while ((dwBort = GetNextFireBort(dwBort, vFirePos)) != INVALID_BORT_INDEX); + debugFirePositions.emplace_back(vEnemyPos, ARGB(0xFF, 0xFF, 0x00, 0x00), float{}); + debugFirePositions.emplace_back(vFirePos, ARGB(0xFF, 0x00, 0xFF, 0x00), float{}); + } + + Fire2Position(*bortIt, vFirePos, fFireHeight); + bortIt = GetNextFireBort(bortIt, vFirePos); + } return true; } void AIShipCannonController::Execute(float fDeltaTime) { - uint32_t i, j; - UpdateParameters(); const CVECTOR vOurPos = GetAIShip()->GetPos(); @@ -142,14 +132,14 @@ void AIShipCannonController::Execute(float fDeltaTime) { bNotEnoughBalls = false; - for (i = 0; i < aShipBorts.size(); i++) + for (auto &bort : aShipBorts) { - const bool bEnoughBalls = isHaveEnoughtBallsForBort(i); + const bool bEnoughBalls = isHaveEnoughBallsForBort(bort); if (!bEnoughBalls) bNotEnoughBalls = true; - for (j = 0; j < aShipBorts[i].aCannons.size(); j++) + for (auto &aCannon : bort.aCannons) { - AICannon *pC = &aShipBorts[i].aCannons[j]; + AICannon *pC = &aCannon; if (pC->isDamaged()) continue; pC->SetRechargeEnable(bEnoughBalls); @@ -162,9 +152,9 @@ void AIShipCannonController::Execute(float fDeltaTime) if (GetAIShip()->isMainCharacter()) { bNotEnoughBalls = false; - for (i = 0; i < aShipBorts.size(); i++) + for (auto &bort : aShipBorts) { - if (isHaveEnoughtBallsForBort(i)) + if (isHaveEnoughBallsForBort(bort)) continue; bNotEnoughBalls = true; break; @@ -172,27 +162,24 @@ void AIShipCannonController::Execute(float fDeltaTime) core.Event(SHIP_NOT_ENOUGH_BALLS, "l", bNotEnoughBalls); } - for (i = 0; i < aShipBorts.size(); i++) - if (aShipBorts[i].aCannons.size()) + for (auto &bort : aShipBorts) + { + if (!bort.aCannons.empty()) { - AISHIP_BORT *pBort = &aShipBorts[i]; - // set maximum MaxFireDistance for all cannons const float fMaxBortFireDistance = - AICannon::CalcMaxFireDistance(pBort->fOurBortFireHeight + vOurPos.y, GetSpeedV0(), pBort->fFireAngMax); - for (uint32_t j = 0; j < pBort->aCannons.size(); j++) + AICannon::CalcMaxFireDistance(bort.fOurBortFireHeight + vOurPos.y, GetSpeedV0(), bort.fFireAngMax); + for (auto &aCannon : bort.aCannons) { - pBort->aCannons[j].SetMaxFireDistance(fMaxBortFireDistance); + aCannon.SetMaxFireDistance(fMaxBortFireDistance); } - bool bReloaded = pBort->fChargePercent < 0.999f; - int32_t dwReadyCannonsAfter = 0, dwReadyCannonsBefore = 0; - pBort->fChargePercent = 0.0f; - for (uint32_t j = 0; j < pBort->aCannons.size(); j++) + bort.fChargePercent = 0.0f; + for (uint32_t j = 0; j < bort.aCannons.size(); j++) { - AICannon *pC = &pBort->aCannons[j]; + AICannon *pC = &bort.aCannons[j]; if (!(pC->isFired() || pC->isRecharged() || pC->isDamaged() || pC->isEmpty())) dwReadyCannonsBefore++; @@ -201,27 +188,27 @@ void AIShipCannonController::Execute(float fDeltaTime) continue; pC->Execute(fDeltaTime); - pBort->fChargePercent += pC->GetRechargePercent(); + bort.fChargePercent += pC->GetRechargePercent(); if (!(pC->isFired() || pC->isRecharged() || pC->isDamaged() || pC->isEmpty())) dwReadyCannonsAfter++; } // prevent division by zero (mitrocosta) - auto intactCannons = GetBortIntactCannonsNum(i); + const auto intactCannons = GetBortIntactCannonsNum(bort); if (intactCannons > 0) { - pBort->fChargePercent /= intactCannons; + bort.fChargePercent /= intactCannons; } else { - pBort->fChargePercent = .0f; + bort.fChargePercent = .0f; } - if (dwReadyCannonsBefore != dwReadyCannonsAfter && dwReadyCannonsAfter == GetBortIntactCannonsNum(i)) - // pBort->fChargePercent >= 0.999f) + if (dwReadyCannonsBefore != dwReadyCannonsAfter && dwReadyCannonsAfter == GetBortIntactCannonsNum(bort)) + // aShipBorts[i].fChargePercent >= 0.999f) { - core.Event(SHIP_BORT_RELOADED, "as", GetAIShip()->GetACharacter(), pBort->sName.c_str()); - // core.Trace("%s bort is reloaded", pBort->sName.c_str()); + core.Event(SHIP_BORT_RELOADED, "as", GetAIShip()->GetACharacter(), bort.sName.c_str()); + // core.Trace("%s bort is reloaded", aShipBorts[i].sName.c_str()); } // update borts parameters for script @@ -230,117 +217,98 @@ void AIShipCannonController::Execute(float fDeltaTime) ATTRIBUTES *pAPlayer = GetAIShip()->GetACharacter(); ATTRIBUTES *pABorts = pAPlayer->FindAClass(pAPlayer, "Ship.Cannons.Borts"); Assert(pABorts); - pABorts->SetAttribute((char *)pBort->sName.c_str(), ""); - ATTRIBUTES *pACurBort = pABorts->FindAClass(pABorts, (char *)pBort->sName.c_str()); + pABorts->SetAttribute(bort.sName.c_str(), ""); + ATTRIBUTES *pACurBort = pABorts->FindAClass(pABorts, bort.sName.c_str()); Assert(pACurBort); - pACurBort->SetAttributeUseFloat("MaxFireDistance", pBort->fMaxFireDistance); - pACurBort->SetAttributeUseFloat("ChargeRatio", pBort->fChargePercent); + pACurBort->SetAttributeUseFloat("MaxFireDistance", bort.fMaxFireDistance); + pACurBort->SetAttributeUseFloat("ChargeRatio", bort.fChargePercent); pACurBort->SetAttributeUseFloat("DamageRatio", - 1.0f - (static_cast(GetBortIntactCannonsNum(i)) + - static_cast(GetBortDisabledCannonsNum(i))) / - static_cast(pBort->aCannons.size())); + 1.0f - (static_cast(GetBortIntactCannonsNum(bort)) + + static_cast(GetBortDisabledCannonsNum(bort))) / + static_cast(bort.aCannons.size())); // pACurBort->SetAttributeUseFloat("DamageRatio", // 1.0f - static_cast(GetBortIntactCannonsNum(i)) / // static_cast(pBort // ->aCannons.size())); } } -} - -struct tr_vertex -{ - CVECTOR vPos; - uint32_t dwColor; -}; - -std::vector Verts; -#define TR_FORMAT (D3DFVF_XYZ | D3DFVF_DIFFUSE) - -void AIShipCannonController::AddTrg(CVECTOR *pVerts, uint32_t dwColor) -{ - for (uint32_t i = 0; i < 3; i++) - Verts.push_back(tr_vertex{pVerts[i], dwColor}); + } } // return (fire distance) angle -float AIShipCannonController::GetBortHeightAngle(int32_t iBortIndex) +float AIShipCannonController::GetBortHeightAngle(const AISHIP_BORT &bort) const { CMatrix m; - CVECTOR v; - GetAIShip()->GetMatrix()->Get3X3(&m); + CVECTOR v; v.y = 0.0f; - v.x = sinf(aShipBorts[iBortIndex].fFireDir); - v.z = cosf(aShipBorts[iBortIndex].fFireDir); + v.x = sinf(bort.fFireDir); + v.z = cosf(bort.fFireDir); return atan2f((m * v).y, 1.0f); } -float AIShipCannonController::GetFireDistance(bool bMaxFireDistance) +float AIShipCannonController::GetFireDistance(bool bMaxFireDistance) const { float fDistance = (bMaxFireDistance) ? 0.0f : 1e10f; const float fSpeedV0 = GetSpeedV0(); const CVECTOR vOurPos = GetAIShip()->GetPos(); - for (uint32_t i = 0; i < aShipBorts.size(); i++) - if (aShipBorts[i].aCannons.size()) + for (const auto &bort : aShipBorts) + { + if (!bort.aCannons.empty()) { - AISHIP_BORT *pBort = &aShipBorts[i]; - const float fMaxFireDistance = AICannon::CalcMaxFireDistance( - pBort->fOurBortFireHeight + vOurPos.y, fSpeedV0, GetBortHeightAngle(i) + pBort->fFireAngMax); + const float fMaxFireDistance = + AICannon::CalcMaxFireDistance(bort.fOurBortFireHeight + vOurPos.y, fSpeedV0, + GetBortHeightAngle(bort) + bort.fFireAngMax); if (bMaxFireDistance && fDistance < fMaxFireDistance) fDistance = fMaxFireDistance; if (!bMaxFireDistance && fDistance > fMaxFireDistance) fDistance = fMaxFireDistance; } + } return fDistance; } bool AIShipCannonController::UpdateParameters() { - CVECTOR v; - const CVECTOR vOurPos = GetAIShip()->GetPos(); const CVECTOR vZ = !(GetAIShip()->GetMatrix()->Vz()); // updates borts parameters const float fSpeedV0 = GetSpeedV0(); - for (uint32_t i = 0; i < aShipBorts.size(); i++) - if (aShipBorts[i].aCannons.size()) + for (auto &bort : aShipBorts) + { + if (!bort.aCannons.empty()) { - AISHIP_BORT *pBort = &aShipBorts[i]; + bort.fSpeedV0 = fSpeedV0; + bort.fMaxFireDistance = AICannon::CalcMaxFireDistance(bort.fOurBortFireHeight + vOurPos.y, fSpeedV0, GetBortHeightAngle( + bort) + bort.fFireAngMax); + const float fDir = bort.fFireDir; + float fZone = bort.fFireZone; - pBort->fSpeedV0 = fSpeedV0; - pBort->fMaxFireDistance = AICannon::CalcMaxFireDistance(pBort->fOurBortFireHeight + vOurPos.y, fSpeedV0, - GetBortHeightAngle(i) + pBort->fFireAngMax); - - const float fDir = pBort->fFireDir; - float fZone = pBort->fFireZone; - - v = CVECTOR(sinf(fDir), 0.0f, cosf(fDir)); + auto v = CVECTOR(sinf(fDir), 0.0f, cosf(fDir)); RotateAroundY(v.x, v.z, vZ.z, vZ.x); - pBort->vDirection = v; + bort.vDirection = v; /*v = CVECTOR(sinf(fDir - fZone/2.0f), 0.0f, cosf(fDir - fZone/2.0f)); RotateAroundY(v.x,v.z,vZ.z,vZ.x); - pBort->vAngleVectors[0] = v; + aShipBorts[i].vAngleVectors[0] = v; v = CVECTOR(sinf(fDir + fZone/2.0f), 0.0f, cosf(fDir + fZone/2.0f)); RotateAroundY(v.x,v.z,vZ.z,vZ.x); - pBort->vAngleVectors[1] = v;*/ + aShipBorts[i].vAngleVectors[1] = v;*/ } + } return true; } -CVECTOR AIShipCannonController::GetBortDirection(uint32_t dwBort) +CVECTOR AIShipCannonController::GetBortDirection(const AISHIP_BORT &bort) const { - Assert(dwBort != INVALID_BORT_INDEX && dwBort < aShipBorts.size()); - AISHIP_BORT *pBort = &aShipBorts[dwBort]; - - const float fDir = pBort->fFireDir; + const float fDir = bort.fFireDir; auto v = CVECTOR(sinf(fDir), 0.0f, cosf(fDir)); const CVECTOR vZ = !(GetAIShip()->GetMatrix()->Vz()); // FIX-ME? RotateAroundY(v.x, v.z, vZ.z, vZ.x); @@ -360,15 +328,13 @@ CVECTOR AIShipCannonController::GetFirePos(const CVECTOR &vFireDir, float fDista CVECTOR vTempFirePos = vOurPos + !vTempDir; vTempFirePos.y = 0.0f; - uint32_t dwBort = GetFirstFireBort(vTempFirePos); - if (dwBort == INVALID_BORT_INDEX) + const auto bortIt = GetFirstFireBort(vTempFirePos); + if (!IsValid(bortIt)) { - return CVECTOR(1e5f, 0.0f, 1e5f); - Assert(dwBort != INVALID_BORT_INDEX); + return {1e5f, 0.0f, 1e5f}; } - const float fMaxDist = - AICannon::CalcMaxFireDistance(aShipBorts[dwBort].fOurBortFireHeight + vOurPos.y, fSpeedV0, fAngle); + const float fMaxDist = AICannon::CalcMaxFireDistance(bortIt->fOurBortFireHeight + vOurPos.y, fSpeedV0, fAngle); if (fDistance > fMaxDist) fDistance = fMaxDist; @@ -393,66 +359,57 @@ CVECTOR AIShipCannonController::GetFirePos(const CVECTOR &vFireDir) CVECTOR vTempFirePos = vOurPos + !vTempDir; vTempFirePos.y = 0.0f; - uint32_t dwBort = GetFirstFireBort(vTempFirePos); - if (dwBort == INVALID_BORT_INDEX) // FIX-ME + const auto bortIt = GetFirstFireBort(vTempFirePos); + if (!IsValid(bortIt)) // FIX-ME { - return CVECTOR(1e5f, 0.0f, 1e5f); - - __debugbreak(); - bTempFlag = true; - dwBort = GetFirstFireBort(vTempFirePos); - Assert(dwBort != INVALID_BORT_INDEX); + return {1e5f, 0.0f, 1e5f}; } - const float fMaxDist = - AICannon::CalcMaxFireDistance(aShipBorts[dwBort].fOurBortFireHeight + vOurPos.y, fSpeedV0, fAngle); + const float fMaxDist = AICannon::CalcMaxFireDistance(bortIt->fOurBortFireHeight + vOurPos.y, fSpeedV0, fAngle); return vOurPos + fMaxDist * !vFireDir; } -bool AIShipCannonController::isCanFire(const CVECTOR &vCamDir) +bool AIShipCannonController::isCanFire(const CVECTOR &vCamDir) const { const CVECTOR vEnemyDir = !CVECTOR(vCamDir.x, 0.0f, vCamDir.z); - for (uint32_t i = 0; i < aShipBorts.size(); i++) - if (aShipBorts[i].aCannons.size()) + for (const auto &bort : aShipBorts) + { + if (!bort.aCannons.empty()) { - if (aShipBorts[i].isBortDamaged()) + if (bort.isBortDamaged()) continue; - AISHIP_BORT *pBort = &aShipBorts[i]; - - // check angle limit - float fY0; //, fY1; - fY0 = vEnemyDir | pBort->vDirection; - // fY0 = (vEnemyDir ^ pBort->vAngleVectors[1]).y; - // fY1 = (vEnemyDir ^ pBort->vAngleVectors[1]).y; - if (fY0 <= pBort->fCosFireZone) + const float fY0 = vEnemyDir | bort.vDirection; + // fY0 = (vEnemyDir ^ aShipBorts[i].vAngleVectors[1]).y; + // fY1 = (vEnemyDir ^ aShipBorts[i].vAngleVectors[1]).y; + if (fY0 <= bort.fCosFireZone) continue; // if ((SIGN(fY0) == SIGN(fY1)) || (SIGN(fY0) == 1)) continue; // check fire height angle - CVECTOR v1 = pBort->vDirection; //(pBort->vAngleVectors[0] + pBort->vAngleVectors[1]) / 2.0f; + CVECTOR v1 = bort.vDirection; //(aShipBorts[i].vAngleVectors[0] + aShipBorts[i].vAngleVectors[1]) / 2.0f; v1 = !(CVECTOR(v1.x, vCamDir.y, v1.z)); - CVECTOR v2 = !(CVECTOR(v1.x, sinf(GetBortHeightAngle(i)), v1.z)); + CVECTOR v2 = !(CVECTOR(v1.x, sinf(GetBortHeightAngle(bort)), v1.z)); const float fSub = v2.y - v1.y; const float fAng = acosf(Clamp(v1 | v2)); - if (fSub > 0.0f && fAng > fabsf(pBort->fFireAngMin)) + if (fSub > 0.0f && fAng > fabsf(bort.fFireAngMin)) continue; - if (fSub < 0.0f && fAng > fabsf(pBort->fFireAngMax)) + if (fSub < 0.0f && fAng > fabsf(bort.fFireAngMax)) continue; return true; } + } return false; } -bool AIShipCannonController::isCanFireBort(uint32_t dwBort, const CVECTOR &vFirePos, float *pfZapasDistance) +bool AIShipCannonController::isCanFireBort(const AISHIP_BORT &bort, const CVECTOR &vFirePos, + float *pfZapasDistance) const { - AISHIP_BORT *pBort = &aShipBorts[dwBort]; - - if (!pBort->aCannons.size()) + if (bort.aCannons.empty()) return false; - if (pBort->isBortDamaged()) + if (bort.isBortDamaged()) return false; CVECTOR vFireDir = (vFirePos - pOurAIShip->GetPos()); @@ -460,16 +417,14 @@ bool AIShipCannonController::isCanFireBort(uint32_t dwBort, const CVECTOR &vFire const float fFireDist = sqrtf(~(vFirePos - pOurAIShip->GetPos())); // check distance limit - if (fFireDist > pBort->fMaxFireDistance) + if (fFireDist > bort.fMaxFireDistance) return false; - // check angle limit - float fY0; //,fY1; - fY0 = vFireDir | pBort->vDirection; - if (fY0 <= pBort->fCosFireZone) + const float fY0 = vFireDir | bort.vDirection; + if (fY0 <= bort.fCosFireZone) return false; - /*fY0 = (vFireDir ^ pBort->vAngleVectors[0]).y; - fY1 = (vFireDir ^ pBort->vAngleVectors[1]).y; + /*fY0 = (vFireDir ^ aShipBorts[i].vAngleVectors[0]).y; + fY1 = (vFireDir ^ aShipBorts[i].vAngleVectors[1]).y; if (bTempFlag) { core.Trace("AIShipCannonController: bort = %d, fY0 = %.8f, fY1 = %.8f", dwBort, fY0, fY1); @@ -477,160 +432,232 @@ bool AIShipCannonController::isCanFireBort(uint32_t dwBort, const CVECTOR &vFire if ((SIGN(fY0) == SIGN(fY1)) || (SIGN(fY0) == 1)) return false;*/ if (pfZapasDistance) - *pfZapasDistance = pBort->fMaxFireDistance - fFireDist; + *pfZapasDistance = bort.fMaxFireDistance - fFireDist; return true; } -uint32_t AIShipCannonController::GetBestFireBortOnlyDistance(CVECTOR vFirePos, float fZapasDistance) +auto AIShipCannonController::GetBestFireBortOnlyDistance(CVECTOR vFirePos, float fZapasDistance) + -> decltype(aShipBorts)::iterator { const float fFireDist = sqrtf(~(vFirePos - pOurAIShip->GetPos())); - uint32_t dwBestBort = INVALID_BORT_INDEX; + auto bestBortIt = std::end(aShipBorts); const CVECTOR vOurPos = GetAIShip()->GetPos(); const auto vOurDir = CVECTOR(sinf(GetAIShip()->GetAng().y), 0.0f, cosf(GetAIShip()->GetAng().y)); float fBestAng = 1e8f; - for (uint32_t i = 0; i < aShipBorts.size(); i++) - if (aShipBorts[i].aCannons.size()) + for (auto bort = std::begin(aShipBorts); bort != std::end(aShipBorts); ++bort) + { + if (!bort->aCannons.empty()) { - AISHIP_BORT *pBort = &aShipBorts[i]; - - if (!pBort->isCharged() || pBort->isBortDamaged()) + if (!bort->isCharged() || bort->isBortDamaged()) continue; const float fSpeedV0 = GetSpeedV0(); - const float fMaxFireDistance = AICannon::CalcMaxFireDistance( - pBort->fOurBortFireHeight + vOurPos.y, fSpeedV0, GetBortHeightAngle(i) + pBort->fFireAngMax); + const float fMaxFireDistance = AICannon::CalcMaxFireDistance(bort->fOurBortFireHeight + vOurPos.y, fSpeedV0, + GetBortHeightAngle(*bort) + bort->fFireAngMax); if (fFireDist > fMaxFireDistance) continue; if (fMaxFireDistance - fFireDist < fZapasDistance) continue; - CVECTOR vBortDir = GetBortDirection(i); + CVECTOR vBortDir = GetBortDirection(*bort); const float fAng = acosf(Clamp(vOurDir | vBortDir)); if (fAng < fBestAng) { fBestAng = fAng; - dwBestBort = i; + bestBortIt = bort; } } - return dwBestBort; + } + return bestBortIt; } -uint32_t AIShipCannonController::GetFirstFireBort(const CVECTOR &vFirePos, float *pfZapasDistance) +auto AIShipCannonController::GetFirstFireBort(const CVECTOR &vFirePos, float *pfZapasDistance) + -> decltype(aShipBorts)::iterator { - for (uint32_t i = 0; i < aShipBorts.size(); i++) - if (aShipBorts[i].aCannons.size() && isCanFireBort(i, vFirePos, pfZapasDistance) && - !aShipBorts[i].isBortDamaged()) - return i; + for (auto it = std::begin(aShipBorts); it != std::end(aShipBorts); ++it) + { + if (!it->aCannons.empty() && isCanFireBort(*it, vFirePos, pfZapasDistance) && !it->isBortDamaged()) + return it; + } - bTempFlag = false; - return INVALID_BORT_INDEX; + return std::end(aShipBorts); } -uint32_t AIShipCannonController::GetNextFireBort(uint32_t dwPrevBort, const CVECTOR &vFirePos, float *pfZapasDistance) +auto AIShipCannonController::GetNextFireBort(const decltype(aShipBorts)::iterator bortIt, const CVECTOR &vFirePos, + float *pfZapasDistance) + -> decltype(aShipBorts)::iterator { - Assert(dwPrevBort != INVALID_BORT_INDEX && dwPrevBort < aShipBorts.size()); - for (uint32_t i = dwPrevBort + 1; i < aShipBorts.size(); i++) - if (aShipBorts[i].aCannons.size() && isCanFireBort(i, vFirePos, pfZapasDistance) && - !aShipBorts[i].isBortDamaged()) - return i; + if (bortIt != std::end(aShipBorts)) + { + for (auto it = bortIt + 1; it != std::end(aShipBorts); ++it) + { + if (!it->aCannons.empty() && isCanFireBort(*it, vFirePos, pfZapasDistance) && !it->isBortDamaged()) + return it; + } + } + return std::end(aShipBorts); +} - return INVALID_BORT_INDEX; +bool AIShipCannonController::IsValid(const decltype(aShipBorts)::const_iterator bortIt) const +{ + return bortIt != std::cend(aShipBorts); } bool AIShipCannonController::isCanFirePos(const CVECTOR &vFirePos) { - return (GetFirstFireBort(vFirePos) != INVALID_BORT_INDEX); + return IsValid(GetFirstFireBort(vFirePos)); } bool AIShipCannonController::isCanFire(AIShip *pEnemy) { Assert(pEnemy); - return (GetFirstFireBort(pEnemy->GetPos()) != INVALID_BORT_INDEX); + return IsValid(GetFirstFireBort(pEnemy->GetPos())); } -float AIShipCannonController::GetSpeedV0() +float AIShipCannonController::GetSpeedV0() const { - ATTRIBUTES *pACannon; ATTRIBUTES *pACharacter = GetAIShip()->GetACharacter(); - pACannon = pACharacter->FindAClass(pACharacter, "Ship.Cannons"); - Assert(pACannon); - return pACannon->GetAttributeAsFloat("SpeedV0"); + ATTRIBUTES *pACannons = pACharacter->FindAClass(pACharacter, "Ship.Cannons"); + Assert(pACannons); + return pACannons->GetAttributeAsFloat("SpeedV0"); } void AIShipCannonController::Realize(float fDeltaTime) { - uint32_t i, j; + using namespace std::chrono_literals; - return; + if (core.Controls->GetDebugAsyncKeyState('H') < 0) + { + debugDrawToggle = !debugDrawToggle; + std::this_thread::sleep_for(100ms); + } - for (i = 0; i < aShipBorts.size(); i++) + if (!debugDrawToggle) { - AISHIP_BORT *pBort = &aShipBorts[i]; + return; + } - for (j = 0; j < pBort->aCannons.size(); j++) + for (auto it = debugFirePositions.begin(); it != debugFirePositions.end();) + { + constexpr auto kDebugFadeTime = 3.0f; + if (auto &[pos, color, dt] = *it; dt <= kDebugFadeTime) { - AICannon *pC = &pBort->aCannons[j]; - if (pC->isDamaged()) - continue; - CVECTOR vCPos = pC->GetPos() - pC->GetDir() * 1.0f; - AIHelper::pRS->DrawSphere(vCPos, fMaxCannonDamageDistance, 0xFFFFFF); + dt += fDeltaTime; + + CVECTOR cPos; + CVECTOR cAng; + float cFov; + AIHelper::pRS->GetCamera(cPos, cAng, cFov); + + const auto dist = (pos - cPos).GetLength(); + + float radius = 0.3f; + if (dist > 1.0f) + { + radius *= sqrtf(dist); + } + AIHelper::pRS->DrawSphere(pos, radius, color); + ++it; + } + else + { + it = debugFirePositions.erase(it); } } - // AIHelper::pRS->DrawRects(&rs, 1, "Line"); - /*char tmp[256], str[256]; - str[0] = 0; - for (uint32_t i=0;i Lines; + Lines.clear(); + + for (const auto &bort : aShipBorts) { - sprintf_s(tmp,"%.3f, ",GetBortHeightAngle(i)); - strcat_s(str,tmp); + for (const auto &cannon : bort.aCannons) + { + if (!cannon.isDamaged()) + { + constexpr auto red = ARGB(0xFF, 0xDC, 0x14, 0x3C); + constexpr auto green = ARGB(0xFF, 0x7C, 0xFC, 0x00); + + const auto &&vPos = cannon.GetPos(); + Lines.emplace_back(vPos, red); + Lines.emplace_back(vPos + 5.0f * cannon.GetDir(), red); + Lines.emplace_back(vPos, green); + Lines.emplace_back(vPos + CVECTOR{0.0f, cannon.GetDirY(), 0.0f}, green); + } + } } - pRS->Print(0,20,str);*/ - if (core.Controls->GetDebugAsyncKeyState('H') < 0) + + if (!Lines.empty()) { - Verts.clear(); - CMatrix m; + AIHelper::pRS->SetTransform(D3DTS_WORLD, CMatrix()); + AIHelper::pRS->DrawLines(Lines.data(), Lines.size() / 2, "Line"); + } - CVECTOR vPosTemp = GetAIShip()->GetPos(); - GetAIShip()->GetMatrix()->Get3X3(m); - CVECTOR vZ = !(m.Vz()); - for (uint32_t i = 0; i < aShipBorts.size(); i++) - if (aShipBorts[i].aCannons.size()) - { - AICannon *pCannon = &aShipBorts[i].aCannons[0]; - // calc fire angle - float fDist = SQR(GetSpeedV0()) / AIHelper::fGravity; - fDist *= sinf(2.0f * (GetBortHeightAngle(i) + aShipBorts[i].fFireAngMax)); - // draw baba - float fDir = aShipBorts[i].fFireDir; - float fRastr = aShipBorts[i].fFireZone; - float fDA = PId2 / 36.0f; - for (float fAng = fDir - fRastr / 2.0f; fAng < fDir + fRastr / 2.0f; fAng += fDA) - { - CVECTOR v[3]; - ZERO(v); - float R = fDist; - v[0].x = vPosTemp.x; - v[0].z = vPosTemp.z; - - v[1].x = R * sinf(fAng); - v[1].z = R * cosf(fAng); - RotateAroundY(v[1].x, v[1].z, vZ.z, vZ.x); - v[1] += v[0]; - - v[2].x = R * sinf(fAng + fDA); - v[2].z = R * cosf(fAng + fDA); - RotateAroundY(v[2].x, v[2].z, vZ.z, vZ.x); - v[2] += v[0]; - AddTrg(&v[0], 0x0F007F00); - } + if (GetAIShip()->isMainCharacter()) + { + std::string buf; + for (const auto &bort : aShipBorts) + { + buf += fmt::format("{:.3f} ", GetBortHeightAngle(bort)); + } + AIHelper::pRS->Print(200, 20, buf.c_str()); + } - CMatrix m; - AIHelper::pRS->SetTransform(D3DTS_WORLD, m); - if (Verts.size()) - AIHelper::pRS->DrawPrimitiveUP(D3DPT_TRIANGLELIST, TR_FORMAT, Verts.size() / 3, &Verts[0], - sizeof(tr_vertex), "ShipCannonAngles"); + struct tr_vertex + { + CVECTOR vPos; + uint32_t dwColor; + }; + + static std::vector Verts; + Verts.clear(); + + CMatrix m; + GetAIShip()->GetMatrix()->Get3X3(m); + const CVECTOR vZ = !(m.Vz()); + const CVECTOR vPosTemp = GetAIShip()->GetPos(); + for (const auto &bort : aShipBorts) + { + if (!bort.aCannons.empty()) + { + // calc fire range + float fDist = SQR(GetSpeedV0()) / AIHelper::fGravity; + fDist *= sinf(2.0f * (GetBortHeightAngle(bort) + aShipBorts[0].fFireAngMax)); + // draw baba + const float fDir = bort.fFireDir; + const float fRastr = bort.fFireZone; + const float fDA = PId2 / 36.0f; + for (float fAng = fDir - fRastr / 2.0f; fAng < fDir + fRastr / 2.0f; fAng += fDA) + { + CVECTOR v[3]; + ZERO(v); + const float R = fDist; + v[0].x = vPosTemp.x; + v[0].z = vPosTemp.z; + + v[1].x = R * sinf(fAng); + v[1].z = R * cosf(fAng); + RotateAroundY(v[1].x, v[1].z, vZ.z, vZ.x); + v[1] += v[0]; + + v[2].x = R * sinf(fAng + fDA); + v[2].z = R * cosf(fAng + fDA); + RotateAroundY(v[2].x, v[2].z, vZ.z, vZ.x); + v[2] += v[0]; + + constexpr auto color = ARGB(0x0A, 0x00, 0x7F, 0x00); + Verts.emplace_back(v[0], color); + Verts.emplace_back(v[1], color); + Verts.emplace_back(v[2], color); } + } + } + + if (!Verts.empty()) + { + AIHelper::pRS->SetTransform(D3DTS_WORLD, CMatrix()); + AIHelper::pRS->DrawPrimitiveUP(D3DPT_TRIANGLELIST, D3DFVF_XYZ | D3DFVF_DIFFUSE, Verts.size() / 3, &Verts[0], + sizeof(tr_vertex), "ShipCannonAngles"); } } @@ -653,23 +680,23 @@ bool AIShipCannonController::Init(ATTRIBUTES *_pAShip) if (!pBortAttribute) break; - aShipBorts.push_back(AISHIP_BORT{}); + aShipBorts.emplace_back(); // AISHIP_BORT * pBort = &aShipBorts[aShipBorts.Add()]; - AISHIP_BORT *pBort = &aShipBorts.back(); - pBort->sName = pBortAttribute->GetThisName(); - pBort->fFireZone = pBortAttribute->GetAttributeAsFloat("FireZone"); - pBort->fFireAngMin = pBortAttribute->GetAttributeAsFloat("FireAngMin"); - pBort->fFireAngMax = pBortAttribute->GetAttributeAsFloat("FireAngMax"); - pBort->fFireDir = pBortAttribute->GetAttributeAsFloat("FireDir"); - pBort->dwNumDamagedCannons = 0; - - pBort->fCosFireZone = cosf(pBort->fFireZone / 2.0f); + AISHIP_BORT &bort = aShipBorts.back(); + bort.sName = pBortAttribute->GetThisName(); + bort.fFireZone = pBortAttribute->GetAttributeAsFloat("FireZone"); + bort.fFireAngMin = pBortAttribute->GetAttributeAsFloat("FireAngMin"); + bort.fFireAngMax = pBortAttribute->GetAttributeAsFloat("FireAngMax"); + bort.fFireDir = pBortAttribute->GetAttributeAsFloat("FireDir"); + bort.dwNumDamagedCannons = 0; + + bort.fCosFireZone = cosf(bort.fFireZone / 2.0f); dwIdx++; // create damages - char str[512]; - sprintf_s(str, "%s.damages", (char *)pBort->sName.c_str()); - pABorts->CreateSubAClass(pABorts, str); + char buf[512]; + sprintf_s(buf, "%s.damages", bort.sName.c_str()); + pABorts->CreateSubAClass(pABorts, buf); } return ScanShipForCannons(); @@ -677,12 +704,6 @@ bool AIShipCannonController::Init(ATTRIBUTES *_pAShip) bool AIShipCannonController::ScanShipForCannons() { - char str[512]; - uint32_t i, j; - CMatrix m; - GEOS::LABEL label; - GEOS::INFO info; - NODE *pNode; ATTRIBUTES *pACharacter = GetAIShip()->GetACharacter(); ATTRIBUTES *pABorts = pACharacter->FindAClass(pACharacter, "Ship.Cannons.Borts"); @@ -692,32 +713,35 @@ bool AIShipCannonController::ScanShipForCannons() // search and add cannons uint32_t dwIdx = 0; - while (pNode = pModel->GetNode(dwIdx)) + NODE *pNode; + while ((pNode = pModel->GetNode(dwIdx))) { + GEOS::INFO info; pNode->geo->GetInfo(info); - for (i = 0; i < static_cast(info.nlabels); i++) + for (size_t i = 0; i < static_cast(info.nlabels); i++) { + GEOS::LABEL label; pNode->geo->GetLabel(i, label); - for (j = 0; j < aShipBorts.size(); j++) + for (auto &bort : aShipBorts) // if (aShipBorts[j] == label.group_name) { - if (storm::iEquals(aShipBorts[j].sName, label.group_name)) + if (storm::iEquals(bort.sName, label.group_name)) { - // ugeen : akella bug fix - aShipBorts[j].aCannons.push_back(AICannon{}); - // AICannon * pCannon = &aShipBorts[j].aCannons[aShipBorts[j].aCannons.Add()]; - AICannon *pCannon = &aShipBorts[j].aCannons.back(); + bort.aCannons.emplace_back(); + AICannon *pCannon = &bort.aCannons.back(); + const CMatrix m; memcpy(m, label.m, sizeof(m)); - aShipBorts[j].fOurBortFireHeight += m.Pos().y; + bort.fOurBortFireHeight += m.Pos().y; pCannon->Init(GetAIShip(), GetAIShip()->GetShipEID(), label); - sprintf_s(str, "%s.damages", label.group_name); - ATTRIBUTES *pADamages = pABorts->FindAClass(pABorts, str); - sprintf_s(str, "c%zd", aShipBorts[j].aCannons.size() - 1); - const float fDamage = pADamages->GetAttributeAsFloat(str, 0.0f); - pADamages->SetAttributeUseFloat(str, fDamage); + char buf[512]; + sprintf_s(buf, "%s.damages", label.group_name); + ATTRIBUTES *pADamages = pABorts->FindAClass(pABorts, buf); + sprintf_s(buf, "c%zd", bort.aCannons.size() - 1); + const float fDamage = pADamages->GetAttributeAsFloat(buf, 0.0f); + pADamages->SetAttributeUseFloat(buf, fDamage); pCannon->SetDamage(fDamage); if (pCannon->isDamaged()) - aShipBorts[j].dwNumDamagedCannons++; + bort.dwNumDamagedCannons++; break; } @@ -726,18 +750,20 @@ bool AIShipCannonController::ScanShipForCannons() } // calculate medium fire point for this ship - for (i = 0; i < aShipBorts.size(); i++) - if (aShipBorts[i].aCannons.size()) + for (auto &bort : aShipBorts) + { + if (!bort.aCannons.empty()) { - aShipBorts[i].fOurBortFireHeight /= static_cast(aShipBorts[i].aCannons.size()); + bort.fOurBortFireHeight /= static_cast(bort.aCannons.size()); - const bool bHaveEnoughBalls = isHaveEnoughtBallsForBort(i); + const bool bHaveEnoughBalls = isHaveEnoughBallsForBort(bort); if (!bHaveEnoughBalls) bNotEnoughBalls = true; - for (j = 0; j < aShipBorts[i].aCannons.size(); j++) - aShipBorts[i].aCannons[j].QuickRecharge(bHaveEnoughBalls); + for (auto &aCannon : bort.aCannons) + aCannon.QuickRecharge(bHaveEnoughBalls); } + } // TEST !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1 /*core.Trace("NumBorts = %d",aShipBorts.size()); @@ -747,53 +773,49 @@ bool AIShipCannonController::ScanShipForCannons() return true; } -uint32_t AIShipCannonController::GetCannonsNum() +uint32_t AIShipCannonController::GetCannonsNum() const { - uint32_t i, dwCannonsNum = 0; - for (i = 0; i < aShipBorts.size(); i++) - dwCannonsNum += GetBortIntactCannonsNum(i); + uint32_t dwCannonsNum = 0; + for (const auto &bort : aShipBorts) + dwCannonsNum += GetBortIntactCannonsNum(bort); return dwCannonsNum; } -uint32_t AIShipCannonController::GetBortIntactCannonsNum(uint32_t dwBortIdx) +uint32_t AIShipCannonController::GetBortIntactCannonsNum(const AISHIP_BORT& bort) const { - Assert(dwBortIdx != INVALID_BORT_INDEX && dwBortIdx < aShipBorts.size()); uint32_t dwCannons = 0; - for (uint32_t j = 0; j < aShipBorts[dwBortIdx].aCannons.size(); j++) - if (!aShipBorts[dwBortIdx].aCannons[j].isDamaged()) + for (const auto &aCannon : bort.aCannons) + if (!aCannon.isDamaged()) dwCannons++; return dwCannons; } // ugeen : need for correct ship cannons random -uint32_t AIShipCannonController::GetBortDisabledCannonsNum(uint32_t dwBortIdx) +uint32_t AIShipCannonController::GetBortDisabledCannonsNum(const AISHIP_BORT &bort) const { - Assert(dwBortIdx != INVALID_BORT_INDEX && dwBortIdx < aShipBorts.size()); uint32_t dwCannons = 0; - for (uint32_t j = 0; j < aShipBorts[dwBortIdx].aCannons.size(); j++) - if (aShipBorts[dwBortIdx].aCannons[j].isDisabled()) + for (const auto &aCannon : bort.aCannons) + if (aCannon.isDisabled()) dwCannons++; return dwCannons; } -bool AIShipCannonController::isHaveEnoughtBallsForBort(uint32_t dwBortIdx) +bool AIShipCannonController::isHaveEnoughBallsForBort(const AISHIP_BORT &bort) const { - Assert(dwBortIdx != INVALID_BORT_INDEX && dwBortIdx < aShipBorts.size()); VDATA *pvData = core.Event(SHIP_GET_CURRENT_BALLS_NUM, "a", GetAIShip()->GetACharacter()); Assert(pvData); - if (static_cast(GetBortIntactCannonsNum(dwBortIdx)) > pvData->GetInt()) + if (static_cast(GetBortIntactCannonsNum(bort)) > pvData->GetInt()) return false; return true; } void AIShipCannonController::Unload() { - uint32_t i, j; - for (i = 0; i < aShipBorts.size(); i++) + for (auto &bort : aShipBorts) { - for (j = 0; j < aShipBorts[i].aCannons.size(); j++) + for (auto &aCannon : bort.aCannons) { - AICannon *pC = &aShipBorts[i].aCannons[j]; + AICannon *pC = &aCannon; if (!pC->isDamaged()) pC->Unload(); } @@ -809,25 +831,22 @@ void AIShipCannonController::Reload() void AIShipCannonController::CheckCannonsBoom(float fTmpCannonDamage, const CVECTOR &vPnt) { char str[512]; - uint32_t i, j; ATTRIBUTES *pACharacter = GetAIShip()->GetACharacter(); ATTRIBUTES *pABorts = pACharacter->FindAClass(pACharacter, "Ship.Cannons.Borts"); Assert(pABorts); - for (i = 0; i < aShipBorts.size(); i++) + for (auto &bort : aShipBorts) { - AISHIP_BORT *pBort = &aShipBorts[i]; - - sprintf_s(str, "%s.damages", (char *)pBort->sName.c_str()); + sprintf_s(str, "%s.damages", bort.sName.c_str()); ATTRIBUTES *pADamages = pABorts->FindAClass(pABorts, str); Assert(pADamages); - ATTRIBUTES *pACurBort = pABorts->FindAClass(pABorts, (char *)pBort->sName.c_str()); + ATTRIBUTES *pACurBort = pABorts->FindAClass(pABorts, bort.sName.c_str()); Assert(pACurBort); - for (j = 0; j < pBort->aCannons.size(); j++) + for (uint32_t j = 0; j < bort.aCannons.size(); j++) { - AICannon *pC = &pBort->aCannons[j]; + AICannon *pC = &bort.aCannons[j]; if (pC->isDamaged()) continue; CVECTOR vCPos = pC->GetPos() - pC->GetDir() * fMaxCannonDamageRadiusPoint; @@ -845,10 +864,10 @@ void AIShipCannonController::CheckCannonsBoom(float fTmpCannonDamage, const CVEC if (pC->isDamaged()) { pACurBort->SetAttributeUseFloat("DamageRatio", - 1.0f - (static_cast(GetBortIntactCannonsNum(i)) + - static_cast(GetBortDisabledCannonsNum(i))) / - static_cast(pBort->aCannons.size())); - // pBort->dwNumDamagedCannons++; + 1.0f - (static_cast(GetBortIntactCannonsNum(bort)) + + static_cast(GetBortDisabledCannonsNum(bort))) / + static_cast(bort.aCannons.size())); + // aShipBorts[i].dwNumDamagedCannons++; // pACurBort->SetAttributeUseFloat("DamageRatio", // 1.0f - static_cast(GetBortIntactCannonsNum(i)) / // static_cast(pBort @@ -862,35 +881,35 @@ void AIShipCannonController::CheckCannonsBoom(float fTmpCannonDamage, const CVEC void AIShipCannonController::ResearchCannons() { char str[512]; - uint32_t i, j; ATTRIBUTES *pACharacter = GetAIShip()->GetACharacter(); ATTRIBUTES *pABorts = pACharacter->FindAClass(pACharacter, "Ship.Cannons.Borts"); Assert(pABorts); - for (i = 0; i < aShipBorts.size(); i++) + for (auto &aShipBort : aShipBorts) { - AISHIP_BORT *pBort = &aShipBorts[i]; + AISHIP_BORT *pBort = &aShipBort; - sprintf_s(str, "%s.damages", (char *)pBort->sName.c_str()); + sprintf_s(str, "%s.damages", aShipBort.sName.c_str()); ATTRIBUTES *pADamages = pABorts->FindAClass(pABorts, str); Assert(pADamages); - ATTRIBUTES *pACurBort = pABorts->FindAClass(pABorts, (char *)pBort->sName.c_str()); + ATTRIBUTES *pACurBort = pABorts->FindAClass(pABorts, aShipBort.sName.c_str()); Assert(pACurBort); - pBort->dwNumDamagedCannons = 0; // not used anywhere, maybe a rudiment? + aShipBort.dwNumDamagedCannons = 0; // not used anywhere, maybe a rudiment? - for (j = 0; j < pBort->aCannons.size(); j++) + for (uint32_t j = 0; j < aShipBort.aCannons.size(); j++) { - AICannon *pC = &pBort->aCannons[j]; + AICannon *pC = &aShipBort.aCannons[j]; sprintf_s(str, "c%d", j); const float fDamage = pADamages->GetAttributeAsFloat(str, 0.0f); pC->SetDamage(fDamage); pADamages->SetAttributeUseFloat(str, pC->GetDamage()); if (pC->isDamaged()) { - pBort->dwNumDamagedCannons++; - pACurBort->SetAttributeUseFloat("DamageRatio", 1.0f - static_cast(GetBortIntactCannonsNum(i)) / - static_cast(pBort->aCannons.size())); + aShipBort.dwNumDamagedCannons++; + pACurBort->SetAttributeUseFloat("DamageRatio", + 1.0f - static_cast(GetBortIntactCannonsNum(aShipBort)) / + static_cast(aShipBort.aCannons.size())); } } } @@ -902,13 +921,11 @@ void AIShipCannonController::Save(CSaveLoad *pSL) { pSL->SaveDword(bReload); pSL->SaveDword(bNotEnoughBalls); - pSL->SaveDword(bTempFlag); + pSL->SaveDword({}); // TODO: $core-state-legacy pSL->SaveDword(aShipBorts.size()); - for (uint32_t i = 0; i < aShipBorts.size(); i++) + for (auto &B : aShipBorts) { - AISHIP_BORT &B = aShipBorts[i]; - pSL->SaveString(B.sName); pSL->SaveFloat(B.fFireZone); pSL->SaveFloat(B.fFireAngMin); @@ -924,8 +941,10 @@ void AIShipCannonController::Save(CSaveLoad *pSL) pSL->SaveVector(B.vDirection); pSL->SaveDword(B.aCannons.size()); - for (uint32_t j = 0; j < B.aCannons.size(); j++) - B.aCannons[j].Save(pSL); + for (auto &aCannon : B.aCannons) + { + aCannon.Save(pSL); + } } } @@ -933,13 +952,12 @@ void AIShipCannonController::Load(CSaveLoad *pSL) { bReload = pSL->LoadDword() != 0; bNotEnoughBalls = pSL->LoadDword() != 0; - bTempFlag = pSL->LoadDword() != 0; + pSL->LoadDword(); // TODO: $core-state-legacy const uint32_t dwNum = pSL->LoadDword(); for (uint32_t i = 0; i < dwNum; i++) { - aShipBorts.push_back(AISHIP_BORT{}); - // AISHIP_BORT & B = aShipBorts[aShipBorts.Add()]; + aShipBorts.emplace_back(); AISHIP_BORT &B = aShipBorts.back(); B.sName = pSL->LoadString(); @@ -959,7 +977,7 @@ void AIShipCannonController::Load(CSaveLoad *pSL) const uint32_t dwNumCannons = pSL->LoadDword(); for (uint32_t j = 0; j < dwNumCannons; j++) { - B.aCannons.push_back(AICannon{}); + B.aCannons.emplace_back(); B.aCannons.back().Load(pSL, GetAIShip(), GetAIShip()->GetShipEID()); } } diff --git a/src/libs/sea_ai/src/ai_ship_cannon_controller.h b/src/libs/sea_ai/src/ai_ship_cannon_controller.h index 8e46a176a..a0bdc6b9c 100644 --- a/src/libs/sea_ai/src/ai_ship_cannon_controller.h +++ b/src/libs/sea_ai/src/ai_ship_cannon_controller.h @@ -12,15 +12,15 @@ class VAI_INNEROBJ; class AIShipCannonController { private: - AIShip *pOurAIShip; + AIShip *pOurAIShip{}; - ATTRIBUTES *pAShip; + ATTRIBUTES *pAShip{}; bool bReload; // we must start reload at next frame bool bNotEnoughBalls; // if we haven't enough balls - bool bTempFlag; - RS_RECT rs; + bool debugDrawToggle{false}; + std::vector> debugFirePositions; private: struct AISHIP_BORT @@ -46,23 +46,23 @@ class AIShipCannonController void ClearCharge() { fChargePercent = 0.0f; - }; + } - bool isCharged() const + [[nodiscard]] bool isCharged() const { return fChargePercent >= 1.0f; - }; + } - bool isBortDamaged() const + [[nodiscard]] bool isBortDamaged() const { return dwNumDamagedCannons == aCannons.size(); } AISHIP_BORT() + : fOurBortFireHeight(0.0f) { ClearCharge(); - fOurBortFireHeight = 0.0f; - }; + } int operator==(const char *pStr) const { @@ -79,32 +79,40 @@ class AIShipCannonController bool ScanShipForCannons(); - bool Fire2Position(uint32_t dwBort, const CVECTOR &vFirePos, float fFireHeight); + bool Fire2Position(AISHIP_BORT &bort, const CVECTOR &vFirePos, float fFireHeight); - float GetSpeedV0(); + [[nodiscard]] float GetSpeedV0() const; public: - uint32_t GetCannonsNum(); + [[nodiscard]] uint32_t GetCannonsNum() const; - float GetFireDistance(bool bMaxFireDistance); + [[nodiscard]] float GetFireDistance(bool bMaxFireDistance) const; // bort section - float GetBortHeightAngle(int32_t iBortIndex); - bool isCanFireBort(uint32_t dwBort, const CVECTOR &vFirePos, float *pfZapasDistance = nullptr); - uint32_t GetFirstFireBort(const CVECTOR &vFirePos, float *pfZapasDistance = nullptr); - bool isHaveEnoughtBallsForBort(uint32_t dwBortIdx); - uint32_t GetNextFireBort(uint32_t dwPrevBort, const CVECTOR &vFirePos, float *pfZapasDistance = nullptr); - CVECTOR GetBortDirection(uint32_t dwBort); - uint32_t GetBestFireBortOnlyDistance(CVECTOR vFirePos, float fZapasDistance); + [[nodiscard]] decltype(aShipBorts)::iterator GetFirstFireBort(const CVECTOR &vFirePos, + float *pfZapasDistance = nullptr); + [[nodiscard]] decltype(aShipBorts)::iterator GetNextFireBort(decltype(aShipBorts)::iterator bortIt, + const CVECTOR &vFirePos, + float *pfZapasDistance = nullptr); + [[nodiscard]] bool IsValid(decltype(aShipBorts)::const_iterator bortIt) const; + + [[nodiscard]] float GetBortHeightAngle(const AISHIP_BORT &bort) const; + [[nodiscard]] bool isCanFireBort(const AISHIP_BORT &bort, const CVECTOR &vFirePos, + float *pfZapasDistance = nullptr) const; + [[nodiscard]] bool isHaveEnoughBallsForBort(const AISHIP_BORT &bort) const; + + [[nodiscard]] CVECTOR GetBortDirection(const AISHIP_BORT &bort) const; + [[nodiscard]] decltype(aShipBorts)::iterator GetBestFireBortOnlyDistance(CVECTOR vFirePos, + float fZapasDistance); CVECTOR GetFirePos(const CVECTOR &vFireDir); CVECTOR GetFirePos(const CVECTOR &vFireDir, float fDistance); - uint32_t GetBortIntactCannonsNum(uint32_t dwBortIdx); - uint32_t GetBortDisabledCannonsNum(uint32_t dwBortIdx); + [[nodiscard]] uint32_t GetBortIntactCannonsNum(const AISHIP_BORT &bort) const; + [[nodiscard]] uint32_t GetBortDisabledCannonsNum(const AISHIP_BORT &bort) const; // fire test - bool isCanFirePos(const CVECTOR &vFirePos); // is we can fire to position - bool isCanFire(AIShip *pEnemy); // is we can fire to enemy ship - bool isCanFire(const CVECTOR &vCamDir); // is we can fire to camera direction + bool isCanFirePos(const CVECTOR &vFirePos); // is we can fire to position + bool isCanFire(AIShip *pEnemy); // is we can fire to enemy ship + [[nodiscard]] bool isCanFire(const CVECTOR &vCamDir) const; // is we can fire to camera direction // fire section bool Fire(const CVECTOR &vFirePos); // fire to position @@ -114,11 +122,7 @@ class AIShipCannonController // reload section void Unload(); // unload cannons void Reload(); // set flag to reload - - // temp - void AddTrg(CVECTOR *pVerts, uint32_t dwColor); - // temp - + // Cannon boom check void CheckCannonsBoom(float fTmpCannonDamage, const CVECTOR &vPnt); void ResearchCannons(); // boal 08.08.06 method of recalculating guns on a ship @@ -135,18 +139,17 @@ class AIShipCannonController pOurAIShip = pShip; } - AIShip *GetAIShip() const + [[nodiscard]] AIShip *GetAIShip() const { return pOurAIShip; } // default constructor/destructor AIShipCannonController(AIShip *); - ~AIShipCannonController(); static float fMaxCannonDamageDistance; static float fMaxCannonDamageRadiusPoint; void Save(CSaveLoad *pSL); void Load(CSaveLoad *pSL); -}; +}; \ No newline at end of file diff --git a/src/libs/sea_ai/src/ai_ship_task_controller.cpp b/src/libs/sea_ai/src/ai_ship_task_controller.cpp index 79df127fd..1b0220d4a 100644 --- a/src/libs/sea_ai/src/ai_ship_task_controller.cpp +++ b/src/libs/sea_ai/src/ai_ship_task_controller.cpp @@ -50,11 +50,10 @@ void AIShipTaskController::DoAttackRotate() auto *pCC = GetAIShip()->GetCannonController(); - const auto dwBort = pCC->GetBestFireBortOnlyDistance(vFirePos, 20.0f + FRAND(50.0f)); - - if (INVALID_BORT_INDEX != dwBort) + const auto bortIt = pCC->GetBestFireBortOnlyDistance(vFirePos, 20.0f + FRAND(50.0f)); + if (pCC->IsValid(bortIt)) { - const auto vBortDir = pCC->GetBortDirection(dwBort); + const auto vBortDir = pCC->GetBortDirection(*bortIt); const auto fRotate = ((vBortDir | vOurDir) > 0.0f) ? -1.2f : 1.2f; GetAIShip()->GetRotateController()->AddRotate(fRotate); GetAIShip()->GetSpeedController()->AddSpeed(0.5f); @@ -71,16 +70,18 @@ void AIShipTaskController::FindRunAwayPoint() const auto fWindK = 10.0f; // impact factor for wind // check ships - for (uint32_t i = 0; i < AIShip::AIShips.size(); i++) - if (GetAIShip() != AIShip::AIShips[i]) + for (auto &i : AIShip::AIShips) + { + if (GetAIShip() != i) { - if (!Helper.isEnemy(AIShip::AIShips[i]->GetACharacter(), GetAIShip()->GetACharacter())) + if (!Helper.isEnemy(i->GetACharacter(), GetAIShip()->GetACharacter())) continue; - auto vDir = AIShip::AIShips[i]->GetPos() - GetAIShip()->GetPos(); + auto vDir = i->GetPos() - GetAIShip()->GetPos(); const auto fDistance = sqrtf(~vDir); vRAPoint += ((!vDir) * fShipK * Clamp(1.0f - fDistance / 1000.0f)); iNumPoints++; } + } // check forts if (AIFort::pAIFort) diff --git a/src/libs/sea_ai/src/ai_ship_touch_controller.cpp b/src/libs/sea_ai/src/ai_ship_touch_controller.cpp index ea010270e..e50e83c8e 100644 --- a/src/libs/sea_ai/src/ai_ship_touch_controller.cpp +++ b/src/libs/sea_ai/src/ai_ship_touch_controller.cpp @@ -46,8 +46,8 @@ CVECTOR *AIShipTouchController::GetPentagonBox() vBox[2] = CVECTOR(vBoxSize.x, 0.0f, vBoxSize.z / 1.5f); vBox[3] = CVECTOR(0.0f, 0.0f, vBoxSize.z); vBox[4] = CVECTOR(-vBoxSize.x, 0.0f, vBoxSize.z / 1.5f); - for (uint32_t i = 0; i < 5; i++) - vBox[i] = vOurPos + m * vBox[i]; + for (auto &i : vBox) + i = vOurPos + m * i; return &vBox[0]; } @@ -245,19 +245,19 @@ void AIShipTouchController::Realize(float fDeltaTime) void AIShipTouchController::Save(CSaveLoad *pSL) { pSL->SaveDword(aTouchRays.size()); - for (uint32_t i = 0; i < aTouchRays.size(); i++) + for (auto &aTouchRay : aTouchRays) { - pSL->SaveFloat(aTouchRays[i].fMinDist); - pSL->SaveFloat(aTouchRays[i].fDist); - pSL->SaveFloat(aTouchRays[i].fEarthDist); + pSL->SaveFloat(aTouchRay.fMinDist); + pSL->SaveFloat(aTouchRay.fDist); + pSL->SaveFloat(aTouchRay.fEarthDist); } pSL->SaveFloat(fLeftRaysFree); pSL->SaveFloat(fRightRaysFree); pSL->SaveFloat(fRaySize); pSL->SaveFloat(fSpeedFactor); pSL->SaveFloat(fRotateFactor); - for (uint32_t i = 0; i < 5; i++) - pSL->SaveVector(vBox[i]); + for (auto i : vBox) + pSL->SaveVector(i); } void AIShipTouchController::Load(CSaveLoad *pSL) @@ -270,6 +270,6 @@ void AIShipTouchController::Load(CSaveLoad *pSL) fRaySize = pSL->LoadFloat(); fSpeedFactor = pSL->LoadFloat(); fRotateFactor = pSL->LoadFloat(); - for (uint32_t i = 0; i < 5; i++) - vBox[i] = pSL->LoadVector(); + for (auto &i : vBox) + i = pSL->LoadVector(); } diff --git a/src/libs/sea_ai/src/sea_ai.cpp b/src/libs/sea_ai/src/sea_ai.cpp index 40d50b043..2dcbf90ae 100644 --- a/src/libs/sea_ai/src/sea_ai.cpp +++ b/src/libs/sea_ai/src/sea_ai.cpp @@ -15,8 +15,8 @@ SEA_AI::SEA_AI() SEA_AI::~SEA_AI() { - for (uint32_t i = 0; i < AIGroup::AIGroups.size(); i++) - STORM_DELETE(AIGroup::AIGroups[i]); + for (auto &i : AIGroup::AIGroups) + STORM_DELETE(i); AIGroup::AIGroups.clear(); AIShip::AIShips.clear(); Helper.Uninit(); @@ -45,9 +45,9 @@ void SEA_AI::Execute(uint32_t Delta_Time) bFirstInit = false; } - for (uint32_t i = 0; i < AIGroup::AIGroups.size(); i++) + for (auto &i : AIGroup::AIGroups) { - AIGroup::AIGroups[i]->Execute(fDeltaTime); + i->Execute(fDeltaTime); } RDTSC_E(dwRDTSC); @@ -58,9 +58,9 @@ extern uint32_t dwTotal; void SEA_AI::Realize(uint32_t Delta_Time) { const auto fDeltaTime = 0.001f * static_cast(Delta_Time); - for (uint32_t i = 0; i < AIGroup::AIGroups.size(); i++) + for (auto &i : AIGroup::AIGroups) { - AIGroup::AIGroups[i]->Realize(fDeltaTime); + i->Realize(fDeltaTime); } // core.Trace("%d",dwTotal); // AIHelper::pRS->Print(0,90,"%d",dwRDTSC);//dwTotal); @@ -364,8 +364,8 @@ void SEA_AI::Save(const char *pStr) AIBalls::pAIBalls->Save(&SL); SL.SaveDword(AIGroup::AIGroups.size()); - for (uint32_t i = 0; i < AIGroup::AIGroups.size(); i++) - AIGroup::AIGroups[i]->Save(&SL); + for (auto &i : AIGroup::AIGroups) + i->Save(&SL); if (AIFort::pAIFort) AIFort::pAIFort->Save(&SL);