EnergyNet

Данная библиотека для Inner Core представляет собой инструмент для быстрого создания новых типов энергии и имеет большой функционал для работы с ними.

Импорт

Для добавления библиотеки в мод ее файл (energy-net.js) нужно добавить в директорию lib/ в директории мода (если таковой нету, то ее нужно создать).
Для импорта библиотеки в мод в заголовочном файле (или если он остутвует в первом файле кода) следует добавить строку:
IMPORT("EnergyNet");

Модули

  1. EnergyTypeRegistry - модуль для регистрации новых типов энергии.
  2. EnergyTileRegistry - модуль для привязки типов энергии к TileEntity. 
  3. EnergyNetBuilder - модуль построения энергосетей и взаимодействия с ними.

Создание нового типа энергии

EnergyTypeRegistry.assureEnergyType("name", value) - создает новый тип энергии и возвращает его, если такой тип энергии уже существует, новый создан не будет, а вернется уже существующий, таким образом если 2 мода создают один тип энергии, он будет общий.

Параметры:

  • name - уникальное название энергии, обычно используется сокращение ("Eu" - energy units, "RF" - redstone flux и т.п.)
  • value - сколько Eu (единиц энергии IndustrialCraft) содержится в 1 единице данного типа энергии, данное значение используется для конвертации из одного вида энергии в другой. Энергия Eu принята за эталон.

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

  • <energyType>.name - имя данного типа энергии.
  • <energyType>.registerWire(id, value) – регистрирует провод с данным ид и устанавливает для него лимит по приёму энергии, записанный в параметре value.
  • <energyType>.onNetOverload – функция, вызывающаяся при превышение лимита энергии в проводе. Для продвинутых разработчиков

Пример:

// в начале мода импортируем библиотеку (она должна находиться в lib/) importLib("energylib.js", "*");

// создаем тип энергии redstone flux
var energyRF = EnergyTypeRegistry.assureEnergyType("RF", 0.25);
// регистрируем блок-проводник для данного типа энергии
energyRF.registerWire(BlockID.RFconduct, 2000);

Механика передачи энергии

Энергия может передаваться как по проводам, так и напрямую от генератора к соседним механизмам. Для этого подобные механизмы объдиняются в энергосети. Энергосети - это программные объекты, которые передают энергию к подключенным к ним механизмам или другим энергосетям. Энергия передаётся пакетами с определённым количеством энергии и напряжением.

Энергосети формируются следующим образом:
Для каждого блока генератора создаётся своя энергосеть, соединяющая его с подключенными к нему машинами-потребителями и энергосетями проводов. Энергосети проводов объединяют блоки с одним ид и соединяются с другими сетями того же типа энергии и машинами-потребителями энергии. Такая система позволяет разбивать провода по размеру пакета энергии, который они могут передать. Напряжение пакета энергии - это параметр, позволяющий объединять множество пакетов меньшего размера в один и передать его как будто бы с размером меньшего пакета.

Привязка типов энергии к TileEntity

EnergyTileRegistry.addEnergyTypeForId(tileEntityId, energyType) - добавляет tile entity с данным id дополнительные события, которые позволяют ему работать с данным типом энергии. К одному tile entity можно привязать несколько разных типов энергии.
Параметры:

  • tileEntityId – id блока, на который был зарегистрирован нужный tile entity.
  • energyType - тип энергии, который требуется к нему привязать.

Новые события:

  • energyTick: function(type, src) { /* … */ } - вызывается каждый тик после функции tick для каждой энергосети, привязанной к данному tile entity.
    Параметры:
    • type - название типа энергии, для которого вызвано это событие.
    • src - объект типа EnergySource для добавления энергии
  • energyReceive: function(type, amount, voltage) { /* … */ } – вызывается при приёме пакета энергии данным tile entity. Должна возвращать количество энергии, которое удалось добавить.
    Параметры:
    • type - название типа энергии
    • amount – количество энергии
    • voltage – напряжение энергии
  • isEnergySource: function(type) {return true;} – определяет, может ли tile entity вырабатывать энергию данного типа. Если да, то для него строится энергосеть.
  • canReceiveEnergy: function(side, type) {return true/false;} – определяет, может ли tile entity получать энергию даного типа и с каких сторон. Вызывается при попытке соединения tile entity к энергосети.
  • canExtractEnergy: function(side, type) {return true/false;} – определяет, с каких сторон tile entity может выдавать энергию.

Объект EnergySource

Данный объект является интерфейсом для добавления энергии в сеть, который передается в события для работы с энергией (src).
Методы:

  • src.add(amount, voltage) - добавляет в сеть данное кол-во энергии (amount), возвращает, какое кол-во энергии добавить не удалось из-за переполнения (0, если вся энергия добавлена). Если значение voltage (напряжение) не указано, то оно будет равно amount.
  • src.addAll(amount, voltage) - аналогичен методу add, но ничего не возвращает и работает быстрее, потому что добавляет энергию в буфер сети, позволяя объединять в один пакет множество пакетов, созданных генераторами.

Работа с энгергитическими сетями

Большая часть методов модуля EnergyNetBuilder технические и используются только внутри библиотеки.Однако некоторые из них могут быть полезны и в модах:

EnergyNetBuilder.rebuildTileNet(объект tile entity) – удаляет все энергосети механизма и перестраивает все его соединения с другими сетями. Необходимо вызвать при изменении сторон, через которые tile entity может получать или передавать энергию.

EnergyNetBuilder.getNetOnCoords(x, y, z) – возвращает сеть, если на данных координатах есть её провод. Используется в IndustrialCraft для нанесения урона от оголённых проводов и для мультиметра.

EnergyNetBuilder.getNetByBlock(x, y, z, wireId) – возвращает сеть, если блок на данных координатах имеет ид, указанное в параметре wireId.

Примеры

Генератор

// Cоздадим блок с id "RFgenerator", который будет выробатывать энергию.
TileEntity.registerPrototype(BlockID.RFgenerator, {
    isEnergySource: function() {
        return true; // может генерировать энергию
    },
    canReceiveEnergy: function(){
        return false; // не может получать энергию
    },
    energyTick: function(type, src) {
        src.addAll(10); // генерирует 10 RF за тик. Так как сразу отдаёт всю энергию, используется более быстрый метод.
    }
});

// привяжем к этому tile entity наш тип энергии
EnergyTileRegistry.addEnergyTypeForId(BlockID.RFgenerator, energyRF);

Потребитель

 

// Cоздадим блок с id "RFconsumer", который будет потреблять энергию для производства алмазов.
TileEntity.registerPrototype(BlockID.RFconsumer, {
    defaultValues: {
        progress: 0 // сохраняемое значение прогресса работы
    },
    energyReceive: function(type, amount, voltage) {
        this.data.progress += amount; // увеличиваем прогресс производства алмаза.
        return amount; // и возвращаем сколько забрали энергии
    },
    tick: function(){
        if(this.data.progress >= 10000){
            this.data.progress = 0;
            World.drop(this.x, this.y +1, this.z, 264, 1); // дропнуть алмаз на координатах tile entity.
        }
    }
});

// привяжем к этому tile entity наш тип энергии
EnergyTileRegistry.addEnergyTypeForId(BlockID.RFconsumer, energyRF);
 

Хранилище

Стороны приёма и отправки энергии для хранилища должны быть разделены. Иначе энергия между двумя связанных друг с другом механизмами могут бесконечно обмениваться энергией друг с другом, игнорируя другие tile enity.

//Cоздадим блок с id "RFstorage" и настроим его так, чтобы он отдавал энергию снизу, а принимал сбоку или сверху.
TileEntity.registerPrototype(BlockID.RFstorage, {
    defaultValues: {
        energy: 0 // сохраняемое значение, обозначающее запасенную энергию
    },
    isEnergySource: function() {
        return true; // блок может отдавать энергию
    }
    canReceiveEnergy: function(side, type) {
        return side != 0; // side != 0 выведет true, если сторона любая, кроме нижней.
    } ,
    canExtractEnergy: function(side, type) {
        return side == 0; // выведет true при подключении блока для выхода энергии с нижней стороны.
    },
    getCapacity: function(){
        return 2e6; // установим лимит хранилища энергии в 2 миллиона (2e6 - это способ записи числа 2*106)
    },
    energyReceive: function(type, amount, voltage) {
        amount = Math.min(amount, 1000); // устанавлимаем максимальное количество энергии, которое может принять механизм равным 1000.
        var add = Math.min(amount, this.getCapacity() - this.data.energy); // уменьшаем количество энергии, так, чтобы хранилище не переполнялось;
        this.data.energy += add; // добавляем энергию в хранилище
        return add; // и возвращаем сколько забрали энергии
    },
    energyTick: function(type, src){
        var output = Math.min(1000, this.data.energy); // определяем, сколько энергии блок может отдать
        this.data.energy += src.add(output) - output; // прибавляем к хранилищу количество энергии, которое осталось после отправки пакета, и вычитаем сколько отправляли.
    },
});

// привяжем к этому tile entity наш тип энергии
EnergyTileRegistry.addEnergyTypeForId(BlockID.RFstorage, energyRF);