Перейти к содержимому


Фотография

Интересный скрипт миссии "BusMod" by rooft0p, разбор полётов.

скрипт миссии

  • Авторизуйтесь для ответа в теме
Сообщений в теме: 99

#1 vorotkov

vorotkov

    Активный участник

  • Пользователи
  • PipPipPip
  • 63 сообщений

Отправлено 07 March 2015 - 10:56

Добрый день!

Есть такой мод, как "BusMod Beta V1.0.1.1 by rooft0p aka moochaka"

 

Если кратко, то это скрипт миссии "Водитель автобуса".

 

Очень интересуют следующие вопросы:

 

1. В нём реализована прокладка маршрута к заданной точке (как GPS), как в игровых миссиях.

<РЕШЕНО для данного мода, но пример ниже пока до конца не доковырял>
Поиски по сети вывели на такую информацию. Здесь рассматривается возможнось создания маршрута гоночного трека на карте и автор вроде как добивается требуемого результата.
В качестве решения даётся такой код (синтаксис vb.Net):

    Native.Function.Call("SET_IGNORE_NO_GPS_FLAG", 1)
        Native.Function.Call("START_GPS_RACE_TRACK", 10)
        Native.Function.Call("RENDER_RACE_TRACK", 0)

        Dim tmpPointer As Native.Pointer = New Native.Pointer(GetType(Vector3))

        For Each r As TRace.TRacePoint In RE_editRace.LoadedRacePoints
            r.blipPos = myNative.attachBlipToCoord(r.pos)
            r.blipPos.Icon = BlipIcon.Misc_Destination
            tmpPointer.SetValue(r.pos)
            Native.Function.Call("ADD_POINT_TO_GPS_RACE_TRACK", tmpPointer)
        Next

        Native.Function.Call("RENDER_RACE_TRACK", 1)

'i removed SET_IGNORE_NO_GPS_FLAG and still working, not sure what it does ^^
'to clear the track we call Native.Function.Call("RENDER_RACE_TRACK", 0)

Суть в том, что я особо не шарю в программировании и полностью понять как это написать в рабочем сценарии не понял...
Вижу, что идёт работа с указателем (As Native.Pointer), что ему присваиваются свойства координатного типа данных (As Vector3), понятно, что идёт нативный вызов функции с указателем ("Native.Function.Call("ADD_POINT_TO_GPS_RACE_TRACK", tmpPointer), но вот какие параметры у tmpPointer и как они присвоены?

Если можно, приведите пример рабочего кода с пояснениями.

В принципе, <РЕШЕНО>.

 

2. <РЕШЕНО>
 

3. <РЕШЕНО>

4. Фиксируется проезд на красный свет светофора и столкновения с транспортными средствами. Через IS_CAR_STOPPED_AT_TRAFFIC_LIGHTS и IS_CAR_TOUCHING_CAR? Можно поподробнее?
   И, в свете наличия в игре светофоров и возможности регистрации их сигналов, было бы интересно создать мод, который будет показывать сигнал впереди стоящего светофора. Это полезно, когда играешь с видом из кабины и не видно светофоров.

 

Далее, у меня есть вопросы относящиеся в целом к игре:

5. Есть скриптовые команды на открывание/закрывание дверей/капота/багажника транспортного средства.
Но! Открывание дверей/капота/багажника включает игровую анимацию этого действия, а закрывание запускает только действие без анимации.
Только у автобуса передняя дверь закрывается с анимацией, но только в момент, когда в него входит/выходит пэд.
Возможно это связано с выделением времени на операцию, т.е. на закрытие стоит ноль...
Как получить анимацию на закрывание?

<можно сказать РЕШЕНО, сделал подобие эмулятора данного действия, не задействуя анимацию>

6. <РЕШЕНО>

7. В игре стоит ограничение на количество мест в транспорте, равное 4. В автобусе, как таковом, мест естественно больше ;-) Я подозреваю, что методом, использованным listener вот здесь возможно добиться изменения данного ограничения и введения дополнительных аргументов для обозначения новых мест для посадки. Ну и правкой под это дело стандартной модели автобуса с разметкой новых мест.

Или может быть можно обойти это ограничение, виртуально прикрепив одно т/с к другому? Есть же команды типа .Attach применяемые к объекту и потом при посадке пассажиров использовать параметры рассадки от 2-х/3-х/4-х т/с?

 

Буду благодарен любым пояснениям, высказанным мыслям по данным вопросам.

 

P.S. был бы весьма признателен за любые исходники для изучения скриптинга GTA IV

 

P.P.S. Возник вопрос по назначению клавиш для скрипта, касательно использования модификаторов.

 

Вариант A:

e.KeyWithModifiers   - Returns the key combined with modifier (Shift, Control, Alt) information. (As System.Windows.Forms.Keys)
Т.е. это, как я понял, для самостоятельного назначения модификатора (клавиша модификатора)

Построение использовал такое:

Private Sub Main_KeyDown(ByVal sender As Object, ByVal e As GTA.KeyEventArgs) Handles MyBase.KeyDown
        If e.KeyWithModifiers = Keys.Tab AndAlso e.Key = Keys.E Then Game.DisplayText("Keys [KeyWithModifiers]+[E] is Pressed", 1000)
End Sub

Результат - игра скрипт съела, но результата не выдала. Пробовал по разному, но видимо чего-то не догнал...

Поисков по сети дали только один близкий ответ.

 

Вариант B:

Модификатор с конструкцией BindKey(Keys.E, AddressOf Deystvie1)

Нашёл в сети такое решение, где прописывается условие для работы вышеозначенной конструкции

Код получился такой:

BindKey(Keys.Alt,True, Keys.E,True, AddressOf Deystvie2)

Результат как и в предыдущем случае - игра схавала и ноль.

 

Подскажите, где неправ.

 

<РЕШЕНО>


Сообщение отредактировал vorotkov: 12 April 2015 - 23:25


#2 VcSaJen

VcSaJen

    Активный участник

  • Пользователи
  • PipPipPip
  • 270 сообщений
  • Пол:Мужчина
  • Интересы:GTA, скриптинг в GTA.


Отправлено 14 March 2015 - 14:33

Если надо любые исходники скриптов, то тут можно скачать (Delphi на Alice, последний на C++ Script Hook):
http://forums.gtamod...?showtopic=2168, файл GameSrcRaCon.rar
http://forums.gtamod...?showtopic=2152
http://forums.gtamod...?showtopic=2591

Также полезно смотреть декомпилированные оригинальные скрипты: http://gtamaps.net/f...showtopic=13856 (ещё был пак от Alexander'а, но там битая ссылка)
 

P.P.S. Возник вопрос по назначению клавиш для скрипта, касательно использования модификаторов.

Да не мучайся ты с модификаторами, используй просто
bool CustomFiberThread::KeyPressed(int key)
{
return (GetKeyState(key) & 0x80000000) != 0;
}
Shift и т.д. он тоже берёт.

Сообщение отредактировал VcSaJen: 14 March 2015 - 14:43


#3 vorotkov

vorotkov

    Активный участник

  • Пользователи
  • PipPipPip
  • 63 сообщений

Отправлено 14 March 2015 - 19:15

Спасибо за совет! Посмотрю и попробую.



#4 vorotkov

vorotkov

    Активный участник

  • Пользователи
  • PipPipPip
  • 63 сообщений

Отправлено 17 March 2015 - 18:50

Подскажите пж-та, как закрыть запущенную форму по событию на отжатие клавиши? Важно именно отжатие.

 

Вот код (синтаксис VB.NET):

Public Class GTA_Forms
    Inherits Script

    Public Sub New()
        Wait(1000)
    End Sub

    Private Sub Main_KeyUp(ByVal sender As Object, ByVal e As GTA.KeyEventArgs) Handles MyBase.KeyUp
        If e.Key = Keys.D1 Then
            Dim Form1 As New Form1_Window
            Form1.Show()
        End If
    End Sub

End Class

Public Class Form1_Window
   Inherits GTA.Forms.Form

    Private Sub Main_KeyUp(ByVal sender As Object, ByVal e As GTA.KeyEventArgs) Handles MyBase.KeyUp
        If e.Key = Keys.D2 Then Me.Close
    End Sub
End Class

По нажатию "1" окно запускается, а вот уже в запущенной форме на "2" не реагирует.

Если щелкнуть по открытой форме (т.е. фокус окажется на окне), то "2" сработает.

Почитал, что нужно использовать

Me.KeyPreview = True

Добавил в код "Form1_Window" это так:

   Public Sub New()

       Me.KeyPreview = True

   End Sub

 

Только не кушает GTA его...

 

В качестве рабочего примера, можно представить запуск в игре консоли .Net ScriptHook (v1.7.1.7b) от HazardX (по нажатию клавиши [ ` ] (тильда)).

Это та же форма и при её запуске мы можем сразу печатать текст, не кликая перед этим по ней мышкой.

Т.е. у неё или был параметр типа "Me.KeyPreview = True" (отслеживать события с обработкой клавиш до переноса фокуса на форму) или был принудительно выставлен фокус на эту форму, что-то типа "Form1.Focus()" или "Form1.SetFocus".

В документации к скриптхуку я что-то не нашёл вышеперечисленных методов или их аналогов по работе с формами...

.


Сообщение отредактировал vorotkov: 18 March 2015 - 11:53


#5 vorotkov

vorotkov

    Активный участник

  • Пользователи
  • PipPipPip
  • 63 сообщений

Отправлено 18 March 2015 - 16:31

Собственно для чего спрашиваю про формы - накидал модик "'Полная остановка при торможении без автоматического включения реверса", но хочется по правильному выстраивать обработку событий. Кому интересно, вот файлик: AutoReversOff.vb.

P.S. У кого клавиши разгона/торможения отличаются от стандартных W/S, замените Keys.W и Keys.S в скрипте.


Сообщение отредактировал vorotkov: 18 March 2015 - 16:41


#6 vorotkov

vorotkov

    Активный участник

  • Пользователи
  • PipPipPip
  • 63 сообщений

Отправлено 18 March 2015 - 17:18

Думал нашёл альтернативу ".Focus()" - ".ShowDialog()", ан нет...


Сообщение отредактировал vorotkov: 18 March 2015 - 17:31


#7 vorotkov

vorotkov

    Активный участник

  • Пользователи
  • PipPipPip
  • 63 сообщений

Отправлено 28 March 2015 - 00:13

Кто-нибудь знает как получить координату конкретного колеса на автомобиле?



#8 НикИТОС

НикИТОС

    Активный участник

  • Пользователи
  • PipPipPip
  • 127 сообщений
  • Пол:Мужчина


Отправлено 28 March 2015 - 11:07

Кто-нибудь знает как получить координату конкретного колеса на автомобиле?

Возможно, так.

#9 vorotkov

vorotkov

    Активный участник

  • Пользователи
  • PipPipPip
  • 63 сообщений

Отправлено 28 March 2015 - 16:52

Спасибо! Интересная функция!



#10 vorotkov

vorotkov

    Активный участник

  • Пользователи
  • PipPipPip
  • 63 сообщений

Отправлено 05 April 2015 - 16:38

Объясните пж-та, как правильно пользоваться FORCE_CAR_LIGHTS и на что она конкретно влияет. Пробовал так:

If Player.Character.isSittingInVehicle Then
   Native.Function.Call("FORCE CAR LIGHTS", Player.Character.CurrentVehicle, 1)
End If

Т.е. так я пытался в вечернее время, когда у т/с горят габаритные огни и ближний свет фар их потушить.


Сообщение отредактировал vorotkov: 05 April 2015 - 17:16


#11 Chipsman

Chipsman

    Активный участник

  • Главные администраторы
  • PipPipPip
  • 786 сообщений
  • Пол:Не определился


Отправлено 05 April 2015 - 17:32

FORCE_CAR_LIGHTS


#12 НикИТОС

НикИТОС

    Активный участник

  • Пользователи
  • PipPipPip
  • 127 сообщений
  • Пол:Мужчина


Отправлено 05 April 2015 - 18:03

Объясните пж-та, как правильно пользоваться FORCE_CAR_LIGHTS и на что она конкретно влияет. Пробовал так:

If Player.Character.isSittingInVehicle Then
   Native.Function.Call("FORCE CAR LIGHTS", Player.Character.CurrentVehicle, 1)
End If
Т.е. так я пытался в вечернее время, когда у т/с горят габаритные огни и ближний свет фар их потушить.

Ты ведь заключил этот код в бесконечный цикл? Не знаю, как обстоят дела в используемом тобой хуке, но обычно такие вещи оборачивают в while (TRUE), чтоб проверка проводилась постоянно, а не один раз после запуска скрипта.

Сообщение отредактировал НикИТОС: 05 April 2015 - 18:17


#13 vorotkov

vorotkov

    Активный участник

  • Пользователи
  • PipPipPip
  • 63 сообщений

Отправлено 05 April 2015 - 18:26

FORCE_CAR_LIGHTS

Точно! Вот ведь я растяпа... :lol:

Всем спасибо за помощь! :)


Сообщение отредактировал vorotkov: 05 April 2015 - 18:27


#14 vorotkov

vorotkov

    Активный участник

  • Пользователи
  • PipPipPip
  • 63 сообщений

Отправлено 05 April 2015 - 22:54

Ещё вопрос, как использовать GET_CAR_COORDINATES, GET_CHAR_COORDINATES, GET_CAR_CHAR_IS_USING, GET_OFFSET_FROM_CAR_IN_WORLD_COORDS ?

Не пойму, что делаю не так:

If Player.Character.isSittingInVehicle Then
   Dim pX As Single, pY As Single, pZ As Single
   Native.Function.Call("GET_CAR_COORDINATES", Player.Character.CurrentVehicle, pX, pY, pZ)
   Game.DisplayText("Vehicle Position:" & "  X: " & pX & "  Y: " &  pY & "  Z: " &  pZ)
End If
Dim pX As Single, pY As Single, pZ As Single
Native.Function.Call("GET_CHAR_COORDINATES", Player.Character, pX, pY, pZ)
Game.DisplayText("Position:  " & "  X: " & pX & "  Y: " &  pY & "  Z: " &  pZ)
If Player.Character.isSittingInVehicle Then
   Dim veh As Vehicle
   Native.Function.Call("GET_CAR_CHAR_IS_USING", Player.Character, veh)
   If Exists(v) Then Game.Console.Print("Vehicle.Name:  " & veh.Name)
End If
If Player.Character.isSittingInVehicle Then
   Dim pos As Vector3
   Native.Function.Call("GET_OFFSET_FROM_CAR_IN_WORLD_COORDS", v, 2, 0, 0, pos.X, pos.Y, pos.Z)
   Game.DisplayText("Vehicle OffSet Position:  " & pos.ToString)
End If

А GET_PLAYER_CHAR вообще загадка. Требует CONVERT_INT_TO_PLAYERINDEX, который в свою очередь хочет GET_PLAYER_ID, а вот этот уже работает только сам по себе, не давая присвоить получаемое значение какой-либо переменной или просто вывести его на экран:

Native.Function.Call("GET_PLAYER_ID")   'Так не ругается, но и использовать в таком варианте бессмысленно

Dim id As Integer = Native.Function.Call("GET_PLAYER_ID")   ' Так ругается

Game.DisplayText("Player ID:  " & Native.Function.Call("GET_PLAYER_ID").ToString)   'И так ругается

Сообщение отредактировал vorotkov: 05 April 2015 - 23:19


#15 НикИТОС

НикИТОС

    Активный участник

  • Пользователи
  • PipPipPip
  • 127 сообщений
  • Пол:Мужчина


Отправлено 06 April 2015 - 13:00

Ещё вопрос, как использовать GET_CAR_COORDINATES, GET_CHAR_COORDINATES, GET_CAR_CHAR_IS_USING, GET_OFFSET_FROM_CAR_IN_WORLD_COORDS ?
Не пойму, что делаю не так:

If Player.Character.isSittingInVehicle Then
   Dim pX As Single, pY As Single, pZ As Single
   Native.Function.Call("GET_CAR_COORDINATES", Player.Character.CurrentVehicle, pX, pY, pZ)
   Game.DisplayText("Vehicle Position:" & "  X: " & pX & "  Y: " &  pY & "  Z: " &  pZ)
End If
Dim pX As Single, pY As Single, pZ As Single
Native.Function.Call("GET_CHAR_COORDINATES", Player.Character, pX, pY, pZ)
Game.DisplayText("Position:  " & "  X: " & pX & "  Y: " &  pY & "  Z: " &  pZ)
If Player.Character.isSittingInVehicle Then
   Dim veh As Vehicle
   Native.Function.Call("GET_CAR_CHAR_IS_USING", Player.Character, veh)
   If Exists(v) Then Game.Console.Print("Vehicle.Name:  " & veh.Name)
End If

Я, конечно, в этом синтаксисе ничего не понимаю, но если "p" от слова "pointer", то, наверное, надо так:
If Player.Character.isSittingInVehicle Then
   Dim X As Single, Y As Single, Z As Single
   Native.Function.Call("GET_CAR_COORDINATES", Player.Character.CurrentVehicle, pX, pY, pZ)
   Game.DisplayText("Vehicle Position:" & "  X: " & X & "  Y: " &  Y & "  Z: " &  Z)
End If

А GET_PLAYER_CHAR вообще загадка. Требует CONVERT_INT_TO_PLAYERINDEX, который в свою очередь хочет GET_PLAYER_ID, а вот этот уже работает только сам по себе, не давая присвоить получаемое значение какой-либо переменной или просто вывести его на экран:

Native.Function.Call("GET_PLAYER_ID")   'Так не ругается, но и использовать в таком варианте бессмысленно

Dim id As Integer = Native.Function.Call("GET_PLAYER_ID")   ' Так ругается

Game.DisplayText("Player ID:  " & Native.Function.Call("GET_PLAYER_ID").ToString)   'И так ругается

Хидер из SCOCL в синтаксисе C:
Скрытый текст

Сообщение отредактировал НикИТОС: 06 April 2015 - 13:45


#16 vorotkov

vorotkov

    Активный участник

  • Пользователи
  • PipPipPip
  • 63 сообщений

Отправлено 06 April 2015 - 22:25

Также можешь попробовать
Dim PedPointer As New Native.Pointer(GetType(Ped))
      Native.Function.Call("GET_PLAYER_CHAR", Player, PedPointer)
      Dim PlayerChar As Ped = PedPointer

 

Большое спасибо!

Твоё предположение об использовании указателей при вызове нативной функции для принятия данных в переменные оказалось абсолютно верным!
Видимо это верно для всех методов получения данных из GTA, не смотря на то, что в описаниях нативных функций ничего об этом не говорится, а указывается непосредственно переменная и её тип.
Подставив везде для получения данных указатели, всё заработало!

 

Не сработал только GET_PLAYER_ID, но это видимо из-за особенностей вызова нативных функций в Net ScriptHook v1.7.1.7b by HazardX. Автор здраво предположил, что этим никто пользоваться не будет, ведь хук уже выдаёт результат выполнения "CONVERT_INT_TO_PLAYERINDEX" в переменной "Player", поэтому нет возможности получить данные из Native.Function.Call("GET_PLAYER_ID").


Сообщение отредактировал vorotkov: 06 April 2015 - 22:26


#17 vorotkov

vorotkov

    Активный участник

  • Пользователи
  • PipPipPip
  • 63 сообщений

Отправлено 07 April 2015 - 17:23

Вот так как-бы работает, но выдаёт "0": 

Dim pID As Integer = Native.Function.Call(Of Integer)("GET_PLAYER_ID")
Game.DisplayText("Player ID:  " & pID.ToString)

То же самое, но с указателем (так же выдаёт "0"):

Dim pID As New Native.Pointer(GetType(Integer))
pID = Native.Function.Call(Of Integer)("GET_PLAYER_ID") 
Game.DisplayText("Player ID:  " & pID.ToString)

Сообщение отредактировал vorotkov: 07 April 2015 - 17:29


#18 НикИТОС

НикИТОС

    Активный участник

  • Пользователи
  • PipPipPip
  • 127 сообщений
  • Пол:Мужчина


Отправлено 07 April 2015 - 18:47

Вот так как-бы работает, но выдаёт "0": 

Dim pID As Integer = Native.Function.Call(Of Integer)("GET_PLAYER_ID")
Game.DisplayText("Player ID:  " & pID.ToString)
То же самое, но с указателем (так же выдаёт "0"):
Dim pID As New Native.Pointer(GetType(Integer))
pID = Native.Function.Call(Of Integer)("GET_PLAYER_ID") 
Game.DisplayText("Player ID:  " & pID.ToString)

А зачем тебе ID игрока? По-моему, в GTA IV .NET ScriptHook есть класс Player и ещё куча других, созданных специально для того, чтобы скриптер не парился с нейтивами. То есть там должны быть Player.ID и Player.Char или Player.Character, при помощи которых ты сможешь напрямую работать с игроком. Можешь даже просто попробовать что-то вроде
Dim pID As Integer = Player.ID
Game.DisplayText("Player ID:  " & pID.ToString)


#19 vorotkov

vorotkov

    Активный участник

  • Пользователи
  • PipPipPip
  • 63 сообщений

Отправлено 08 April 2015 - 03:39

Да, в хуке уже есть Player.ID, Player.Index, и кстати они так же выдают ноль :)

Я хочу разобраться в основах скриптинга GTA, дабы понимать как всё работает, поэтому и ковыряюсь )



#20 vorotkov

vorotkov

    Активный участник

  • Пользователи
  • PipPipPip
  • 63 сообщений

Отправлено 08 April 2015 - 03:58

Вот кстати столкнулся с ещё одной непонятностью:

В Net ScriptHook v1.7.1.7b by HazardX есть функция "Player.Character.Invincible" - неуязвимость персонажа.

Если повесить её на кнопку, то она прекрасно работает:

Private NumPad0_sw As Boolean

Private Sub Main_KeyDown(ByVal sender As Object, ByVal e As GTA.KeyEventArgs) Handles MyBase.KeyDown
        If e.Key = Keys.NumPad0 Then
            NumPad0_sw = Not NumPad0_sw
            If NumPad0_sw Then
                'Player.Character.Invincible = True
                Game.DisplayText("Player.Character.Invincible = True")
               Else
                Player.Character.Invincible = False
                Game.DisplayText("Player.Character.Invincible = False")
            End If
        End If
End Sub

А вот если её поставить просто в запуск при загрузке скрипта, то она нефурычит...

Public Sub New()
   Wait(1000)
   Player.Character.Invincible = True
End Sub

Подумал, может в хуке ошибка, попробовал найти там корни этой функции:

static void SetCharInvincible(Ped c, b8 enable) { Native::Function::Invoke<ScriptVoid>("SET_CHAR_INVINCIBLE", c, enable); }

Т.е. это SET_CHAR_INVINCIBLE

Подставил в скрипт:

Native.Function.Call("SET_CHAR_INVINCIBLE", Player.Character, True)

Результат, как и описан выше. Как думаешь, в чём подвох?






Количество пользователей, читающих эту тему: 2

0 пользователей, 2 гостей, 0 анонимных