//////////////////////////////////////////////////////////////////////////////// // ColAndreas Plugin Include /////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// #if defined _colandreas_included #endinput #endif #define _colandreas_included #pragma library colandreas #define COLANDREAS_VERSION (10400) //a.b.c 10000*a+100*b+c #define COLANDREAS (COLANDREAS_VERSION) // Default extra ID types #define CA_EXTRA_1 0 #define CA_EXTRA_2 1 #define CA_EXTRA_3 2 #define CA_EXTRA_4 3 #define CA_EXTRA_5 4 #define CA_EXTRA_6 5 #define CA_EXTRA_7 6 #define CA_EXTRA_8 7 #define CA_EXTRA_9 8 #define CA_EXTRA_10 9 // ColAndreas currently supports 50000 user collision objects (This can be raised as needed) #if defined MAX_CA_OBJECTS #if MAX_CA_OBJECTS > 50000 #error [ColAndreas] MAX_CA_OBJECTS is too high, maximum value is 50000 #endif #else #define MAX_CA_OBJECTS 10000 #endif // Water object ID #define WATER_OBJECT 20000 // Object types (Player objects are supported as dynamic only) #define OBJECT_TYPE_OBJECT 0 #define OBJECT_TYPE_DYNAMIC 1 #if !defined FLOAT_INFINITY #define FLOAT_INFINITY (Float:0x7F800000) #endif // Maximum number of raycasts in CA_RayCastMultiLine #define MAX_MULTICAST_SIZE 99 /**--------------------------------------------------------------------------**\ CA_Init 0 when there is no data loaded (ex. when you don't have the data file) 1 when loaded map successfully or was already loaded \**--------------------------------------------------------------------------**/ native CA_Init(); /**--------------------------------------------------------------------------**\ CA_RemoveBuilding The model to be removed The coordinates in which the objects will be removed The radius around the specified point to remove from 0 when the map is already initialized 1 when successfully removed You must use this function before using `CA_Init` \**--------------------------------------------------------------------------**/ native CA_RemoveBuilding(modelid, Float:x, Float:y, Float:z, Float:radius); /**--------------------------------------------------------------------------**\ CA_RayCastLine The beginning point of the ray The ending point of the ray The point that the ray collided 0 if the ray didn't collide with anything WATER_OBJECT if the ray collided with water The model of the object the ray collided \**--------------------------------------------------------------------------**/ native CA_RayCastLine(Float:StartX, Float:StartY, Float:StartZ, Float:EndX, Float:EndY, Float:EndZ, &Float:x, &Float:y, &Float:z); /**--------------------------------------------------------------------------**\ CA_RayCastLineID The beginning point of the ray The ending point of the ray The point that the ray collided -1 if the ray collided with a static object or water 0 if the ray didn't collide with anything The index of the object the ray collided This only works with objects created with `add` enabled in `CA_CreateObject`, such as the objects created by the "_DC" functions \**--------------------------------------------------------------------------**/ native CA_RayCastLineID(Float:StartX, Float:StartY, Float:StartZ, Float:EndX, Float:EndY, Float:EndZ, &Float:x, &Float:y, &Float:z); /**--------------------------------------------------------------------------**\ CA_RayCastLineExtraID The extra ID index The beginning point of the ray The ending point of the ray The point that the ray collided -1 if the ray collided with a static object or water -1 if the extra ID is unmodified 0 if the ray didn't collide with anything The index of the object the ray collided This only works with objects created with `add` enabled in `CA_CreateObject`, such as the objects created by the "_DC" functions \**--------------------------------------------------------------------------**/ native CA_RayCastLineExtraID(type, Float:StartX, Float:StartY, Float:StartZ, Float:EndX, Float:EndY, Float:EndZ, &Float:x, &Float:y, &Float:z); /**--------------------------------------------------------------------------**\ CA_RayCastMultiLine The beginning point of the ray The ending point of the ray The points that the ray collided The distances between the beginning point and the point collided The object models that the ray collided The maximum number of points to collide -1 if the ray collided with more points than than permitted by the `size` parameter or `size` is higher than MAX_MULTICAST_SIZE value 0 if the ray didn't collide with anything The number of points collided \**--------------------------------------------------------------------------**/ native CA_RayCastMultiLine(Float:StartX, Float:StartY, Float:StartZ, Float:EndX, Float:EndY, Float:EndZ, Float:retx[], Float:rety[], Float:retz[], Float:retdist[], ModelIDs[], size = sizeof(retx)); /**--------------------------------------------------------------------------**\ CA_RayCastLineAngle The beginning point of the ray The ending point of the ray The point that the ray collided The rotation of the face that the ray collided 0 if the ray didn't collide with anything WATER_OBJECT if the ray collided with water The model of the object the ray collided \**--------------------------------------------------------------------------**/ native CA_RayCastLineAngle(Float:StartX, Float:StartY, Float:StartZ, Float:EndX, Float:EndY, Float:EndZ, &Float:x, &Float:y, &Float:z, &Float:rx, &Float:ry, &Float:rz); /**--------------------------------------------------------------------------**\ CA_RayCastReflectionVector The beginning point of the ray The ending point of the ray The point that the ray collided The reflection vector of the face that the ray collided 0 if the ray didn't collide with anything WATER_OBJECT if the ray collided with water The model of the object the ray collided \**--------------------------------------------------------------------------**/ native CA_RayCastReflectionVector(Float:startx, Float:starty, Float:startz, Float:endx, Float:endy, Float:endz, &Float:x, &Float:y, &Float:z, &Float:nx, &Float:ny, &Float:nz); /**--------------------------------------------------------------------------**\ CA_RayCastLineNormal The beginning point of the ray The ending point of the ray The point that the ray collided The surface normal of the face that the ray collided 0 if the ray didn't collide with anything WATER_OBJECT if the ray collided with water The model of the object the ray collided \**--------------------------------------------------------------------------**/ native CA_RayCastLineNormal(Float:startx, Float:starty, Float:startz, Float:endx, Float:endy, Float:endz, &Float:x, &Float:y, &Float:z, &Float:nx, &Float:ny, &Float:nz); /**--------------------------------------------------------------------------**\ CA_ContactTest The object model to be tested The object position to test The object rotation to test 0 if the object model doesn't collide with the world with the specified 1 otherwise \**--------------------------------------------------------------------------**/ native CA_ContactTest(modelid, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz); /**--------------------------------------------------------------------------**\ CA_EulerToQuat GTA euler rotations to be converted The quaternion angles returned Always 1 \**--------------------------------------------------------------------------**/ native CA_EulerToQuat(Float:rx, Float:ry, Float:rz, &Float:x, &Float:y, &Float:z, &Float:w); /**--------------------------------------------------------------------------**\ CA_QuatToEuler The quaternion angles to be converted GTA euler rotations returned Always 1 \**--------------------------------------------------------------------------**/ native CA_QuatToEuler(Float:x, Float:y, Float:z, Float:w, &Float:rx, &Float:ry, &Float:rz); /**--------------------------------------------------------------------------**\ CA_GetModelBoundingSphere The object model The offset of the model's bounding sphere The radius of the model's bounding sphere 0 if the model is invalid 1 otherwise \**--------------------------------------------------------------------------**/ native CA_GetModelBoundingSphere(modelid, &Float:offx, &Float:offy, &Float:offz, &Float:radius); /**--------------------------------------------------------------------------**\ CA_GetModelBoundingBox The object model The "minimum" point of the model's bounding box The "maximum" point of the model's bounding box 0 if the model is invalid 1 otherwise \**--------------------------------------------------------------------------**/ native CA_GetModelBoundingBox(modelid, &Float:minx, &Float:miny, &Float:minz, &Float:maxx, &Float:maxy, &Float:maxz); /**--------------------------------------------------------------------------**\ CA_SetObjectExtraID The index of the ColAndreas object The index of the extra ID to be set The data stored in the extra ID Always 1 (which needs to be changed to be like CA_GetObjectExtraID's returns...) \**--------------------------------------------------------------------------**/ native CA_SetObjectExtraID(index, type, data); /**--------------------------------------------------------------------------**\ CA_GetObjectExtraID The index of the ColAndreas object The index of the extra ID to be set -1 if the index or type is invalid The data stored in the extra ID \**--------------------------------------------------------------------------**/ native CA_GetObjectExtraID(index, type); /**--------------------------------------------------------------------------**\ CA_RayCastLineEx The beginning point of the ray The ending point of the ray The point that the ray collided The quaternion rotation of the object that the ray collided The position of the object that the ray collided 0 if the ray didn't collide with anything WATER_OBJECT if the ray collided with water The model of the object the ray collided \**--------------------------------------------------------------------------**/ native CA_RayCastLineEx(Float:StartX, Float:StartY, Float:StartZ, Float:EndX, Float:EndY, Float:EndZ, &Float:x, &Float:y, &Float:z, &Float:rx, &Float:ry, &Float:rz, &Float:rw, &Float:cx, &Float:cy, &Float:cz); /**--------------------------------------------------------------------------**\ CA_RayCastLineAngleEx The beginning point of the ray The ending point of the ray The point that the ray collided The rotation of the face that the ray collided The position of the object that the ray collided The rotation of the object that the ray collided 0 if the ray didn't collide with anything WATER_OBJECT if the ray collided with water The model of the object the ray collided \**--------------------------------------------------------------------------**/ native CA_RayCastLineAngleEx(Float:StartX, Float:StartY, Float:StartZ, Float:EndX, Float:EndY, Float:EndZ, &Float:x, &Float:y, &Float:z, &Float:rx, &Float:ry, &Float:rz, &Float:ocx, &Float:ocy, &Float:ocz, &Float:orx, &Float:ory, &Float:orz); // Internal Functions: /**--------------------------------------------------------------------------**\ CA_CreateObject The collision model to create The position in which to create the collision model The rotation of the collision model Whether or not to store this objects index for manual management -1 if the specified model has no collision (should be changed to -2, to avoid confusion with unmanaged objects) -1 if `add` is false The index of the created collision object ONLY CREATES THE COLLISION, NOT THE IN-GAME OBJECT \**--------------------------------------------------------------------------**/ native CA_CreateObject(modelid, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz, bool:add = false); /**--------------------------------------------------------------------------**\ CA_DestroyObject The index of the object to be destroyed -1 if the specified model has no collision (should be changed to -2, to avoid confusion with unmanaged objects) -1 if `add` is false The index of the created collision object \**--------------------------------------------------------------------------**/ native CA_DestroyObject(index); /**--------------------------------------------------------------------------**\ CA_IsValidObject Checks if an object with the ID provided exists. -1 if the specified model has no collision 0 if the object does not exist 1 if the object exists \**--------------------------------------------------------------------------**/ native CA_IsValidObject(index); /**--------------------------------------------------------------------------**\ CA_SetObjectPos The index of the object to be moved The new position 0 if the object doesn't exist 1 if the new position was set successfully \**--------------------------------------------------------------------------**/ native CA_SetObjectPos(index, Float:x, Float:y, Float:z); /**--------------------------------------------------------------------------**\ CA_SetObjectRot The index of the object to be moved The new rotation 0 if the object doesn't exist 1 if the new rotation was set successfully \**--------------------------------------------------------------------------**/ native CA_SetObjectRot(index, Float:rx, Float:ry, Float:rz); #if defined _Y_ITERATE_LOCAL_VERSION static stock Iterator:CA_Objects; #endif enum CAOBJECTINFO { ColdAndreadsID, ObjectID, ObjectType, #if !defined _Y_ITERATE_LOCAL_VERSION bool:ObjectUsed, #endif } static stock CA_ObjectList[MAX_CA_OBJECTS][CAOBJECTINFO]; //Streamer #if defined STREAMER_TYPE_OBJECT // Static collision object functions (The index is not returned these can not be deleted!) stock STREAMER_TAG_OBJECT:CA_CreateDynamicObjectEx_SC(modelid, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz, Float:streamdistance = STREAMER_OBJECT_SD, Float:drawdistance = STREAMER_OBJECT_DD, worlds[] = { -1 }, interiors[] = { -1 }, players[] = { -1 }, STREAMER_TAG_AREA:areas[] = { STREAMER_TAG_AREA:-1 }, priority = 0, maxworlds = sizeof worlds, maxinteriors = sizeof interiors, maxplayers = sizeof players, maxareas = sizeof areas) { new STREAMER_TAG_OBJECT:id = CreateDynamicObjectEx(modelid, x, y, z, rx, ry, rz, streamdistance, drawdistance, worlds, interiors, players, areas, priority, maxworlds, maxinteriors, maxplayers, maxareas); CA_CreateObject(modelid, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz); return id; } stock STREAMER_TAG_OBJECT:CA_CreateDynamicObject_SC(modelid, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz, vw = -1, interior = -1, playerid = -1, Float:streamdistance = STREAMER_OBJECT_SD, Float:drawdistance = STREAMER_OBJECT_DD, STREAMER_TAG_AREA:areaid = STREAMER_TAG_AREA:-1, priority = 0) { new STREAMER_TAG_OBJECT:id = CreateDynamicObject(modelid, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz, vw, interior, playerid, streamdistance, drawdistance, areaid, priority); CA_CreateObject(modelid, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz); return id; } stock CA_CreateObject_SC(modelid, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz, Float:drawdistance = 300.0) { new id = CreateObject(modelid, x, y, z, rx, ry, rz, drawdistance); if(id != INVALID_OBJECT_ID) CA_CreateObject(modelid, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz); return id; } // Dynamic collision object functions (Removable) stock CA_CreateDynamicObjectEx_DC(modelid, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz, Float:streamdistance = STREAMER_OBJECT_SD, Float:drawdistance = STREAMER_OBJECT_DD, worlds[] = { -1 }, interiors[] = { -1 }, players[] = { -1 }, STREAMER_TAG_AREA:areas[] = { STREAMER_TAG_AREA:-1 }, priority = 0, maxworlds = sizeof worlds, maxinteriors = sizeof interiors, maxplayers = sizeof players, maxareas = sizeof areas) { new index = -1; #if defined _Y_ITERATE_LOCAL_VERSION index = Iter_Free(CA_Objects); #else for(new i = 0; i < MAX_CA_OBJECTS; i++) { if(CA_ObjectList[i][ObjectUsed] == false) { index = i; break; } } #endif if(index > -1) { #if defined _Y_ITERATE_LOCAL_VERSION Iter_Add(CA_Objects, index); #else CA_ObjectList[index][ObjectUsed] = true; #endif CA_ObjectList[index][ObjectID] = _:CreateDynamicObjectEx(modelid, x, y, z, rx, ry, rz, drawdistance, streamdistance, worlds, interiors, players, areas, priority, maxworlds, maxinteriors, maxplayers, maxareas); CA_ObjectList[index][ColdAndreadsID] = CA_CreateObject(modelid, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz, true); CA_ObjectList[index][ObjectType] = OBJECT_TYPE_DYNAMIC; } return index; } stock CA_CreateDynamicObject_DC(modelid, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz, vw = -1, interior = -1, playerid = -1, Float:streamdistance = STREAMER_OBJECT_SD, Float:drawdistance = STREAMER_OBJECT_DD, STREAMER_TAG_AREA:areaid = STREAMER_TAG_AREA:-1, priority = 0) { new index = -1; #if defined _Y_ITERATE_LOCAL_VERSION index = Iter_Free(CA_Objects); #else for(new i = 0; i < MAX_CA_OBJECTS; i++) { if(CA_ObjectList[i][ObjectUsed] == false) { index = i; break; } } #endif if(index > -1) { #if defined _Y_ITERATE_LOCAL_VERSION Iter_Add(CA_Objects, index); #else CA_ObjectList[index][ObjectUsed] = true; #endif CA_ObjectList[index][ObjectID] = _:CreateDynamicObject(modelid, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz, vw, interior, playerid, streamdistance, drawdistance, areaid, priority); CA_ObjectList[index][ColdAndreadsID] = CA_CreateObject(modelid, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz, true); CA_ObjectList[index][ObjectType] = OBJECT_TYPE_DYNAMIC; } return index; } #endif /**--------------------------------------------------------------------------**\ CA_CreateObject_DC The model to create The position in which to create the object The rotation of the object Whether or not to store this objects index for manual management -1 if the object couldn't be created -1 if there are too many "DC" objects The "DC" index of the created object The index returned by this function can only be used by "DC" functions \**--------------------------------------------------------------------------**/ stock CA_CreateObject_DC(modelid, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz, Float:drawdistance = 300.0) { new index = -1; #if defined _Y_ITERATE_LOCAL_VERSION index = Iter_Free(CA_Objects); #else for(new i = 0; i < MAX_CA_OBJECTS; i++) { if(CA_ObjectList[i][ObjectUsed] == false) { index = i; break; } } #endif new id = CreateObject(modelid, x, y, z, rx, ry, rz, drawdistance); if(id == INVALID_OBJECT_ID) return -1; if(index > -1) { #if defined _Y_ITERATE_LOCAL_VERSION Iter_Add(CA_Objects, index); #else CA_ObjectList[index][ObjectUsed] = true; #endif CA_ObjectList[index][ObjectID] = id; CA_ObjectList[index][ColdAndreadsID] = CA_CreateObject(modelid, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz, true); CA_ObjectList[index][ObjectType] = OBJECT_TYPE_OBJECT; } return index; } /**--------------------------------------------------------------------------**\ CA_DestroyObject_DC The DC index of the object to destroy -1 if the index is invalid -1 if the object doesn't exist 1 or next interator index if the object was destroyed \**--------------------------------------------------------------------------**/ stock CA_DestroyObject_DC(index) { // Out of bounds if(index < 0 || index >= MAX_CA_OBJECTS) return -1; #if defined _Y_ITERATE_LOCAL_VERSION if(Iter_Contains(CA_Objects, index)) { new next; Iter_SafeRemove(CA_Objects, index, next); if(CA_ObjectList[index][ObjectType] == OBJECT_TYPE_OBJECT) DestroyObject(CA_ObjectList[index][ObjectID]); #if defined STREAMER_TYPE_OBJECT else if(CA_ObjectList[index][ObjectType] == OBJECT_TYPE_DYNAMIC) DestroyDynamicObject(STREAMER_TAG_OBJECT:CA_ObjectList[index][ObjectID]); #endif CA_DestroyObject(CA_ObjectList[index][ColdAndreadsID]); return next; } #else if(CA_ObjectList[index][ObjectUsed]) { if(CA_ObjectList[index][ObjectType] == OBJECT_TYPE_OBJECT) DestroyObject(CA_ObjectList[index][ObjectID]); #if defined STREAMER_TYPE_OBJECT else if(CA_ObjectList[index][ObjectType] == OBJECT_TYPE_DYNAMIC) DestroyDynamicObject(STREAMER_TAG_OBJECT:CA_ObjectList[index][ObjectID]); #endif CA_ObjectList[index][ObjectUsed] = false; CA_DestroyObject(CA_ObjectList[index][ColdAndreadsID]); return 1; } #endif return -1; } /**--------------------------------------------------------------------------**\ CA_SetObjectPos_DC The DC index of the object to be moved The new position -1 if the index is invalid -1 if the object doesn't exist 1 if the new position was set successfully \**--------------------------------------------------------------------------**/ stock CA_SetObjectPos_DC(index, Float:x, Float:y, Float:z) { // Out of bounds if(index < 0 || index >= MAX_CA_OBJECTS) return -1; #if defined _Y_ITERATE_LOCAL_VERSION if(Iter_Contains(CA_Objects, index)) { if(CA_ObjectList[index][ObjectType] == OBJECT_TYPE_OBJECT) SetObjectPos(CA_ObjectList[index][ObjectID], x, y, z); #if defined STREAMER_TYPE_OBJECT else if(CA_ObjectList[index][ObjectType] == OBJECT_TYPE_DYNAMIC) SetDynamicObjectPos(STREAMER_TAG_OBJECT:CA_ObjectList[index][ObjectID], x, y, z); #endif CA_SetObjectPos(CA_ObjectList[index][ColdAndreadsID], x, y, z); } #else if(CA_ObjectList[index][ObjectUsed]) { if(CA_ObjectList[index][ObjectType] == OBJECT_TYPE_OBJECT) SetObjectPos(CA_ObjectList[index][ObjectID], x, y, z); #if defined STREAMER_TYPE_OBJECT else if(CA_ObjectList[index][ObjectType] == OBJECT_TYPE_DYNAMIC) SetDynamicObjectPos(STREAMER_TAG_OBJECT:CA_ObjectList[index][ObjectID], x, y, z); #endif SetObjectPos(CA_ObjectList[index][ObjectID], x, y, z); CA_SetObjectPos(CA_ObjectList[index][ColdAndreadsID], x, y, z); return 1; } #endif return -1; } /**--------------------------------------------------------------------------**\ CA_SetObjectRot_DC The DC index of the object to be moved The new rotation -1 if the index is invalid -1 if the object doesn't exist 1 if the new rotation was set successfully \**--------------------------------------------------------------------------**/ stock CA_SetObjectRot_DC(index, Float:rx, Float:ry, Float:rz) { // Out of bounds if(index < 0 || index >= MAX_CA_OBJECTS) return -1; #if defined _Y_ITERATE_LOCAL_VERSION if(Iter_Contains(CA_Objects, index)) { if(CA_ObjectList[index][ObjectType] == OBJECT_TYPE_OBJECT) SetObjectRot(CA_ObjectList[index][ObjectID], rx, ry, rz); #if defined STREAMER_TYPE_OBJECT else if(CA_ObjectList[index][ObjectType] == OBJECT_TYPE_DYNAMIC) SetDynamicObjectRot(STREAMER_TAG_OBJECT:CA_ObjectList[index][ObjectID], rx, ry, rz); #endif CA_SetObjectRot(CA_ObjectList[index][ColdAndreadsID], rx, ry, rz); } #else if(CA_ObjectList[index][ObjectUsed]) { if(CA_ObjectList[index][ObjectType] == OBJECT_TYPE_OBJECT) SetObjectRot(CA_ObjectList[index][ObjectID], rx, ry, rz); #if defined STREAMER_TYPE_OBJECT else if(CA_ObjectList[index][ObjectType] == OBJECT_TYPE_DYNAMIC) SetDynamicObjectRot(STREAMER_TAG_OBJECT:CA_ObjectList[index][ObjectID], rx, ry, rz); #endif CA_SetObjectRot(CA_ObjectList[index][ColdAndreadsID], rx, ry, rz); return 1; } #endif return -1; } /**--------------------------------------------------------------------------**\ CA_DestroyAllObjects_DC Destroys all DC objects \**--------------------------------------------------------------------------**/ stock CA_DestroyAllObjects_DC() { #if defined _Y_ITERATE_LOCAL_VERSION foreach(new i : CA_Objects) { if(CA_ObjectList[i][ObjectType] == OBJECT_TYPE_OBJECT) i = CA_DestroyObject_DC(i); } #else for(new i = 0; i < MAX_CA_OBJECTS; i++) { if(CA_ObjectList[i][ObjectUsed]) { if(CA_ObjectList[i][ObjectType] == OBJECT_TYPE_OBJECT) CA_DestroyObject_DC(i); } } #endif } /**--------------------------------------------------------------------------**\ CA_FindZ_For2DCoord The ColAndreas alternative for MapAndreas's entire function This function does everything MapAndreas is capable of doing, and without the ground limit \**--------------------------------------------------------------------------**/ stock CA_FindZ_For2DCoord(Float:x, Float:y, &Float:z) { if(CA_RayCastLine(x, y, 700.0, x, y, -1000.0, x, y, z)) return 1; return 0; } // Explode ray casts in every direction stock CA_RayCastExplode(Float:cX, Float:cY, Float:cZ, Float:Radius, Float:intensity = 20.0, Float:collisions[][3]) { if(intensity < 1.0 || intensity > 360.0 || (((360.0 / intensity) - floatround((360.0 / intensity), floatround_floor)) * intensity)) return 0; new index; for(new Float:lat = -180.0; lat < 180.0; lat += (intensity * 0.75)) for(new Float:lon = -90.0; lon < 90.0; lon += intensity) { new Float:LAT = lat * 3.141593 / 180.0, Float:LON = lon * 3.141593 / 180.0, Float:x = -Radius * floatcos(LAT) * floatcos(LON), Float:y = Radius * floatcos(LAT) * floatsin(LON), Float:z = Radius * floatsin(LAT); if(CA_RayCastLine(cX, cY, cZ, cX + x, cY + y, cZ + z, x, y, z)) { collisions[index][0] = x; collisions[index][1] = y; collisions[index][2] = z; index++; } } return index; } /**--------------------------------------------------------------------------**\ CA_IsPlayerOnSurface The playerid to check The distance to check for the ground 0 if the player is not on the ground 1 if the player is on the ground \**--------------------------------------------------------------------------**/ stock CA_IsPlayerOnSurface(playerid, Float:tolerance=1.5) { new Float:x, Float:y, Float:z; GetPlayerPos(playerid, x, y, z); // Check if player is actually on the ground if(!CA_RayCastLine(x, y, z, x, y, z-tolerance, x, y, z)) return 0; return 1; } /**--------------------------------------------------------------------------**\ CA_RemoveBarriers Always 1 Removes all of the barrier object collisions You must use this function before using `CA_Init` \**--------------------------------------------------------------------------**/ stock CA_RemoveBarriers() { static const BarrierIDS[] = { 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, 4519, 4520, 4521, 4522, 4523, 4524, 4525, 4526, 4527, 16436, 16437, 16438, 16439, 1662 }; for(new i = 0; i < sizeof(BarrierIDS); i++) CA_RemoveBuilding(BarrierIDS[i], 0.0, 0.0, 0.0, 4242.6407); return 1; } /**--------------------------------------------------------------------------**\ CA_RemoveBreakableBuildings Always 1 Removes all of the breakable object collisions You must use this function before using `CA_Init` \**--------------------------------------------------------------------------**/ stock CA_RemoveBreakableBuildings() { static const BreakableIDs[] = { 625, 626, 627, 628, 629, 630, 631, 632, 633, 642, 643, 644, 646, 650, 716, 717, 737, 738, 792, 858, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 904, 905, 941, 955, 956, 959, 961, 990, 993, 996, 1209, 1211, 1213, 1219, 1220, 1221, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1235, 1238, 1244, 1251, 1255, 1257, 1262, 1264, 1265, 1270, 1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, 1291, 1293, 1294, 1297, 1300, 1302, 1315, 1328, 1329, 1330, 1338, 1350, 1351, 1352, 1370, 1373, 1374, 1375, 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1415, 1417, 1418, 1419, 1420, 1421, 1422, 1423, 1424, 1425, 1426, 1428, 1429, 1431, 1432, 1433, 1436, 1437, 1438, 1440, 1441, 1443, 1444, 1445, 1446, 1447, 1448, 1449, 1450, 1451, 1452, 1456, 1457, 1458, 1459, 1460, 1461, 1462, 1463, 1464, 1465, 1466, 1467, 1468, 1469, 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1481, 1482, 1483, 1514, 1517, 1520, 1534, 1543, 1544, 1545, 1551, 1553, 1554, 1558, 1564, 1568, 1582, 1583, 1584, 1588, 1589, 1590, 1591, 1592, 1645, 1646, 1647, 1654, 1664, 1666, 1667, 1668, 1669, 1670, 1672, 1676, 1684, 1686, 1775, 1776, 1949, 1950, 1951, 1960, 1961, 1962, 1975, 1976, 1977, 2647, 2663, 2682, 2683, 2885, 2886, 2887, 2900, 2918, 2920, 2925, 2932, 2933, 2942, 2943, 2945, 2947, 2958, 2959, 2966, 2968, 2971, 2977, 2987, 2988, 2989, 2991, 2994, 3006, 3018, 3019, 3020, 3021, 3022, 3023, 3024, 3029, 3032, 3036, 3058, 3059, 3067, 3083, 3091, 3221, 3260, 3261, 3262, 3263, 3264, 3265, 3267, 3275, 3276, 3278, 3280, 3281, 3282, 3302, 3374, 3409, 3460, 3516, 3794, 3795, 3797, 3853, 3855, 3864, 3884, 11103, 12840, 16627, 16628, 16629, 16630, 16631, 16632, 16633, 16634, 16635, 16636, 16732, 17968 }; for(new i = 0; i < sizeof(BreakableIDs); i++) CA_RemoveBuilding(BreakableIDs[i], 0.0, 0.0, 0.0, 4242.6407); return 1; } /**--------------------------------------------------------------------------**\ CA_IsPlayerInWater The playerid to check The depth The depth of the player 0 if the player is not in water 1 if the player is in water \**--------------------------------------------------------------------------**/ stock CA_IsPlayerInWater(playerid, &Float:depth, &Float:playerdepth) { new Float:x, Float:y, Float:z, Float:retx[10], Float:rety[10], Float:retz[10], Float: retdist[10], modelids[10]; GetPlayerPos(playerid, x, y, z); new collisions = CA_RayCastMultiLine(x, y, z+1000.0, x, y, z-1000.0, retx, rety, retz, retdist, modelids, 10); if(collisions > 0) { for(new i = 0; i < collisions; i++) { if(modelids[i] == WATER_OBJECT) { depth = FLOAT_INFINITY; for(new j = 0; j < collisions; j++) { if(retz[j] < depth) depth = retz[j]; } depth = retz[i] - depth; if(depth < 0.001 && depth > -0.001) depth = 100.0; playerdepth = retz[i] - z; if(playerdepth < -2.0) return 0; return 1; } } } return 0; } /**--------------------------------------------------------------------------**\ CA_IsPlayerNearWater The playerid to check The distance to check for water The height the player can be from the water 0 if the player is not in water 1 if the player is in water Checks for water all around the player \**--------------------------------------------------------------------------**/ stock CA_IsPlayerNearWater(playerid, Float:dist=3.0, Float:height=3.0) { new Float:x, Float:y, Float:z, Float:tmp; GetPlayerPos(playerid, x, y, z); for(new i; i < 6; i++) if(CA_RayCastLine(x + (dist * floatsin(i * 60.0, degrees)), y + (dist * floatcos(i * 60.0, degrees)), z + height, x + (dist * floatsin(i * 60.0, degrees)), y + (dist * floatcos(i * 60.0, degrees)), z - height, tmp, tmp, tmp) == WATER_OBJECT) return 1; return 0; } /**--------------------------------------------------------------------------**\ CA_IsPlayerFacingWater The playerid to check The distance to check for water The height the player can be from the water 0 if the player is not in water 1 if the player is in water Checks for water only in front of the player \**--------------------------------------------------------------------------**/ stock CA_IsPlayerFacingWater(playerid, Float:dist=3.0, Float:height=3.0) { new Float:x, Float:y, Float:z, Float:r, Float:tmp; GetPlayerPos(playerid, x, y, z); GetPlayerFacingAngle(playerid, r); if(CA_RayCastLine(x + (dist * floatsin(-r, degrees)), y + (dist * floatcos(-r, degrees)), z, x + (dist * floatsin(-r, degrees)), y + (dist * floatcos(-r, degrees)), z - height, tmp, tmp, tmp) == WATER_OBJECT) return 1; return 0; } /**--------------------------------------------------------------------------**\ CA_IsPlayerBlocked The playerid to check The distance to check for a wall The height the wall can be from the ground 0 if the player is not blocked 1 if the player is blocked \**--------------------------------------------------------------------------**/ stock CA_IsPlayerBlocked(playerid, Float:dist=1.5, Float:height=0.5) { new Float:x, Float:y, Float:z, Float:endx, Float:endy, Float:fa; GetPlayerPos(playerid, x, y, z); z -= 1.0 + height; GetPlayerFacingAngle(playerid, fa); endx = (x + dist * floatsin(-fa,degrees)); endy = (y + dist * floatcos(-fa,degrees)); if(CA_RayCastLine(x, y, z, endx, endy, z, x, y, z)) return 1; return 0; } /**--------------------------------------------------------------------------**\ Float:CA_GetRoomHeight A point in the area to be checked 0.0 if there is either no floor or no ceiling The distance from the ceiling to the floor \**--------------------------------------------------------------------------**/ stock Float:CA_GetRoomHeight(Float:x, Float:y, Float:z) { new Float:fx, Float:fy, Float:fz, Float:cx, Float:cy, Float:cz; if(CA_RayCastLine(x, y, z, x, y, z-1000.0, fx, fy, fz)) { if(CA_RayCastLine(x, y, z, x, y, z+1000.0, cx, cy, cz)) return floatsqroot(((fx-cx)*(fx-cx))+((fy-cy)*(fy-cy))+((fz-cz)*(fz-cz))); } return 0.0; } /**--------------------------------------------------------------------------**\ Float:CA_GetRoomCenter A point in the area to be checked The center X and Y of the area -1.0 if there isn't enough collisions to determine the center The radius of the circle formed by the test \**--------------------------------------------------------------------------**/ stock Float:CA_GetRoomCenter(Float:x, Float:y, Float:z, &Float:m_x, &Float:m_y) { new Float:pt1x, Float:pt1y, Float:pt2x, Float:pt2y, Float:pt3x, Float:pt3y, Float:tmp; if(!CA_RayCastLine(x, y, z, x + 1000.0 * floatcos(0.0, degrees), y + 1000.0 * floatsin(0.0, degrees), z, pt1x, pt1y, tmp) || !CA_RayCastLine(x, y, z, x + 1000.0 * floatcos(120.0, degrees), y + 1000.0 * floatsin(120.0, degrees), z, pt2x, pt2y, tmp) || !CA_RayCastLine(x, y, z, x + 1000.0 * floatcos(-120.0, degrees), y + 1000.0 * floatsin(-120.0, degrees), z, pt3x, pt3y, tmp)) return -1.0; new Float:yDelta_a = pt2y - pt1y, Float:xDelta_a = pt2x - pt1x, Float:yDelta_b = pt3y - pt2y, Float:xDelta_b = pt3x - pt2x; if (floatabs(xDelta_a) <= 0.000000001 && floatabs(yDelta_b) <= 0.000000001) { m_x = 0.5 * (pt2x + pt3x); m_y = 0.5 * (pt1y + pt2y); return VectorSize(m_x - pt1x, m_y - pt1y, 0.0); } new Float:aSlope = yDelta_a / xDelta_a, Float:bSlope = yDelta_b / xDelta_b; if (floatabs(aSlope-bSlope) <= 0.000000001) return -1.0; m_x = (aSlope * bSlope * (pt1y - pt3y) + bSlope * (pt1x + pt2x) - aSlope * (pt2x + pt3x)) / (2.0 * (bSlope - aSlope)); m_y = -1.0 * (m_x - (pt1x + pt2x) / 2.0) / aSlope + (pt1y + pt2y) / 2.0; return VectorSize(m_x - pt1x, m_y - pt1y, 0.0); } // Hooked functions public OnFilterScriptExit() { CA_DestroyAllObjects_DC(); if (funcidx("CA_OnFilterScriptExit") != -1) { return CallLocalFunction("CA_OnFilterScriptExit", ""); } return 1; } #if defined _ALS_OnFilterScriptExit #undef OnFilterScriptExit #else #define _ALS_OnFilterScriptExit #endif #define OnFilterScriptExit CA_OnFilterScriptExit forward CA_OnFilterScriptExit(); public OnGameModeExit() { CA_DestroyAllObjects_DC(); if (funcidx("CA_OnGameModeExit") != -1) { return CallLocalFunction("CA_OnGameModeExit", ""); } return 1; } #if defined _ALS_OnGameModeExit #undef OnGameModeExit #else #define _ALS_OnGameModeExit #endif #define OnGameModeExit CA_OnGameModeExit forward CA_OnGameModeExit(); /* Create a object with collision in ColAndreas dynamic CA_CreateObject_DC(modelid, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz, Float:drawdistance = 300.0) Destroy a object with collision in ColAndreas CA_DestroyObject_DC(index) Destoys all objects streamer/regular CA_DestroyAllObjects_DC() MapAndreas replacement function CA_FindZ_For2DCoord(Float:x, Float:y, &Float:z) Explode ray casts in every direction CA_RayCastExplode(Float:cX, Float:cY, Float:cZ, Float:Radius, Float:intensity = 20.0, Float:collisions[][3]) Checks if a player is standing on any surface (prevent animation exploit when falling) CA_IsOnSurface(playerid, Float:tolerance=1.5) Removes all barries this function only works BEFORE using CA_Init() CA_RemoveBarriers() Removes all dynamic breakable objects, also only works BEFORE using CA_Init() CA_RemoveBreakableBuildings() Checks if a player is in the water depth returns the lowest collision point found playerdepth returns how deep the player is below the surface CA_IsPlayerInWater(playerid, &Float:depth, &Float:playerdepth) Checks if a player is near water (returns 0 if they are actually in the water) distance is the radius to check Height is how high above the water to detect CA_IsNearWater(playerid, Float:dist=3.0, Float:height=3.0) // Check if a player is blocked by a wall CA_IsBlocked(playerid, Float:dist=1.5, Float:height=0.5) Notes: Recommended loading order - RemoveBuildings - Init static map - Add static objects There is currently no support for virtual worlds / interior or per player with streamer objects */