Space engineers как создать ботов

Обновлено: 20.05.2024

void Main()
// varitables
IMyPistonBase DoorPiston = GridTerminalSystem.GetBlockWithName("DoorPiston") as IMyPistonBase;
IMySensorBlock DoorSensor = GridTerminalSystem.GetBlockWithName("DoorSensor") as IMySensorBlock;
IMySensorBlock CloseSensor = GridTerminalSystem.GetBlockWithName("CloseSensor") as IMySensorBlock;
IMySoundBlock SoundMessage = GridTerminalSystem.GetBlockWithName("SoundMessage") as IMySoundBlock;
IMyLargeInteriorTurret DoorTurret= GridTerminalSystem.GetBlockWithName("DoorTurret") as IMyLargeInteriorTurret; //
IMyLargeInteriorTurret DoorTurret2= GridTerminalSystem.GetBlockWithName("DoorTurret2") as IMyLargeInteriorTurret; //

if (DoorSensor.DetectOwner == true || CloseSensor.DetectOwner == true)
DoorPiston.GetActionWithName("Reverse").Apply(DoorPiston);
DoorTurret.GetActionWithName("OnOff").Apply(DoorTurret);
DoorTurret2.GetActionWithName("OnOff").Apply(DoorTurret2);
SoundMessage.GetActionWithName("PlaySound").Apply(SoundMessage);
>
>

Я далек от программирования, однако любопытство взяло верх над полным отсутствием грамотности в этом вопросе. Решил по аналогии запилить освещение.
Суть: Подходишь к прожектору (в зону досягаемости сенсора) - он включается. Отходишь (в зону недосягаемости сенсора) - выключается.
Первое действие получилось - прожектор включается. А вот с выключением не выходит.
Для того чтобы прожектор погас, нужно выйти из зоны действия прожектора и зайти в нее обратно. Причем значение "true" для сенсора совсем не обязательно и сенсор вызывает действие скрипта на прог.блоке без него.

IMySensorBlock Sensor1 = GridTerminalSystem.GetBlockWithName("Sensor1") as IMySensorBlock; IMyReflectorLight Light1 = GridTerminalSystem.GetBlockWithName("Light1") as IMyReflectorLight; if (Sensor1.DetectOwner) if (Sensor1.DetectOwner == true) if (Sensor1.DetectOwner == false)

Но все по прежнему.

Пробовал и в таком:

if (Sensor1.DetectOwner == true) if (Sensor1.DetectOwner == false)

В таком случае прожектор включается и не выключается вообще.
Т.е. значения true и false в нашем случае не работают? И почему? Или они вообще в игровом коде не задействуются?
Подумал о такой вещи как бездействие сенсора, т.е. код отсутствия действия, или состояние бездействия как еще одно действие. Например: Sensor.NotDetect
Но такого не нашел.

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

if (Sensor1.DetectOwner == false) - этот событие происходит видимо когда в поле сенсора попадает кто нибудь, отличный от овнера. Чтобы сенсор срабатывал когда в его поле никого нету, должно быть другое состояние, посмотри в офф статье. я пока не нашел.
Получается при этом условии ты заходишь в поле сенсора, он проверят ты овнер или нет. если ты овнер - срабатывает первое условие, если не овнер - второе. а если ты овнер и не находишься в поле то ничего не срабатывает и он горит всегла, как-то так походу) Сам не так давно начал играть и разбираться в игре но на мой скромный взгляд тут не хватает таймера с запуском проверки наличия владельца в зоне досягаемости сенсора. да и еще не совсем понятно куда делся оператор ELSE или в данной версии языка он отсутствует?

Если кому-то поможет сделать скрипт проще и короче.

В данном примере есть создание новой переменной блока "Поршня"

IMyPistonBase DoorPiston = GridTerminalSystem.GetBlockWithName("DoorPiston") as IMyPistonBase

IMyPistonBase - тип переменной блока;

DoorPiston - имя переменной; (лучше его задавать одноимённым с названием блока в терминале, дабы избежать путаницы)

"DoorPiston" - то, что в скобках после GetBlockWithName(), есть название блока в терминале

as IMyPistonBase - данное выражение говорит о том, что всю строку после знака "=" надо считать как тип данных IMyPistonBase (важно, иначе присвоение значения переменной не произойдёт);

Вот теперь у нас есть переменная DoorPiston, готовая к применению и отвечающая исключительно за нужный блок. Так вот тут далее, когда остальным переменным присваиваются необходимые блоки идёт условие и действие, если данное условие верно

Внутри есть строка действия:

Данный код понимается так: блок DoorPiston, произведи поиск действия в своём списке действий по точному названию "Reverse" (GetActionWithName() - поиск и получения действия из списка действий, доступных блоку по точному названию) и примени его к блоку DoorPiston (Apply() - применить к блоку в скобках действие, которое мы получили).

Данная строка долгая для написания и занимает много символов (а запас символов в программном блоке ограничен), да и получается какая-то нелепость с ненужным поиском действия (ведь мы его знаем. зачем его искать в списке?) поэтому лучше использовать несколько другой способ, реализующий абсолютно точно такое же действие напрямую:

Читается так: блок DoorPiston, произведи действие Reverse.

Дело в том, что действие является некоторым методом для блока (Методы, процедуры и функции в конце имеют круглые скобки со значением или без, но они обязательны). Для любого блока будет верным писать действия в такой формулировке:

Space engineers как создать ботов

Владислав Олійник

Скрипт для посадки на планеты.
Аля "Остановить поршень когда посадочное шасси зацепится за астероид"
================================================================
void Main(string argument)
IMyPistonBase LandingPiston = GridTerminalSystem.GetBlockWithName("LandingPistonName") as IMyPistonBase;
IMyLandingGear LandingGear = GridTerminalSystem.GetBlockWithName("LandingGearName") as IMyLandingGear;

if(LandingGear.IsLocked)
LandingPiston.GetActionWithName("ResetVelocity").Apply(LandingPiston);
LandingPiston.GetActionWithName("IncreaseVelocity").Apply(LandingPiston);;
>

КАК заставить это работать:

LandingPistonName и LandingGearName это названия в панели управления (в терминале) поршня и шасси соответственно. Желательно использовать англ.язык и названия без пробелов. К примеру: LandPiston_1; Gear2 и т.п. Я не ручаюсь за работу с кирилицей)
Это все, что вам нужно заменить в скрипте.

Далее таймер: выставляем задержку таймера в 1 секунду (на минимум), ставим в Setup Action запуск отчета таймера и Run программируемого блока.

ОЧЕНЬ ВАЖНО: главное правильно поставить соответствия между программируемым блоком, поршнем и шасси. Ибо может выйти так: "когда шасси1 закреплено остановить поршень2" - сами понимаете такой вариант не катит никаким образом))

p.s. в воркшоп выставлю позже, когда будет готов прототип и видеодемонстрация.

Для работы ЛЮБОГО количества шлюзов требуется ОДИН программируемый блок.

Отображение провреждённых/недостоенных блоков.
Само собой автоматическое :)

Закрытие дверей при падении давления (разгерметизации).
Возможна поблочная настройка, тогда двери где давление выровнялось откроются - закрытым останется только сектор с утечкой.

p.s.
Обращайте внимание - если включить в основную группу ВНЕШНИЕ двери то после стабилизации давления они откроются :D будьте внимательны.

Михаил Сметанкин

Невероятно полезный скрипт, который позволяет с помощью одного нажатия кнопки выбрать положение ротора или поршня. За подробностями смотрите видео по ссылке.

Павел Гусаров

Скрипт предназначен для ведения огня очередями, для этого он попеременно отключает заряженные орудия - здорово повышает огневую мощь и удобство стрельбы. Поддерживает автоматизацию огня. Автор не я.

Ставите необходимое количество оружия, прогблок, таймер и еще какой-нибудь блок, у которого есть опция включить-выключить (обычно это лампа).

Переименовываете все орудия одинаково, к примеру "Пушка", без номеров и всего остального.

Загружаете в прогблок скрипт, меняете значение GUN_NAME на "Пушка". Выставляете задержку стрельбы - значение TIME_STEP, чем больше, тем быстрее стреляет, для некоторых орудий максимальная указана в самом скрипте в комментариях, никогда не ставьте отрицательное значение и ноль. Поставите слишком большое значение TIME_STEP - скрипт будет работать быстрее, чем у орудий задержка между выстрелами, и они будут стрелять как попало. Компилируете и сохраняете.

Таймер переименовываете в "sequencerCycler", лампу переименовываете в "sequencerToggle". На таймере выставляете одно действие - запустить программируемый блок, задержку можно не трогать.

Запускаете прогблок. Включаете блок с именем "sequencerToggle".

Заряжаете орудия жмете на гашетку. Для автоматизации стрельбы просто соберите заскриптованные орудия в группу, и повесьте на горячую клавишу вкл/выкл стрельбы.

Если не все орудия заряжены полностью, то стрелять будет как попало.

При начале стрельбы бывает стреляет сразу из двух орудий.

Имена всех задействованных блоков можно менять в самом скрипте, таким образом можно сделать несколько групп орудий. Если "sequencerToggle" выключен, орудия будут стрелять как обычно - залпом.

Александр Михайлов

Михаил Сметанкин

Михаил Сметанкин

Jin Roh

Никита Селиванов

Адам, не совсем мод - плагин, выводит изображения с камер и турелей на любые LCD

Олег Резанков

Простой скрипт, который на левый дисплей выводит предупреждения о повреждениях, заканчивающемся боезапасе и малом количестве ресурсов. На правый дисплей выводится содержимое всех хранилищ корабля. Центральный дисплей отображает визуальное предупреждение (картинкой).
Имеет возможность небольшой настройки под себя в самом начале скрипта, где необходимо будет прописать свои ЖК панели для работы скрипта. По-умолчанию стоит: ЖК панель слева, ЖК панель справа, ЖК панель центр

Работает на версии 01_171_003 без модов на пиратке.

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

Олег Резанков

Иван,
public void Main(string argument)
<
IMyOxygenTank hTank = GridTerminalSystem.GetBlockWithName("Hydrogen Tank") as IMyOxygenTank;
IMyTextPanel disp = GridTerminalSystem.GetBlockWithName("LCD 1") as IMyTextPanel;
disp.WritePublicText(hTank.GetOxygenLevel().ToString(), false); //заполненность бака
>
выдает значение float от 0 до 1, где 1 - полный бак

Олег Резанков

В программируемом блоке появилась возможность сохранять переменные.
Если заметили, по-умолчанию кроме Main() в редакторе появились две функции public Program() и public void Save().

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

Функция Save() так же автоматически запускается и сохраняет предоставленное строковое значение. Сохранение происходит не каждый запуск скрипта. Заметил, что сохраняется, когда открываю редактор программируемого блока или сохраняю игру, других триггеров для срабатывания этой функции я не обнаружил.

Если снести программируемый блок, построить другой и вставить туда идентичный код, сохранения не восстанавливаются.

Переменная сохраняется после редактирования скрипта, отключения бортового питания и перезапуска игры (пока не нашел случая, в котором переменная бы не загрузилась).

Пример прикреплен ниже.

Insane Engineer

Может быть и не самый полезный , но прикольный =) Это музыкальный плеер. Проект старый, но оригинальный. Думаю Доп. информации не надо . Ссылка:

Андрей Луцюк

Описание: Скрипт подсчитывает содержимое инвентарей, перемещает позицию, которая не строится в конец очереди сборщика.
Умеет сортировать содержимое по контейнерам и дозаказывать компоненты в ассемблере на основании установленных лимитов.

Настройка:
в поле CustomData вносятся параметры для инициализации скрипта: (любая из строк может быть пустой и будет пропущена)

первая строка - название сборщика из которого берутся лимиты (останавливаем сборщик заказываем компоненты в том количестве,
в каком они всегда должны быть и прописываем название в эту строку)

все последующие строки устанавливают настройки контейнеров, в формате МаскаПоискаКонтейнера:ЧтоВНемЛежит,ЧтоВНемЛежит
что лежит можно указывать частично, типы указываются со * сначала,
например: *контейнер:Строительный - будет складывать Строительный компонент в контейнеры, заканчивающиеся на «контейнер»
*готовая продукция*:*компон,*боепри - все компоненты и боеприпасы будут перемещены в контейнеры в названии которых встречается «готовая продукция»

При первом запуске скрипта инициализация производится автоматически, далее по команде.

Команды: Скрипт поддерживает команды с параметрами. Команда и параметр разделяются «:»

Доступные команды и параметры:
init:panel,limit,storage,reload
производит переинициализацию скрипта из CustomData программного блока, параметрами можно ограничивать что инициализировать
panel - заново ищет текстовые панелей
limit - ищет сборщик из которого берутся лимиты
storage - перенастройка контейнеров
reload - поиск и запись доступных ассемблеров и блоков в которых будет в дальнейшем происходит поиск

? - Выводит информацию о текущих ассемблерах, лимитам и тестовым панелям, с любым параметром также выведет все обслуживаемые блоки с инвентарями

limit:название ассемблера - добавляет к существующим, лимиты из ассемблера. без параметров - очищает все установленные ранее лимиты

>:МаскаПоискаКонтейнера:ЧтоВНемЛежит,ЧтоВНемЛежит
устанавливает отбор для сортировки элементов в контейнере. Если перед первым параметром добавить +, будут добавлены доступные элементы иначе заменены

mask:маска поиска блоков
Устанавливает маску которая применяется при поиске обрабатываемых инвентарей, если маска пустая строка обрабатываются все доступные инвентари

reload:bloc,ass
Находит и запоминает все ассемблеры и блоки в которых будет в дальнейшем происходить поиск. Параметрами можно ограничивать что нужно искать. Без параметров ищет все.
Unload:маска
Производит единоразовое перемещение элементов из блоков подходящих под маску в установленные контейнеры. Полезно при разгрузке бурового корабля.

Скрипт находит все блоки ассемблеров и инвентаре, а затем обходит эти списки. Поэтому если необходимо заново найти инвентари или ассемблеры вызовите команду reload. Если необходимо переинициализировать текстовые панели воспользуйтесь командой init. Это поможет при разрушении готовых или достройке новых блоков.

Все настройки скрипт сохраняет и восстанавливает автоматически, при перезагрузке ничего перенастраивать не нужно

Space engineers как создать ботов



Space Engineers

11 сен. 2018 в 22:23 Привет инженеры!
Есть ли возможность спавнить ботов без участия человека? Если коротко: на сервере будет стоять большое здание, и при приближении любого игрока там должны спавниться боты с патронами и ураном, типо как на пиратских станциях. Такое возможно?

Возможно но сложно.
вообще Боты спавнятся чисто антеной! Все как на пирацких кораблях, ставите на своей базе(корабле) антену, переименуете ее как у пиратов и именно ее "отдаете" фракции "пираты". Дальше антена, пока есть электричество, и игроки рядом, начинает спавнить ботов. скорость спавна, колво и тип ботов меняется в соответствующих файлах.

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

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

Space engineers как создать ботов

Матвей Кузнецов

Ну вот и обещанный гайд по программированию или скриптингу в Space Engineers. Это первая часть гайда и в ней мы рассмотрим объвление переменных и типы переменных.

И так, для начала мы установим Programmable block на нашу станцию/корабль.Открываем панель управления блока и жмякаем на кнопку "Edit". Мы сразу же видим:

Данный код создаёт метод Main в нашей внутриигровой "программе" в которой и будут происходить наши действия.Без него код не запуститься.

Писать код мы будем между строк, для этого кликаем ЛКМ после скобочки < и жмём Enter.

int числа от -2147483648 до 2147483647
bool значения true или false
string текстовые значения, тобишь текст
double дробные числа (0.5, 21.691 и т.д)

Создадим переменную one типа int и зададим ей значение 100, для этого пишем в коде int one = 100

У нас должно получиться так:

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

Создадим ещё две переменных типа int.

int one = 100;
int two = 50;
int zn = one - two;

Что мы сделали?Мы создали две переменные "one" и "two", значение one = 100, значение two = 50, создали ещё одну переменную zn, значение которой равняется разности двух переменных.То-есть 100-50, значение переменной zn будет равняться 50.

Так же можно делить: /
Умножать: *
Складывать: +

На ближайшие 6 часов - это всё, ждите новых гайдов :)
В следующем гайде речь пойдёт о операторах условий и циклах, а также мы создадим первый рабочий код.

Виктор Кузнецов

Всем доброго времени суток. У вас не бомбит по поводу отсутствия обещанных гайдов? А у меня припекло.
//Так что, возьму на себя смелость написать гайд. Тему возьмём обещанную “Ветвление и циклы”. Как и положено зазнайке, я буду слегка выпендриваться большим количеством теории, но всё же
постараюсь сократить её до необходимого минимума.//

Виктор Кузнецов

----------------------------------------------------------------------------------------------—
В качестве примера мы с вами разберём кодовый замок, сделанный на основе сенсора. Сенсор будет выполнять в данном случае функцию ячейки памяти. (Поясняю, у сенсора 6 параметров которые мы можем изменять и проверять) Всё что нам надо также знать это увеличение сенсора и метод кодирвоания (экспериментальным, увеличение сенсора-2,45 за одно нажатие кнопки. Максимально значение 50, минимальное 1, значит диапазон возможных значений- 20. Следовательно, мы сделаем код из 3 ячеек, с 20-ю значениями в каждой). Одна из особенностей данной системы в том, что для правильной комбинации может быть множество вариантов. Это может быть сумма чисел, их разность и т.д. Мы будем использовать метод сравнение чисел.

Итак, вот готовый код:
void Main()<
var GTS=GridTerminalSystem;
var CODE=GTS.GetBlockWithName("code") as IMySensorBlock;//Блок сенсора с именем code, будет выполнять роль памяти для кодирования.
var DOOR=GTS.GetBlockWithName("door") as IMyDoor;//Блок двери с именем door
int A=1;//Это первое число в коде
int B=2;//Второе число в коде
int C=3;//Третье число в коде
//Наш код: 6 15 8 (6-нажатий по первой кнопке,15 по второй и 8 по третьей), я вынес его отдельно для более удобного изменения
//Не пугайтесь того, что будет дальше. Это всего лишь преобразование. int- мы преобразуем float в integerб предварительно вычтя 1 и поделив на 2.45, чтобы получить целое число в любом случае.
int Ac=(int)((CODE.LeftExtend-1)/2.45);//Это первый символ введённый входящим
int Bc=(int)((CODE.RightExtend-1)/2.45);//Это второй символ введённый входящим
int Cc=(int)((CODE.TopExtend-1)/2.45);//Это третий символ введённый входящим
// Проверяет правильно ли введён код, и открывает дверь.
if ((Ac==A) || (Bc==A) || (Cc==C) ) DOOR.GetActionWithName("Open_On").Apply(DOOR);
//Здесь будет использоваться вторая часть моего гайда, циклы.
for (int i=1; i<=20; i++)//Мы просто уменьшаем значение памяти сенсора, до исходных еденичек.
<
CODE.GetActionWithName("DecreaseRight").Apply(CODE);
CODE.GetActionWithName("DecreaseLeft").Apply(CODE);
CODE.GetActionWithName("DecreaseTop").Apply(CODE);
>
>

Для работы кода у вас должно быть:
1 сенсор с именем code, со всеми полями установленными на чистую 1 (1.0000)
3 кнопки, с действиями по увеличению расширения сенсора code (налево,направо,вверх)
1 кнопка с действием Run программируемый блок.
1 программируемый блок с кодом
1 дверь с именем door

Читайте также: