processLineOfSight(
//координаты старта
Float: start_x,
Float: start_y,
Float: start_z,
//координаты конца, в них же записываются координаты последней доступной точки
&Float: end_x,
&Float: end_y,
&Float: end_z,
//параметры проверки
bool: check_vehicles, //true - проверять машины, false - пропускать машины
bool: check_players ) //true - проверять игроков, false - пропускать игроков
#define radiusCollision 3.0
processLineOfSight( Float: start_x, Float: start_y, Float: start_z, &Float: end_x, &Float: end_y, &Float: end_z, bool: check_vehicles, bool: check_players ){//by Seregamil
new distance_between_points = floatround( VectorSize( end_x - start_x, end_y - start_y, end_z - start_z ) );
if( distance_between_points == 0 )
return ;
new Float: pack_pos_x = floatdiv( end_x - start_x, float( distance_between_points ) ),
Float: pack_pos_y = floatdiv( end_y - start_y, float( distance_between_points ) ),
Float: pack_pos_z = floatdiv( end_z - start_z, float( distance_between_points ) ),
Float: map_z = 0.0,
j = -1, Float: pos_x, Float: pos_y, Float: pos_z , i = 1;
do{
start_x += pack_pos_x;
start_y += pack_pos_y;
start_z += pack_pos_z;
if( check_vehicles ){
for( ; i != MAX_VEHICLES; i++ ){
if( !IsValidVehicle( i ) ) continue;
GetVehiclePos( i, pos_x, pos_y, pos_z );
if( VectorSize( pos_x - start_x, pos_y - start_y, pos_z - start_z ) > radiusCollision ) continue;
end_x = start_x;
end_y = start_y;
end_z = start_z;
return ;
}
}
if( check_players ){
for( i = GetMaxPlayers() - 1; i != -1; i-- ){
if( IsPlayerNPC( i ) || !IsPlayerConnected( i ) ) continue;
GetPlayerPos( i, pos_x, pos_y, pos_z );
if( !IsPlayerInRangeOfPoint( i , radiusCollision, pos_x, pos_y, pos_z ) ) continue;
end_x = start_x;
end_y = start_y;
end_z = start_z;
return ;
}
}
MapAndreas_FindZ_For2DCoord( start_x, start_y, map_z );
if( map_z < start_z )
continue;
end_x = start_x;
end_y = start_y;
end_z = start_z;
break;
}
while( ++j < distance_between_points );
}
new Float:x = 0.0, Float:y = 0.0, Float:z = 0.0, Object = CreateObject( 2000, -10.4548,55.2839,12.1676, 0.0, 0.0, 0.0 );
processLineOfSight( -10.4548,55.2839,12.1676, x,y,z, false, true );
MoveObject(Object, x,y,z,3.0);
Функция, рисующая луч в игровом мире от одной точки до другой и возвращающая позицию, в которой луч столкнулся с объектом/машиной/игроком.
|
forward MoveObjectWithAcceleration( objectid, Float: startSpeed, Float: endSpeed, Float: x, Float: y, Float: z, accelerationTime );
public MoveObjectWithAcceleration( objectid, Float: startSpeed, Float: endSpeed, Float: x, Float: y, Float: z, accelerationTime ){//by Seregamil
if( !IsValidObject( objectid ) )
return ;
new Float: newSpeed = ( endSpeed + startSpeed ) / 10 + startSpeed ;
if( newSpeed >= endSpeed )
return ;
MoveObject( objectid, x, y, z, newSpeed );
SetTimerEx( "MoveObjectWithAcceleration", accelerationTime / 10, false, "ifffffi", objectid, newSpeed, endSpeed, x, y, z, accelerationTime );
}
MoveObjectWithAcceleration( Объект, начальная скорость, конечная скорость, координаты XYZ финальной позиции, Время в мс, за которое объект должен ускориться );
stock GetVehicleDriftAngle(vehicleid, &Float:fVehDriftAngle)
{
static
Float: fVehVelocity[3],
Float: fVehAngle,
Float: fVehMoveAngle;
if (!GetVehicleVelocity(vehicleid, fVehVelocity[0], fVehVelocity[1], fVehVelocity[2])) {
return 0;
}
if (!floatcmp(fVehVelocity[0], 0.0) && !floatcmp(fVehVelocity[1], 0.0)) {
fVehDriftAngle = 0.0;
return 1;
}
fVehMoveAngle = -atan2(fVehVelocity[0], fVehVelocity[1]);
GetVehicleZAngle(vehicleid, fVehAngle);
if (floatcmp(fVehAngle, 180.0) == 1) {
fVehAngle -= 360.0;
}
fVehDriftAngle = floatsub(fVehMoveAngle, fVehAngle);
if (floatcmp(fVehDriftAngle, -180.0) == -1) {
fVehDriftAngle += 360.0;
}
else if (floatcmp(fVehDriftAngle, 180.0) == 1) {
fVehDriftAngle -= 360.0;
}
return 1;
}
Fix_IsPlayerConnected(playerid) return (0 <= playerid <= 65535) ? (IsPlayerConnected(playerid)) : (0);
#define IsPlayerConnected(%0) Fix_IsPlayerConnected(%0)
Вчера обнаружил баг IsPlayerConnected. Если указать число больше 65535, то из-за типа данных оно будет идти по кругу, т.е. 65536 > 0, 65537 > 1 и т.д. (то же самое можно проделать со значениями, которые меньше 0). Функция вернет 1, а в вашем скрипте произойдет обращение к несуществующей ячейке.
pawn Code:
|
... Если указать число больше 65535, то из-за типа данных оно будет идти по кругу ...
|
#define IsPlayerConnected(%0) ((0 <= %0 < MAX_PLAYERS) ? IsPlayerConnected(%0) : false)
Я не об этом. Править надо не это а то место где у вас сюда приходит невалидное значение. Вы боритесь со следствием, а бороться надо с причиной!
Да и код для темы по оптимизации не оптимизирован: pawn Code:
|
Ваша оптимизация радует, особенно бесконечный цикл, из-за которого компиляция так и не закончится.
|
Он имеет в виду внутри замены есть код который заменяется и дефайн начинает, бесконечно сам себя заменять.
![]() Особенность компилятора ![]() |
native Copy_IsPlayerConnected(playerid) = IsPlayerConnected;
#define IsPlayerConnected(%0) ((0 <= (%0) < MAX_PLAYERS) ? (Copy_IsPlayerConnected(%0)) : (0))
Есть у кого urlencode? Или принцип ее работы. На какие символы она заменяет буквы?
|
Узнал о интересной возможности:
pawn Код:
|
Описать принцип кто может? Что делает эта "интересная возможность"
|
stock GetFreeAttachSlot(playerid)
{
for(new i = 10; i--;) if(!IsPlayerAttachedObjectSlotUsed(playerid, i)) return i;
return 0;
}