IKARUS - Это скрипт-пакет, который был разработан немецким модостроителем Sektenspinner'ом.
Этот пакет позволяет расширить нам, другим модостроителям, возможности.Что же такое делает он, чтобы получить новые способы улучшения качества и повышения интереса к модам?
Не секрет, что возможности стандартного набора модостроителя ограничены переданными Пираньями материалами.
Но любой скриптёр, втягиваясь и осваивая язык Даедалус, спустя некоторое время утыкается в стены, которые он пытается обойти разными извращёнными способами.
У него в определённый момент возникает вопрос к себе, но адресованный реально Пираньям. "Ну почему они не сделали функцию просто получения времени" или "почему нет функции деэкипировки отдельного типа оружия?" Что, реально сложно это было?
Нет, это было абсолютно несложно, но мы имеем то, что имеем. Может ввиду того факта, что для написания игры им хватило именно этого набора функций, что они и отдали на растерзание игрокам-модостроителям.
Ладно, это лирика. Теперь перейдём к физике.
Что же нам позволяет расширить потенциал? Здесь ответ как в известной программе: "Показать всё, что скрыто!"
Пример.
Что у нас представляет объект класса C_NPC (человек, монстр)?
Это объект, которому мы можем задать порядка тридцати полей (урон, защита, вид, флаг, имя и ещё некоторые.)
Что же представляет объект класса oCNpc (тот класс, что реально используется игрой) - это класс, имеющий более 250 полей только относящихся к нему + ещё около 40, относящихся к общему классу zCVob. И это частный пример, но уже чувствуете разницу? Пускай, 99% из 100 может нам и не нужна, ну а вдруг???
Далее, продолжаем.
Пакет позволяет читать из памяти (+ изменять в памяти) процесса игры практически любую информацию. Тут главное знать, что, где и как?
Теперь немного мат.части.
Представим себе кусок памяти наглядно:
[ячейка памяти],[ячейка памяти],[ячейка памяти],[ячейка памяти],[ячейка памяти],[ячейка памяти],[ячейка памяти] и т.д.
Каждая ячейка в понятном для нас виде имеет размер 1Байт, которая хранит в себе информацию в 16-ричной системе. Также она имеет свой собственный адрес.
В языке Даедалус есть переменные и константы трех видов (int - целое цисло, float - число с плавающей точной, string - строка).
Переменные типа int и float - занимают в памяти 4 ячейки (4 Байта).
Переменные !пользовательского! типа string (которого реально нет в языке Си++) занимают в удобном для нашем понимании виде 20 ячеек (20 Байт).
Адресом переменной в памяти по сути является адрес первой ячейки.
Получается, зная адрес ячейки памяти, тип хранимой в ней информации, мы можем в любой момент времени прочитать или изменить её.
Теперь на примере конкретного объекта, глянем, что он из себя представляет в памяти:
Код:
class zCObject
{
var int _vtbl;
var int refCtr;
var int hashIndex;
var int hashNext;
var string objectName;
};
Далее, есть следующее поле, оно смещено относительно первого поля на 4 Байта. Именно столько занимает первая ячейка типа int.
И т.д.
Получаем, что если в памяти подряд находятся два элемента класса zCObject, то они предствляют следующее
[1-ый объект имеет адрес 1234(наобум) размером 4Байта+4Байта+4Байта+4Байта+20Байт(36Байт)],[второй объект уже будет иметь адрес 1234+36 и занимать столько же]
То есть по адресу 1234 +16 мы можем прочитать поле objectName первого объекта.
По адресу 1234+36+8 мы можем прочитать поле hashIndex второго объекта.
Теперь подытожим на конкретном примере:
Имеем НПС. Он в памяти имеет адрес 1000.
Глядя в описание расширенного типа oCNpc, хочу прочитать поле idx.
Он смещён относительно начала на 288 Байт.
У нас есть два способа прочитать.
Первый - получить ссылку на НПС как на объект класса oCNpc и банально прочитать:
var int x; x = oCNpc.idx;
Второй - прочитать значение ячейки памяти, с помощью функции пакета Ikarus MEM_ReadInt(var int address)
Это одна из функций, которая читает из памяти число типа int по адресу address
var int x; x = MEM_ReadInt(1000+288);
На этом вступление окончено.
ВТОРАЯ ЧАСТЬ.
Какие вообще сосредоточены возможности в пакете ИКАРУС
- -Чтение и изменение памяти
- -Вызов практически любой скрытой в движке игры функции
Какой практический смысл на примере (из описания автора и от меня):
- - включение/выключение режима MARVIN
- - постановка игры на паузу в любой момент
- - включить-выключить дождь/снег в любой момент
- - узнать, какая клавиша сейчас нажата игроком.
- - найти любой ВОБ в игре и поменять ему параметры (передвинуть, удалить, сменить внешний вид и т.д)
- - наполнить сундук барахлом или открыть запертую где-то дверь.
- - организовать циклы.
ТРЕТЬЯ ЧАСТЬ.
Рассмотрим некоторые базовые функции пакета Икарус.
1. MEM_ReadInt(var int address);
2. MEM_ReadString(var int address);
Как нетрудно догадаться из названия и внешнего вида функции, первая - читает из памяти число типа int, вторая - строку, - по адресу address;
3. MEM_WriteInt(var int x, var int address)
4. MEM_WriteString(var string y, var int address)
Опять же всё очень просто: обе записывают в память по адресу address своё значение (x - число типа int, y - строковое значение).
5. func int MEM_InstToPtr (var instance inst)
6. func instance MEM_PtrToInst (var int ptr)
Здесь чуть сложнее. Первая возвращает указатель на инстанцию (число, являющееся адресом объекта в памяти ). Вторая - делает обратное, по указателю получает ссылку на инстанцию.
Я не буду приводить полный перечень функций и их описание, ибо всё это уже есть в документации, идущей в комплекте со скрипт-пакетом.
Пусть она и на немецком языке, но всё достаточно понятно становится, даже если это прогнать через любой переводчик. Не скажу, что на выходе получается текст равный по смыслу авторскому, но технический смысл спокойно улавливается.
ЧЕТВЁРТАЯ ЧАСТЬ.
Интеграция пакета Икарус в скрипты (взято из документации автора):
Распаковываем архив со скриптами к себе в проект. Приведу на своём примере:
Вот моя корневая структура проекта:
..\_Intern\
..\AI\
..\Ikarus1_2
..\Items
..\Story
..\gothic.src
Как видите от оригинала отличается наличием папки Ikarus1_2
В неё просто распакованы все файлы. И в gothic.src добавлено следующее:
_Intern\Constants.d
_Intern\Classes.d
AI\AI_Intern\AI_Constants.d
//Пакет Икарус
Ikarus1_2\Ikarus_Const_G2.d
Ikarus1_2\Misc.d
Ikarus1_2\oCAiHuman.d
Ikarus1_2\oCGame.d
Ikarus1_2\oCInfoManager.d
Ikarus1_2\oCItem.d
Ikarus1_2\oCMob.d
Ikarus1_2\oCNpc.d
Ikarus1_2\oCZoneMusic.d
Ikarus1_2\zCCamera.d
Ikarus1_2\zCConsole.d
Ikarus1_2\zCMenu.d
Ikarus1_2\zCMesh.d
Ikarus1_2\zCOption.d
Ikarus1_2\zCParser.d
Ikarus1_2\zCSkyController.d
Ikarus1_2\zCTexture.d
Ikarus1_2\zCTrigger.d
Ikarus1_2\zCWaynet.d
Ikarus1_2\zCWorld.d
Ikarus1_2\zCZoneZFog.d
Ikarus1_2\Ikarus.d
Ikarus1_2\float.d
//конец пакета
AI\AI_Intern\BodyStates.d
_Intern\Classes.d
AI\AI_Intern\AI_Constants.d
//Пакет Икарус
Ikarus1_2\Ikarus_Const_G2.d
Ikarus1_2\Misc.d
Ikarus1_2\oCAiHuman.d
Ikarus1_2\oCGame.d
Ikarus1_2\oCInfoManager.d
Ikarus1_2\oCItem.d
Ikarus1_2\oCMob.d
Ikarus1_2\oCNpc.d
Ikarus1_2\oCZoneMusic.d
Ikarus1_2\zCCamera.d
Ikarus1_2\zCConsole.d
Ikarus1_2\zCMenu.d
Ikarus1_2\zCMesh.d
Ikarus1_2\zCOption.d
Ikarus1_2\zCParser.d
Ikarus1_2\zCSkyController.d
Ikarus1_2\zCTexture.d
Ikarus1_2\zCTrigger.d
Ikarus1_2\zCWaynet.d
Ikarus1_2\zCWorld.d
Ikarus1_2\zCZoneZFog.d
Ikarus1_2\Ikarus.d
Ikarus1_2\float.d
//конец пакета
AI\AI_Intern\BodyStates.d
ССЫЛКИ:
Тема по скрипт-пакету на WOG.de: http://forum.worldofplayers.de/forum/threads/969446-Skriptpaket-Ikarus-3
Пакет Ikarus (версия 1.2), компиляция только игрой: http://exodus.worldofgothic.com/team/Sektenspinner/Ikarus_Skriptpaket.zip
Пакет Ikarus (версия 1.1.4), компиляция игрой и GS: http://exodus.worldofgothic.com/team/Sektenspinner/Ikarus_Skriptpaket_1.1.4.zip