Коллекция функций / макросов

Функция, рисующая луч в игровом мире от одной точки до другой и возвращающая позицию, в которой луч столкнулся с объектом/машиной/игроком.

Аргументы:
PHP Code:
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 - пропускать игроков 
Функция:
PHP Code:
#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 );
} 
Дополнительные функции, используемые в системе:
native IsValidVehicle(vehicleid);
Плагин MapAndreas: https://sampforum.blast.hk/showthread.php?tid=275492

Пример использования:
PHP Code:
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); 
Reply

Quote:
Originally Posted by Seregamil1
View Post
Функция, рисующая луч в игровом мире от одной точки до другой и возвращающая позицию, в которой луч столкнулся с объектом/машиной/игроком.
Никогда и не при каких обстоятельствах не используйте с алгоритмами поиска пути или видимости для НПС/зомби. Ибо сие творение для разового использования и при большой дистанции способно повесить сервер.
Reply

Функция, которая равномерно развивает скорость объекта от заданной минимальной, до заданной максимальной, за заданное количество времени.

[ame]http://www.youtube.com/watch?v=b2Z0PsWKRQg[/ame]

Сама функция:

PHP Code:
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 );
} 
Использование:
PHP Code:
MoveObjectWithAcceleration( Объект, начальная скорость, конечная скорость, координаты XYZ финальной позиции, Время в мс, за которое объект должен ускориться ); 
Reply

GetVehicleDriftAngle
Данная функция получает угол и направление заноса транспортного средства.

pawn Code:
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;
}
Направление заноса
  • Угол < 0 - смещение направления транспорта влево относительно направления движения.
  • Угол > 0 - смещение направления транспорта вправо относительно направления движения.
Reply

Вчера обнаружил баг IsPlayerConnected. Если указать число больше 65535, то из-за типа данных оно будет идти по кругу, т.е. 65536 > 0, 65537 > 1 и т.д. (то же самое можно проделать со значениями, которые меньше 0). Функция вернет 1, а в вашем скрипте произойдет обращение к несуществующей ячейке.

pawn Code:
Fix_IsPlayerConnected(playerid) return (0 <= playerid <= 65535) ? (IsPlayerConnected(playerid)) : (0);
#define IsPlayerConnected(%0) Fix_IsPlayerConnected(%0)
Reply

Quote:
Originally Posted by stabker
View Post
Вчера обнаружил баг IsPlayerConnected. Если указать число больше 65535, то из-за типа данных оно будет идти по кругу, т.е. 65536 > 0, 65537 > 1 и т.д. (то же самое можно проделать со значениями, которые меньше 0). Функция вернет 1, а в вашем скрипте произойдет обращение к несуществующей ячейке.

pawn Code:
Fix_IsPlayerConnected(playerid) return (0 <= playerid <= 65535) ? (IsPlayerConnected(playerid)) : (0);
#define IsPlayerConnected(%0) Fix_IsPlayerConnected(%0)
это не баг, это переполнение ячейки.
Reply

Quote:
Originally Posted by Stepashka
View Post
это не баг, это переполнение ячейки.
Я это и имел ввиду =>
Quote:
Originally Posted by stabker
View Post
... Если указать число больше 65535, то из-за типа данных оно будет идти по кругу ...
Reply

Quote:
Originally Posted by stabker
View Post
Я это и имел ввиду =>
Я не об этом. Править надо не это, а то место где у вас сюда приходит невалидное значение. Вы боритесь со следствием, а бороться надо с причиной!

Да и код для темы по оптимизации не оптимизирован:
pawn Code:
#define IsPlayerConnected(%0) ((0 <= %0 < MAX_PLAYERS) ? IsPlayerConnected(%0) : false)
Reply

Quote:
Originally Posted by Stepashka
View Post
Я не об этом. Править надо не это а то место где у вас сюда приходит невалидное значение. Вы боритесь со следствием, а бороться надо с причиной!

Да и код для темы по оптимизации не оптимизирован:
pawn Code:
#define IsPlayerConnected(%0) ((0 <= %0 < MAX_PLAYERS) ? IsPlayerConnected(%0) : false)
По поводу причины - прочитайте мой пост выше. Возможно вы и правы, но меня такое решение вполне устраивает, учитывая, что причин может быть много.

65535 вместо MAX_PLAYERS специально использовал, чтобы функционал оставался в пределах разрешенного (мало ли, что я с ней делать хочу).

Ваша оптимизация радует, особенно бесконечный цикл, из-за которого компиляция так и не закончится.

В общем, мое дело предложить, ваше дело отказаться.
Reply

Quote:
Originally Posted by stabker
Посмотреть сообщение
Ваша оптимизация радует, особенно бесконечный цикл, из-за которого компиляция так и не закончится.
В его коде нет бесконечного цикла, вообще цикла нет.
Reply

Quote:
Originally Posted by ZiGGi
Посмотреть сообщение
В его коде нет бесконечного цикла, вообще цикла нет.
Он имеет в виду внутри замены есть код который заменяется и дефайн начинает бесконечно сам себя заменять.
Особенность компилятора
Reply

Quote:
Originally Posted by Stepashka
Посмотреть сообщение
Он имеет в виду внутри замены есть код который заменяется и дефайн начинает, бесконечно сам себя заменять.
Особенность компилятора
А, ну да.
Reply

Узнал о интересной возможности:

pawn Код:
native Copy_IsPlayerConnected(playerid) = IsPlayerConnected;
#define IsPlayerConnected(%0) ((0 <= (%0) < MAX_PLAYERS) ? (Copy_IsPlayerConnected(%0)) : (0))
Reply

Есть у кого urlencode? Или принцип ее работы. На какие символы она заменяет буквы?
Reply

Quote:
Originally Posted by Jon_De
Посмотреть сообщение
Есть у кого urlencode? Или принцип ее работы. На какие символы она заменяет буквы?
Кодирование URL
Reply

Quote:
Originally Posted by stabker
Посмотреть сообщение
Узнал о интересной возможности:

pawn Код:
native Copy_IsPlayerConnected(playerid) = IsPlayerConnected;
#define IsPlayerConnected(%0) ((0 <= (%0) < MAX_PLAYERS) ? (Copy_IsPlayerConnected(%0)) : (0))
Описать принцип кто может? Что делает эта "интересная возможность"
Reply

Quote:
Originally Posted by Makar007
Посмотреть сообщение
Описать принцип кто может? Что делает эта "интересная возможность"
Copy_IsPlayerConnected объявляется копией метода IsPlayerConnected.
Reply

А почему в первом случае есть аргумент, а во втором нет?
Reply

Quote:
Originally Posted by OKStyle
Посмотреть сообщение
А почему в первом случае есть аргумент, а во втором нет?
Определение прототипа функции и присвоение ему указателя на другую функцию (по сути funcidx)
Reply

OKStyle, любитель толстого кода?

Твоя функция ошибочна, она обязана вернуть значение

pawn Код:
stock GetFreeAttachSlot(playerid)
{
    for(new i = 10; i--;) if(!IsPlayerAttachedObjectSlotUsed(playerid, i)) return i;
    return 0;
}
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)