implemented collectives in script

This commit is contained in:
Nikolay Korolev 2020-12-20 17:07:58 +03:00
parent ae7cb92437
commit fc72ff24d0
5 changed files with 980 additions and 13 deletions

View File

@ -58,7 +58,7 @@ int32 CTheScripts::StoreVehicleIndex;
bool CTheScripts::StoreVehicleWasRandom;
CRunningScript *CTheScripts::pIdleScripts;
CRunningScript *CTheScripts::pActiveScripts;
uint32 CTheScripts::NextFreeCollectiveIndex;
int32 CTheScripts::NextFreeCollectiveIndex;
int32 CTheScripts::LastRandomPedId;
uint16 CTheScripts::NumberOfUsedObjects;
bool CTheScripts::bAlreadyRunningAMissionScript;
@ -1810,8 +1810,8 @@ void CTheScripts::Init()
OnAMissionForContactFlag[i] = 0;
}
for (int i = 0; i < MAX_NUM_COLLECTIVES; i++){
CollectiveArray[i].index = -1;
CollectiveArray[i].unk_data = 0;
CollectiveArray[i].colIndex = -1;
CollectiveArray[i].pedIndex = 0;
}
NextFreeCollectiveIndex = 0;
LastRandomPedId = -1;

View File

@ -10,6 +10,7 @@ class CVehicle;
class CPed;
class CObject;
class CPlayerInfo;
enum eObjective;
class CRunningScript;
@ -38,6 +39,10 @@ void FlushLog();
#define KEY_LENGTH_IN_SCRIPT 8
#if GTA_VERSION <= GTA_PS2_160
#define GTA_SCRIPT_COLLECTIVE
#endif
struct intro_script_rectangle
{
bool m_bIsUsed;
@ -213,8 +218,8 @@ enum {
struct tCollectiveData
{
int32 index;
uint32 unk_data;
int32 colIndex;
int32 pedIndex;
};
enum {
@ -286,7 +291,7 @@ class CTheScripts
static bool StoreVehicleWasRandom;
static CRunningScript *pIdleScripts;
static CRunningScript *pActiveScripts;
static uint32 NextFreeCollectiveIndex;
static int32 NextFreeCollectiveIndex;
static int32 LastRandomPedId;
static uint16 NumberOfUsedObjects;
static bool bAlreadyRunningAMissionScript;
@ -393,6 +398,25 @@ private:
static int32 GetNewUniqueScriptSphereIndex(int32 index);
static void RemoveScriptSphere(int32 index);
#ifdef GTA_SCRIPT_COLLECTIVE
static void AdvanceCollectiveIndex()
{
if (NextFreeCollectiveIndex == INT32_MAX)
NextFreeCollectiveIndex = 0;
else
NextFreeCollectiveIndex++;
}
static int AddPedsInVehicleToCollective(int);
static int AddPedsInAreaToCollective(float, float, float, float);
static int FindFreeSlotInCollectiveArray();
static void SetObjectiveForAllPedsInCollective(int, eObjective, int16, int16);
static void SetObjectiveForAllPedsInCollective(int, eObjective, CVector, float);
static void SetObjectiveForAllPedsInCollective(int, eObjective, CVector);
static void SetObjectiveForAllPedsInCollective(int, eObjective, void*);
static void SetObjectiveForAllPedsInCollective(int, eObjective);
#endif
friend class CRunningScript;
friend class CHud;
friend void CMissionCleanup::Process();
@ -511,6 +535,14 @@ private:
void CharInAreaCheckCommand(int32, uint32*);
void CarInAreaCheckCommand(int32, uint32*);
#ifdef GTA_SCRIPT_COLLECTIVE
void LocateCollectiveCommand(int32, uint32*);
void LocateCollectiveCharCommand(int32, uint32*);
void LocateCollectiveCarCommand(int32, uint32*);
void LocateCollectivePlayerCommand(int32, uint32*);
void CollectiveInAreaCheckCommand(int32, uint32*);
#endif
#ifdef MISSION_REPLAY
bool CanAllowMissionReplay();
#endif

View File

@ -853,7 +853,12 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
UpdateCompareFlag(CWorld::Players[ScriptParams[0]].m_WBState == WBSTATE_PLAYING);
return 0;
}
//case COMMAND_SET_COLL_OBJ_NO_OBJ:
#ifdef GTA_SCRIPT_COLLECTIVE
case COMMAND_SET_COLL_OBJ_NO_OBJ:
CollectParameters(&m_nIp, 1);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_NONE);
return 0;
#endif
default:
script_assert(0);
}
@ -863,65 +868,314 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
int8 CRunningScript::ProcessCommands600To699(int32 command)
{
switch (command){
/* Collective commands are not implemented until LCS.
#ifdef GTA_SCRIPT_COLLECTIVE
case COMMAND_SET_COLL_OBJ_WAIT_ON_FOOT:
CollectParameters(&m_nIp, 1);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_WAIT_ON_FOOT);
return 0;
case COMMAND_SET_COLL_OBJ_FLEE_ON_FOOT_TILL_SAFE:
CollectParameters(&m_nIp, 1);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE);
return 0;
case COMMAND_SET_COLL_OBJ_GUARD_SPOT:
{
CollectParameters(&m_nIp, 4);
CVector pos = *(CVector*)&ScriptParams[1];
if (pos.z <= MAP_Z_LOW_LIMIT)
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_GUARD_AREA, pos);
return 0;
}
case COMMAND_SET_COLL_OBJ_GUARD_AREA:
{
CollectParameters(&m_nIp, 5);
float infX = *(float*)&ScriptParams[1];
float supX = *(float*)&ScriptParams[3];
if (infX > supX) {
infX = *(float*)&ScriptParams[3];
supX = *(float*)&ScriptParams[1];
}
float infY = *(float*)&ScriptParams[2];
float supY = *(float*)&ScriptParams[4];
if (infY > supY) {
infY = *(float*)&ScriptParams[4];
supY = *(float*)&ScriptParams[2];
}
CVector pos;
pos.x = (infX + supX) / 2;
pos.y = (infY + supY) / 2;
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
float radius = Max(pos.x - infX, pos.y - infY);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_GUARD_AREA, pos, radius);
return 0;
}
case COMMAND_SET_COLL_OBJ_WAIT_IN_CAR:
CollectParameters(&m_nIp, 1);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_WAIT_IN_CAR);
return 0;
case COMMAND_SET_COLL_OBJ_KILL_CHAR_ON_FOOT:
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_KILL_CHAR_ON_FOOT, pPed);
return 0;
}
case COMMAND_SET_COLL_OBJ_KILL_PLAYER_ON_FOOT:
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CWorld::Players[ScriptParams[1]].m_pPed;
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_KILL_CHAR_ON_FOOT, pPed);
return 0;
}
case COMMAND_SET_COLL_OBJ_KILL_CHAR_ANY_MEANS:
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_KILL_CHAR_ANY_MEANS, pPed);
return 0;
}
case COMMAND_SET_COLL_OBJ_KILL_PLAYER_ANY_MEANS:
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CWorld::Players[ScriptParams[1]].m_pPed;
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_KILL_CHAR_ANY_MEANS, pPed);
return 0;
}
case COMMAND_SET_COLL_OBJ_FLEE_CHAR_ON_FOOT_TILL_SAFE:
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, pPed);
return 0;
}
case COMMAND_SET_COLL_OBJ_FLEE_PLAYER_ON_FOOT_TILL_SAFE:
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CWorld::Players[ScriptParams[1]].m_pPed;
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, pPed);
return 0;
}
case COMMAND_SET_COLL_OBJ_FLEE_CHAR_ON_FOOT_ALWAYS:
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS, pPed);
return 0;
}
case COMMAND_SET_COLL_OBJ_FLEE_PLAYER_ON_FOOT_ALWAYS:
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CWorld::Players[ScriptParams[1]].m_pPed;
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS, pPed);
return 0;
}
case COMMAND_SET_COLL_OBJ_GOTO_CHAR_ON_FOOT:
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_GOTO_CHAR_ON_FOOT, pPed);
return 0;
}
case COMMAND_SET_COLL_OBJ_GOTO_PLAYER_ON_FOOT:
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CWorld::Players[ScriptParams[1]].m_pPed;
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_GOTO_CHAR_ON_FOOT, pPed);
return 0;
}
case COMMAND_SET_COLL_OBJ_LEAVE_CAR:
CollectParameters(&m_nIp, 1);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_LEAVE_CAR);
return 0;
case COMMAND_SET_COLL_OBJ_ENTER_CAR_AS_PASSENGER:
{
CollectParameters(&m_nIp, 2);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_ENTER_CAR_AS_PASSENGER, pVehicle);
return 0;
}
case COMMAND_SET_COLL_OBJ_ENTER_CAR_AS_DRIVER:
{
CollectParameters(&m_nIp, 2);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_ENTER_CAR_AS_DRIVER, pVehicle);
return 0;
}
/*
case COMMAND_SET_COLL_OBJ_FOLLOW_CAR_IN_CAR:
case COMMAND_SET_COLL_OBJ_FIRE_AT_OBJECT_FROM_VEHICLE:
case COMMAND_SET_COLL_OBJ_DESTROY_OBJECT:
*/
case COMMAND_SET_COLL_OBJ_DESTROY_CAR:
{
CollectParameters(&m_nIp, 2);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_DESTROY_CAR, pVehicle);
return 0;
}
case COMMAND_SET_COLL_OBJ_GOTO_AREA_ON_FOOT:
{
CollectParameters(&m_nIp, 5);
float infX = *(float*)&ScriptParams[1];
float supX = *(float*)&ScriptParams[3];
if (infX > supX) {
infX = *(float*)&ScriptParams[3];
supX = *(float*)&ScriptParams[1];
}
float infY = *(float*)&ScriptParams[2];
float supY = *(float*)&ScriptParams[4];
if (infY > supY) {
infY = *(float*)&ScriptParams[4];
supY = *(float*)&ScriptParams[2];
}
CVector pos;
pos.x = (infX + supX) / 2;
pos.y = (infY + supY) / 2;
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
float radius = Max(pos.x - infX, pos.y - infY);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_GOTO_AREA_ON_FOOT, pos, radius);
return 0;
}
/*
case COMMAND_SET_COLL_OBJ_GOTO_AREA_IN_CAR:
case COMMAND_SET_COLL_OBJ_FOLLOW_CAR_ON_FOOT_WITH_OFFSET:
case COMMAND_SET_COLL_OBJ_GUARD_ATTACK:
*/
case COMMAND_SET_COLL_OBJ_FOLLOW_ROUTE:
CollectParameters(&m_nIp, 3);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_FOLLOW_ROUTE, ScriptParams[1], ScriptParams[2]);
return 0;
case COMMAND_SET_COLL_OBJ_GOTO_COORD_ON_FOOT:
case COMMAND_SET_COLL_OBJ_GOTO_COORD_IN_CAR:
{
CollectParameters(&m_nIp, 3);
CVector pos(*(float*)&ScriptParams[1], *(float*)&ScriptParams[2], CWorld::FindGroundZForCoord(*(float*)&ScriptParams[1], *(float*)&ScriptParams[2]));
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_GOTO_AREA_ON_FOOT, pos);
return 0;
}
//case COMMAND_SET_COLL_OBJ_GOTO_COORD_IN_CAR:
case COMMAND_SET_COLL_OBJ_RUN_TO_AREA:
{
CollectParameters(&m_nIp, 5);
float infX = *(float*)&ScriptParams[1];
float supX = *(float*)&ScriptParams[3];
if (infX > supX) {
infX = *(float*)&ScriptParams[3];
supX = *(float*)&ScriptParams[1];
}
float infY = *(float*)&ScriptParams[2];
float supY = *(float*)&ScriptParams[4];
if (infY > supY) {
infY = *(float*)&ScriptParams[4];
supY = *(float*)&ScriptParams[2];
}
CVector pos;
pos.x = (infX + supX) / 2;
pos.y = (infY + supY) / 2;
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
float radius = Max(pos.x - infX, pos.y - infY);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_RUN_TO_AREA, pos, radius);
return 0;
}
case COMMAND_SET_COLL_OBJ_RUN_TO_COORD:
{
CollectParameters(&m_nIp, 3);
CVector pos(*(float*)&ScriptParams[1], *(float*)&ScriptParams[2], CWorld::FindGroundZForCoord(*(float*)&ScriptParams[1], *(float*)&ScriptParams[2]));
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_RUN_TO_AREA, pos);
return 0;
}
case COMMAND_ADD_PEDS_IN_AREA_TO_COLL:
{
CollectParameters(&m_nIp, 3);
float X = *(float*)&ScriptParams[0];
float Y = *(float*)&ScriptParams[1];
float Z = CWorld::FindGroundZForCoord(X, Y);
float radius = *(float*)&ScriptParams[2];
ScriptParams[0] = CTheScripts::AddPedsInAreaToCollective(X, Y, Z, radius);
StoreParameters(&m_nIp, 1);
return 0;
}
case COMMAND_ADD_PEDS_IN_VEHICLE_TO_COLL:
CollectParameters(&m_nIp, 1);
ScriptParams[0] = CTheScripts::AddPedsInVehicleToCollective(ScriptParams[0]);
StoreParameters(&m_nIp, 1);
return 0;
case COMMAND_CLEAR_COLL:
CollectParameters(&m_nIp, 1);
for (int i = 0; i < MAX_NUM_COLLECTIVES; i++) {
if (CTheScripts::CollectiveArray[i].colIndex == ScriptParams[0]) {
CTheScripts::CollectiveArray[i].colIndex = -1;
CTheScripts::CollectiveArray[i].pedIndex = 0;
}
}
return 0;
case COMMAND_IS_COLL_IN_CARS:
{
CollectParameters(&m_nIp, 1);
bool result = true;
for (int i = 0; i < MAX_NUM_COLLECTIVES; i++) {
CPed* pPed = CPools::GetPedPool()->GetAt(CTheScripts::CollectiveArray[i].pedIndex);
if (!pPed) {
CTheScripts::CollectiveArray[i].colIndex = -1;
CTheScripts::CollectiveArray[i].pedIndex = 0;
}
else {
result = false;
break;
}
}
UpdateCompareFlag(result);
return 0;
}
case COMMAND_LOCATE_COLL_ANY_MEANS_2D:
case COMMAND_LOCATE_COLL_ON_FOOT_2D:
case COMMAND_LOCATE_COLL_IN_CAR_2D:
case COMMAND_LOCATE_STOPPED_COLL_ANY_MEANS_2D:
case COMMAND_LOCATE_STOPPED_COLL_ON_FOOT_2D:
case COMMAND_LOCATE_STOPPED_COLL_IN_CAR_2D:
LocateCollectiveCommand(command, &m_nIp);
return 0;
case COMMAND_LOCATE_COLL_ANY_MEANS_CHAR_2D:
case COMMAND_LOCATE_COLL_ON_FOOT_CHAR_2D:
case COMMAND_LOCATE_COLL_IN_CAR_CHAR_2D:
LocateCollectiveCharCommand(command, &m_nIp);
return 0;
case COMMAND_LOCATE_COLL_ANY_MEANS_CAR_2D:
case COMMAND_LOCATE_COLL_ON_FOOT_CAR_2D:
case COMMAND_LOCATE_COLL_IN_CAR_CAR_2D:
LocateCollectiveCarCommand(command, &m_nIp);
return 0;
case COMMAND_LOCATE_COLL_ANY_MEANS_PLAYER_2D:
case COMMAND_LOCATE_COLL_ON_FOOT_PLAYER_2D:
case COMMAND_LOCATE_COLL_IN_CAR_PLAYER_2D:
LocateCollectivePlayerCommand(command, &m_nIp);
return 0;
case COMMAND_IS_COLL_IN_AREA_2D:
case COMMAND_IS_COLL_IN_AREA_ON_FOOT_2D:
case COMMAND_IS_COLL_IN_AREA_IN_CAR_2D:
case COMMAND_IS_COLL_STOPPED_IN_AREA_2D:
case COMMAND_IS_COLL_STOPPED_IN_AREA_ON_FOOT_2D:
case COMMAND_IS_COLL_STOPPED_IN_AREA_IN_CAR_2D:
CollectiveInAreaCheckCommand(command, &m_nIp);
return 0;
case COMMAND_GET_NUMBER_OF_PEDS_IN_COLL:
*/
{
CollectParameters(&m_nIp, 1);
int total = 0;
for (int i = 0; i < MAX_NUM_COLLECTIVES; i++) {
CPed* pPed = CPools::GetPedPool()->GetAt(CTheScripts::CollectiveArray[i].pedIndex);
if (!pPed) {
CTheScripts::CollectiveArray[i].colIndex = -1;
CTheScripts::CollectiveArray[i].pedIndex = 0;
}
else {
total++;
}
}
ScriptParams[0] = total;
StoreParameters(&m_nIp, 1);
return 0;
}
#endif
case COMMAND_SET_CHAR_HEED_THREATS:
{
CollectParameters(&m_nIp, 2);
@ -1046,7 +1300,31 @@ int8 CRunningScript::ProcessCommands600To699(int32 command)
pPed->SetObjective(OBJECTIVE_GOTO_AREA_ANY_MEANS, pos, radius);
return 0;
}
//case COMMAND_SET_COLL_OBJ_GOTO_AREA_ANY_MEANS:
#ifdef GTA_SCRIPT_COLLECTIVE
case COMMAND_SET_COLL_OBJ_GOTO_AREA_ANY_MEANS:
{
CollectParameters(&m_nIp, 5);
float infX = *(float*)&ScriptParams[1];
float supX = *(float*)&ScriptParams[3];
if (infX > supX) {
infX = *(float*)&ScriptParams[3];
supX = *(float*)&ScriptParams[1];
}
float infY = *(float*)&ScriptParams[2];
float supY = *(float*)&ScriptParams[4];
if (infY > supY) {
infY = *(float*)&ScriptParams[4];
supY = *(float*)&ScriptParams[2];
}
CVector pos;
pos.x = (infX + supX) / 2;
pos.y = (infY + supY) / 2;
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
float radius = Max(pos.x - infX, pos.y - infY);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_GOTO_AREA_ANY_MEANS, pos, radius);
return 0;
}
#endif
case COMMAND_IS_PLAYER_STOPPED:
{
CollectParameters(&m_nIp, 1);

View File

@ -244,7 +244,12 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
pPed->SetObjective(OBJECTIVE_CATCH_TRAIN);
return 0;
}
//case COMMAND_SET_COLL_OBJ_CATCH_TRAIN:
#ifdef GTA_SCRIPT_COLLECTIVE
case COMMAND_SET_COLL_OBJ_CATCH_TRAIN:
CollectParameters(&m_nIp, 1);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_CATCH_TRAIN);
return 0;
#endif
case COMMAND_SET_PLAYER_NEVER_GETS_TIRED:
{
CollectParameters(&m_nIp, 2);
@ -1090,7 +1095,12 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
case COMMAND_GIVE_PLAYER_DETONATOR:
CGarages::GivePlayerDetonator();
return 0;
//case COMMAND_SET_COLL_OBJ_STEAL_ANY_CAR:
#ifdef GTA_SCRIPT_COLLECTIVE
case COMMAND_SET_COLL_OBJ_STEAL_ANY_CAR:
CollectParameters(&m_nIp, 1);
CTheScripts::SetObjectiveForAllPedsInCollective(ScriptParams[0], OBJECTIVE_STEAL_ANY_CAR);
return 0;
#endif
case COMMAND_SET_OBJECT_VELOCITY:
{
CollectParameters(&m_nIp, 4);

View File

@ -1304,6 +1304,487 @@ int16 CRunningScript::GetPadState(uint16 pad, uint16 button)
return 0;
}
#ifdef GTA_SCRIPT_COLLECTIVE
void CRunningScript::LocateCollectiveCommand(int32 command, uint32* pIp)
{
bool b3D, result, debug, decided = false;
float X, Y, Z, dX, dY, dZ;
switch (command) {
case COMMAND_LOCATE_COLL_ANY_MEANS_2D:
case COMMAND_LOCATE_COLL_ON_FOOT_2D:
case COMMAND_LOCATE_COLL_IN_CAR_2D:
case COMMAND_LOCATE_STOPPED_COLL_ANY_MEANS_2D:
case COMMAND_LOCATE_STOPPED_COLL_ON_FOOT_2D:
case COMMAND_LOCATE_STOPPED_COLL_IN_CAR_2D:
b3D = false;
break;
default:
b3D = true;
break;
}
CollectParameters(pIp, b3D ? 8 : 6);
X = *(float*)&ScriptParams[1];
Y = *(float*)&ScriptParams[2];
if (b3D) {
Z = *(float*)&ScriptParams[3];
dX = *(float*)&ScriptParams[4];
dY = *(float*)&ScriptParams[5];
dZ = *(float*)&ScriptParams[6];
debug = ScriptParams[7];
}
else {
dX = *(float*)&ScriptParams[3];
dY = *(float*)&ScriptParams[4];
debug = ScriptParams[5];
}
result = true;
for (int i = 0; i < MAX_NUM_COLLECTIVES && result; i++) {
if (ScriptParams[0] != CTheScripts::CollectiveArray[i].colIndex)
continue;
CPed* pPed = CPools::GetPedPool()->GetAt(CTheScripts::CollectiveArray[i].pedIndex);
if (!pPed) {
CTheScripts::CollectiveArray[i].colIndex = -1;
CTheScripts::CollectiveArray[i].pedIndex = 0;
continue;
}
CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
switch (command) {
case COMMAND_LOCATE_STOPPED_COLL_ANY_MEANS_2D:
case COMMAND_LOCATE_STOPPED_COLL_ON_FOOT_2D:
case COMMAND_LOCATE_STOPPED_COLL_IN_CAR_2D:
if (!CTheScripts::IsPedStopped(pPed)) {
result = false;
decided = true;
}
break;
default:
break;
}
if (!decided) {
bool in_area;
if (b3D) {
in_area = X - dX <= pos.x &&
X + dX >= pos.x &&
Y - dY <= pos.y &&
Y + dY >= pos.y &&
Z - dZ <= pos.z &&
Z + dZ >= pos.z;
}
else {
in_area = X - dX <= pos.x &&
X + dX >= pos.x &&
Y - dY <= pos.y &&
Y + dY >= pos.y;
}
result = false;
if (in_area) {
switch (command) {
case COMMAND_LOCATE_COLL_ANY_MEANS_2D:
case COMMAND_LOCATE_STOPPED_COLL_ANY_MEANS_2D:
result = true;
break;
case COMMAND_LOCATE_COLL_ON_FOOT_2D:
case COMMAND_LOCATE_STOPPED_COLL_ON_FOOT_2D:
result = !pPed->bInVehicle;
break;
case COMMAND_LOCATE_COLL_IN_CAR_2D:
case COMMAND_LOCATE_STOPPED_COLL_IN_CAR_2D:
result = pPed->bInVehicle;
break;
default:
script_assert(false);
break;
}
}
}
}
UpdateCompareFlag(result);
if (debug)
CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) {
if (b3D)
CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
else
CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY);
}
}
void CRunningScript::LocateCollectiveCharCommand(int32 command, uint32* pIp)
{
bool b3D, result, debug;
float X, Y, Z, dX, dY, dZ;
switch (command) {
case COMMAND_LOCATE_COLL_ANY_MEANS_CHAR_2D:
case COMMAND_LOCATE_COLL_ON_FOOT_CHAR_2D:
case COMMAND_LOCATE_COLL_IN_CAR_CHAR_2D:
b3D = false;
break;
default:
b3D = true;
break;
}
CollectParameters(pIp, b3D ? 6 : 5);
CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
script_assert(pTarget);
if (pTarget->bInVehicle) {
X = pTarget->m_pMyVehicle->GetPosition().x;
Y = pTarget->m_pMyVehicle->GetPosition().y;
Z = pTarget->m_pMyVehicle->GetPosition().z;
}
else {
X = pTarget->GetPosition().x;
Y = pTarget->GetPosition().y;
Z = pTarget->GetPosition().z;
}
dX = *(float*)&ScriptParams[2];
dY = *(float*)&ScriptParams[3];
if (b3D) {
dZ = *(float*)&ScriptParams[4];
debug = ScriptParams[5];
}
else {
debug = ScriptParams[4];
}
result = true;
for (int i = 0; i < MAX_NUM_COLLECTIVES && result; i++) {
if (ScriptParams[0] != CTheScripts::CollectiveArray[i].colIndex)
continue;
CPed* pPed = CPools::GetPedPool()->GetAt(CTheScripts::CollectiveArray[i].pedIndex);
if (!pPed) {
CTheScripts::CollectiveArray[i].colIndex = -1;
CTheScripts::CollectiveArray[i].pedIndex = 0;
continue;
}
CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
bool in_area;
if (b3D) {
in_area = X - dX <= pos.x &&
X + dX >= pos.x &&
Y - dY <= pos.y &&
Y + dY >= pos.y &&
Z - dZ <= pos.z &&
Z + dZ >= pos.z;
}
else {
in_area = X - dX <= pos.x &&
X + dX >= pos.x &&
Y - dY <= pos.y &&
Y + dY >= pos.y;
}
result = false;
if (in_area) {
switch (command) {
case COMMAND_LOCATE_COLL_ANY_MEANS_CHAR_2D:
result = true;
break;
case COMMAND_LOCATE_COLL_ON_FOOT_CHAR_2D:
result = !pPed->bInVehicle;
break;
case COMMAND_LOCATE_COLL_IN_CAR_CHAR_2D:
result = pPed->bInVehicle;
break;
default:
script_assert(false);
break;
}
}
}
UpdateCompareFlag(result);
if (debug)
CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) {
if (b3D)
CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
else
CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY);
}
}
void CRunningScript::LocateCollectiveCarCommand(int32 command, uint32* pIp)
{
bool b3D, result, debug;
float X, Y, Z, dX, dY, dZ;
switch (command) {
case COMMAND_LOCATE_COLL_ANY_MEANS_CAR_2D:
case COMMAND_LOCATE_COLL_ON_FOOT_CAR_2D:
case COMMAND_LOCATE_COLL_IN_CAR_CAR_2D:
b3D = false;
break;
default:
b3D = true;
break;
}
CollectParameters(pIp, b3D ? 6 : 5);
CVehicle* pTarget = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
script_assert(pTarget);
X = pTarget->GetPosition().x;
Y = pTarget->GetPosition().y;
Z = pTarget->GetPosition().z;
dX = *(float*)&ScriptParams[2];
dY = *(float*)&ScriptParams[3];
if (b3D) {
dZ = *(float*)&ScriptParams[4];
debug = ScriptParams[5];
}
else {
debug = ScriptParams[4];
}
result = true;
for (int i = 0; i < MAX_NUM_COLLECTIVES && result; i++) {
if (ScriptParams[0] != CTheScripts::CollectiveArray[i].colIndex)
continue;
CPed* pPed = CPools::GetPedPool()->GetAt(CTheScripts::CollectiveArray[i].pedIndex);
if (!pPed) {
CTheScripts::CollectiveArray[i].colIndex = -1;
CTheScripts::CollectiveArray[i].pedIndex = 0;
continue;
}
CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
bool in_area;
if (b3D) {
in_area = X - dX <= pos.x &&
X + dX >= pos.x &&
Y - dY <= pos.y &&
Y + dY >= pos.y &&
Z - dZ <= pos.z &&
Z + dZ >= pos.z;
}
else {
in_area = X - dX <= pos.x &&
X + dX >= pos.x &&
Y - dY <= pos.y &&
Y + dY >= pos.y;
}
result = false;
if (in_area) {
switch (command) {
case COMMAND_LOCATE_COLL_ANY_MEANS_CAR_2D:
result = true;
break;
case COMMAND_LOCATE_COLL_ON_FOOT_CAR_2D:
result = !pPed->bInVehicle;
break;
case COMMAND_LOCATE_COLL_IN_CAR_CAR_2D:
result = pPed->bInVehicle;
break;
default:
script_assert(false);
break;
}
}
}
UpdateCompareFlag(result);
if (debug)
CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) {
if (b3D)
CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
else
CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY);
}
}
void CRunningScript::LocateCollectivePlayerCommand(int32 command, uint32* pIp)
{
bool b3D, result, debug;
float X, Y, Z, dX, dY, dZ;
switch (command) {
case COMMAND_LOCATE_COLL_ANY_MEANS_PLAYER_2D:
case COMMAND_LOCATE_COLL_ON_FOOT_PLAYER_2D:
case COMMAND_LOCATE_COLL_IN_CAR_PLAYER_2D:
b3D = false;
break;
default:
b3D = true;
break;
}
CollectParameters(pIp, b3D ? 6 : 5);
CVector pos = CWorld::Players[ScriptParams[1]].GetPos();
X = pos.x;
Y = pos.y;
Z = pos.z;
dX = *(float*)&ScriptParams[2];
dY = *(float*)&ScriptParams[3];
if (b3D) {
dZ = *(float*)&ScriptParams[4];
debug = ScriptParams[5];
}
else {
debug = ScriptParams[4];
}
result = true;
for (int i = 0; i < MAX_NUM_COLLECTIVES && result; i++) {
if (ScriptParams[0] != CTheScripts::CollectiveArray[i].colIndex)
continue;
CPed* pPed = CPools::GetPedPool()->GetAt(CTheScripts::CollectiveArray[i].pedIndex);
if (!pPed) {
CTheScripts::CollectiveArray[i].colIndex = -1;
CTheScripts::CollectiveArray[i].pedIndex = 0;
continue;
}
CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
bool in_area;
if (b3D) {
in_area = X - dX <= pos.x &&
X + dX >= pos.x &&
Y - dY <= pos.y &&
Y + dY >= pos.y &&
Z - dZ <= pos.z &&
Z + dZ >= pos.z;
}
else {
in_area = X - dX <= pos.x &&
X + dX >= pos.x &&
Y - dY <= pos.y &&
Y + dY >= pos.y;
}
result = false;
if (in_area) {
switch (command) {
case COMMAND_LOCATE_COLL_ANY_MEANS_PLAYER_2D:
result = true;
break;
case COMMAND_LOCATE_COLL_ON_FOOT_PLAYER_2D:
result = !pPed->bInVehicle;
break;
case COMMAND_LOCATE_COLL_IN_CAR_PLAYER_2D:
result = pPed->bInVehicle;
break;
default:
script_assert(false);
break;
}
}
}
UpdateCompareFlag(result);
if (debug)
CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) {
if (b3D)
CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ);
else
CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY);
}
}
void CRunningScript::CollectiveInAreaCheckCommand(int32 command, uint32* pIp)
{
bool b3D, result, debug, decided = false;
float infX, infY, infZ, supX, supY, supZ;
switch (command) {
case COMMAND_IS_COLL_IN_AREA_2D:
case COMMAND_IS_COLL_IN_AREA_ON_FOOT_2D:
case COMMAND_IS_COLL_IN_AREA_IN_CAR_2D:
case COMMAND_IS_COLL_STOPPED_IN_AREA_2D:
case COMMAND_IS_COLL_STOPPED_IN_AREA_ON_FOOT_2D:
case COMMAND_IS_COLL_STOPPED_IN_AREA_IN_CAR_2D:
b3D = false;
break;
default:
b3D = true;
break;
}
CollectParameters(pIp, b3D ? 8 : 6);
infX = *(float*)&ScriptParams[1];
infY = *(float*)&ScriptParams[2];
if (b3D) {
infZ = *(float*)&ScriptParams[3];
supX = *(float*)&ScriptParams[4];
supY = *(float*)&ScriptParams[5];
supZ = *(float*)&ScriptParams[6];
if (infZ > supZ) {
infZ = *(float*)&ScriptParams[6];
supZ = *(float*)&ScriptParams[3];
}
debug = ScriptParams[7];
}
else {
supX = *(float*)&ScriptParams[3];
supY = *(float*)&ScriptParams[4];
debug = ScriptParams[5];
}
if (infX > supX) {
float tmp = infX;
infX = supX;
supX = tmp;
}
if (infY > supY) {
float tmp = infY;
infY = supY;
supY = tmp;
}
result = true;
for (int i = 0; i < MAX_NUM_COLLECTIVES && result; i++) {
if (ScriptParams[0] != CTheScripts::CollectiveArray[i].colIndex)
continue;
CPed* pPed = CPools::GetPedPool()->GetAt(CTheScripts::CollectiveArray[i].pedIndex);
if (!pPed) {
CTheScripts::CollectiveArray[i].colIndex = -1;
CTheScripts::CollectiveArray[i].pedIndex = 0;
continue;
}
CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
switch (command) {
case COMMAND_IS_COLL_STOPPED_IN_AREA_2D:
case COMMAND_IS_COLL_STOPPED_IN_AREA_ON_FOOT_2D:
case COMMAND_IS_COLL_STOPPED_IN_AREA_IN_CAR_2D:
if (!CTheScripts::IsPedStopped(pPed)) {
result = false;
decided = true;
}
break;
default:
break;
}
if (!decided) {
bool in_area;
if (b3D) {
in_area = infX <= pos.x &&
supX >= pos.x &&
infY <= pos.y &&
supY >= pos.y &&
infZ <= pos.z &&
supZ >= pos.z;
}
else {
in_area = infX <= pos.x &&
supX >= pos.x &&
infY <= pos.y &&
supY >= pos.y;
}
result = false;
if (in_area) {
switch (command) {
case COMMAND_IS_COLL_IN_AREA_2D:
case COMMAND_IS_COLL_STOPPED_IN_AREA_2D:
result = true;
break;
case COMMAND_IS_COLL_IN_AREA_ON_FOOT_2D:
case COMMAND_IS_COLL_STOPPED_IN_AREA_ON_FOOT_2D:
result = !pPed->bInVehicle;
break;
case COMMAND_IS_COLL_IN_AREA_IN_CAR_2D:
case COMMAND_IS_COLL_STOPPED_IN_AREA_IN_CAR_2D:
result = pPed->bInVehicle;
break;
default:
script_assert(false);
break;
}
}
}
}
UpdateCompareFlag(result);
if (debug)
CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT);
if (CTheScripts::DbgFlag) {
if (b3D)
CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ);
else
CTheScripts::DrawDebugSquare(infX, infY, supX, supY);
}
}
#endif
void CTheScripts::PrintListSizes()
{
@ -1717,6 +2198,172 @@ void CTheScripts::HighlightImportantAngledArea(uint32 id, float x1, float y1, fl
CShadows::RenderIndicatorShadow(id, 2, gpGoalTex, &center, supX - center.x, 0.0f, 0.0f, center.y - supY, 0);
}
#ifdef GTA_SCRIPT_COLLECTIVE
int CTheScripts::AddPedsInVehicleToCollective(int index)
{
int colIndex = NextFreeCollectiveIndex;
AdvanceCollectiveIndex();
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(index);
script_assert(pVehicle);
CPed* pDriver = pVehicle->pDriver;
if (pDriver && !pDriver->IsPlayer() && pDriver->CharCreatedBy != MISSION_CHAR && pDriver->m_nPedType != PEDTYPE_COP) {
int index = FindFreeSlotInCollectiveArray();
if (index > -1) {
CollectiveArray[index].colIndex = colIndex;
CollectiveArray[index].pedIndex = CPools::GetPedPool()->GetIndex(pDriver);
}
}
for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++) {
CPed* pPassenger = pVehicle->pPassengers[i];
if (pPassenger && !pPassenger->IsPlayer() && pPassenger->CharCreatedBy != MISSION_CHAR && pPassenger->m_nPedType != PEDTYPE_COP) {
int index = FindFreeSlotInCollectiveArray();
if (index > -1) {
CollectiveArray[index].colIndex = colIndex;
CollectiveArray[index].pedIndex = CPools::GetPedPool()->GetIndex(pPassenger);
}
}
}
return colIndex;
}
int CTheScripts::AddPedsInAreaToCollective(float x, float y, float z, float radius)
{
int16 numFound;
CEntity* pEntities[64];
int colIndex = NextFreeCollectiveIndex;
AdvanceCollectiveIndex();
CWorld::FindObjectsInRange(CVector(x, y, z), radius, true, &numFound, 64, pEntities, false, true, true, false, false);
for (int16 i = 0; i < numFound; i++) {
if (pEntities[i]->GetType() == ENTITY_TYPE_PED) {
CPed* pPed = (CPed*)pEntities[i];
if (pPed && !pPed->IsPlayer() && pPed->CharCreatedBy != MISSION_CHAR && pPed->m_nPedType != PEDTYPE_COP) {
int index = FindFreeSlotInCollectiveArray();
if (index > -1) {
CollectiveArray[index].colIndex = colIndex;
CollectiveArray[index].pedIndex = CPools::GetPedPool()->GetIndex(pPed);
}
}
}
else if (pEntities[i]->GetType() == ENTITY_TYPE_VEHICLE) {
CVehicle* pVehicle = (CVehicle*)pEntities[i];
CPed* pDriver = pVehicle->pDriver;
if (pDriver && !pDriver->IsPlayer() && pDriver->CharCreatedBy != MISSION_CHAR && pDriver->m_nPedType != PEDTYPE_COP) {
int index = FindFreeSlotInCollectiveArray();
if (index > -1) {
CollectiveArray[index].colIndex = colIndex;
CollectiveArray[index].pedIndex = CPools::GetPedPool()->GetIndex(pDriver);
}
}
for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++) {
CPed* pPassenger = pVehicle->pPassengers[i];
if (pPassenger && !pPassenger->IsPlayer() && pPassenger->CharCreatedBy != MISSION_CHAR && pPassenger->m_nPedType != PEDTYPE_COP) {
int index = FindFreeSlotInCollectiveArray();
if (index > -1) {
CollectiveArray[index].colIndex = colIndex;
CollectiveArray[index].pedIndex = CPools::GetPedPool()->GetIndex(pPassenger);
}
}
}
}
}
return colIndex;
}
int CTheScripts::FindFreeSlotInCollectiveArray()
{
for (int i = 0; i < MAX_NUM_COLLECTIVES; i++) {
if (CollectiveArray[i].colIndex == -1)
return i;
}
return -1;
}
void CTheScripts::SetObjectiveForAllPedsInCollective(int colIndex, eObjective objective, int16 p1, int16 p2)
{
for (int i = 0; i < MAX_NUM_COLLECTIVES; i++) {
if (CollectiveArray[i].colIndex = colIndex) {
CPed* pPed = CPools::GetPedPool()->GetAt(CollectiveArray[i].pedIndex);
if (pPed == nil) {
CollectiveArray[i].colIndex = -1;
CollectiveArray[i].pedIndex = 0;
}
else {
pPed->bScriptObjectiveCompleted = false;
pPed->SetObjective(objective, p1, p2);
}
}
}
}
void CTheScripts::SetObjectiveForAllPedsInCollective(int colIndex, eObjective objective, CVector p1, float p2)
{
for (int i = 0; i < MAX_NUM_COLLECTIVES; i++) {
if (CollectiveArray[i].colIndex = colIndex) {
CPed* pPed = CPools::GetPedPool()->GetAt(CollectiveArray[i].pedIndex);
if (pPed == nil) {
CollectiveArray[i].colIndex = -1;
CollectiveArray[i].pedIndex = 0;
}
else {
pPed->bScriptObjectiveCompleted = false;
pPed->SetObjective(objective, p1, p2);
}
}
}
}
void CTheScripts::SetObjectiveForAllPedsInCollective(int colIndex, eObjective objective, CVector p1)
{
for (int i = 0; i < MAX_NUM_COLLECTIVES; i++) {
if (CollectiveArray[i].colIndex = colIndex) {
CPed* pPed = CPools::GetPedPool()->GetAt(CollectiveArray[i].pedIndex);
if (pPed == nil) {
CollectiveArray[i].colIndex = -1;
CollectiveArray[i].pedIndex = 0;
}
else {
pPed->bScriptObjectiveCompleted = false;
pPed->SetObjective(objective, p1);
}
}
}
}
void CTheScripts::SetObjectiveForAllPedsInCollective(int colIndex, eObjective objective, void* p1)
{
for (int i = 0; i < MAX_NUM_COLLECTIVES; i++) {
if (CollectiveArray[i].colIndex = colIndex) {
CPed* pPed = CPools::GetPedPool()->GetAt(CollectiveArray[i].pedIndex);
if (pPed == nil) {
CollectiveArray[i].colIndex = -1;
CollectiveArray[i].pedIndex = 0;
}
else {
pPed->bScriptObjectiveCompleted = false;
pPed->SetObjective(objective, p1);
}
}
}
}
void CTheScripts::SetObjectiveForAllPedsInCollective(int colIndex, eObjective objective)
{
for (int i = 0; i < MAX_NUM_COLLECTIVES; i++) {
if (CollectiveArray[i].colIndex = colIndex) {
CPed* pPed = CPools::GetPedPool()->GetAt(CollectiveArray[i].pedIndex);
if (pPed == nil) {
CollectiveArray[i].colIndex = -1;
CollectiveArray[i].pedIndex = 0;
}
else {
pPed->bScriptObjectiveCompleted = false;
pPed->SetObjective(objective);
}
}
}
}
#endif //GTA_SCRIPT_COLLECTIVE
bool CTheScripts::IsPedStopped(CPed* pPed)
{
if (pPed->bInVehicle)