GTA Builder Форум

GTA Vice City => Общие вопросы => Тема начата: Jak łaska za praca от Апрель 08, 2015, 06:51:47 pm

Название: Как перебрать все обьекты в игре?
Отправлено: Jak łaska za praca от Апрель 08, 2015, 06:51:47 pm
Как перебрать все объекты в игре?
Как убивать их, или что будет если убрать объект из списка а затем вернуть в список?
Название: Re: Как перебрать все обьекты в игре?
Отправлено: Sektor от Апрель 08, 2015, 07:04:42 pm
Все объекты, это которые? Зачем таким заниматься. Там по моему нет понятие списки, там есть пулы.
Название: Re: Как перебрать все обьекты в игре?
Отправлено: Jak łaska za praca от Апрель 08, 2015, 11:05:17 pm
Я хотел перебрать все Vehicle но сформулировал неудачно. =)
А в пуле указатели или память уже подготовленая.
Название: Re: Как перебрать все обьекты в игре?
Отправлено: Sektor от Апрель 09, 2015, 12:39:43 am
Ну так в слепую не чего, не сказать. Надо как минимум порыться там.
Название: Re: Как перебрать все обьекты в игре?
Отправлено: xanser от Апрель 12, 2015, 08:39:15 pm
Примерно так можно перебрать всех:

Код: C++
  1. struct  CPool
  2. {
  3.         DWORD   objects;
  4.         DWORD   flags;
  5.         DWORD   size;
  6.         DWORD   top;
  7. };
  8.  
  9. auto    PedPool         = (CPool **)    0x97F2AC;
  10. auto    VehiclePool     = (CPool **)    0xA0FDE4;
  11.  
  12. void TrafficProcess()
  13. {
  14.         ClosestVehicle = 0;
  15.         float Radius, ClosestRadius = 9999;
  16.  
  17. // перебор всех машин
  18.         CAutomobile *TrafficVehicle = (CAutomobile *)VehiclePool[0]->objects;
  19.         for (DWORD i=0;i<VehiclePool[0]->size;i++)
  20.         {
  21.                 TrafficCarProcess(&TrafficVehicle[i].Vehicle); // получили указатель СVehicle, делаем с ним что хотим в TrafficCarProcess()
  22.  
  23.                 // PlayerPed у меня класса CPed
  24.                 Radius = pow(PlayerPed->physical.entity.matrix.rw.pos.x-TrafficVehicle[i].Vehicle.physical.entity.matrix.rw.pos.x,2)+
  25.                                  pow(PlayerPed->physical.entity.matrix.rw.pos.y-TrafficVehicle[i].Vehicle.physical.entity.matrix.rw.pos.y,2);
  26.                 if (Radius<min(ClosestRadius,50))
  27.                 {
  28.                         ClosestRadius  = Radius;
  29.                         ClosestVehicle = &TrafficVehicle[i].Vehicle; // поиск ближайшего авто
  30.                 }
  31.         }
  32. //      ClosestVehicle ближнее авто
  33.  
  34. // перебор всех людей
  35.         CPlayerPed *TrafficPed = (CPlayerPed *)PedPool[0]->objects;
  36.         for (DWORD i=0;i<PedPool[0]->size;i++)
  37.         {
  38.                 TrafficPedProcess(&TrafficPed[i].Ped); // получили указатель CPed, делаем с ним что хотим в TrafficPedProcess()
  39.         }
  40.         for (int i=1;i<PlayerPed->closestPedsCount;i++) // *0x56C*      CPed            *closestPeds[10];
  41.         {
  42.                 PlayerPed->closestPeds[i-1]; // ближние к игроку люди
  43.         }
  44. }
Название: Re: Как перебрать все обьекты в игре?
Отправлено: Jak łaska za praca от Апрель 14, 2015, 02:37:58 am
А чем отличается CAutomobile от CVehicle. CAutomobile это дополнительное описание для CVehicle ( как автомобиль игрока )?
Название: Re: Как перебрать все обьекты в игре?
Отправлено: xanser от Апрель 14, 2015, 05:07:08 am
Глянь эти структуры в IDA, CVehicle это любой транспорт, которым может быть автомобиль CAutomobile, лодка CBoat, вертолет CHeli и т.д. Соответственно все эти классы включают в себя CVehicle в качестве общих характеристик транспорта, плюс дополнительные для каждого класса свойства.

P.S. Я использовал тут классы CAutomobile и CPlayerPed (лучше сказать структуры), потому что в пуле, как я понял, смещение по элементам идет именно на размер таких структур, т.е. чтобы тупо построить цикл.
Название: Re: Как перебрать все обьекты в игре?
Отправлено: Sektor от Апрель 14, 2015, 03:14:44 pm
Цитировать
А чем отличается CAutomobile от CVehicle

Код: C++
  1. class CAutomobile : public CVehicle

Наследованный класс. Только имей введу, если будешь делать наследование, удали это поле:

Код: C++
  1.  CVehicle __parent; // - именно вот это.
Название: Re: Как перебрать все обьекты в игре?
Отправлено: Jak łaska za praca от Апрель 16, 2015, 03:44:48 am
В hGta.h от Sector'a CAutomobile нету где кто кому не жалко киньте наработки если хотите в Личку.
Хотя тут вроде все хорошо https://code.google.com/p/vice-players/source/browse/#svn%2Ftrunk%2FClient (https://code.google.com/p/vice-players/source/browse/#svn%2Ftrunk%2FClient) .
Название: Re: Как перебрать все обьекты в игре?
Отправлено: Sektor от Апрель 17, 2015, 01:18:35 am
Могу только в кратце, потому-что столько всего тащить предаться, мама, не горюй:


Код: C++
  1.  
  2. #pragma pack(push, 1)
  3.  
  4. class CVehicle : public CPhysical
  5. {
  6.  
  7. public:
  8.   CHandlingVehicle *pVehicleHandling;
  9.   CHandlingFlying *pFlyingHandling;
  10.   CVehicleAI vehicleAI;
  11.   char primaryColor;
  12.   char secondaryColor;
  13.   char tertiaryColor;
  14.   char quaternaryColor;
  15.   WORD field_1A4;
  16.   WORD field_1A6;
  17.   CPed *pDriver;
  18.   DWORD passangers[8];
  19.   BYTE numOfPassangers;
  20.   BYTE field_1CD;
  21.   BYTE field_1CE;
  22.   BYTE field_1CF;
  23.   BYTE maxPassangers;
  24.   char gap_1d1[19];
  25.   DWORD field_1E4;
  26.   DWORD fire;
  27.   int field_1EC;
  28.   int field_1F0;
  29.   int field_1F4;
  30.   BYTE reference;
  31.   BYTE flags;
  32.   BYTE flags2;
  33.   BYTE modelFlags;
  34.   BYTE field_1FC;
  35.   BYTE field_1FD;
  36.   BYTE field_1FE;
  37.   BYTE field_1FF;
  38.   char field_200;
  39.   BYTE field_201;
  40.   char gap_202[2];
  41.   DWORD health;
  42.   DWORD field_208;
  43.   DWORD field_20C;
  44.   DWORD field_210;
  45.   DWORD field_214;
  46.   DWORD field_218;
  47.   DWORD field_21C;
  48.   WORD field_220;
  49.   WORD field_222;
  50.   DWORD field_224;
  51.   DWORD field_228;
  52.   DWORD field_22C;
  53.   DWORD doorStatus;
  54.   BYTE lastDamageType;
  55.   char gap_235[3];
  56.   DWORD field_238;
  57.   BYTE field_23C;
  58.   BYTE field_23D;
  59.   BYTE field_23E;
  60.   char gap_23f[1];
  61.   DWORD horn;
  62.   BYTE field_244;
  63.   BYTE sirenOn;
  64.   BYTE field_246;
  65.   BYTE field_247;
  66.   char field_248[80];
  67.   DWORD field_298;
  68.   DWORD carType;
  69. };
  70.  
  71.  
  72.  
  73. struct CAutomobile : public CVehicle
  74. {
  75.   CDamageManager damageManager;
  76.   char field_2B8;
  77.   char gap_2b9[3];
  78.   CAutomobileDoor doors[6];
  79.   CNode *automobileNodes[20];
  80.   int field_3E4[40];
  81.   int field_484[4];
  82.   int field_494[4];
  83.   int field_4A4[4];
  84.   int field_4B4;
  85.   int field_4B8[4];
  86.   char field_4C8[4];
  87.   char gap_4cc[4];
  88.   int field_4D0[4];
  89.   int field_4E0[4];
  90.   int field_4F0;
  91.   int field_4F4;
  92.   char gap_4f8[8];
  93.   char field_500;
  94.   char flags;
  95.   char field_502;
  96.   char gap_503[1];
  97.   __int16 field_504;
  98.   __int16 field_506;
  99.   int field_508;
  100.   int field_50C;
  101.   int field_510;
  102.   char gap_514[28];
  103.   int field_530;
  104.   int field_534;
  105.   int field_538;
  106.   float field_53C;
  107.   int field_540;
  108.   int field_544;
  109.   int field_548[6];
  110.   int field_560;
  111.   int field_564[4];
  112.   RwV3d field_574[4];
  113.   int field_5A4;
  114.   int field_5A8;
  115.   int field_5AC;
  116.   int field_5B0;
  117.   int field_5B4;
  118.   int field_5B8;
  119.   int field_5BC;
  120.   char gap_5c0[4];
  121.   char field_5C4;
  122.   char field_5C5;
  123.   char field_5C6;
  124.   char gap_5c7[1];
  125.   int field_5C8;
  126.   int field_5CC[4];
  127. };
  128. #pragma pack(pop)
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
Название: Re: Как перебрать все обьекты в игре?
Отправлено: xanser от Май 16, 2015, 09:43:45 pm
Можно попробовать еще такой вариант. Ничего не перебирать, игра и так постоянно это делает в таких функциях как например 0x589AD0 CAutomobile::PreRender(), достаточно внедриться туда и проверить id модели, а дальше делать с ней что угодно, ну или полностью переписать эту функцию, расширив под свои нужды. Для педов и всего остального тоже наверняка есть такие функции Render и PreRender. И скорее всего все эти функции вызываются для существующих объектов, то есть нет необходимости проверять, что объект не пропал.
Название: Re: Как перебрать все обьекты в игре?
Отправлено: Jak łaska za praca от Май 23, 2015, 03:55:41 am
Код: C++
  1. void FrameProcess()
  2. {
  3.     CAutomobile *TrafficVehicle = (CAutomobile *)VehiclePool[0]->objects;
  4.     for (dword i=0;i<VehiclePool[0]->size;i++)
  5.     {
  6.         CEdict *pEdict = NetVehiclePool->at( (int)i );
  7.  
  8.         if ( pEdict )
  9.         {
  10.             if ( &TrafficVehicle[i].Vehicle != (CNetVehicle *)pEdict->pvPrivateData->pVehicle )
  11.             {
  12.                 (CNetVehicle *)pEdict->pvPrivateData->Distroy();
  13.                 CNetVehicle::SpawnFromTraffic( pEdict, &TrafficVehicle[i].Vehicle );
  14.             }
  15.         }
  16.         else
  17.         {
  18.             pEdict = NetVehiclePool->CreateEdict( (int) i );
  19.             CNetVehicle::SpawnFromTraffic( pEdict, &TrafficVehicle[i].Vehicle );
  20.         }
  21.     }
  22.  
  23.     CPlayerPed *TrafficPed = (CPlayerPed *)PedPool[0]->objects;
  24.     for (dword i=0;i<PedPool[0]->size; i++)
  25.     {
  26.         CEdict *pEdict = NetPedPool->at( (int)i );
  27.  
  28.         if ( pEdict )
  29.         {
  30.             if ( &TrafficPed[i].Ped != (CNetPed *)pEdict->pvPrivateData->pPed )
  31.             {
  32.                 (CNetPed *)pEdict->pvPrivateData->Distroy();
  33.                 CNetPed::SpawnFromTraffic( pEdict, &TrafficVehicle[i].Ped );
  34.             }
  35.         }
  36.         else
  37.         {
  38.             pEdict = NetPedPool->CreateEdict( (int) i );
  39.             CNetPed::SpawnFromTraffic( pEdict, &TrafficVehicle[i].Ped );
  40.         }
  41.     }
  42. }

Я не знаю поведение игры. Будет ли этот псевдокод код правильно работать?
Название: Re: Как перебрать все обьекты в игре?
Отправлено: Sektor от Май 23, 2015, 04:14:37 am
Прекрати мучатся, объяви пулы, таким образом:

CPools.h

Код: C++
  1.  
  2. #pragma pack(push, 1)
  3.  
  4. struct tPoolObjectFlags {
  5.   unsigned char  uID : 7;
  6.   unsigned char  bIsFreeSlot : 1;
  7. };
  8.  
  9. template<class A, class B = A> class CPool
  10. {
  11. public:
  12.   B * objects;
  13.   tPoolObjectFlags *flags;
  14.   DWORD size;
  15.   DWORD top;
  16. };
  17.  
  18. class CPools {
  19.  
  20. public:
  21.    static CPool<CPed, CPlayerPed> *& pPedPool;
  22.    static CPool<CVehicle, CAutomobile> *& pVehiclePool;
  23.    static CPool<CObject> *& pObjectPool;
  24.  
  25.    static CPed* GetPed(int);
  26.    static int   GetPedRef(CPed*);
  27.    static int   GetVehicleRef(CVehicle*);
  28.    static CVehicle* GetVehicle(int);
  29.    static CObject* GetObject(int);
  30.    static int GetObjectRef(CObject *);
  31. };
  32.  
  33. #pragma pack(pop)
  34.  

CPools.cpp

Код: C++
  1.  
  2. CPed * CPools::GetPed(int handle){
  3.         return ((CPed*(__cdecl*)(int))0x04C0000)(handle);
  4. }
  5.  
  6. // Get Ped Handle
  7. int CPools::GetPedRef(CPed * pPed){
  8.           return ((int (__cdecl*)(CPed*))0x04C0020)(pPed);
  9. }
  10.  
  11. CVehicle* CPools::GetVehicle(int handle){
  12.          return ((CVehicle*(__cdecl*)(int))0x04BFFC0)(handle);
  13. }
  14.  
  15. int CPools::GetVehicleRef(CVehicle* pVehicle){
  16.          return ((int (__cdecl*)(CVehicle*))0x04BFFE0)(pVehicle);
  17. }
  18.  
  19. CObject * CPools::GetObject(int handle){
  20.          return ((CObject *(__cdecl*)(int))0x04BFF80)(handle);
  21. }
  22.  
  23. int CPools::GetObjectRef(CObject * pObject){
  24.         return ((int (__cdecl*)(CObject *))0x04BFFA0)(pObject);
  25. }
  26.  
  27. CPool<CPed, CPlayerPed> *& CPools::pPedPool = *(CPool<CPed, CPlayerPed>**)0x097F2AC;
  28. CPool<CVehicle, CAutomobile> *& CPools::pVehiclePool = *(CPool<CVehicle, CAutomobile>**)0x0A0FDE4;
  29. CPool<CObject> *& CPools::pObjectPool = *(CPool<CObject> **)0x094DBE0;
  30.  
  31.  


А дальше работай:

Код: C++
  1. // С педами:
  2.  
  3.  
  4.         CPed *ped;
  5.  
  6.         for (int i = 0; i < CPools::pPedPool->size; i++) {
  7.                  ped = &CPools::pPedPool->objects[i];
  8.  
  9.                 if (!CPools::pPedPool->flags[i].bIsFreeSlot)
  10.                    {
  11.  
  12.                            if (ped->IsPlayer() == false)
  13.                              {
  14.                                 //Если пед не игрок, дальше че нибудь с педом делаем
  15.                                  ped->health = 0; // К примеру.
  16.                              }
  17.  
  18.                    }
  19.  
  20.                 }
  21.  
  22.  


Тоже самое и с транспортом:

Код: C++
  1. CVehicle * pVehicle;
  2.  
  3.         for (int i = 0; i < CPools::pVehiclePool->size; i++) {
  4.                  pVehicle = &CPools::pVehiclePool->objects[i];
  5.  
  6.                 if (!CPools::pVehiclePool->flags[i].bIsFreeSlot)
  7.                    {
  8.                       // Нашли машинку, можем с ней что нибудь делать.
  9.  
  10.                    }
  11.  
  12.                 }
Название: Re: Как перебрать все обьекты в игре?
Отправлено: Jak łaska za praca от Сентябрь 10, 2016, 09:44:06 pm
Если я увеличу размер выделенной памяти в ручную в CPool<CVehicle> *&ms_VehiclesPool; в игре появится возможность рождать больше транспорта или нет?
Рождать через опкод например.
Название: Re: Как перебрать все обьекты в игре?
Отправлено: Jak łaska za praca от Сентябрь 10, 2016, 10:39:56 pm
Где можно узнать номер и секвенцию анимации и главное изменить?
Название: Re: Как перебрать все обьекты в игре?
Отправлено: Shagg_E от Сентябрь 12, 2016, 08:31:41 pm
Если я увеличу размер выделенной памяти в ручную в CPool<CVehicle> *&ms_VehiclesPool; в игре появится возможность рождать больше транспорта или нет?
Рождать через опкод например.

Поковыряй этот мод (http://www.gtagarage.com/mods/show.php?id=2160) на предмет того, как там взломаны лимиты. По опыту использования скажу, что он не только позволяет ломануть лимиты уличного трафика, но и позволяет больше транспорта
Цитировать
Рождать через опкод


-----------------------------------------------------------------

Где можно узнать номер и секвенцию анимации и главное изменить?

В аттаче добавил способ проигрывания через CLEO всех игровых анимаций с моим списком её номеров. Он неполный, также есть лист под авторством другого чувака (http://www.pawfectmedia.com/mods/vc_anim_list.txt): он более подробный, в нем что-то указано так же, а что-то - по-другому(например - IDLE_ROCKET и т.п.).
Название: Re: Как перебрать все обьекты в игре?
Отправлено: Jak łaska za praca от Сентябрь 13, 2016, 01:05:24 am
Там отсутствует vcversion.dll
Название: Re: Как перебрать все обьекты в игре?
Отправлено: Shagg_E от Сентябрь 13, 2016, 02:08:25 pm
Там отсутствует vcversion.dll

В других модах этого автора есть эта dll, например - GTA:Martial Arts (http://www.gtagarage.com/mods/show.php?id=2508)
Название: Re: Как перебрать все обьекты в игре?
Отправлено: xanser от Март 15, 2019, 07:02:28 am
Дошло дело до перебора объектов в игре (поиск ближайшей заправочной колонки). Использованы строки кода:
Код: C++
  1. static CPool<CObject> *& pObjectPool;
Код: C++
  1. CPool<CObject> *& CPools::pObjectPool = *(CPool<CObject> **)0x094DBE0;
Код: C++
  1. CObject * pObject;
  2. for (int i = 0; i < CPools::pObjectPool->size; i++) {
  3.      pObject = &CPools::pObjectPool->objects[i];
  4.      if (!CPools::pObjectPool->flags[i].bIsFreeSlot) {
  5.           if (pObject->id == OBJECT_PETROLPUMP) {
  6.                 // Нашли объект, но не тут-то было
  7.           }
  8.      }
  9. }

Первый объект находится правильно, а дальше происходит сдвиг на 12 байт с каждым новым объектом. Возникает вопрос, либо шаблон пула не подходит для CObject, либо в основе не класс CObject с размером 0x194. То есть если создать расширенный класс CObject с размером 0x1A0, то все становится правильно. Хочется понять, почему так, если кому-то еще это интересно.
Название: Re: Как перебрать все обьекты в игре?
Отправлено: kenking от Март 15, 2019, 08:35:26 am
Этот пул CPool<CObject, CCutsceneObject> *&ms_pObjectPool; не только для CObject, но и для CCutsceneObject.

Цитировать
То есть если создать расширенный класс CObject с размером 0x1A0, то все становится правильно.
Это класс CCutsceneObject, размер как раз 0x1A0
https://github.com/DK22Pac/plugin-sdk/blob/master/plugin_vc/game_vc/CCutsceneObject.h (https://github.com/DK22Pac/plugin-sdk/blob/master/plugin_vc/game_vc/CCutsceneObject.h)


UPD:
Да у меня тоже не получилось перебрать объекты. Странно...
DK же делал пример для объектов SA и там это работает.


UPD2:
Действительно, всё работает, я оказывается не тот ID объекта в свой проверочный код написал.  :)
Название: Re: Как перебрать все обьекты в игре?
Отправлено: xanser от Март 15, 2019, 11:26:06 am
Спасибо, все встало на свои места. Для приведенного примера тогда надо указать так:

Код: C++
  1. static CPool<CObject, CCutsceneObject> *& pObjectPool;
Код: C++
  1. CPool<CObject, CCutsceneObject> *& CPools::pObjectPool = *(CPool<CObject, CCutsceneObject> **)0x094DBE0;
Название: Re: Как перебрать все обьекты в игре?
Отправлено: Saint от Март 16, 2019, 01:45:46 pm
Спасибо, все встало на свои места. Для приведенного примера тогда надо указать так:

Код: C++
  1. static CPool<CObject, CCutsceneObject> *& pObjectPool;
Код: C++
  1. CPool<CObject, CCutsceneObject> *& CPools::pObjectPool = *(CPool<CObject, CCutsceneObject> **)0x094DBE0;

это позволит удалять любые объекты (постоянные) карты? такие как дома, пальмы и т.д.
Название: Re: Как перебрать все обьекты в игре?
Отправлено: xanser от Март 16, 2019, 05:25:33 pm
Пул рассчитан на 460 объектов, вряд ли это карта. Это пикапы и всякие объекты из object.dat
Для "удаления" можно использовать функцию CEntity::PreRender и там каждому нужному объекту установить масштаб в ноль или нулевую прозрачность.