|
| 1 | +#include <plugin.h> // Plugin-SDK version 1002 from 2025-12-09 23:18:09 |
| 2 | +#include <CDecisionMakerTypes.h> |
| 3 | +#include <CCivilianPed.h> |
| 4 | +#include <CStreaming.h> |
| 5 | +#include <CWorld.h> |
| 6 | + |
| 7 | +using namespace plugin; |
| 8 | + |
| 9 | +struct Main |
| 10 | +{ |
| 11 | + bool initialized = false; |
| 12 | + |
| 13 | + CPed* ped = nullptr; |
| 14 | + eDecisionMakerType decisionMakerHandle = eDecisionMakerType::UNKNOWN; |
| 15 | + |
| 16 | + Main() |
| 17 | + { |
| 18 | + // register event callbacks |
| 19 | + Events::restartGameEvent += []{ gInstance.OnGameRestart(); }; |
| 20 | + Events::gameProcessEvent += []{ gInstance.OnGameProcess(); }; |
| 21 | + } |
| 22 | + |
| 23 | + void OnGameRestart() |
| 24 | + { |
| 25 | + initialized = false; |
| 26 | + // our Ped and DecisionMaker will be removed by game itself |
| 27 | + } |
| 28 | + |
| 29 | + void OnGameProcess() |
| 30 | + { |
| 31 | + if (!initialized) |
| 32 | + { |
| 33 | + // create decision maker |
| 34 | + auto dmManager = CDecisionMakerTypes::GetInstance(); |
| 35 | + if (!dmManager) return; // try again later |
| 36 | + |
| 37 | + CDecisionMaker templateDm; // empty |
| 38 | + decisionMakerHandle = dmManager->AddDecisionMaker(&templateDm); |
| 39 | + |
| 40 | + if (decisionMakerHandle != eDecisionMakerType::UNKNOWN) // take note the game only has 10 slots for custom DMs |
| 41 | + { |
| 42 | + dmManager->AddEventResponse(decisionMakerHandle, eEventType::EVENT_GUN_AIMED_AT, |
| 43 | + eTaskType::TASK_SIMPLE_HANDS_UP, |
| 44 | + DecisionChances(4, 4, 4, 4), // 4/5 chance |
| 45 | + DecisionContext(true, false) |
| 46 | + ); |
| 47 | + |
| 48 | + dmManager->AddEventResponse(decisionMakerHandle, eEventType::EVENT_GUN_AIMED_AT, |
| 49 | + eTaskType::TASK_SIMPLE_DUCK, |
| 50 | + DecisionChances(1, 1, 1, 1), // 1/5 chance |
| 51 | + DecisionContext(true, false) |
| 52 | + ); |
| 53 | + } |
| 54 | + |
| 55 | + // create ped |
| 56 | + constexpr auto MODEL = 70; // scientist |
| 57 | + CStreaming::RequestModel(MODEL, eStreamingFlags::PRIORITY_REQUEST); |
| 58 | + CStreaming::LoadAllRequestedModels(true); |
| 59 | + ped = new CCivilianPed(PED_TYPE_CIVMALE, MODEL); |
| 60 | + |
| 61 | + if (!ped) return; // try again later |
| 62 | + |
| 63 | + ped->SetPosn(FindPlayerPed()->TransformFromObjectSpace(CVector(0.0f, 3.0f, 0.0f))); |
| 64 | + ped->SetOrientation(0.0f, 0.0f, 0.0f); |
| 65 | + CWorld::Add(ped); |
| 66 | + ped->PositionAnyPedOutOfCollision(); |
| 67 | + |
| 68 | + ped->m_fMaxHealth = ped->m_fHealth = 1000.0f; // stronger for tests |
| 69 | + |
| 70 | + if (ped->m_pIntelligence) |
| 71 | + { |
| 72 | + ped->m_pIntelligence->SetPedDecisionMakerType(decisionMakerHandle); |
| 73 | + } |
| 74 | + |
| 75 | + initialized = true; |
| 76 | + } |
| 77 | + } |
| 78 | +} gInstance; |
0 commit comments