[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
Форум » Игры серии GTA » GTA San Andreas » Вопросы по скриптингу Sanny Builder (Вы можете получить ответы на вопросы по SB)
Вопросы по скриптингу Sanny Builder
wmysterio
Администраторы
Скриптер
22.11.11 21:52
Offline
Если у вас возник вопрос по скриптингу Sanny Builder, обращайтесь! Мы постараемся решить вашу проблему wink Это ещё не значит, что все прям бросятся решать во чтобы то не стало, но ответ вы сможете вы получить как вариант решения или как невозможность или сложность решения.
УВАЖАЕМЫЕ ПОЛЬЗОВАТЕЛИ! ПРОСЬБА КОД СКРИПТОВ ПОМЕЩАТЬ В КОНСТРУКЦИЮ КОДА:

или

Также указывайте полный код скрипта, иначе причина ошибок может быть и не выявлена.
Прикрепления: 0248203.png(0.9 Kb) · 9085525.png(0.2 Kb)

Fox1324
Пользователи
01.10.14 19:46
Offline
Привет, я новичок и хотел бы спросить.А что означают переменные от 1@ до 33@??? Я не могу понять их предназначение(

wmysterio
Администраторы
Скриптер
01.10.14 19:56
Offline
Цитата Fox1324 ()
Привет, я новичок и хотел бы спросить.А что означают переменные от 1@ до 33@??? Я не могу понять их предназначение(
Суть и назначение переменных от 1@ до 33@ одно: временно хранить какие-либо данные. Получают данные либо с опкодов либо задают вручную.

Fox1324
Пользователи
01.10.14 21:42
Offline
Вот что обозначает эта запись? Мы присваиваем переменной именно что? Кнопку? или что-то другое?: 33@ = 0

Добавлено (01.10.14, 19:34)
---------------------------------------------
и что значит в коде двойной знак равно? Например
if
not 13@==-1

Добавлено (01.10.14, 20:02)
---------------------------------------------
И то есть не имеет значения, какую переменную ты возьмёшь для Временного хранения информации?

Добавлено (01.10.14, 20:42)
---------------------------------------------
И что обозначает этот код?
if and
  33@ > 500
  750 > 33@
И можно просьбу небольшую, если у вас есть на сайте все уроки по этим кодам, дайте ссылку)


wmysterio
Администраторы
Скриптер
02.10.14 03:53
Offline
Цитата Fox1324 ()
И можно просьбу небольшую, если у вас есть на сайте все уроки по этим кодам, дайте ссылку)
С этого и нужно было начинать smile Все уроки по скриптингу доспутны на этом сайте. Ссылку на уроки найдёте вверху сраницы или тут: ссылка. Самые первые уроки ищите в конце архива, так как отсортированы они по дате добавления. Там, думаю, найдёте ответы на вопросы по тем коммандам, что вы спрашивали.

Если влом переключать страницы, то можете скачать уроки в архиве здесь.

Fox1324
Пользователи
02.10.14 15:47
Offline
Извините, а вы не можете детально этот код объяснить, так как учебник я уже почти весь прочитал, а вот не  понимаю почему переменным присваиваются именно эти цифры((
// This file was decompiled using SASCM.ini published by GTAG (http://gtag.gtagaming.com/opcode-database) on 14.6.2013
{$CLEO .cs}
//-------------MAIN---------------
0000: NOP
thread 'RELOAD'
:RELOAD_13
wait 100
if
   Player.Defined($PLAYER_CHAR)
else_jump @RELOAD_13
0A96: 0@ = actor $PLAYER_ACTOR struct
0@ += 1816
0A8D: 1@ = read_memory 0@ size 1 virtual_protect 0
0A96: 0@ = actor $PLAYER_ACTOR struct
0@ += 1440
1@ *= 28
005A: 0@ += 1@ // (int)
0@ += 4
if
0AB0:   key_pressed 82
else_jump @RELOAD_13
0A8C: write_memory 0@ size 4 value 2 virtual_protect 1
0624: add 1.0 to_float_stat 69
0624: add 1.0 to_float_stat 70
0624: add 1.0 to_float_stat 71
0624: add 1.0 to_float_stat 72
0624: add 1.0 to_float_stat 73
0624: add 1.0 to_float_stat 74
0624: add 1.0 to_float_stat 75
0624: add 1.0 to_float_stat 76
0624: add 1.0 to_float_stat 77
0624: add 1.0 to_float_stat 78
0624: add 1.0 to_float_stat 79
jump @RELOAD_13

Добавлено (02.10.14, 14:47)
---------------------------------------------
Это скрипт перезарядки в гта, я взял пример


wmysterio
Администраторы
Скриптер
02.10.14 17:21
Offline
Цитата Fox1324 ()
Извините, а вы не можете детально этот код объяснить, так как учебник я уже почти весь прочитал, а вот не понимаю почему переменным присваиваются именно эти цифры((
Это увиличивает статы игрока - повышают уровень умений для оружи:
Код
0624: add 1.0 to_float_stat 69  
  0624: add 1.0 to_float_stat 70  
  0624: add 1.0 to_float_stat 71  
  0624: add 1.0 to_float_stat 72  
  0624: add 1.0 to_float_stat 73  
  0624: add 1.0 to_float_stat 74  
  0624: add 1.0 to_float_stat 75  
  0624: add 1.0 to_float_stat 76  
  0624: add 1.0 to_float_stat 77  
  0624: add 1.0 to_float_stat 78  
  0624: add 1.0 to_float_stat 79


Этот участок
Код
0A96: 0@ = actor $PLAYER_ACTOR struct  
  0@ += 1816  
  0A8D: 1@ = read_memory 0@ size 1 virtual_protect 0  
  0A96: 0@ = actor $PLAYER_ACTOR struct  
  0@ += 1440  
  1@ *= 28  
  005A: 0@ += 1@ // (int)  
  0@ += 4  
  if  
  0AB0:   key_pressed 82  
  else_jump @RELOAD_13  
  0A8C: write_memory 0@ size 4 value 2 virtual_protect 1  
Это уже участок кода, где идёт вычисление адреса памяти игры(в оперативке, или там где прописан адрес) путём арифметических операций. Я прокомментировал что за числа:
Код
// This file was decompiled using SASCM.ini published by GTAG (http://gtag.gtagaming.com/opcode-database) on 14.6.2013  
{$CLEO .cs}  
//-------------MAIN---------------  
0000: NOP  
thread 'RELOAD'  
:RELOAD_13  
wait 100  
if  
Player.Defined($PLAYER_CHAR)  
else_jump @RELOAD_13  
0A96: 0@ = actor $PLAYER_ACTOR struct  
0@ += 1816 // получаем текущий слот оружия
0A8D: 1@ = read_memory 0@ size 1 virtual_protect 0 // читаем адрес и записываем результат в 1@
0A96: 0@ = actor $PLAYER_ACTOR struct  
0@ += 1440 // получаем адрес начала структуры слотов оружия
1@ *= 28 // Умножаем текущий слот на 28. Каждый слот оружия имеет размер 28 байт
005A: 0@ += 1@ // (int) // вычесляем адрес нужного слота относительно начала структуры слотов оружия
0@ += 4 // получаем характеристику "Статус оружия" которая находится со смещением в 4.
if  
0AB0:   key_pressed 82 // если игрок нажал клавишу R
else_jump @RELOAD_13  
0A8C: write_memory 0@ size 4 value 2 virtual_protect 1 // то записываем 2 в качестве статуса для адреса, который мы вычислии ранее. Статус 2 - это перезарядка
//повышаем характеристики
0624: add 1.0 to_float_stat 69  
0624: add 1.0 to_float_stat 70  
0624: add 1.0 to_float_stat 71  
0624: add 1.0 to_float_stat 72  
0624: add 1.0 to_float_stat 73  
0624: add 1.0 to_float_stat 74  
0624: add 1.0 to_float_stat 75  
0624: add 1.0 to_float_stat 76  
0624: add 1.0 to_float_stat 77  
0624: add 1.0 to_float_stat 78  
0624: add 1.0 to_float_stat 79  
jump @RELOAD_13
Все адреса по структуре можно узнать тут.

Fox1324
Пользователи
02.10.14 20:40
Offline
Спасибо огромное, извините, а у вас есть уроки про адреса? Манипуляции с памятью?:)

wmysterio
Администраторы
Скриптер
02.10.14 21:09
Offline
Цитата Fox1324 ()
Спасибо огромное, извините, а у вас есть уроки про адреса? Манипуляции с памятью?:)
Незачто. Есть. Вот: 1, 2, 3, 4, 5

Fox1324
Пользователи
02.10.14 21:33
Offline
Извините, а можно я вам в ЛС буду писать? Просто нужно обсудить с вами вопросы некоторые, интересно ваше мнение smile

wmysterio
Администраторы
Скриптер
02.10.14 21:37
Offline
Цитата Fox1324 ()
Извините, а можно я вам в ЛС буду писать?
можно и нужно

wmysterio
Администраторы
Скриптер
23.10.14 18:24
Offline
Всем привет! У меня есть один вопрос к опытным в игровой памяти скриптеров.
В документации написно
Код
CPhysical +0xB9 = [word] Количество субьектов, с которыми соприкасается субьект
CPhysical +0xBC = [24 bytes] 6 субьектов, с которыми соприкасается субьект
CPhysical +0xD8 = [float] Величина урона
Если перевести всё в десятичные числа, то получится:
Код
185
188
216
Получается, на количество припадает 3 байта(188 - 185), а на субъекты 28 байт(216 - 188). Как видите, здесь нестыковка какая-то. Как правильно поступить? Могут в смещениях быть "пустоты", ведь word не может быть 3 байта(только 2 или 4). Или я ошибаюсь.

Данные брал здесь.

Напишите правильные смещения, пожалуйста.

BoPoH
Друзья
24.10.14 00:07
Offline
Смещение 0xB9 - явно не количество субъектов, соприкасаемых с данным субъектом. Больше похоже на тип поверхности, с которой соприкасается субъект (ID типа коллизии).
0xBC - вроде как и правда субъекты, с которыми соприкасается данный субъект.
0xD8 - не совсем величина урона. Скорее сила, прикладываемая к субъекту каким-либо из других субъектов (либо сумма всех сил, действующих на субъект). Лично я взял за основу структуру педа игрока и начал бежать в стену. Это значение поднялось с нуля до ~5-10 единиц, т.е. примерно совпадает со скоростью игрока. Получается, что стена действует на игрока с этой силой (хотя тут наверное всё-таки скорость а не сила, ну да хер знает, мы не физики, вдаваться в подробности не будем), чтобы он оставался на месте).
В структурах конечно бывают пустоты. Всё зависит от того, по какому правилу было установлено выравнивание структуры. В SA вроде 4-байтное выравнивание. Следовательно, если мы объявим такую структуру:
Код
struct myStruct    
{
       BYTE a1;
       WORD a2;
       int a3;
};
И при этом будем использовать выравнивание в 4 байта, то между вордом и интом появится ещё один пустой байт - так формируются блоки по 4 байта, ведь того требует выравнивание.
Код
struct myStruct
{
       BYTE a1;
       WORD a2;
       BYTE pad;
       int a3;
};
Отсюда и появляются иногда поля-пустышки в структурах. С другой стороны - не факт, что там пустышка. Возможно, там есть какое-то используемое игрой значение длиной в байт. Просто те, кто писал статью с оффсетами, не смогли разобрать, что это за значение, поэтому не указали его в статье. Но это вовсе не значит, что там нет ничего или ворд вдруг начинает занимать 3 байта xD
Отредактировал BoPoH - Пятница, 24.10.14, 00:09

wmysterio
Администраторы
Скриптер
24.10.14 01:13
Offline
BoPoHСпасибо за ответ, друг. Теперь мне многое прояснилось! Кстати, может ты встречал похожие статьи с адресами?

BoPoH
Друзья
24.10.14 23:37
Offline
Цитата wmysterio ()
Кстати, может ты встречал похожие статьи с адресами?
Кроме той - нет. Обычно использую непосредственно структуры, описанные в базе IDA, разбираю функции, по ним дополняю и правлю структуры.
Всегда рад помочь)

Slivkin-Sergey
Модераторы
06.11.14 17:37
Offline
Вопрос немного, наверное, не по теме - а зачем вообще нужно это 4-байтное выравнивание?

Кстати, я пробовал в поле-пустышку в структуре актёра записать какое-то значение (не помню, какое, давно дело было) интовское, и потом считать его (пустышка занимала 4 байта). Но игра вела себя так, будто никакого числа там нет и в помине. Т.е., я так понимаю, не всё так просто, и без объявления элемента структуры в экзешнике ничего туда записываться не будет?

И вот ещё. Хотелось бы узнать, эта функция узнаёт позицию кости в матрице? Вынул из одного скрипта.

Код
:BONEPOS
0A96: 0@ = actor 0@ struct
0AA8: call_function_method 0x532B20 struct 0@ num_params 0 pop 0 33@
0@ += 0x18
0A8D: 0@ = read_memory 0@ size 4 virtual_protect 0
0AA7: call_function 0x734A40 num_params 1 pop 1 clump 0@ hier 10@
0AA7: call_function 0x7C51A0 num_params 2 pop 2 bone 1@ clump 10@ get_id 11@
10@ += 8
0A8D: 10@ = read_memory 10@ size 4 virtual_protect 0
11@ *= 0x40
005A: 10@ += 11@  // (int)
0AC7: 12@ = var 2@ offset
0AC7: 13@ = var 20@ offset
0AA7: call_function 0x54EEF0 num_params 4 pop 4 offset 12@ matrix 10@ someint 1 out 13@ nop 14@   
0AB2: ret 3 20@ 21@ 22@


И если да, то в каком месте указывается номер кости?
Отредактировал Slivkin-Sergey - Четверг, 06.11.14, 18:00

wmysterio
Администраторы
Скриптер
07.11.14 01:20
Offline
Цитата Slivkin-Sergey ()
Вопрос немного, наверное, не по теме - а зачем вообще нужно это 4-байтное выравнивание?
для оптимизации работы процессора, имхо

BoPoH
Друзья
07.11.14 01:59
Offline
Цитата Slivkin-Sergey ()
И вот ещё. Хотелось бы узнать, эта функция узнаёт позицию кости в матрице? Вынул из одного скрипта.
Уточни, кто автор скрипта? Если я не ошибаюсь, эту функцию писал я для alexey1999.
Да, эта функция возвращает позицию кости.
Вызов её происходит следующим образом (если память мне не изменяет):

Код
0AB1: call_scm_func @BONEPOS 2 actor $PLAYER_ACTOR bone_id 5 get_pos 1@ 2@ 3@
Первый параметр - актёр. Второй - ид кости (не такой же, как для опкодов, которые крепят объект к кости).
Соответственно, в переменные 1@ 2@ 3@ мы получим позицию кости.
У этой функции есть один минус (точнее это минус scm-движка) - мы получаем позицию кости из предыдущего кадра.

Цитата Slivkin-Sergey ()
Кстати, я пробовал в поле-пустышку в структуре актёра записать какое-то значение (не помню, какое, давно дело было) интовское, и потом считать его (пустышка занимала 4 байта).
Пустышек в 4 байта не бывает. Если поле никак не названо/описано где-либо (в IDA или на каких-нибудь сайтах), это не значит, что это поле ни за что не отвечает. Возможно, то поле, которое ты проверял, используется игрой в редких особых случаях, поэтому ничего внешне не изменилось.
Цитата Slivkin-Sergey ()
Т.е., я так понимаю, не всё так просто, и без объявления элемента структуры в экзешнике ничего туда записываться не будет?
Не путай исходники и скомплированный екзешник.
Структура существует в исходниках. В машинном коде структур, как таковых, нет. Там есть чтение и запись в определённый адрес памяти. Структуры там выражаются в виде смещения от адреса объекта, которому соответствует данная структура. Т.е. в процессе компиляции программы, структура как-бы преобразуется в оффсеты. Каждому полю соответствует свой оффсет. Приведу пример. У нас есть структура на C++:

Код
struct MyStruct
{
      int a;
      int b;
      float c;
};

В данном случае у "a" будет оффет 0, у "b" будет оффсет 4, а у "c" - 8.
Приведу пример на SB, чтобы было яснее. К примеру у нас есть адрес объекта, структура которого - MyStruct. Его адрес записан в переменную 1@. Если мы захотим записать число 5 в поле "b", то нам нужно сделать следующее:

Код
1@ += 4 // помним, что у поля b оффсет 4
0A8C: write_memory 1@ size 4 value 5 virtual_protect 0

А если нам, например, захочется совершить сразу две операции? Записать число 1.5 в поле "c" и прочесть значение поля "b"?
Если не брать во внимание оптимизацию кода и сделать код более наглядным, то:
Код
0A8E: 2@ = 1@ + 8 // int
0A8E: 3@ = 1@ + 4 // int
0A8C: write_memory 2@ size 4 value 1.5 virtual_protect 0 // запишем 1.5 в поле c
0A8D: 4@ = read_memory 3@ size 4 virtual_protect 0 // прочтём значение поля b в переменную 4@

Но иногда использовать кучу дополнительных переменных нельзя. Тогда можно оптимизировать код:

Код
1@ += 8
0A8C: write_memory 2@ size 4 value 1.5 virtual_protect 0 // запишем 1.5 в поле c
1@ -= 4
0A8D: 4@ = read_memory 3@ size 4 virtual_protect 0 // прочтём значение поля b в переменную 4@

Так мы сэкономили переменные, хотя код стал менее читаемым. В таких случаях, чтобы не забыть, можно оставить комментарий к коду (ваш кэп).

Цитата Slivkin-Sergey ()
Вопрос немного, наверное, не по теме - а зачем вообще нужно это 4-байтное выравнивание?
Это своего рода оптимизация. Судя по тому, что я откопал в гугле, невыровненные структуры занимают больше процессорного времени и больше обращений к оперативной памяти. Впрочем, речь идёт о наносекундах, так что если обращений не миллионы в секунду, то отсутствие выравнивания не критично.
Отредактировал BoPoH - Пятница, 07.11.14, 02:07

Slivkin-Sergey
Модераторы
07.11.14 06:25
Offline
Цитата BoPoH ()
Возможно, то поле, которое ты проверял, используется игрой в редких особых случаях, поэтому ничего внешне не изменилось.

А почему я не могу использовать поле в своих целях, пока оно не используется игрой?
Цитата BoPoH ()
Не путай исходники и скомплированный екзешник.

Я как раз имел ввиду исходники. Но вот про организацию структур в машинном коде не знал. Если это происходит примерно так (синтаксис плохой, но суть такая):
Код
mov EAX,[var+02C] // var - структура, 02C - смещение элемента (цифра с потолка) относительно начала структуры

то, получается, можно и в ассемблере создавать некие подобия структур.
Цитата BoPoH ()
Уточни, кто автор скрипта? Если я не ошибаюсь, эту функцию писал я для alexey1999.

Так точно.
А выравнивание - это #pragma pack, верно?
Отредактировал Slivkin-Sergey - Пятница, 07.11.14, 06:26

BoPoH
Друзья
08.11.14 00:04
Offline
Цитата Slivkin-Sergey ()
А почему я не могу использовать поле в своих целях, пока оно не используется игрой?
Ты ж не знаешь, когда оно используется, а когда нет. Если знаешь - тогда можно. И можно только тогда, когда не используется игрой.

Цитата Slivkin-Sergey ()
Если это происходит примерно так (синтаксис плохой, но суть такая) то, получается, можно и в ассемблере создавать некие подобия структур.
 Если писать программы на ассемблере, там есть возможность объявления структур. И выглядит это, кажется, примерно так:

Код
mov EAX, [var+MyStruct.field_1]
В процессе компиляции выражение MyStruct.field_1 будет преобразовано в соответствующий оффсет.
Когда же мы используем средства реверс-инжиниринга (например IDA), то у нас нет данных о структурах. Поэтому там пишется непосредственно сам оффсет (как ты и показал).
Цитата Slivkin-Sergey ()
А выравнивание - это #pragma pack, верно?
Да, это выравнивание для конкретной структуры, которая заключена в эту прагму. Выравнивание для всех остальных структур проекта определяется настройками проекта. В Visual Studio их можно найти так:
Проект -> Свойства -> Свойства конфигурации -> C/C++ -> Создание кода -> Выравнивание членов структур
Отредактировал BoPoH - Суббота, 08.11.14, 00:05

Slivkin-Sergey
Модераторы
10.11.14 19:49
Offline
2Рас недавно выкладывал конструктор CPool:
Цитата DK22Pac ()
void CPool{
this -> m_Objects = new B[maxCount]; // Выделяем память под массив обьектов
this -> m_ByteMap = new tPoolObjectFlags[maxCount]; // выделяем память под массив флагов для обьектов
this -> m_bInitialized = true;
this -> m_Size = maxCount;
this -> m_Top = -1;
for(int i = 0; i < maxCount; i++)
this -> m_ByteMap[i].bIsFreeSlot = true;
}


Меня интересует, как можно выделить один массив под флаги объектов и жить спокойно, если у объекта их явно >1 (взрывоустойчивость, физика...)? Сомневаюсь, что флаги хранятся в битах элементов, т.к. не припомню такого в БД адресов памяти.

Форум » Игры серии GTA » GTA San Andreas » Вопросы по скриптингу Sanny Builder (Вы можете получить ответы на вопросы по SB)
Поиск: