Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Страница 1 из 2 1 2 ПоследняяПоследняя
Показано с 1 по 10 из 14

Тема: SetPlayerPosEx

  1. #1
    Аватар для #iDanny
    Пользователь

    Статус
    Оффлайн
    Регистрация
    06.03.2018
    Сообщений
    15
    Репутация:
    0 ±

    SetPlayerPosEx

    Всем привет.

    В группе форума столкнулся на одного интересного персонажа, он не мог решить проблему с подгрузкой объектов. Накидал ему функцию чтобы "фризило", воть. Сейчас успокоился, немного оптимизировал и добавил функционала и делюсь с вами.

    Параметры:
    *обязательные*
    • playerid - id телепортируемого игрока
    • x, y, z - координаты X, Y, Z телепортируемого места
    *не обязательные*
    • angle - угол поворота
    • virtualworldid - id виртуального мира
    • interiorid - id интеръера
    • vehicletp - режим телепорта транспорта (1 - ТП с транспортом, 0 - Без). П.с: условии для проверки на нахождение в транспорте не требуется, функция это предусматривает.
    • passengertp - режим телепорта пассажиров (работает при включенном "vehicletp"): 0 - слапнуть, 1 - телепортировать вместе.
    • freezetime - время до разморозки игрока (используйте 0 чтобы не замораживать). Default: 0


    Пример использования:
    PHP код:
    CMD:tp(playerid)
    {
        
    SetPlayerPosEx(playerid0.00.02.0);
        return 
    SendClientMessage(playerid, -1, !"Вы телепортированы в центр карты.");

    Функция:
    PHP код:
    stock
        SetPlayerPosEx
    (playeridFloat:xFloat:yFloat:zFloat:angle 0.0,
            
    virtualworldid = -1interiorid = -1vehicletp 0passengertp 0freezetime 0)
    {
        new
            
    vehicleid GetPlayerVehicleID(playerid);
            
        
    #if defined Streamer_IncludeFileVersion
        
    Streamer_UpdateEx(playeridxyzvirtualworldidinteriorid);
        
    #endif
        
    if(!vehicletp || GetPlayerState(playerid) != PLAYER_STATE_DRIVER)
        {
            
    SetPlayerPos(playeridxyz);
            
            if(-
    != interiorid)
                
    SetPlayerInterior(playeridinteriorid);
            
            if(-
    != virtualworldid)
                
    SetPlayerVirtualWorld(playeridvirtualworldid);

            if(
    0.0 != angle)
                
    SetPlayerFacingAngle(playeridangle);
            
            if(
    freezetime)
            {
                
    TogglePlayerControllable(playerid0);
                
    SetTimerEx(!"@__unfreezeLoadInt"freezetime0, !"i"playerid);
            }
            return 
    SetCameraBehindPlayer(playerid);
        }
        
        static
            
    Float:pos_x,
            
    Float:pos_y,
            
    Float:pos_z;

        
    GetPlayerPos(playeridpos_xpos_ypos_z);

        if(-
    != interiorid)
            
    LinkVehicleToInterior(vehicleidinteriorid);

        if(-
    != virtualworldid)
            
    SetVehicleVirtualWorld(vehicleidvirtualworldid);
        
    #if defined foreach
        
    foreach(Playeri)
    #else
        
    for(new iMAX_PLAYERSi++)
    #endif
        
    {
            if(
    GetPlayerVehicleID(i) == vehicleid)
            {
                if(!
    passengertp)
                {
                    
    #if defined Streamer_IncludeFileVersion
                    
    Streamer_UpdateEx(ixyzvirtualworldidinteriorid);
                    
    #endif
                    
    if(-!= interiorid)
                        
    SetPlayerInterior(iinteriorid);

                    if(-
    != virtualworldid)
                        
    SetPlayerVirtualWorld(ivirtualworldid);
                        
                    
    SetCameraBehindPlayer(i);
                }
                else
                    
    SetPlayerPos(ipos_xpos_y+0.5pos_z+1.0);
            }
        }
        
    SetVehiclePos(vehicleidxy1.0);

        if(
    angle != 0.0)
            
    SetVehicleZAngle(vehicleidangle);

        
    SetPlayerPos(playeridxyz);
        
    PutPlayerInVehicle(playeridvehicleid0);
        return 
    SetCameraBehindPlayer(playerid);
    }

    @
    __unfreezeLoadInt(playerid);
    @
    __unfreezeLoadInt(playerid)
        return 
    TogglePlayerControllable(playerid1); 
    • Автор: Danny Moore
    Последний раз редактировалось #iDanny; 08.03.2018 в 01:50. Причина: v1.2

  2. #2
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  3. #3
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от DeimoS Посмотреть сообщение
    Следует заметить, что тот инклуд был написан ещё в конце 2013-го, я тогда не учёл возможность телепортации пассажиров в транспорте (которая учтена в этой теме). Впрочем, это не так уж и сложно добавить.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  4. #4
    Аватар для whale
    Пользователь

    Статус
    Оффлайн
    Регистрация
    10.04.2014
    Сообщений
    74
    Репутация:
    17 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Следует заметить, что тот инклуд был написан ещё в конце 2013-го, я тогда не учёл возможность телепортации пассажиров в транспорте (которая учтена в этой теме). Впрочем, это не так уж и сложно добавить.
    Думаю, что вариант ниже вполне подойдёт (если нет - укажите на ошибки, пожалуйста). Правда, пришлось сначала делать проверку с tppassenger и уже после запускать цикл, ибо как-то не хотелось создавать 3 переменные при каждой итерации (в случае с функцией ТС`а игроков телепортирует на координаты playerid и немного в сторону, в этом случае их просто смещает с их координат).

    PHP код:
    stock SetPlayerPosEx(playeridFloat:xFloat:yFloat:zinterior cellminworld cellmintpcar 1tppassenger 1)
    {
        
    Streamer_ToggleIdleUpdate(playerid1);

        if(
    dc_spp__control{playerid})
        {
            
    TogglePlayerControllable(playerid0);
            
    SetTimerEx("@__dc_spp__unfreeze"DC_SPP__FREEZE_TIME0"d"playerid);
        }

        
    Streamer_UpdateEx(playeridxyzworldinterior);

        if(
    interior != cellmin)
            
    SetPlayerInterior(playeridinterior);

        if(
    world != cellmin)
            
    SetPlayerVirtualWorld(playeridworld);

        if(
    tpcar && GetPlayerState(playerid) == PLAYER_STATE_DRIVER)
        {
            new 
                
    veh GetPlayerVehicleID(playerid);

            if(
    world != cellmin)
                
    SetVehicleVirtualWorld(vehworld);

            
    SetVehiclePos(vehxyz);

            if(
    tppassenger)
            {
                
    #if defined foreach
                
    foreach(new iPlayer)
                
    #elseif defined GetPlayerPoolSize
                
    for(new GetPlayerPoolSize(); >= 0i--)
                
    #else
                
    for(new MAX_PLAYERS>= 0i--)
                
    #endif
                
    {
                    if(
    == IsPlayerConnected(i))
                        continue;

                    if(
    != playerid && GetPlayerVehicleID(i) == veh)
                    {
                        if(
    interior != cellmin)
                            
    SetPlayerInterior(iinterior);

                        if(
    world != cellmin)
                            
    SetPlayerVirtualWorld(iworld);
                    }
                }
            }
            else
            {
                new
                    
    Float:pos_x,
                    
    Float:pos_y,
                    
    Float:pos_z;

                
    #if defined foreach
                
    foreach(new iPlayer)
                
    #elseif defined GetPlayerPoolSize
                
    for(new GetPlayerPoolSize(); >= 0i--)
                
    #else
                
    for(new MAX_PLAYERS>= 0i--)
                
    #endif
                
    {
                    if(
    == IsPlayerConnected(i))
                        continue;

                    if(
    != playerid && GetPlayerVehicleID(i) == veh)
                    {
                        
    GetPlayerPos(ipos_xpos_ypos_z);
                        
    SetPlayerPos(ipos_xpos_y 0.5pos_z 1.0);
                    }
                }
            }
        }
        else
            
    SetPlayerPos(playeridxyz);


  5. Пользователь сказал cпасибо:
    #iDanny (07.03.2018)
  6. #5
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от Twixyck Посмотреть сообщение
    Думаю, что вариант ниже вполне подойдёт (если нет - укажите на ошибки, пожалуйста). Правда, пришлось сначала делать проверку с tppassenger и уже после запускать цикл, ибо как-то не хотелось создавать 3 переменные при каждой итерации (в случае с функцией ТС`а игроков телепортирует на координаты playerid и немного в сторону, в этом случае их просто смещает с их координат.
    Спасибо, конечно, но я уже добавил нужный код, правда, не настолько сложный (хотя бы потому, что в моём варианте нет опции tppassenger, хоть я и могу добавить её в будущем, если кому понадобится).

    EDIT: Очень некрасиво смотрится, когда одна ветка if взята в фигурные скобки, а другая нет, сбивает с толку.
    PHP код:
    if(tpcar && GetPlayerState(playerid) == PLAYER_STATE_DRIVER
    {
        
    // ...
    }
    else
        
    SetPlayerPos(playeridxyz); 
    Поскольку после ветки else больше никакого кода нет (конец функции), ИМХО лучше сделать ветвление по принципу отсечки, без else.
    PHP код:
    if(tpcar == || GetPlayerState(playerid) != PLAYER_STATE_DRIVER)
        return 
    SetPlayerPos(playeridxyz);
    // ... 
    Также в цикле с перебором игроков вызывается IsPlayerConnected() - зачем? Мало того, что это не нужно в случае с foreach, так проверка на подключение и без того встроена в другие функции, работающие с ID игроков. Например, GetPlayerVehicleID() вернёт 0 (неправильный ID транспорта), если игрок не подключен, т.е. можно сделать так:
    PHP код:
    if (GetPlayerVehicleID() != veh)
        continue; 
    Вот так элегантно можно вызовом одной функции и проверить подключение, и получить ID ТС игрока.

    Учитывать возможность того, что функция GetPlayerPoolSize() не объявлена, тоже сомнительно, времена 0.3z прошли ещё 3 года назад.

    Касаемо содержимого цикла, проверку на равенство i и playerid можно выкинуть, вынеся действия только с playerid в ветку if, в которой обрабатывается ситуация, когда игрок не за рулём (см. выше).
    PHP код:
    if(tpcar == || GetPlayerState(playerid) != PLAYER_STATE_DRIVER)
    {
        if(
    interior != -1)
            
    SetPlayerInterior(playeridinterior);
        if(
    world != -1)
            
    SetPlayerVirtualWorld(playeridworld); 
        return 
    SetPlayerPos(playeridxyz);

    Также можно сэкономить несколько байт за счёт упаковки строк.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  7. Пользователь сказал cпасибо:
    whale (07.03.2018)
  8. #6
    Аватар для #iDanny
    Пользователь

    Статус
    Оффлайн
    Регистрация
    06.03.2018
    Сообщений
    15
    Репутация:
    0 ±
    Скоро обновлю функцию. Меня больше беспокоит то, что если игрок заморожен "в другом скрипте" (например командой /freeze) мой скрипт разморозит его. Если есть мысли по этой теме - буду рад их услышать.

  9. #7
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от #iDanny Посмотреть сообщение
    Скоро обновлю функцию. Меня больше беспокоит то, что если игрок заморожен "в другом скрипте" (например командой /freeze) мой скрипт разморозит его. Если есть мысли по этой теме - буду рад их услышать.
    Насколько знаю, нет такой функции, которой можно узнать состояние заморозки игрока, и которая правильно работает при заморозке из других скриптов. ИМХО, самый железный способ здесь - перехватить функцию TogglePlayerControllable из плагина, чтобы отслеживать заморозку из всех скриптов, и из того же плагина предоставить функцию IsPlayerControllable. Перебор это или нет - вам решать.
    EDIT: Либо это, либо взаимодействие с помощью PVar'ов.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  10. #8
    Аватар для #iDanny
    Пользователь

    Статус
    Оффлайн
    Регистрация
    06.03.2018
    Сообщений
    15
    Репутация:
    0 ±
    Daniel_Cortez,

    Увы, скорее всего так и есть. Думал вынести функцию в отдельный инклюд и перехватить функцию TogglePlayerControllable в скрипте, но я счёл это "вмешательством" в чужой код. Увы, не знаток в написании плагинов, скорее всего так и оставлю. Пользователям остается предусматривать это в своих модах, или коллективно просить кую добавить функцию IsPlayerControllable
    Последний раз редактировалось #iDanny; 08.03.2018 в 01:51.

  11. #9
    Аватар для #iDanny
    Пользователь

    Статус
    Оффлайн
    Регистрация
    06.03.2018
    Сообщений
    15
    Репутация:
    0 ±
    Функция обновлена до версии 1.2.

    Исправлена ошибка, когда транспорту задавалось неправильный ID виртуального мира.
    Добавлена поддержка стримера, теперь загрузка объектов начинается до телепорта игрока в указанное место.

  12. #10
    Аватар для SliM
    Пользователь

    Статус
    Оффлайн
    Регистрация
    06.11.2015
    Сообщений
    40
    Репутация:
    10 ±
    а зачем эти условия?
    PHP код:
    if(-!= interiorid)
        
    SetPlayerInterior(playeridinteriorid);
    if(-
    != virtualworldid)
        
    SetPlayerVirtualWorld(playeridvirtualworldid);
    if(
    0.0 != angle)
        
    SetPlayerFacingAngle(playeridangle); 
    по дефолту установить 0 заместо -1
    PHP код:
    Float:angle 0.0virtualworldid 0interiorid 0
     SetPlayerInterior
    (playeridinteriorid);
    SetPlayerVirtualWorld(playeridvirtualworldid);
    SetPlayerFacingAngle(playeridangle); 
    ну с углом поворота можно и оставить условие...

 

 
Страница 1 из 2 1 2 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •