Объявление функции в глобальной области видимости вводит глобальную функцию, а объявление переменной – глобальный объект. Глобальный объект существует на протяжении всего времени выполнения программы. Время жизни глобального объекта начинается с момента запуска программы и заканчивается с ее завершением.Т.е. обьект будет создан при аттаче dll (будет вызван конструктор), а разрушен - при детаче (будет вызван деструктор).
или удали зависимость вручную (нужно убрать обьявление _D3D_INCLUDE в настройках проекта plugin_vc):Удалил. Плагин VC собрался. А пример VC_DXFont не идёт. Там же #include <d3dx8.h>
уже поправил это (зависимость от d3d8) в VC, скачай репозиторий зановоСкачал и новую версию. Здесь плагин VC не собирается. Вот
00A5: 0@ = create_car #PONY at 0.0 0.0 0.0
А пример VC_DXFont не идёт. Там же #include <d3dx8.h>
Скачал и новую версию. Здесь плагин VC не собирается. Вот
Уже добавил эти файлы.За пример в видео спасибо, но я имел ввиду создание транспорта в определённых координатах, с загрузкой модели
Опкод 00A5 вызывает функцию CCarCtrl::CreateCarForScript. Пока что её нету в sdk (класс CCarCtrl пока что добавлен только частично), но я добавлю.
1>------ Перестроение всех файлов начато: проект: VC_DXFont, Конфигурация: Release Win32 ------
1> Main.cpp
1>Main.obj : error LNK2001: неразрешенный внешний символ ""struct IDirect3DDevice8 * & _RwD3DDevice" (?_RwD3DDevice@@3AAPAUIDirect3DDevice8@@A)"
1>D:\Games\GTA Vice City 1.0\VC_DXFont.asi : fatal error LNK1120: неразрешенных внешних элементов: 1
========== Перестроение всех проектов: успешно: 0, с ошибками: 1, пропущено: 0 ==========
plugin_vc пересобрал с _D3D_INCLUDE?Да.
прямо сейчас занимаюсь классом CCarCtrl, после покажу пример создания транспорта и манипулирования им.Жду с нетерпением. Спасибо, что подробно всё разъясняешь.
Да.Попробуй именно пересобрать (не Build, а Rebuild).
Попробуй именно пересобрать (не Build, а Rebuild).Так и делал. Пересобрал ещё раз - тоже самое.
А после этого пересобери VC_DXFont.
Пример по спавну авто и управлению компонентом уже добавил.За пример с подробными комментариями огромное спасибо!
Спрашивай если что-то не понятно.Как вращать компоненты (CMatrix__rotateAroundX, CMatrix__rotateAroundY, CMatrix__rotateAroundZ)? Попробовал так:
if (automobile->m_aCarNodes[CAR_DOOR_RR])
automobile->m_aCarNodes[CAR_DOOR_RR]->modelling.at.z += 1.57f;
и так:if (automobile->m_aCarNodes[CAR_DOOR_RF])
automobile->m_aCarNodes[CAR_DOOR_RF]->modelling.up.z += 1.57f;
Вот что вышло: ;Dquat.Set(m_angle, 0.0f, 0.0f);
где 3 параметра - вращение в радианах по осям y, z, x, соответственно.LPDIRECT3DDEVICE8 &_RwD3DDevice = *(LPDIRECT3DDEVICE8 *)0x7897A8;
как у меня на скринеПо поводу VC_DXFont - в plugin_vc открой в студии файл game_vc/RenderWare.cpp и глянь, не закомменчена ли строкаВот:
CStreaming::RequestModel(modelId, 2);
цифра 2 что означает?CStreaming::RequestModel(modelID, 0);
void CVehicle::OpenDoor(CPed* ped, int componentId, eDoors door, float doorOpenRatio, bool playSound)
eDoors door - что ставить? В клео я ставил 0-5, а здесь пишет аргумент типа int несовместим с параметром типа "eDoors". {$CLEO .cs}
05E5: 15@ = game_version
if
15@ == 0
then
6@ = 0x52E660
7@ = 0x545930
8@ = 0x52EF90
9@ = 0x52E750
else
if
15@ == 1
then
6@ = 0x52E8A0
7@ = 0x545B30
8@ = 0x52F1D0
9@ = 0x52E990
else
05DC: end_custom_thread
end
end
var
12@: float
end
while true
wait 0
if
Player.Defined($PLAYER_CHAR)
then
if and
$ONMISSION == 0
Actor.Driving($PLAYER_ACTOR)
80DE: not player $PLAYER_CHAR driving_vehicle_type #PREDATOR
80DE: not player $PLAYER_CHAR driving_vehicle_type #SPEEDER
80DE: not player $PLAYER_CHAR driving_vehicle_type #REEFER
80DE: not player $PLAYER_CHAR driving_vehicle_type #GHOST
then
if
05EE: key_pressed 219 // [
then
0@ = 17 // ComponentID
1@ = 0 // eDoors
gosub @open_component // капот
repeat
wait 0
until 85EE: not key_pressed 219 // [
end
if
05EE: key_pressed 221 // ]
then
0@ = 18
1@ = 1
gosub @open_component // багажник
repeat
wait 0
until 85EE: not key_pressed 221 // ]
end
if and
05EE: key_pressed 186 // ;
05EE: key_pressed 187 // =
then
0@ = 15
1@ = 2
gosub @open_component // левая передняя дверь
repeat
wait 0
until 85EE: not key_pressed 187 // =
end
if and
05EE: key_pressed 222 // '
05EE: key_pressed 187 // =
then
0@ = 11
1@ = 3
gosub @open_component // правая передняя дверь
repeat
wait 0
until 85EE: not key_pressed 187 // =
end
if and
05EE: key_pressed 186 // ;
05EE: key_pressed 189 // -
then
0@ = 16
1@ = 4
gosub @open_component // левая задняя дверь
repeat
wait 0
until 85EE: not key_pressed 189 // -
end
if and
05EE: key_pressed 222 // '
05EE: key_pressed 189 // -
then
0@ = 12
1@ = 5
gosub @open_component // правая задняя дверь
repeat
wait 0
until 85EE: not key_pressed 189 // -
end
end
end
end
:open_component
if
Actor.Driving($PLAYER_ACTOR)
then
03C0: 10@ = actor $PLAYER_ACTOR car
05E7: 10@ = car 10@ struct
0085: 11@ = 10@
05E4: call_function_method 6@ struct 11@ num_params 1 pop 0 0@ {1..19} 2@ // IsComponentPresent
if
2@ == 1
then
0085: 3@ = 10@
3@ += 0x288 // CDamageManager
05E4: call_function_method 7@ struct 3@ num_params 1 pop 0 1@ {0..5} 4@ // GetDoorStatus
if
4@ <> 3
then
05E4: call_function_method 8@ struct 10@ num_params 1 pop 0 1@ {0..5} 5@ // IsDoorFullyOpen
if
5@ == 0
then
for 12@ = 0.0 TO 1.0 step 0.1
05E3: call_function_method 9@ struct 10@ num_params 3 pop 0 12@ 1@ 0@ {1..19} // CAutomobile__OpenDoor
wait 0
end
else
for 12@ = 1.0 DOWNTO 0.0 step 0.1
05E3: call_function_method 9@ struct 10@ num_params 3 pop 0 12@ 1@ 0@ {1..19} // CAutomobile__OpenDoor
wait 0
end
end
end
end
end
return
Вот:
1) При обновлении sdk как лучше обновить у себя? Достаточно ли будет копировать новые файлы с заменой старых и пересобрать плагин? Шаблон пересобирать надо или нет?
2) В SA_CreateCarКод: [Выделить]CStreaming::RequestModel(modelId, 2);
цифра 2 что означает?
а в SA_PedSpawner стоит 0Код: [Выделить]CStreaming::RequestModel(modelID, 0);
enum eStreamingFlags {
GAME_REQUIRED = 0x2, // Модель нужна игре? (Сохранять в памяти, пока не будет вызвана SetModelIsDeletable, дальше - пусть игра сама решает, когда удалить модель)
MISSION_REQUIRED = 0x4, // Модель нужна миссии? (Сохранять в памяти, пока не будет вызвана SetMissionDoesntRequireModel, дальше - пусть игра сама решает, когда удалить модель)
KEEP_IN_MEMORY = 0x8, // Сохранять в памяти, пока мы сами не выгрузим модель (RemoveModel)
PRIORITY_REQUEST = 0x10 // Особый приоритет загруки (в функции LoadAllRequestedModels есть параметр на загрузку только таких моделей)
};
Эти описания - примерные, я их только вчера составил, и не было времени всё проверить. Раньше этого перечисления я вообще нигде не находил :)Вот здесьКод: [Выделить]void CVehicle::OpenDoor(CPed* ped, int componentId, eDoors door, float doorOpenRatio, bool playSound)
eDoors door - что ставить? В клео я ставил 0-5, а здесь пишет аргумент типа int несовместим с параметром типа "eDoors".
static_cast<eDoors>(5)
Вот код моего скрипта (для GTA3, но не суть), не пойму, как сделать такое в плагине (для SA). Цикл for в частности, как реализовать wait 0? Можно пример? Пожалуйста ???
Но я бы советовал использовать специальные утилиты для обновления/изменения:Скачал, установил.
Git for Windows
TortoiseGit
Создать аккаунт на github.kenkingGitHub (никнейм kenking уже кто-то занял, наглость какая ;D)
Сообщить мне свой никнейм (мне нужно будет добавить его в список редакторов).
Тебе нужно мыслить по-другому - ты "вклиниваешься" в процесс каждый фрейм.Буду пробовать, после клео как-то непривычно. Ещё раз большое спасибо за подробные пояснения!
Заметь, что и в твоём скрипте, и в этом примере есть небольшая проблема - это выполнение действий над авто в цикле, без доп. проверки на существование этого авто. Чисто теоретически - пока обрабатывается открытие/закрытие, с авто может что-то случитьсяЕсть такое дело. Я проверку там в общем-то сознательно не поставил, потому как при написании такого скрипта для VC во время процесса открывания/закрывания компонента специально взрывал авто и вылета не было, поскольку авто сразу не удаляется. Ну так-то проверку лучше ставить, согласен.
для VC хорошо бы и версию 1.1 учитыватьНе думаю, что ради этого стоит напрягаться - сейчас мало кто учитывает 1.1: даже MVL работает лишь с 1.0
Не думаю, что ради этого стоит напрягаться - сейчас мало кто учитывает 1.1 - даже MVL работает лишь с 1.0Я в клео скриптах учитываю. В библиотеке клео тоже учитывали это дело. Не думаю, что это большой напряг для того, кто разбирается в этом. Ну автору, конечно, решать.
if (automobile->m_damageManager.GetDoorStatus(doorId) != 3)
Для VC и GTA3 значение 3 - это компонент отсутствует, т.е. он повредился и отвалился. Для SA такое состояние компонента будет 4. Однако при замене 3 на 4 плагин перестаёт работать, т.е. компоненты не открываются и не закрываются. Это как понимать?Если ты знаешь значения этого перечисления - можешь их добавить в файле CDamageManager.h, и далее использовать их при вызове (напр. DOOR_FRONT_LEFT).Добавил:
enum eDoors
{
BONNET = 0,
BOOT = 1,
DOOR_FRONT_LEFT = 2,
DOOR_FRONT_RIGHT = 3,
DOOR_REAR_LEFT = 4,
DOOR_REAR_RIGHT = 5
};
enum ePanels
{
WING_FRONT_LEFT = 0,
WING_FRONT_RIGHT = 1,
WINDSCREEN = 4,
BUMP_FRONT = 5,
BUMP_REAR = 6
};
А есть ли в планах и для GTA3 плагин сделать?Нет. Даже на plugin_vc у меня времени почти нет.
kenkingGitHub (никнейм kenking уже кто-то занял, наглость какая ;D)Кинул тебе инвайт.
Не думаю, что это большой напряг для того, кто разбирается в этом.Я не скажу, что это очень сложно. Это просто требует времени. Много времени. Сейчас в plugin-sdk (SA) более 2700 адресов.
Для VC и GTA3 значение 3 - это компонент отсутствует, т.е. он повредился и отвалился. Для SA такое состояние компонента будет 4. Однако при замене 3 на 4 плагин перестаёт работать, т.е. компоненты не открываются и не закрываются. Это как понимать?Действительно, не работает.
Добавил:Как будет время - можешь попробовать сделать коммит.
Нет. Даже на plugin_vc у меня времени почти нет.Жаль, было бы хорошо собрать плагин для GTA3, VC и SA в один "инструмент". А если ещё сделать для IV и V - это была бы самая крутая вещь для скриптинга GTA.
Я не скажу, что это очень сложно. Это просто требует времени. Много времени. Сейчас в plugin-sdk (SA) более 2700 адресов.Да для SA это в общем-то без надобности. Я скрипты писал тоже только под exe 1.0. Да и остальные скриптёры тоже.
Поиск всех этих адресов в exe какой-либо другой версии может занять месяцы (с моим графиком). Я для себя вообще отбросил этот вариант.
Действительно, не работает.Вот теперь всё отлично!
UPD: разобрался, это ошибка в sdk. Дело в том, что есть 2 функции GetDoorStatus. Одна в качестве аргумента принимает перечисление eDoors, вторая - id компонента. В sdk эти функции были перепутаны. Уже исправил.
Как я понял, после каждого обновления надо пересобирать плагин?Да.
Что означают эти предупреждения и "кирпичи". Какие нужны действия?Красным отмечены файлы, которые ты изменил (и которые, по идее, нужно "закоммитить"). Зелёный - совпадает с текущим (на репозитарии). Серый - файлы игнорируются (не включаются в коммит и их нету в репозитории).
Красным отмечены файлы, которые ты изменил (и которые, по идее, нужно "закоммитить")При сборке примеров у меня выходило сообщение компилятора:
Main.obj : найден .netmodule MSIL или модуль, откомпилированный с параметром /GL; перезапускается компоновка с параметром /LTCG; добавьте /LTCG в командную строку компоновки для повышения производительности компоновщикаВ общем я добавил во все примеры. Также по незнанию, я начал было экспериментировать в этом решении. ??? "Откатил" всё назад. Теперь буду учиться в своём решении, а не в plugin-sdk.
Как будет время - можешь попробовать сделать коммит.Вот и сделал... :(
В в CDamageManager.h есть ещё "пустые" перечисленияТоже какие-то перечисления. Надо смотреть код функций
tComponent
tComponentGroup
eWheels
Ну с eWheels вроде, как понятно - это 6 колёс, а остальные что означают?
Вот и сделал... :(Ты о чём? Вроде всё правильно сделал.
Ты о чём? Вроде всё правильно сделал.Да там https://github.com/DK22Pac/plugin-sdk/tree/master/examples (https://github.com/DK22Pac/plugin-sdk/tree/master/examples) теперь везде
CDamageManager: added enum ePanels and enum eDoors
:007F0ED0 ; RwFrame *__cdecl RwFrameScale(RwFrame *frame, RwV3D *v, int combine)
Как добавить в плагин? 1) Как от найденного компонента перейти к child, next, root, а также прочитать их названия (+ 172 // NodeName)?Если у тебя есть указатель на RwFrame, используй оператор -> для доступа к членам структуры:
2) Какой алгоритм добавления новой функции в плагин?Эта функция уже есть в sdk.
Допустим, я знаю такой адрес:Код: [Выделить]:007F0ED0 ; RwFrame *__cdecl RwFrameScale(RwFrame *frame, RwV3D *v, int combine)
Как добавить в плагин?
3) Планируешь ли добавить в примеры код IVF? Не устаю повторять - это лучший мод на эту тему, когда-либо сделанный для SA! Хорошо бы с комментариями добавить его в примеры (ну или выслать в ЛС, если можно). Кстати, (я про это писал уже на GCU форуме) в версии IVF 2.1 на прицепах поворотники не работают.Для начала нужно весь код IVF адаптировать под новый sdk. Тогда, возможно, выложу исходники на github.
Эта функция уже есть в sdk.Это я для примера. А как её правильно вызывать? Для клео ты мне тогда объяснял, теперь, что-то не пойму здесь как надо.
Если у тебя есть указатель на RwFrame, используй оператор -> для доступа к членам структуры:А название компонента, как прочитать? В клео по смещению + 172 читалось имя компонента. Я делал скрипт для дверей автобусов, там в модель добавлялись вспомогательные компоненты и их названия были величины углов, на которые нужно вращать двери (у разных моделей разные значения), потом я считывал название этого компонента (child, next) и переводил из string в float, получал значение угла вращения.
Тогда, возможно, выложу исходники на github.Было бы здорово!
RwFrameForAllChildren(frame - родительский фрейм (доступ к детям которого надо получить
DrawFrameHierarchyNames - функция (функция-коллбэк), которую надо выполнить для каждого ребёнка,
offset - наши данные, которые будут переданы в функцию-коллбэк );
Можно расшифровать так:А как её правильно вызывать? Для клео ты мне тогда объяснял, теперь, что-то не пойму здесь как надо.
#include <plugin.h>
#include "game_sa\common.h"
#include "game_sa\CFont.h"
using namespace plugin;
class VehicleGetPosition {
public:
VehicleGetPosition() {
Events::drawingEvent += [] {
CVehicle *vehicle = FindPlayerVehicle(-1, false);
if (vehicle) {
// Настраивем вывод текста
CFont::SetScale(0.5f, 1.0f);
CFont::SetColor(CRGBA(255, 255, 255, 255));
CFont::SetAlignment(ALIGN_LEFT);
CFont::SetOutlinePosition(1);
CFont::SetDropColor(CRGBA(0, 0, 0, 255));
CFont::SetBackground(false, false);
CFont::SetFontStyle(FONT_SUBTITLES);
CFont::SetProp(true);
CFont::SetWrapx(600.0f);
CVector vspeed = vehicle->m_vLinearVelocity;
float speed = sqrt(vspeed.x*vspeed.x + vspeed.y*vspeed.y + vspeed.z*vspeed.z);
speed *= 180;
float vhealth = vehicle->m_fHealth;
float vmass = vehicle->m_fMass;
CVector posn = vehicle->GetPosition();
char t_speed[16];
char t_health[16];
char t_vmass[16];
char t_posnx[16];
char t_posny[16];
char t_posnz[16];
sprintf(t_speed, "speed %.0f km/h", speed);
sprintf(t_health, "health %.0f \%\%", vhealth/10.0f);
sprintf(t_vmass, "massa %.1f kg", vmass);
sprintf(t_posnx, "posn x %.2f", posn.x);
sprintf(t_posny, "posn y %.2f", posn.y);
sprintf(t_posnz, "posn z %.2f", posn.z);
CFont::PrintString(5.0f, 5.0f, t_speed);
CFont::PrintString(5.0f, 25.0f, t_health);
CFont::PrintString(5.0f, 45.0f, t_vmass);
CFont::PrintString(5.0f, 65.0f, t_posnx);
CFont::PrintString(5.0f, 85.0f, t_posny);
CFont::PrintString(5.0f, 105.0f, t_posnz);
}
};
}
} vehicleGetPosition;
namespase "plugin::Events" не содержит члена "vehicleSetModelEvent"
Пример вызоваСпасибо, теперь ясно. Но есть одно но - при RwMatrixScale если вращать компонент, например дверь, то она принимает стандартный размер. В клео я поэтому вызывал RwFrameScale - тогда компонент при вращении остаётся запланированного масштаба. По примеру попробовал вызвать RwFrameScale так:
RwFrameScale(automobile->m_aCarNodes[CAR_DOOR_LR], &scale, rwCOMBINEPRECONCAT);
Не знаю правильно или нет, но компонент масштабируется, но при вращении опять становится стандартного размера. А при rwCOMBINEREPLACE так и вовсе оказывается в центре модели (как и при вращении с этим параметром после RwMatrixScale). В клео нормально работало, что я делаю не так? RwV3d savedPosn = automobile->m_aCarNodes[CAR_DOOR_LF]->modelling.pos;
RwV3d scale = { 2.0f, 2.0f, 2.0f };
RwMatrixScale(&automobile->m_aCarNodes[CAR_DOOR_LF]->modelling, &scale, rwCOMBINEREPLACE);
automobile->m_aCarNodes[CAR_DOOR_LF]->modelling.pos = savedPosn;
Можно, как ты написал до этого:RwV3d scale = { 2.0f, 2.0f, 2.0f };
RwMatrixScale(&automobile->m_aCarNodes[CAR_DOOR_LR]->modelling, &scale, rwCOMBINEPRECONCAT);
только combine поменять на rwCOMBINEPRECONCATпример, показывает как использовать VehicleExtendedData.работает.
CVector vspeed = vehicle->m_vLinearVelocity;
float speed = sqrt(vspeed.x*vspeed.x + vspeed.y*vspeed.y + vspeed.z*vspeed.z);
speed *= 180;
Верно?Со скоростью "разобрался" так:
Верно?
Также не понятно, как вывести название транспорта.
В клео я поэтому вызывал RwFrameScale - тогда компонент при вращении остаётся запланированного масштаба.
[code=cpp][/code
Можешь показать свой код в клео?
{$CLEO .cs}
20@ = 0.5 // X
21@ = 0.5 // Y
22@ = 0.5 // Z
while true
wait 0
if
Player.Defined($PLAYER_CHAR)
then
if and
Actor.Driving($PLAYER_ACTOR)
0AB0: key_pressed 53
then
03C0: 0@ = actor $PLAYER_ACTOR car
0A97: 0@ = car 0@ struct
0A8E: 0@ = 0@ + 0x18
0A8D: 0@ = read_memory 0@ size 4 virtual_protect 0
0AA7: call_function 0x4C5400 num_params 2 pop 2 _nodename "chassis_dummy" _rwObject 0@ _store_to 1@
if
1@ > 0
then
0AA5: call {RwFrameScale} 0x7F0ED0 num_params 3 pop 3 _combine 1 _v 20@v _frame 1@
end
repeat
wait 0
until 8AB0: not key_pressed 53
end
end
end
(http://savepic.net/8372643m.jpg) (http://savepic.net/8372643.jpg) (http://savepic.net/8373667m.jpg) (http://savepic.net/8373667.jpg)Находишь gxt-ключ названия в структуре модели транспорта (CVehicleModelInfo) и переводишь его в текст (CText::Get(char* ключ))Спасибо.
.text:0043A570 _cheatSpawnTankerTruck proc near
В sdk ты его не добавил? Я во всяком случае в CCheat его не нашёл. Ведь по-идеи он там должен быть? Или в других файлах? Попробовал туда добавить так:Давно задаюсь вопросом - можно ли переписать эту функцию так, чтобы считывать пары ID тягача и ID прицепа из текстового файла (ну в крайнем случае в сам плагин набрать это сочетание, ну лучше считывать из текстового файла) и потом аналогичным образом спаунить другие тягачи с прицепами, ведь нормального спаунера авто с прицепами так и не сделали.Можно полноситью заменить оригинальную функцию своей.
CCheat я особо не разбирал.А добавил-то я правильно?
В sdk была только функция VehicleChear для спавна авто.
Да.ЦитироватьCCheat я особо не разбирал.А добавил-то я правильно?
В sdk была только функция VehicleChear для спавна авто.
Можно было бы вообще разделить процессы открытия/закрытия и обработки клавиш (чтобы эти процессы выполнялись одновременно).Т.е. нажал клавишу, дверь открывается\закрывается и в это же время нажал другую клавишу и одновременно пошло открытие\закрытие другой двери? И т.д. Можно это показать для этого же примера? (SA_OpenDoorExample) https://github.com/DK22Pac/plugin-sdk/blob/master/examples/SA_OpenDoorExample/Main.cpp (https://github.com/DK22Pac/plugin-sdk/blob/master/examples/SA_OpenDoorExample/Main.cpp)
2) Какой загрузчик asi использовать для VC, чтобы скрипты загружались не из корневого каталога, а из \scripts ?Ultimate ASI Loader (https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases)
kenking, покажу позже.Хорошо. Ещё интересует создание спецактёра. Там же отличается (в клео по-крайне мере) загрузка модели, создание актёра, выгрузка модели и т.д. Также интересна установка (и удаление) деталей тюнинга на транспорт. Такие примеры были бы тоже кстати.
Ultimate ASI Loader (https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases)Спасибо.
Т.е. нажал клавишу, дверь открывается\закрывается и в это же время нажал другую клавишу и одновременно пошло открытие\закрытие другой двери? И т.д. Можно это показать для этого же примера?
В этом примере процессы обработки нажатия клавиш и открытия/закрытия компонентов разделены.Круто! Спасибо за пример.
{$CLEO} // 0 - 48 , 9 -57
var
0@: array 5 of Integer // digits 0 1 2 3 4
17@: Integer // index
6@: Integer // current_digit
7@: Integer // SUM
8@: Integer // KEY_HOLD
15@: Integer // KEY
end
const
DIGIT = 0@
i = 17@
CURRENT_DIGIT = 6@
SUM = 7@
KEY_HOLD = 8@
KEY = 15@
end
CURRENT_DIGIT = 1
while true
wait 0
if or
not player.Defined($PLAYER_CHAR)
$ONMISSION <> 0
then
CURRENT_DIGIT = 1
SUM = 0
KEY_HOLD = False
for i = 0 to 4
0006: DIGIT[i] = 0
end
continue
end
if
8AB0: not key_pressed 2
then
if and
SUM > 0
SUM < 19010
then
if
07DE: model SUM exists // versionB
then
0AA7: call_function 0x4C5AA0 num_params 1 pop 1 SUM 9@ // isModelCar
0AA7: call_function 0x4C5B60 num_params 1 pop 1 SUM 10@ // isModelBike
0AA7: call_function 0x4C5C20 num_params 1 pop 1 SUM 11@ // isModelBmx
0AA7: call_function 0x4C5BF0 num_params 1 pop 1 SUM 12@ // isModelQuad
0AA7: call_function 0x4C5C50 num_params 1 pop 1 SUM 13@ // isModelTrailer
0AA7: call_function 0x4C5BC0 num_params 1 pop 1 SUM 14@ // isModelMTruck
if or
081E: model SUM boat
081F: model SUM plane
0820: model SUM heli
9@ == True
then
0ADD: spawn_car_with_model SUM at_player_location
else
if or
10@ == 8766721 // True
11@ == 8766721 // True
12@ == 8766721 // True
13@ == 8766721 // True
14@ == True
then
0ADD: spawn_car_with_model SUM at_player_location
end
end
end
end
CURRENT_DIGIT = 1
SUM = 0
KEY_HOLD = False
for i = 0 to 4
0006: DIGIT[i] = 0
end
continue
end // key pressed 2
if
KEY_HOLD == False
then
if
0AB0: key_pressed 8
then
KEY_HOLD = True
if
CURRENT_DIGIT > 1
then
CURRENT_DIGIT /= 10
008F: 16@ = integer CURRENT_DIGIT to_float
0AEF: 16@ = log 16@ base 10.0 //all floats
SUM = 0
0092: 16@ = float 16@ to_integer
16@ -= 1
for i = 0 to 16@
0016: DIGIT[i] /= 10
005A: SUM += DIGIT[i] // (int)
end
end
else
if
SUM >= 19010
then
continue
end
KEY = 48
for i = 0 to 9
if
0AB0: key_pressed KEY
then
008F: 16@ = integer CURRENT_DIGIT to_float
0AEF: 16@ = log 16@ base 10.0 //all floats
SUM = 0
0092: 16@ = float 16@ to_integer
0085: DIGIT[16@] = i // int
for i = 0 to 16@
if
001D: 16@ > i // (int)
then
0012: DIGIT[i] *= 10
end
005A: SUM += DIGIT[i] // (int)
end
CURRENT_DIGIT *= 10
KEY_HOLD = True
break
end
KEY += 1
end
end
else // KEY_HOLD == True
if and
8AB0: not key_pressed 48
8AB0: not key_pressed 49
8AB0: not key_pressed 50
8AB0: not key_pressed 51
8AB0: not key_pressed 52
then
if and
8AB0: not key_pressed 53
8AB0: not key_pressed 54
8AB0: not key_pressed 55
8AB0: not key_pressed 56
8AB0: not key_pressed 57
8AB0: not key_pressed 8
then
KEY_HOLD = False
end
end
end // KEY_HOLD == False
if
CURRENT_DIGIT > 1
then
03F0: enable_text_draw 1
045A: draw_text_1number 320.0 240.0 GXT 'NUMBER' number SUM
end
end
Круто! Спасибо за пример.Пример не самый простой получился... Для полного понимания нужно ознакомиться с понятиями
1) Названия классов могут совпадать в разных плагинах? Никакого конфликта не будет? Или всё, что делается в одном плагине остальных никак не касается?Да, можешь использовать одинаковые названия.
2) В конце кода это зачем?Эти переменные были обьявлены как статические внутри класса.
CModelInfo::IsVehicleModelType возвращает boolean (true/false), зачем переводить его в VehicleModelInfo, и сравнивать с -1 и 6 - непонятно.После перевода получается тип модели (0=car, 9=bike, 11=trailer и т.д.). А если модель не является транспортом или вообще нет такой модели, то получается значение -1, а 6 - это модель типа train. Вот я и проверяю, что набранное число - это ID модели транспорта и при этом не является моделью train. Потому как, если модель train, то происходит вылет игры. По другому я не придумал, как проверить. Денис проверял, что модель есть (в моём коде сравнение с -1) и она является любой из моделей, кроме train (в моём коде сравнение с 6). Так-то плагин в работе я проверил, всё работает. Просто по самому коду - может, где-то можно, что-то оптимизировать?
if
07DE: model SUM exists // versionB
then
0AA7: call_function 0x4C5AA0 num_params 1 pop 1 SUM 9@ // isModelCar
0AA7: call_function 0x4C5B60 num_params 1 pop 1 SUM 10@ // isModelBike
0AA7: call_function 0x4C5C20 num_params 1 pop 1 SUM 11@ // isModelBmx
0AA7: call_function 0x4C5BF0 num_params 1 pop 1 SUM 12@ // isModelQuad
0AA7: call_function 0x4C5C50 num_params 1 pop 1 SUM 13@ // isModelTrailer
0AA7: call_function 0x4C5BC0 num_params 1 pop 1 SUM 14@ // isModelMTruck
if or
081E: model SUM boat
081F: model SUM plane
0820: model SUM heli
9@ == True
then
0ADD: spawn_car_with_model SUM at_player_location
else
if or
10@ == 8766721 // True
11@ == 8766721 // True
12@ == 8766721 // True
13@ == 8766721 // True
14@ == True
then
0ADD: spawn_car_with_model SUM at_player_location
end
end
end
Видимо эта функция не предназначена для работы с таким типом транспорта.
Давно задаюсь вопросом - можно ли переписать эту функцию так, чтобы считывать пары ID тягача и ID прицепа из текстового файла (ну в крайнем случае в сам плагин набрать это сочетание, ну лучше считывать из текстового файла) и потом аналогичным образом спаунить другие тягачи с прицепами, ведь нормального спаунера авто с прицепами так и не сделали.
KeyCheck.hДобавил в \plugin_sa\game_sa или надо было в другое место добавлять?
KeyCheck.cpp
По поводу скрипта Дениса:Ну да, так лучше, чем в моём варианте. :)
Я бы вообще переделал обработку набора числа.
В C++ можно сделать всё намного "чище".
Вот что получилось:Класс! Спасибо за пример и пояснения! Есть один момент - при повторном спауне первый тягач благополучно удаляется, а вот первый прицеп нет и получается ко второму тягачу цепляются два прицепа, через некоторое время они взрываются. Для прицепа нужен RemoveReferences. Как добавить?
Добавил в \plugin_sa\game_sa или надо было в другое место добавлять?
Есть один момент - при повторном спауне первый тягач благополучно удаляется, а вот первый прицеп нет и получается ко второму тягачу цепляются два прицепа, через некоторое время они взрываются. Для прицепа нужен RemoveReferences. Как добавить?
И ещё сразу по прицепам есть вопрос - можно ли в трафике в процессе создания транспорта проверить, если модель определённого ID (тягач), то цеплять к нему прицеп. Цеплять не на весь транспорт с таким ID, а выборочно, ну скажем через определённое время? Цеплять разные прицепы?
Добавь
trailer->m_nStatus = 4; // что это за статус - без понятияПроверил, с значениями 0-2 прицеп становится поверх тягача, 3 тоже, что и 4 получился результат.
Добавляй в проект твоего плагина.Упс.. а я добавил в \plugin_sa\game_sa да ещё и коммит сделал... поторопился... Убрать из \plugin_sa\game_sa и сделать новый коммит или ты сам исправишь?
2) Имеет ли значение в какой процесс "вклиниваться"?
3) Имеет ли значение каким способом это делать? ТакКод: C++или так
Events::gameProcessEvent += [] { };Код: C++
OpenDoorExample() { Events::gameProcessEvent.Add(Process); }
4) Как я понял, если надо, чтобы два действия обрабатывались одновременно, надо "вклиниваться" в два разных процесса?
5) Как в плагине проверить $ONMISSION == 0
{$CLEO .cs}
0000:
const
AVTO = 0@ // авто
MODEL_AVTO = 1@ // модель авто
CLASS_AVTO = 2@ // класс авто
STRUCT_AVTO = 3@ // структура авто
ENGINE_TYPE = 4@ // тип двигателя
EXHAUST = 5@ // тип выхлопа
PARTICLE_1 = 6@ // эффект_1
PARTICLE_2 = 7@ // эффект_2
DOUBLE = 8@ // вспомогательная переменная
X_1 = 9@ // координата Х_1
Y_1 = 10@ // координата Y_1
Z_1 = 11@ // координата Z_1
X_2 = 12@ // координата Х_2
end
var
X_1: Float
X_2: Float
end
while true
wait 0
if
Player.Defined($PLAYER_CHAR)
then
if
actor.Driving($PLAYER_ACTOR)
then
03C0: AVTO = actor $PLAYER_ACTOR car // транспорт игрока
if
01C1: car AVTO stopped // транспорт стоит
then
if
00E1: key_pressed 0 16
then
0441: MODEL_AVTO = car AVTO model // модель транспорта
08EC: CLASS_AVTO = car AVTO type // класс транспорта
if and
0A01: model MODEL_AVTO car // транспорт = авто
04A4: CLASS_AVTO == 4 // @ == any // класс авто worker
then
0A97: STRUCT_AVTO = car AVTO struct // структура авто
STRUCT_AVTO += 0x384
0A8D: STRUCT_AVTO = read_memory STRUCT_AVTO size 4 virtual_protect 0 // получили указатель на handling-структуру
STRUCT_AVTO += 0x75
0A8D: ENGINE_TYPE = read_memory STRUCT_AVTO size 1 virtual_protect 0 // получили тип двигателя
if
ENGINE_TYPE == 68 // тип двигателя = дизель
then
MODEL_AVTO *= 4
MODEL_AVTO += 0xA9B0C8
0A8D: STRUCT_AVTO = read_memory MODEL_AVTO size 4 virtual_protect 0 // CModel
STRUCT_AVTO += 0x5C
0A8D: STRUCT_AVTO = read_memory STRUCT_AVTO size 4 virtual_protect 0 // vehicle struct
STRUCT_AVTO += 0x48
0A8D: X_1 = read_memory STRUCT_AVTO size 4 virtual_protect 0 // X_1
STRUCT_AVTO += 4
0A8D: Y_1 = read_memory STRUCT_AVTO size 4 virtual_protect 0 // Y_1
STRUCT_AVTO += 4
0A8D: Z_1 = read_memory STRUCT_AVTO size 4 virtual_protect 0 // Z_1
//---определение второго глушителя---
0A97: STRUCT_AVTO = car AVTO struct
STRUCT_AVTO += 0x384
0A8D: STRUCT_AVTO = read_memory STRUCT_AVTO size 4 virtual_protect 0
STRUCT_AVTO += 0xCC
0A8D: EXHAUST = read_memory STRUCT_AVTO size 4 virtual_protect 0
if
08B7: test EXHAUST bit 13
then
DOUBLE = 2
X_2 = X_1
X_2 *= -1.0
else
DOUBLE = 1
end
//----------------------------------
066C: PARTICLE_1 = attach_particle "riot_smoke" to_car AVTO with_offset X_1 Y_1 Z_1 rotation 0.0 0.0 0.0 flag 1
064C: make_particle PARTICLE_1 visible
if
DOUBLE == 2
then
066C: PARTICLE_2 = attach_particle "riot_smoke" to_car AVTO with_offset X_2 Y_1 Z_1 rotation 0.0 0.0 0.0 flag 1
064C: make_particle PARTICLE_2 visible
end
wait 500
0650: destroy_particle PARTICLE_1
if
DOUBLE == 2
then
0650: destroy_particle PARTICLE_2
end
end
end
end
end
end
end
end
01C1: car AVTO stopped
Посмотрел опкод в базе и нашёл функцию.text:004861F0 CScriptEngine__isVehicleStopped proc near
Добавил в CVehicle00E1: key_pressed 0 16
В базе нашёл функцию.text:00485B10 _CScriptThread__getPlayerKeyState proc near
Только куда и как её добавить в sdk не разобрался.066C: PARTICLE_1 = attach_particle "riot_smoke" to_car AVTO with_offset X_1 Y_1 Z_1 rotation 0.0 0.0 0.0 flag 1
064C: make_particle PARTICLE_1 visible
0650: destroy_particle PARTICLE_1
Пока набросал примерный код без учёта непонятных моментов. Создание партицикла заменил на создание короны.Это CTheScripts::IsVehicleStopped(CVehicle *). Вообще, класс CScriptEngine (который в старой базе) - это CTheScripts ("Скрипты"). CScriptThread из старой базы - CRunningScript ("Исполняемый скрипт").Код: [Выделить].text:004861F0 CScriptEngine__isVehicleStopped proc near
2) Не нашёл в sdk замены (нашёл только перечисление ePadButton)ЭтоКод: [Выделить]00E1: key_pressed 0 16
В базе нашёл функциюКод: [Выделить].text:00485B10 _CScriptThread__getPlayerKeyState proc near
short CRunningScript::GetPadState(unsigned short player, unsigned short key)
Тебе надо смотреть в CPad.5) Работу с партициклами в sdk я тоже не нашёлДа, по партиклам почти ничего не было. Теперь есть.
Ещё в sdk есть перечисление eCommandName. Как можно использовать в написании плагина?Это просто перечисление опкодов.
позволяет ставить модели авто,обладающие особыми способностями, к примеру фары у ZR350, ковш у Dozer'a ... на лю6ые другие свободные ID с сохранением всех рабочих деталей
1>VehicleAdvanced.cpp(62): error C2676: бинарный "*": "CMatrixLink" не определяет этот оператор или преобразование к типу приемлемо к встроенному оператору
1>VehicleAdvanced.cpp(83): error C2676: бинарный "*": "CMatrixLink" не определяет этот оператор или преобразование к типу приемлемо к встроенному оператору
1>VehicleAdvanced.cpp(91): error C2676: бинарный "*": "CMatrixLink" не определяет этот оператор или преобразование к типу приемлемо к встроенному оператору
{TRAILER_HOOKs}
Reset(F);
{FIRST'n'LAST Hook}
CodePtr := VirtualAlloc(0, 1000 , MEM_COMMIT , PAGE_READWRITE) ;
VirtualProtect(ptr($6AF26C),5,PAGE_READWRITE,OldProtect);
PByte($6AF26C)^:= $E9; // jmp
PInteger($6AF26D)^:= Integer(CodePtr) - $6AF26C - 5; // Alloced place
While not EOF(F) do
begin
ReadLn(F,StrName);
if not (strpos(PChar(StrName),'[TRAILER_HOOKs]')=nil) then break;
end;
Count:= ReadIntValue('MAIN','TRAILER_HOOKs');
For i:= 0 to Count-1 do
begin
ReadLn(F,S[i]);
PByte(Integer(CodePtr)+i*6)^:= $66;
PByte(Integer(CodePtr)+i*6+1)^:= $3D;
PSmallInt(Integer(CodePtr)+i*6+2)^:= StrToInt(S[i]);
PByte(Integer(CodePtr)+i*6+4)^:= $74;
PByte(Integer(CodePtr)+i*6+5)^:= (Count-i-1)*6 + $A;
end;
PByte(Integer(CodePtr)+Count*6)^:= $66; // cmp
PByte(Integer(CodePtr)+Count*6+1)^:= $3D; // ax
PByte(Integer(CodePtr)+Count*6+2)^:= $02; // id
PByte(Integer(CodePtr)+Count*6+3)^:= $02; // 2 b
PByte(Integer(CodePtr)+Count*6+4)^:= $0F; // jnz
PByte(Integer(CodePtr)+Count*6+5)^:= $85; // $6AF284
PInteger(Integer(CodePtr)+Count*6+6)^:= $6AF272 - (Integer(CodePtr)+Count*6+10);
PByte(Integer(CodePtr)+Count*6+10)^:= $E9; // jmp $6AF2CC
PInteger(Integer(CodePtr)+Count*6+11)^:= $6AF2CC - (Integer(CodePtr)+Count*6+15);
CloseFile(F);
{TRAILER_HOOKs_END}
Есть плагин fastman92 лимит-аджастер. Там тоже есть попытка сделать дополнительные модели. Проект отличный, можно расширять карту, воду, кол-во авто итд. Так вот к чему это я, может вам объединиться с ним касательно части новых фишек для авто. Возможно его дело пойдет быстрее.С меня в данный момент польза для fastman'а вряд ли будет, я только начал изучать. ;D
Вместо ini я бы использовал такой формат
По-моему, так намного удобнее.
Я бы сделал так, по аналогии с vehicles.ide:
Или вообще всё в отдельный файл и убрать метки trucks и end.Надо ещё один объект std::stringstream и std::vector для float значений? А как сопоставлять их значения? Или как-то по другому? Вот, допустим, первой колонкой идёт набор ID каких-то моделей транспорта, второй колонкой идёт какое-то значение float (допустим, угол поворота фар). Как их правильно считать и сопоставить угол и ID?
Добавил все функции класса CGeneral, теперь там есть такое:Это хорошо. В скриптах я частенько пользовался этими опкодами.
Эти функции используются в опкодах 0208 и 0209.
Как будет свободное время разбери пожалуйста это дело. Вопрос с прицепами интересен многим пользователям. Было написано несколько скриптов на эту тему (в том числе и у меня есть такой скрипт), но это всё не то.И ещё сразу по прицепам есть вопрос - можно ли в трафике в процессе создания транспорта проверить, если модель определённого ID (тягач), то цеплять к нему прицеп. Цеплять не на весь транспорт с таким ID, а выборочно, ну скажем через определённое время? Цеплять разные прицепы?Можно, надо разбирать CCarCtrl::GenerateOneRandomCar.
Обновился пример CreateCar, теперь вместо CCheat::VehicleCheat там используется своя функция спавна.Просьба пояснить эти строчки:
Просьба пояснить эти строчки:Код: C++
reinterpret_cast<CBike *>(vehicle)->m_nDamageFlags |= 0x10; reinterpret_cast<CBmx *>(vehicle)->m_nDamageFlags |= 0x10;
и эти:Код: C++
reinterpret_cast<CBike *>(vehicle)->PlaceOnRoadProperly(); reinterpret_cast<CAutomobile *>(vehicle)->PlaceOnRoadProperly();
Верно ли?
Дальше задумался над кодом для спидометра, но не нашёл функции для вращения текстуры стрелки.
Действительно, в оригинальных классах нету такой функции (для отрисовки текстуры с наклоном). Надо самому писать.Стоп, а как в опкоде это реализовали? Там и скейл, и поворот текстуры на экране. Помню, что работает(когда-то давнооо скриптил для SA)..
Понятно, что отрисовать текстуру с поворотом в игре можно, что в Вайсе, что в СА.ЦитироватьДействительно, в оригинальных классах нету такой функции (для отрисовки текстуры с наклоном). Надо самому писать.Стоп, а как в опкоде это реализовали? Там и скейл, и поворот текстуры на экране. Помню, что работает(когда-то давнооо скриптил для SA)..
074B: draw_sprite_with_rotation 20 coords 428@ 429@ scale 430@ 431@ angle $TEMPVAR_ANGLE rgba 220 220 220 404@
Или вы про Вайс говорите?
Всё так же.Спасибо. А в этом случае удалять эту текстуру надо? Т.е. если у меня в Events::initRwEvent
Из спрайта ты можешь получить доступ к текстуре.Код: C++
mySprite.m_pTexture
Понятно, что отрисовать текстуру с поворотом в игре можно, что в Вайсе, что в СА.Ничего себе...сказывается, что опыта у меня пока маловато - я думал, что если есть опкод, то ничего особо самому писать не нужно(думал, что для каждого опкода есть функция)... просто пока ковырял примитивные опкоды ;D
Я имел ввиду, что отдельной функции для этого нету.
Ещё например, установка винила на авто.С этим разобрался. Набросал пример:
В первом примере надо определить переменную entries.Код: C++
vector<SettingsTest::MyData> SettingsTest::entries;
Разобрался, спасибо!
По самому коду есть какие-либо замечания?Вроде всё правильно.
ФункцияДа, есть такое. CVehicleModelInfo не до конца доработан.Код: C++описание есть, а определения нет (и другие функции из CVehicleModelInfo), добавил так:
int GetNumRemaps();Код: C++
// Converted from thiscall int CVehicleModelInfo::GetNumRemaps(void) 0x4C86B0 int CVehicleModelInfo::GetNumRemaps() { return ((int(__thiscall *)(CVehicleModelInfo*))0x4C86B0)(this); }
2) Обнаружил интересную вещь - установить покрасочную работу на авто можно ещё так:Можно. Но и сами текстуры надо будет куда-то добавлять (например, в txd авто).Код: C++Получается этим способом можно обойти ограничение на количество покрасочных работ для модели.
vehicle->m_pRemapTexture = pMyTexture;
Есть ли способ "заполучить" текстуру в RwTexture *pMyTexture; (помимо способов:)Есть функции поиска текстуры в txd.Код: C++например, из txd, который находится в gta3.img?
pMyTexture = mySprite.m_pTexture; //и pMyTexture = RwD3D9DDSTextureRead("models\\image", 0);
А для коллизии колёс как будет?Колёса, вроде бы, это тоже сферы. Не уверен. Позже гляну.
А можно как-то масштабировать тень модели?
Подскажи пожалуйста, как таким же образом определить MyData *GetDataInfoForModel(unsigned int BaseModelId)Обьявляй всё как статические члены (static).
Можно. Но и сами текстуры надо будет куда-то добавлять (например, в txd авто).Да, в txd авто - это самый приемлемый вариант.
Есть функции поиска текстуры в txd.Из существующего txd модели. У некоторых моделей есть по два набора покрасок (по четыре покрасочных работ в каждом наборе). Приходится ставить на выбор 4 из них. Если остальные 4 поместить в txd модели, доставать их оттуда и ставить таким образомКод: C++Вторая функция добавлена в последнем коммите.
RwTexture* RwTexDictionaryFindNamedTexture(RwTexDictionary* dict, const RwChar* name); // поиск по имени, RenderWare.h RwTexture* RwTexDictionaryFindHashNamedTexture(RwTexDictionary* txd, unsigned int hash); // поиск по хеш-ключу, common.h
TXD можно достать из пула (если она загружена).
Ты хочешь загружать из дополнительного txd или из уже существующего?
Обьявляй всё как статические члены (static).Вот с объявлением
Статические переменные дополнительно определяй за пределами класса.
Можно пример, как достать текстуру (несколько текстур) из txd модели.
Вот с объявлениемКод: C++за пределами класса у меня как раз и непонятка возникла. Покажи пожалуйста.
MyData *GetDataInfoForModel(unsigned int BaseModelId)
Обновил код, т.к. могли возникнуть проблемы с порядком создания обьектов (главного класса и вектора).А если так, то будет нормально, правильно я понимаю?
Вот в такой вот ситуации
>d:\projects\plugin-sdk\plugin_sa\game_sa\TxdDef.h(19): warning C4161: #pragma pack(pop...): число извлечений из стека превышает число занесений
А если так, то будет нормально, правильно я понимаю?Код: C++
vector<int> vec; // определяем переменную vec (вызывается конструктор std::vector) class A { A() { // Конструктор класса A vec.push_back(5); // Добавляем элемент в вектор } } a; // определяем обьект a класса A (вызывается конструктор A)
2) При сборке какого-либо проекта с подключениемКод: C++проект собирается, но студия выдаёт предупреждение
#include "game_sa\CTxdStore.h"Цитировать>d:\projects\plugin-sdk\plugin_sa\game_sa\TxdDef.h(19): warning C4161: #pragma pack(pop...): число извлечений из стека превышает число занесений
3) С поддержкой Windows XP какой-либо проект нельзя собрать?
4) Если объединять примеры для zr350 и тягачей, то считывание с vehicle_advanced.dat надо делать так?
Собирать с тулсетом для XP (v140_xp).
Если у тебя он не установлен, можно скачать и установить.
C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.CppBuild.targets(1193,5): warning MSB8030: The linker switch "Minimum Required Version" requires "SubSystem" to be set. Without "SubSystem", the "Minimum Required Version" would not be passed to linker and could prevent to the output binary from running on older Operating Systems.
Попробуй поставить SubSystem на Windows.
Какая именно ошибка выходит на WinXP?Плагин просто не работает, т.е. ничего не происходит. Я собирал для ребят твои примеры GPS и Универсальные поворотники. Скинул на тест эти же плагины, собранные по-новой. Протестируют, посмотрим какой будет результат. Но по-любому в целевой платформе надпись Windows так и не появилась. :(
У меня пустой проект с настройками для XP (тулсет, субсистема) нормально запускается (проверил на виртуальной машине с XP SP3).А у тебя в позиции целевая платформа надпись Windows при этом есть?
Также есть функции RwMatrixRotate/RwFrameRotate, которые вращают матрицу/фрейм вокруг оси (ось можно задать своим вектором).Да, покажи пожалуйста такие примеры для открытия и закрытия, например, капота авто функциями RwMatrixRotate/RwFrameRotate и методом CMatrix.
Ну и ещё вариант - вращение методами CMatrix: RotateX,RotateY,RotateZ и другими (см. файл CMatrix.h) Eсли будет нужно, то покажу на примере.
Да, покажи пожалуйста такие примеры для открытия и закрытия, например, капота авто функциями RwMatrixRotate/RwFrameRotate и методом CMatrix.С вызовом RwMatrixRotate/RwFrameRotate разобрался.
Documents\Visual Studio 2015\Templates\ProjectTemplates
Заменить пути на свои в файле ProjectSA.vcxproj.Просьба протестировать этот плагин на XP (это кар спаунер (https://github.com/DK22Pac/plugin-sdk/tree/master/examples/SA_VehicleSpawner) + сообщение при аттаче).Ребята протестили. Теперь работает и на XP.
Сделал новый шаблон проекта (для SA).Собрал для теста два плагина с новым шаблоном. Проверил у родственников на компьютере с Windows XP SP2 - работают! :D Спасибо! ;)
Для сборки под XP выбрать режим Rel-XP.
Просьба показать вызов методов CMatrix.
[29]Вот я тоже хотел узнать. Это разве не побайтовое смещение?
void ***X = (void ***)this
приводим this (CVehicle *) к (void ***) (то же самое, что reinterpret_cast<void ***>(this))void **Y = *X
Разыменовываем указатель void *** ("читаем" значение по адресу (this + 0) - получаем указатель на таблицу виртуальных методов (void **, массив указателей на void *))void *Z = Y[29]
Получаем элемент с индексом 29 в этой таблице, получили указатель void *auto F = ((float (__thiscall *)(CVehicle*, unsigned int))Z
Приводим этот указатель к указателю на функцию нужного типаF(this, door)
И тут же вызываем эту функцию.Вот я тоже хотел узнать. Это разве не побайтовое смещение?Если у тебя массив char (размер = 1 байт) - то да, побайтовое.
Прост я выдернул напрямую кусок псевдокода из IDA - он блокирует/разблокирует управление игроком. Всё работает, но что конкретно тут происходит - я не знаю:Как именно ты получаешьКод: C++
//вначале неким способом мы получаем __int16 *GetPadInt //потом следующие строчки служат для управления управлением, лол:
вначале неким способом мы получаем __int16 *GetPadInt?
GetPadInt[120] // получить элемент с индексом 120 в массиве GetPadInt,
//что происходит на последних двух строчках^ - хз
Это вызов метода из таблицы виртуальных методов (virtual table, "vtable").
Почему именно 5-ый бит - открывай калькулятор в режиме "Программист" и разбирайся :)Да вот тут опять загвоздка - я не понимаю, почему 5й, а не 6й бит(если считать справа налево), ведь 6й становится нулем:
Да вот тут опять загвоздка - я не понимаю, почему 5й, а не 6й бит(если считать справа налево), ведь 6й становится нулем:5ый - потому, что биты обычно считают от нуля. Даже в калькуляторе это видно.
И последний вопрос: если есть адрес массива float a, то являются ли следующие варианты идентичными:Нет.
Я все обьявления и определения (методов класса) генерировал автоматом.Было бы хорошо. :)
Могу и тебе эту программу подогнать :)
В CVehicleModelInfo.h некоторые функции объявлены как статические, например
выходит "оператор this можно использовать только внутри не статической функции-члена"
Убрать static или как определять эту функцию?
И ещё просьба пояснить момент с определением __cdecl или __thiscall
IDA верно определяет этот момент или не всегда?
Как самому в этом разобраться?
По аналогии с опкодом 0506Подключать надо CRunningScript? Что-то не получается у меня. Добавь пожалуйста в тот код, что я показал.Код: C++
case COMMAND_SET_CAR_MODEL_COMPONENTS: this->CollectParameters(3); // параметр №1 не используется CVehicleModelInfo::ms_compsToUse[0] = ScriptParams[1].i; CVehicleModelInfo::ms_compsToUse[1] = ScriptParams[2].i; return OR_CONTINUE;
Когда именно вылетает (на загрузке или в процессе игры)?Да файл открывает и данные считываются. Но я имел ввиду не этот конкретно код, а в общем.
Файл открывается, данные считываются?
По CVehicleModelInfo - вроде всё правильно у тебяСделал коммит.
Подключать надо CRunningScript? Что-то не получается у меня. Добавь пожалуйста в тот код, что я показал.
А в случае с плагинами, как находить из-за какого плагина был вылет и в каком месте кода ошибка?
1>------ Перестроение всех файлов начато: проект: TankerTruck, Конфигурация: Rel-XP Win32 ------
1> Main.cpp
1>Main.obj : error LNK2001: неразрешенный внешний символ ""public: static char * CVehicleModelInfo::ms_compsUsed" (?ms_compsUsed@CVehicleModelInfo@@2PADA)"
1>D:\Games\GTA San Andreas\scripts\TankerTruck.asi : fatal error LNK1120: неразрешенных внешних элементов: 1
========== Перестроение всех проектов: успешно: 0, с ошибками: 1, пропущено: 0 ==========
но студия ругаетсяНадо определить эти переменные в CVehicleModelInfo.cpp.
В показанных ранее примерах в этих строчкахВызов 0x486B00 уже можно заменить наКод: C++
CallMethod<NoRet, 0x506EA0, unsigned int, int, float, float>(0xB6BC90, audioEventId, volume, speed); Call<NoRet, 0x486B00, CVector const&, CEntity *>(trailer->GetPosition(), trailer);
теперь подчёркиваются красным
Call<NoRet и CallMethod<NoRet
Студия ругается, что идентификатор не определён и отсутствуют экземпляры шаблон функции...
Там есть 2 разные переменные, compsUsed и compsToUse.Вот теперь всё отлично. :) Спасибо!
Надо именно во второе записывать.
Там надо unsigned short поменять на wchar_t.Пришлось в настройках прописать _CRT_NON_CONFORMING_SWPRINTFS, иначе мой тестовый плагин не собирался.
Обнови проект.
А вот с этими строчками игра зависает. >:(Код: C++
CFont::SetColor(CRGBA(255, 255, 255, 255)); CFont::SetDropColor(CRGBA(0, 0, 0, 255));
Так должно работатьАга так работает, спасибо. ;)
.text:00446A93 loc_446A93: ; CODE XREF: CRunningScript::ProcessCommands700To799(int)+22j
.text:00446A93 ; DATA XREF: .data:off_5EF4D0o
.text:00446A93 0 lea eax, [edi+10h] ; jumptable 004458C2 case 34
.text:00446A96 0 mov ecx, edi
.text:00446A98 0 push 1
.text:00446A9A 0 push eax
.text:00446A9B 0 call _ZN14CRunningScript17CollectParametersEPjs ; CRunningScript::CollectParameters(uint *,short)
.text:00446AA0 0 mov ecx, ds:ScriptParams
.text:00446AA6 0 xor al, al
.text:00446AA8 0 imul ecx, 4Fh
.text:00446AAB 0 mov esi, ds:_ZN6CWorld7PlayersE[ecx*4] ; CWorld::Players
.text:00446AB2 0 cmp byte ptr [esi+314h], 0
.text:00446AB9 0 jz short loc_446ADC
.text:00446ABB 0 mov edx, [esi+310h]
.text:00446AC1 0 movsx ebx, word ptr [edx+5Ch]
.text:00446AC5 0 cmp ebx, 6Eh
.text:00446AC8 0 jz short loc_446ADA
.text:00446ACA 0 cmp ebx, 80h
.text:00446AD0 0 jz short loc_446ADA
.text:00446AD2 0 cmp ebx, 94h
.text:00446AD8 0 jnz short loc_446ADC
.text:00446AC5 cmp ebx, 6Eh
.text:00446ACA cmp ebx, 80h
.text:00446AD2 cmp ebx, 94h
Что-то я тебе не совсем понимаю.А так?
CheckIfTaxiModel - это проверка. Зачем её вызывать таким образом?
В опкоде SET_TAXI_LIGHTS не один параметр, а два.
Ты понимаешь, как работает опкод IS_PLAYER_IN_TAXI ?Устанавливается флаг в ноль.
Проверка id начинается тут: 0x446AC5. id у нас записан в регистре ebx. начиная с адреса 0x446AC5, мы можем видоизменить кодПрошу прощения за проявленные тормоза. ;D
В опкод надо передавать хендл, а не указатель.Просьба показать пример, а то я сейчас опять наворочу чего попало, потом стыдно будет. :(
По "огонькам" - думаю, надо посмотреть в месте, где создается корона.В коронах я не нашёл. Но есть ещё опкод IS_TAXI. Может он на это влияет. Хотел сделать подобно показанному тобой примеру, но там id в eax, а номера для команды 'push eax' не знаю.
.text:00444CA5 cmp eax, 6Eh
.text:00444CA8 jz short loc_444CB8
.text:00444CAA cmp eax, 80h
.text:00444CAF jz short loc_444CB8
.text:00444CB1 cmp eax, 94h
.text:00444CB6 jnz short loc_444CBA
.text:00444CB8
.text:00444CB8 loc_444CB8: ; CODE XREF: CRunningScript::ProcessCommands600To699(int)+188j
.text:00444CB8 ; CRunningScript::ProcessCommands600To699(int)+18Fj
.text:00444CB8 mov dl, 1
.text:00444CBA
.text:00444CBA loc_444CBA: ; CODE XREF: CRunningScript::ProcessCommands600To699(int)+196j
.text:00444CBA mov ecx, ebp ; this
Хотел сделать подобно показанному тобой примеру, но там id в eax, а номера для команды 'push eax' не знаю.
Нет, ограничений нет.Это хорошо.
Я бы сделал так:Это для меня не совсем понятно.
по поводу двигателя: покопай опкод 02D4, я так для Vice делал.Спасибо. Там получается так:
#A - key: dumper up_down, manhole open_closed
#B - key: dumper up, manhole open
#C - key: dumper down, manhole closed
#D - key: cement on/off
#E -
#F -
#G -
#H -
#A, B, C, D, E, F, G, H
keys
110, 104, 98, 46,
end
03C0: 1@ = actor $PLAYER_ACTOR car
0A97: 2@ = car 1@ struct
0AA6: call_method 0x6D6A40 struct 2@ params 1 pop 0 %какой-либо ид машины из vehicles.dat%
Как писал ДенисНо метод работает только при следующих условиях:
1.Предварительно загружена новая модель.
2.Старая и новая модели однотипны (например, 4-дверное авто заменить на 2-дверное не получится, только 4-дверное на 4-дверное).
{$CLEO .cs} // VC 1.0
6@ = -1
while true
wait 0
if
0256: player $PLAYER_CHAR defined
then
if and
05EE: key_pressed 52 // 4
Actor.Driving($PLAYER_ACTOR)
84C9: not player $player_char driving_flying_vehicle
847E: not player $player_char driving_a_motorbike
84A8: not player $PLAYER_CHAR driving_boat
then
03C0: 0@ = actor $PLAYER_ACTOR car
0441: 1@ = car 0@ model
0506: set_car_model 1@ next_variation 6@ 6@
05E7: 2@ = car 0@ struct
05E3: call_method 0x59E590 struct 2@ params 1 pop 0 1@ // CAutomobile::SetModelIndex
0085: 7@ = 6@
7@ += 1
01E3: show_text_1number_styled GXT 'NUMBER' number 7@ time 2000 style 4
if
not 6@ >= 5
then
6@ += 1
else
6@ = -1
end
repeat
wait 0
until 85EE: not key_pressed 52 // 4
end
end
end
05E7: 2@ = car 0@ struct
05E3: call_method 0x59E590 struct 2@ params 1 pop 0 1@
Хотел перенести на основу plugin-sdk, но не вышло пока. Вот эти строчки не знаю, как реализоватьВроде это самое простое, у меня так, на plugin-sdk по аналогии.Код: [Выделить]05E7: 2@ = car 0@ struct
05E3: call_method 0x59E590 struct 2@ params 1 pop 0 1@
Вроде это самое простое, у меня так, на plugin-sdk по аналогии.Нет. Это виртуальная функция. Вызывать надо из vtable.
1>III_test_sdk.cpp
1>D:\Projects\plugin-sdk\plugin_III\extensions\ScriptCommands.h(60): error C2664: "void plugin::test::ScriptCode::operator <<(unsigned int *)": невозможно преобразовать аргумент 1 из "CVehicle *" в "char"
1>D:\Projects\plugin-sdk\plugin_III\extensions\ScriptCommands.h(60): note: Не существует контекста, в котором такое преобразование возможно
1>D:\Projects\plugin-sdk\plugin_III\extensions\ScriptCommands.h(84): note: см. ссылку на создание экземпляров функции шаблон при компиляции "void plugin::test::ScriptCode::Pack<CVehicle*>(T)"
1> with
1> [
1> T=CVehicle *
1> ]
1>III_test_sdk.cpp(21): note: см. ссылку на создание экземпляров функции шаблон при компиляции "bool plugin::test::ScriptCommand<plugin::test::GET_CAR_HEADING,CVehicle*>(CVehicle *)"
1>Сборка проекта "III_test.vcxproj" завершена с ошибкой.
========== Перестроение всех проектов: успешно: 0, с ошибками: 1, пропущено: 0 ==========
В GTA3 неправильно обьявлен методУпс... там для CObject и CPed по-ходу тоже было неправильно. Исправил. https://github.com/DK22Pac/plugin-sdk/commit/fd30dab12f942bad5cf997244e5e128718858d11 (https://github.com/DK22Pac/plugin-sdk/commit/fd30dab12f942bad5cf997244e5e128718858d11)Код: C++Он должен возвращать int (хендл).
CVehicle* CPools::GetVehicleRef(CVehicle* vehicle)
Надо вызывать такСпасибо. Теперь работает.Код: C++
float angleZ = 0.0f; ScriptCommand<GET_CAR_HEADING>(CPools::GetVehicleRef(vehicle), &angleZ);
case 0x174u:
CRunningScript::CollectParameters(a1, (CRunningScript *)(a1 + 16), (unsigned int *)1, v163);
v115 = (CVehicle *)CPool_CVehicle_CAutomobile_GetAt(CPools::ms_pVehiclePool, ScriptParams);
v116 = atan2(
*(float *)&v115->physical.entity.m_placement.matrix.matrix.top.y,
-*(float *)&v115->physical.entity.m_placement.matrix.matrix.top.x);
*(float *)&v205 = flt_5EEDE0 * v116 * flt_5EEDE4;
if ( *(float *)&v205 >= (double)flt_5EEDDC )
*(float *)&v205 = *(float *)&v205 + flt_5EEDE8;
if ( *(float *)&v205 > (double)flt_5EEDE8 )
*(float *)&v205 = *(float *)&v205 - flt_5EEDE8;
ScriptParams = v205;
CRunningScript::StoreParameters((CRunningScript *)(v4 + 16), (unsigned int *)1, v169);
result = 0;
break;
1>------ Перестроение всех файлов начато: проект: III_NewChooseComponent, Конфигурация: GTA3 Release Win32 ------
1>D:\Programs\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.10.25017\bin\HostX86\x86\CL.exe /c /I"D:\Projects\plugin-sdk\plugin_iii\\" /I"D:\Projects\plugin-sdk\plugin_iii\game_iii\\" /I"D:\Projects\plugin-sdk\shared\\" /Zi /nologo /W3 /WX- /diagnostics:classic /sdl /O2 /Oi /Oy- /GL /D _NDEBUG /D _USING_V110_SDK71_ /D _CRT_SECURE_NO_WARNINGS /D _CRT_NON_CONFORMING_SWPRINTFS /D GTA3 /D "GTAGAME_NAME=\"3\"" /D "GTAGAME_ABBR=\"3\"" /D "GTAGAME_ABBRLOW=\"3\"" /D "GTAGAME_PROTAGONISTNAME=\"Claude\"" /D "GTAGAME_CITYNAME=\"Liberty City\"" /D PLUGIN_SGV_10EN /D _USING_V110_SDK71_ /D _WINDLL /D _MBCS /Gm- /EHsc /MT /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /std:c++latest /Fo"D:\Projects\GTA-Projects\III_NewChooseComponent\.obj\GTA3\Release\\" /Fd"D:\Projects\GTA-Projects\III_NewChooseComponent\.obj\GTA3\Release\vc141.pdb" /Gd /TP /analyze- /errorReport:prompt /Zc:threadSafeInit- III_NewChooseComponent.cpp
1>III_NewChooseComponent.cpp
1>D:\Programs\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.10.25017\bin\HostX86\x86\link.exe /ERRORREPORT:PROMPT /OUT:"D:\Games\Grand Theft Auto III\scripts\III_NewChooseComponent.III.asi" /NOLOGO /LIBPATH:"D:\Projects\plugin-sdk\output\lib\\" plugin_iii.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /PDB:"D:\Games\Grand Theft Auto III\scripts\III_NewChooseComponent.III.pdb" /SUBSYSTEM:WINDOWS,"5.01" /OPT:REF /OPT:ICF /LTCG /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"D:\Games\Grand Theft Auto III\scripts\III_NewChooseComponent.III.lib" /MACHINE:X86 /SAFESEH /DLL "D:\Projects\GTA-Projects\III_NewChooseComponent\.obj\GTA3\Release\III_NewChooseComponent.obj"
1>III_NewChooseComponent.obj : error LNK2001: неразрешенный внешний символ ""public: static void __cdecl plugin::patch::RedirectJump(int,void *,bool)" (?RedirectJump@patch@plugin@@SAXHPAX_N@Z)"
1>D:\Games\Grand Theft Auto III\scripts\III_NewChooseComponent.III.asi : fatal error LNK1120: неразрешенных внешних элементов: 1
1>Сборка проекта "III_NewChooseComponent.vcxproj" завершена с ошибкой.
========== Перестроение всех проектов: успешно: 0, с ошибками: 1, пропущено: 0 ==========
1>------ Перестроение всех файлов начато: проект: III_NewChooseComponent, Конфигурация: GTA3 Release Win32 ------
1>D:\Programs\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.10.25017\bin\HostX86\x86\CL.exe /c /I"D:\Projects\plugin-sdk\plugin_iii\\" /I"D:\Projects\plugin-sdk\plugin_iii\game_iii\\" /I"D:\Projects\plugin-sdk\shared\\" /Zi /nologo /W3 /WX- /diagnostics:classic /sdl /O2 /Oi /Oy- /GL /D _NDEBUG /D _USING_V110_SDK71_ /D _CRT_SECURE_NO_WARNINGS /D _CRT_NON_CONFORMING_SWPRINTFS /D GTA3 /D "GTAGAME_NAME=\"3\"" /D "GTAGAME_ABBR=\"3\"" /D "GTAGAME_ABBRLOW=\"3\"" /D "GTAGAME_PROTAGONISTNAME=\"Claude\"" /D "GTAGAME_CITYNAME=\"Liberty City\"" /D PLUGIN_SGV_10EN /D _USING_V110_SDK71_ /D _WINDLL /D _MBCS /Gm- /EHsc /MT /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /std:c++latest /Fo"D:\Projects\GTA-Projects\III_NewChooseComponent\.obj\GTA3\Release\\" /Fd"D:\Projects\GTA-Projects\III_NewChooseComponent\.obj\GTA3\Release\vc141.pdb" /Gd /TP /analyze- /errorReport:prompt /Zc:threadSafeInit- III_NewChooseComponent.cpp
1>III_NewChooseComponent.cpp
1>D:\Programs\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.10.25017\bin\HostX86\x86\link.exe /ERRORREPORT:PROMPT /OUT:"D:\Games\Grand Theft Auto III\scripts\III_NewChooseComponent.III.asi" /NOLOGO /LIBPATH:"D:\Projects\plugin-sdk\output\lib\\" plugin_iii.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /PDB:"D:\Games\Grand Theft Auto III\scripts\III_NewChooseComponent.III.pdb" /SUBSYSTEM:WINDOWS,"5.01" /OPT:REF /OPT:ICF /LTCG /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"D:\Games\Grand Theft Auto III\scripts\III_NewChooseComponent.III.lib" /MACHINE:X86 /SAFESEH /DLL "D:\Projects\GTA-Projects\III_NewChooseComponent\.obj\GTA3\Release\III_NewChooseComponent.obj"
1>plugin_iii.lib(Patch.obj) : error LNK2001: неразрешенный внешний символ ""int __cdecl plugin::GetGlobalAddress(int)" (?GetGlobalAddress@plugin@@YAHH@Z)"
1>D:\Games\Grand Theft Auto III\scripts\III_NewChooseComponent.III.asi : fatal error LNK1120: неразрешенных внешних элементов: 1
1>Сборка проекта "III_NewChooseComponent.vcxproj" завершена с ошибкой.
========== Перестроение всех проектов: успешно: 0, с ошибками: 1, пропущено: 0 ==========
Почему имя оружие и его id. Не подходит для получения оружия.В каком смысле не подходят? Смотри перечисления
Если Вас не затруднит, Скажите пожалуйста какие id писать?
перечисления в смысле emum именованные константы?Да, в смысле enum.
Сейчас, конечно за мои вопросы по cleo мне стыдно. Теперь кажется всё Элементарно, чем тогда.Лучше спросить и разобраться в вопросе, чем не спросить и дальше не знать ответа.
как можно получить координаты игрока?Есть статическая функция FindPlayerCoors. В Vice City она не принимает никаких входных параметров и возвращает позицию игрока. Перед её вызовом надо проверять, что игрок существует.
просто хочется упростить получение координат.Так ты не упрощаешь, а усложняешь. Функция GetPosition() как раз и возвращает координаты в виде вектора. Почитай про функции в С++ в том числе про возвращаемые значения и передачу параметров в функции по указателю и по ссылке.
string x,y,z=FindPlayerCoors();То, что ты пытался сделать, называется Structured Binding (https://en.cppreference.com/w/cpp/language/structured_binding), и там надо использовать строго фиксированный синтаксис:
Здравствуйте уважаемый kenking. Простите, пожалуйста, не сразу вам смог ответить. Вот что у меня получилось, координаты выводится.Цитироватьпросто хочется упростить получение координат.Так ты не упрощаешь, а усложняешь. Функция GetPosition() как раз и возвращает координаты в виде вектора. Почитай про функции в С++ в том числе про возвращаемые значения и передачу параметров в функции по указателю и по ссылке.
Вот какой плагин получитсяКак ты любишь усложнять. Зачем писать функцию isPedInVehicle, если player->m_bInVehicle и так показывает, что игрок в авто?
Как найти случайную машину?
Как проверить находится ли машина в заданных координатах?
KeyCheckhttp://forum.gtabuilder.ru/index.php?topic=337.msg2356#msg2356 (http://forum.gtabuilder.ru/index.php?topic=337.msg2356#msg2356)
KeyPressed('M')?. С ним часто возникают проблемы. Хочется проверять клавиши так нажал и только когда отпустишь она вернула true, Чтобы избежать повторного нажатия и клавиша будет нажата только 1 раз. Допустим при нажатии клавиши даётся игроку 500$ я немного дольше подержал и бах у меня 5 миллионов. Это настоящая проблема.Здесь http://forum.gtabuilder.ru/index.php?topic=337.msg3355#msg3355 (http://forum.gtabuilder.ru/index.php?topic=337.msg3355#msg3355) в своём коде ты правильно используешь KeyPressed, а в предыдущем сообщении http://forum.gtabuilder.ru/index.php?topic=337.msg3422#msg3422 (http://forum.gtabuilder.ru/index.php?topic=337.msg3422#msg3422) уже не правильно.
Думал что есть аналог опкода 05F0: 3@ = random_vehicle_near_point 0@ 1@ 2@ in_radius 10.0 find_next 1 pass_wrecked 0 //IF and SETТак там похоже сделано, просто действия "завёрнуты" в опкод и ты их не видишь.
А тут всё по-другому.
Странно, но игра вылетает, если приближаюсь к любому авто.
Вы предоставили два варианта функций. Подскажите, пожалуйста, как именно их вызывать?Смотри аргументы функции и возвращаемое значение.
Зачем?Вот
Если надо найти один рандомный транспорт
проверить, находится ли он в этих координатах?Сравнение дистанции между двумя точками с радиусом как раз и есть эта проверка.
Чтобы машина ехала на определенные координаты, думал, что нужно использоватьЧтобы разобраться, надо смотреть в базе, как устроен соответствующий опкод 00A7: car 0@ drive_to 103.1 -832.3 9.317
CAutoPilot m_autopilot; но как? Буду очень вам признателен если вы подскажите мне.
Не совсем понимаю твою задумку. Для чего это нужно? Примеры чтения данных из файла здесь ранее показывал DK.Здравствуйте, уважаемый kenking, задумка состоит в следующем: при нажатии определённой клавиши, записываются файлы-координаты по трём осям y, x, z. Нужно организовать так, чтобы записывались пока игрок не нажал другую кнопку. Тут без цикла while никак не обойтись. Потом из этого файла эти координаты могли считаться. Скажите, пожалуйста, как реализовать построение условной конструкции в sdk? Например, нажимаешь одну кнопку, выполняется одно, нажимаешь другую-другое. У меня это приводит к зависанию и вылету игры после вывода координат.
Чем заменить скриптовую команду?Надо смотреть в базе, как устроен соответствующий опкод. Если я правильно разобрал опкод
00AD: set_car 36@ max_speed_to 30.0
то получается так:Скажите пожалуйста как создать маркер на машины и удалить его?Ты же в клео разбираешься? Смотри как устроены соответствующие опкоды в базе. Затем смотри в sdk добавлены ли нужные классы.
Добавьте еще, пожалуйста, v->m_pHandling->m_transmissionData.m_fMaxSpeed для vice city его нет.Было добавлено в том же коммите.
CRadar тоже нет для vc.
надо разбирать класс CRadar.
Скажите пожалуйста, как проверить находится ли авто в заданных координатах c радиусом?В предыдущих постах уже писали.
Как пользоваться скриптами командой
COMMAND_GET_CAR_COORDINATES = 0xAA,
как сделать функцию, которая проверяет нажата ли клавиша? возвращает true, только когда эта клавиша отпущена?class KeyCheck http://forum.gtabuilder.ru/index.php?topic=337.msg2356#msg2356 (http://forum.gtabuilder.ru/index.php?topic=337.msg2356#msg2356)
как реализовать функцию waitНужно делать таймер и проверять каждый цикл, прошло ли нужное количество времени.
... в CCarCtrl::JoinCarWithRoadSystemGotoCoors ошибочный лишний третий параметр.Оказывается там всё верно, сорри.
Есть задача, чтобы ped нападал на игрока.Надо смотреть, как устроен соответствующий опкод в базе (я уже ранее писал про это). Опкоды:
Думал, сделать так, через функции не получилось.
пришлось, чтобы пед атаковал игрока, использовать скриптовую команду.
01C9: actor $2324 kill_actor $2291
01CA: actor $853 kill_player $PLAYER_CHAR
//ped->bfFlagsD &= 0x7F;//это метода нетЭто установка флага. В базе и в sdk записи в данный момент не совпадают и не все флаги "обозначены" правильно.
как заставить педа бежать к координатам?В который раз объясняю, что надо смотреть в базе, как устроен соответствующий опкод, без этого не разберёшься.
в некоторые функциях есть параметр CVector, что передаем в таком случае?Вектор и передаём.
за что отвечают эти функции?Переведи названия функций, смотри в базе, где они вызываются, может используются в каких-либо скриптовых командах (опкодах).
Вы пишите- надо смотреть как устроен в базе.Отрыть базу в IDA. Взять простой опкод или простую функцию и попытаться понять, разобрать как он устроен (как работает функция). Мне легче разбирать в псевдокоде (F5).
хорошо, что нужно изучить? Чтобы в ней разбираться.
Не всегда название функции, помогают понять как они работают.Поэтому я и написал, что надо смотреть в базе, где вызываются эти функции.
// чем отличается способы получение вектора?Ничем.
CVector pos = player->GetPosition();
//CVector pos = player->m_placement.pos;
// телепорт чем отличает 2 функции телепорта?Если в названии функции есть приставка Only, то при вращении (например, компонента транспорта) не придётся сохранять координаты позиции компонента, компонент просто повернётся на указанный градус и останется в той же позиции. Если использовать "похожую" функцию без этой приставки в названии, то надо перед вращением считывать координаты позиции компонента, после вращения их восстанавливать, так как координаты сбросятся в ноль после вращения. Аналогично для функций перемещения, только для значений углов поворота.
// v->CanPedJumpThis(player, pos.x);//?? прыжок?.Это проверка может ли сделать прыжок. Смотри в базе, где вызывается
//v->SetObjective(player, OBJECTIVE_RUN_TO_AREA, &pos);//не получается заставить идти педа в координаты.
теперь допустим берём emun OBJECTIVE_SOLICIT_VEHICLE, какие параметры передать в функцию SetObjective.
Пытаюсь разобрать функции в псевдокоде, иногда псевкод простой функции отражается так. Может, он не так должен отображается?Учиться разбирать надо с маленьких функций.
Иногда явного эффекта от функции нет. Например, что даёт функцияЗадержки и не должно быть. По-идеи это установка максимального времени на какое-то действие педа (как я это понимаю).
ped->SetObjectiveTimer(60000);
Да это таймер, но никакой задержка вы действиях педа не наблюдается.
Скажите пожалуйста, когда завершится работа над sdk plugin? чтобы можно было приступить к документации всех функций, тогда новичкам будет легче освоится.Думаю, что ещё несколько лет.
Допустим, CLEO которая является хуком знаю, где посмотреть ее исходник на с++. Может это поможет разобраться? Посоветуйте, пожалуйста, книгу, которая помогла вам стать таким крутым специалистом??Я учусь разбираться в классах игры также, как и ты и крутым специалистом себя не считаю. В некоторых случаях, чтобы ответить на твой вопрос, мне приходится самому его сначала разобрать. Никакой такой книги я не знаю. Мне помогли подсказки и советы DK и других пользователей, которые они писали в этой теме, в целом на этом форуме и других форумах.
Если есть IDA и idb-база, то для "распутывания ниточек" можно использовать такие приёмы:
Как определить, откуда вызывается данная функция?
1.Открываем код функции в основной вкладке.
2.Далее выбираем в меню пункт View - Open Subviews - Function calls - список Caller.
Как определить, откуда происходит обращение к данному адресу?
1.Вставляем курсор между буквами названия адреса. Например здесь
Code:
.data:00B7CB84 _currentTime dd ? ; DATA XREF: _sub_406E50r
вставляем курсор между любыми буквами _currentTime.
2.Жмём X. Открывается список ссылок на данный адрес.
Очень часто случается такое, что декомпилятор (hex-rays) выдаёт ошибку "switch analysis failed".
Случается это в функциях, где используется конструкция switch.
Случается это потому что (моё предположение) разные версии декомпилятора по-разному работают с этой
конструкцией.
В официальных доках рекомендуют вручную настроить эту конструкцию, но есть более простое решение:
пересобрать функцию.
Для этого надо преобразовать функцию в обычные данные, преобразовать данные в код, и создать функцию.
1. Нажимаем U на названии функции (Undefine function).
2. Нажимаем C на первом байте (Code)
3. Нажимаем P (Create function).
В exe есть 2 основных типа адресов - data и text (есть и другие типы). Если проводить аналогию со
скриптами, то адреса типа data можно сравнить с глобальными переменными - в них хранятся различные
значения (например, 0xB7CB84 - [dword] Глобальный таймер в ms, 0x8D2530 - [float] Плотность движения
пешеходов). В ходе игры отдельные процедуры exe читают эти значения или записывают в эти адреса новые
значения. Эти адреса (не все) можно читать/перезаписывать и в скрипте с помощью опкодов 0A8C/0A8D.
Назначение некоторых часто употребляемых data-адресов, а также смещений в структурах можно найти тут:
[url]http://gtamodding.ru[/url] ([url]http://gtamodding.ru[/url])...еса_Памяти_(SA)
Что касается адресов типа text, то в них записаны отдельные команды, из которых в свою очередь
состоят процедуры exe. Сами по себе значения этих адресов во время игры не меняются, но их, как и
адреса data, можно (не все) менять скриптом - в этом случае в опкодах 0A8C/0A8D следует ставить
значение параметра virtual protect, равное 1. Понятно, что в случае изменения значения text-адреса,
процедура, которой он принадлежит, станет работать уже по новому алгоритму.
Для поиска нужных адресов и процедур незаменима idb-база от listener. Открыть её можно с помощью
IDA 5. В окне программы есть несколько вкладок, которые представляют код exe в различном виде.
Основные из них: "IDA View-A" - основной вид. Если текущий участок exe состоит из адресов типа data,
то они отображаются в виде списка, а если текущий участок является какой-то
процедурой (text-адреса), то она отобразится в виде блок-схемы. "Hex View-A" - побайтовое отображение
кода. Многие data-адреса и процедуры в базе проименованы, при активной вкладке "IDA View-A" можно
осуществлять их поиск по названию (Search - Text).
Есть ещё полезная вкладка Functions - список всех процедур exe. Если эта вкладка активна, то можно
осуществить поиск процедуры по названию (Search). Например, осуществив поиск по слову train, можно
найти процедуры, имеющие отношение к поездам. При щелчке по названию процедуры, активируется вкладка
"IDA View-A" и появится блок-схема этой процедуры, по которой можно исследовать, как она
работает (какие процедуры вызывает, со значениями каких адресов оперирует и т.д.).
Как использовать эту скриптовую команду?Скриптовая команда - это опкод, смотришь в eScriptCommands какому номеру опкода соответствует эта команда. Открываешь поиск опкодов в SB, находишь нужный опкод: 0162: tie_marker $2344 to_actor $2320 4 2
Не думал, что маркер, это int. Предполагал, что мы должны передать структуру.Это ID маркера.
Конечно, как всегда столкнулся с трудностями, как использовать скриптовую команду в качестве проверки?
Так же интересная ситуация с выводом целых чисел на экран, они не выводится.
Разобрался с проверками.
Только не получается дать оружие игроку через скриптовую команду.
Это очень удобно использовать скриптовые команды.Скриптовые команды надо использовать в случае отсутствия в sdk нужных функций и классов (ну для тестов ещё, чтобы поучиться). В остальном надо писать код с разобранными функциями. В примере такой альтернативный код закомментирован.
Скажите, пожалуйста, у вас есть список типа для каждого педа\GTA Vice City\data\default.ide раздел peds Default pedtype
Вообще таймеров много, чем они отличаются?Надо смотреть каждую из этих переменных в базе, в каких функциях используются, тогда можно понять чем они отличаются и для чего используются.
Мне нужна именно функция таймер, например, передаешь 1000 мс, получаешь задержку в 1 сек, пробовал через рекурсии не выходит.Задержку по времени между выполнением действий в теме была показана ранее на примере нажатия клавиши. Вот такой пример. Загрузка модели и создание педа вынесены в отдельные функции.
как проверить флаг миссии? И установить его, что миссия запущена.Перед запуском своей миссии проверяешь значение CTheScripts::ScriptSpace[OnAMissionFlag], если оно равно 0, никакая миссия в данным момент не запущена. Запускаешь свою миссию, устанавливаешь значение CTheScripts::ScriptSpace[OnAMissionFlag] в 1. Миссия запущена. Когда миссия заканчивается, ставишь CTheScripts::ScriptSpace[OnAMissionFlag] в 0.
Скажите, пожалуйста, с помощью какой функции можно открыть двери и капот, багажник.1) Скрипт вот https://gta.com.ua/file_details.phtml?id=2832 (https://gta.com.ua/file_details.phtml?id=2832)
только у авто модели MODEL_ENFORCER капот открывается в обратную сторону MODEL_ENFORCERНа модели влаг выставлен неверно. В файле handling.cfg найди строчку ENFORCER и замени 3 цифру с конца 27 на 23
может можно обойти этот баг, без внесение изменений в файл.Это просто ошибка разработчиков. Без исправления этого флага не обойдёшься. В чём проблема заменить одну цифру?
которая возвращает булевое значение подобран ли пикап? как-то работает некорректно. Может что-то напуталС пикапами я не работал. Посмотрел в main, эта проверка вроде для другого пикапа, созданного опкодом 0517
Пытался написать гоночный чекпойнт, есть идея написать миссию гонкуДумаю, что это тоже надо смотреть в main.
как воспроизвести звуковой файл
Вряд ли кто-то будет менять флаг в файле при использовании плагина. возможно, есть способ обойти его.Никто не играет со стандартными моделями давно. А в заменяемых моделях авторы указывают свои настройки, где это исправлено.
Потоки работают, но есть сильное ограничение, нельзя передать указатели на педа, авто и объект. Дело в том, что у запуска функции в новом потоке есть очень сильное ограничение. Мы не можем передать указатели, потому что между состояниями нельзя передавать объекты, которые занимают память. Я думал, как это ограничение обойти? Решил, указатель преобразовать в строку, передать в новый поток, потом эту строку передать в функцию, которая обратно конвертирует строку в числовой указатель и ищет её в пуле. Но, опять произошла проблема, адреса в пуле являются не разыминованные, в отличие от числового указателя. Поэтому поиск никогда не даёт результатов. Буду очень рад, если Вы подскажите как решить эту проблему.Вообще не понял, что ты хочешь сделать.
вчера обновил visual studio 2019 при этом изменилась цветовая палитра. С ней неприятно работать, можете скинуть конфиг с прежней цветовой палитрой.Настроить: Сервис->Параметры->Окружение->Общие->Цветовая тема
как в sdk заставить стрелять ракетами и пулеметом вертолет hunter?Не знаю, не изучал этот вопрос.
Так же ищу функция арестован игрок или нет.
Как можно узнать через функцию, то что мы в него передали, является классом, например, CVehicle.
Есть ли способ заставить ехать машину назад?
можно создать тему lualoader? чтобы выкладывать туда наработки?Форум для того и существует, чтобы научиться чему-то новому и показать свои разработки, которые могут пригодиться другим пользователям.
Скажите, пожалуйста, как помочь сайту материально?Обратись к владельцу ресурса Sektor'у через личное сообщение.
хотелось узнать как сделать таймер на sdk, чтобы потом перенести в lua.Таймер можно реализовать по-разному, зависит от конкретной ситуации, например, так:
Функции, которые вы написали, нет в "CCamera.h", может просто ещё не добавляли в репозиторий.
Допустим, установили камеру в нужных нам координатах, но нужно её развернуть по вертикальной оси или наклонить от себя или от себя, для хорошего операторского ракурса, какие функции для этого использовать?
Почему-то не могу получить 5 или 6 звёзд розыска с помощью скриптовой команды ,
Интересно, можно ли заменить их функциями?Как я уже писал ранее, надо открыть базу и посмотреть соответствующие опкоды. Для разбора опкодов можно взять базу для GTA3, большинство опкодов для VC и тройки одинаковые. А база для тройки разобрана намного больше.
при установке количество денег педа, при его смерти, выпадает сумма денег, которая отличается от установленной, в чём причина такой ситуации?Функцию CPed::CreateDeadPedMoney открой в IDA (нажми F5 для генерации псевдокода на С++)