|
| 1 | +#include "util/EffectBase.h" |
| 2 | +#include "util/GenericUtil.h" |
| 3 | + |
| 4 | +#include <extensions/ScriptCommands.h> |
| 5 | + |
| 6 | +using namespace plugin; |
| 7 | + |
| 8 | +class CJ101Effect : public EffectBase |
| 9 | +{ |
| 10 | +private: |
| 11 | + const int MIN_SPAWN_SEC = 8; |
| 12 | + const int MAX_SPAWN_SEC = 13; |
| 13 | + const int planesId[5] = {511, 512, 476, 593, 513}; |
| 14 | + int timer = 0; |
| 15 | + int planeSpawnTimer = 0; |
| 16 | + |
| 17 | +public: |
| 18 | + bool |
| 19 | + CanActivate () override |
| 20 | + { |
| 21 | + auto *player = FindPlayerPed (); |
| 22 | + return player && !player->m_nAreaCode && GameUtil::IsPlayerSafe (); |
| 23 | + } |
| 24 | + |
| 25 | + void |
| 26 | + OnStart (EffectInstance *inst) override |
| 27 | + { |
| 28 | + timer = 0; |
| 29 | + planeSpawnTimer = inst->Random (MIN_SPAWN_SEC, MAX_SPAWN_SEC) * 1000; |
| 30 | + } |
| 31 | + |
| 32 | + void |
| 33 | + OnTick (EffectInstance *inst) override |
| 34 | + { |
| 35 | + if (!CanActivate ()) return; |
| 36 | + auto *player = FindPlayerPed (); |
| 37 | + |
| 38 | + timer += int (GenericUtil::CalculateTick ()); |
| 39 | + if (timer >= planeSpawnTimer) |
| 40 | + { |
| 41 | + int id = planesId[inst->Random (0, 10000) % std::size (planesId)]; |
| 42 | + auto playerPos = player->GetPosition (); |
| 43 | + auto [pos, angle] |
| 44 | + = GetPositionAndHeading (playerPos, player->GetHeading (), |
| 45 | + inst->Random (0, 1)); |
| 46 | + |
| 47 | + pos.z += inst->Random (0, 5); |
| 48 | + auto *plane = reinterpret_cast<CPlane *> ( |
| 49 | + GameUtil::CreateVehicle (id, pos, angle, true)); |
| 50 | + |
| 51 | + float force = inst->Random (0.8f, 1.1f); |
| 52 | + plane->m_vecMoveSpeed.x = -std::sin (angle) * force; |
| 53 | + plane->m_vecMoveSpeed.y = std::cos (angle) * force; |
| 54 | + plane->SetHeading (angle); |
| 55 | + |
| 56 | + Command<eScriptCommands::COMMAND_PLANE_GOTO_COORDS> ( |
| 57 | + plane, playerPos.x, playerPos.y, playerPos.z, 0.0f, 0.0f); |
| 58 | + |
| 59 | + if (id == 476) plane->SetGearUp (); |
| 60 | + |
| 61 | + plane->m_fHealth = 249.0f; |
| 62 | + |
| 63 | + timer -= inst->Random (MIN_SPAWN_SEC, MAX_SPAWN_SEC) * 1000; |
| 64 | + } |
| 65 | + } |
| 66 | + |
| 67 | + std::pair<CVector, float> |
| 68 | + GetPositionAndHeading (const CVector &playerPos, float playerAngle, |
| 69 | + bool getBehind) |
| 70 | + { |
| 71 | + float dirX = 100.0f * -std::sin (playerAngle); |
| 72 | + float dirY = 100.0f * std::cos (playerAngle); |
| 73 | + |
| 74 | + if (getBehind) |
| 75 | + { |
| 76 | + float posX = playerPos.x - dirX; |
| 77 | + float posY = playerPos.y - dirY; |
| 78 | + float posZ = CWorld::FindGroundZForCoord (posX, posY); |
| 79 | + return {{posX, posY, posZ}, playerAngle}; |
| 80 | + } |
| 81 | + else |
| 82 | + { |
| 83 | + float posX = playerPos.x + dirX; |
| 84 | + float posY = playerPos.y + dirY; |
| 85 | + float posZ = CWorld::FindGroundZForCoord (posX, posY); |
| 86 | + playerAngle -= M_PI; |
| 87 | + return {{posX, posY, posZ}, playerAngle}; |
| 88 | + } |
| 89 | + } |
| 90 | +}; |
| 91 | + |
| 92 | +DEFINE_EFFECT (CJ101Effect, "effect_cj101", 0); |
0 commit comments