Add basic extensions support for power, liquid, items and control.

This commit is contained in:
SFENCE 2021-09-04 18:47:47 +02:00
parent 6f4ccf99e6
commit bb4e861828
9 changed files with 937 additions and 454 deletions

53
API.md
View File

@ -1,10 +1,53 @@
Appliance API
================
# Appliance API
See example folder for appliance examples.
Appliance table parameters
==========================
## Appliances API functions (common)
### appliances.swap_node(pos, name)
* Function swap node by using minetest.swap_node fucntion.
* Metadata of node isn't affected.
* pos - node position
* name - new node name
### appliances.register_craft_type(type_name, type_def)
* Register craft type.
* type_name - Unique name of crafting type
* type_def - table with definition of crafting type
* description - description of crafting type
* icon - icon picture name
* width - width of recipe
* height - height of recipe
* dynamic_display_size - unified_inventory callback only
### appliances.register_craft(craft_def)
* Register craft recipe.
* craft_def - table with craft recipe definition
* type - type of recipe
* output - recipe product
* items - input items
## Appliance recipes
## Appliance power supply
Some power supply should be always registered.
## Appliance object functions
Methods of object appliances.appliance.
### appliance:new(def)
### appliance:power_data_register(power_data)
* Take only useful power_data
## Appliance table parameters
appliance.input\_stack = "input"; -- input stack name, can be nil, can be same as output\_stack
appliance.input\_stack\_size = 1; -- zero value will disable stack creation
@ -32,7 +75,7 @@ Power data
### Keys - ordered by priority:
"LV", "MV", "HV" -> powered by technic LV, MV or HV
"mesecons" -> powered by messecons
"hand" -> powered by punching
"punch" -> powered by punching
"time" -> only time is need to create output

File diff suppressed because it is too large Load Diff

21
control.lua Normal file
View File

@ -0,0 +1,21 @@
appliances.controls = {}
function appliances.add_control(control_name, control_def)
if appliances.all_extensions[control_name] then
minetest.log("error", "Another appliances mod extension with name \""..control_name.."\" is already registered.")
return ;
end
appliances.item_supplies[control_name] = control_def;
appliances.all_extensions[control_name] = control_def;
end
-- mesecons
if appliances.have_mesecons then
local control =
{
};
end
-- digilines?

9
extensions.lua Normal file
View File

@ -0,0 +1,9 @@
local modpath = minetest.get_modpath(minetest.get_current_modname());
appliances.all_extensions = {}
dofile(modpath.."/power_supply.lua");
dofile(modpath.."/liquid_supply.lua");
dofile(modpath.."/item_supply.lua");
dofile(modpath.."/control.lua");

View File

@ -104,4 +104,42 @@ function appliances.register_craft(craft_def)
end
end
end
-- generate conversion table
-- add this vector to position vector to get position on wanted side
local facedir_toside = {front={},back={},right={},left={},bottom={},top={}}
for facedir=0,23 do
axis = math.floor(facedir/4);
around = facedir%4;
facedir_toside.back[facedir] = minetest.facedir_to_dir(axis+around)
facedir_toside.front[facedir] = minetest.facedir_to_dir(axis+(around+2)%4)
facedir_toside.left[facedir] = minetest.facedir_to_dir(axis+(around+1)%4)
facedir_toside.right[facedir] = minetest.facedir_to_dir(axis+(around+3)%4)
facedir_toside.bottom[facedir] = vector.cross(facedir_toside.front[facedir], facedir_toside.left[facedir])
facedir_toside.top[facedir] = vector.multiply(facedir_toside.bottom[facedir], -1)
end
function appliances.get_side_pos(pos_from, side)
local node_from = minetest.get_node(pos_from);
return vector.add(pos_from, facedir_toside[side][node_from.param2%32])
end
appliances.opposite_side = {
front = "back",
back = "front",
right = "left",
left = "right",
bottom = "top",
top = "bottom",
}
function appliances.is_connected_to(pos_from, pos_to, sides)
local node_from = minetest.get_node(pos_from);
for _,side in pairs(sides) do
local side_pos = appliances.get_side_pos(pos_from, side);
if vector.equals(pos_to, side_pos) then
return side
end
end
return nil
end

View File

@ -13,4 +13,5 @@ appliances.have_i3 = minetest.get_modpath("i3")~=nil;
dofile(modpath.."/functions.lua");
dofile(modpath.."/appliance.lua");
dofile(modpath.."/extensions.lua");

123
item_supply.lua Normal file
View File

@ -0,0 +1,123 @@
appliances.item_supplies = {}
function appliances.add_item_supply(supply_name, item_supply)
if appliances.all_extensions[supply_name] then
minetest.log("error", "Another appliances mod extension with name \""..supply_name.."\" is already registered.")
return ;
end
appliances.item_supplies[supply_name] = item_supply;
appliances.all_extensions[supply_name] = item_supply;
end
-- pipeworks
if appliances.pipeworks then
-- tube can insert
function appliance:tube_can_insert (pos, node, stack, direction, owner)
if self.recipes then
if self.have_input then
if (self.input_stack_size <= 1) then
local input = self.recipes.inputs[stack:get_name()];
if input then
return self:recipe_inventory_can_put(pos, self.input_stack, 1, stack, nil);
end
else
for index = 1,self.input_stack_size do
local can_insert = self:recipe_inventory_can_put(pos, self.input_stack, index, stack, nil);
if (can_insert~=0) then
return can_insert;
end
end
end
end
if self.have_usage then
local usage = self.recipes.usages[stack:get_name()];
if usage then
return self:recipe_inventory_can_put(pos, self.use_stack, 1, stack, nil);
end
end
end
return false;
end
function appliance:tube_insert (pos, node, stack, direction, owner)
if self.recipes then
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory();
if self.have_input then
if (self.input_stack_size <= 1) then
local input = self.recipes.inputs[stack:get_name()];
if input then
return inv:add_item(self.input_stack, stack);
end
else
for index = 1,self.input_stack_size do
local can_insert = self:recipe_inventory_can_put(pos, self.input_stack, index, stack, nil);
if (can_insert~=0) then
local input_stack = inv:get_stack(self.input_stack,index);
local remind = input_stack:add_item(stack);
inv:set_stack(self.input_stack,index, input_stack);
return remind;
end
end
end
end
if self.have_usage then
local usages = self.recipes.usages[stack:get_name()];
if usages then
return inv:add_item(self.use_stack, stack);
end
end
end
minetest.log("error", "Unexpected call of tube_insert function. Stack "..stack:to_string().." cannot be added to inventory.")
return stack;
end
-- appliance node callbacks for pipeworks
function appliance:cb_tube_insert_object(pos, node, stack, direction, owner)
local stack = self:tube_insert(pos, node, stack, direction, owner);
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory();
local use_input, use_usage = self:recipe_aviable_input(inv)
if use_input then
self:activate(pos, meta);
end
return stack;
end
function appliance:cb_tube_can_insert(pos, node, stack, direction, owner)
return self:tube_can_insert(pos, node, stack, direction, owner);
end
local item_supply =
{
update_node_def = function (self, power_data, node_def)
node_def.groups.tubedevice = 1;
node_def.groups.tubedevice_receiver = 1;
node_def.tube =
{
insert_object = function(pos, node, stack, direction, owner)
return self:cb_tube_insert_object(pos, node, stack, direction, owner);
end,
can_insert = function(pos, node, stack, direction, owner)
return self:cb_tube_can_insert(pos, node, stack, direction, owner);
end,
connect_sides = {},
input_inventory = self.output_stack,
};
for _,side in pairs(items_connect_sides)do
node_def.connect_sides[side] = 1
end
end,
after_dig_node = function(self, liquid_data, pos)
pipeworks.scan_for_tube_objects(pos);
end,
after_place_node = function(self, liquid_data, pos)
pipeworks.scan_for_tube_objects(pos);
end,
};
appliances.add_item_supply("item_tube", power_supply)
end

67
liquid_supply.lua Normal file
View File

@ -0,0 +1,67 @@
appliances.liquid_supplies = {}
function appliances.add_liquid_supply(supply_name, liquid_supply)
if appliances.all_extensions[supply_name] then
minetest.log("error", "Another appliances mod extension with name \""..supply_name.."\" is already registered.")
return ;
end
appliances.liquid_supplies[supply_name] = liquid_supply;
appliances.all_extensions[supply_name] = liquid_supply;
end
-- pipeworks
if appliances.have_pipeworks then
local pipeworks_pipe_loaded = {
["pipeworks:pipe_1_loaded"] = true,
["pipeworks:pipe_2_loaded"] = true,
["pipeworks:pipe_3_loaded"] = true,
["pipeworks:pipe_4_loaded"] = true,
["pipeworks:pipe_5_loaded"] = true,
["pipeworks:pipe_6_loaded"] = true,
["pipeworks:pipe_7_loaded"] = true,
["pipeworks:pipe_8_loaded"] = true,
["pipeworks:pipe_9_loaded"] = true,
["pipeworks:pipe_10_loaded"] = true,
};
local pipeworks_pipe_with_facedir_loaded = {
["pipeworks:valve_on_loaded"] = true,
["pipeworks:entry_panel_loaded"] = true,
["pipeworks:flow_sensor_loaded"] = true,
["pipeworks:straight_pipe_loaded"] = true,
};
local liquid_supply =
{
-- have_liquid function
have_liquid = function(liquid_data, pos)
local node = minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z});
if node then
if (pipeworks_pipe_loaded[node.name]) then
return true;
end
if (pipeworks_pipe_with_facedir_loaded[node.name]) then
if (minetest.facedir_to_dir(node.param2).y~=0) then
return true;
end
end
end
return false;
end,
update_node_def = function(liquid_data, node_def)
node_def.pipe_connections = {};
for _,pipe_side in pairs(self.liquid_connect_sides) do
node_def.pipe_connections[pipe_side] = true;
node_def.pipe_connections[pipe_side.."_param2"] = pipe_connections[pipe_side];
end
end,
after_place_node = function(self, liquid_data, pos)
pipeworks.scan_for_pipe_objects(pos);
end,
after_dig_node = function(self, liquid_data, pos)
pipeworks.scan_for_pipe_objects(pos);
end,
};
appliances.add_liquid_supply("water_pipe", liquid_supply)
end

250
power_supply.lua Normal file
View File

@ -0,0 +1,250 @@
appliances.power_supplies = {}
function appliances.add_power_supply(supply_name, power_supply)
if appliances.all_extensions[supply_name] then
minetest.log("error", "Another appliances mod extension with name \""..supply_name.."\" is already registered.")
return ;
end
appliances.power_supplies[supply_name] = power_supply;
appliances.all_extensions[supply_name] = power_supply;
end
-- time
if true then
local power_supply =
{
is_powered = function (self, power_supply, pos, meta)
return power_supply.run_speed;
end,
};
appliances.add_power_supply("time", power_supply)
end
-- punch
if true then
local power_supply =
{
is_powered = function (self, power_supply, pos, meta)
local is_powered = meta:get_int("is_powered");
if (is_powered~=0) then
meta:set_int("is_powered", 0);
return power_supply.run_speed;
end
return 0;
end,
power_need = function (self, power_supply, pos, meta)
meta:set_int("is_powered", 0);
end,
power_idle = function (self, power_supply, pos, meta)
meta:set_int("is_powered", 0);
end,
on_punch = function (self, power_supply, pos, node, puncher, pointed_thing)
local meta = minetest.get_meta(pos);
meta:set_int("is_powered", 1);
end,
};
appliances.add_power_supply("punch", power_supply)
end
-- mesecons
if appliances.have_mesecons then
local power_supply =
{
is_powered = function (self, power_supply, pos, meta)
local is_powered = meta:get_int("is_powered");
if (is_powered~=0) then
return power_supply.run_speed;
end
return 0;
end,
power_need = function (self, power_supply, pos, meta)
meta:set_int("LV_EU_demand", power_supply.demand)
end,
power_idle = function (self, power_supply, pos, meta)
meta:set_int("LV_EU_demand", 0)
end,
update_node_def = function (self, power_supply, node_def)
node_def.effector = {
action_on = function (pos, node)
minetest.get_meta(pos):set_int("is_powered", 1);
end,
action_off = function (pos, node)
minetest.get_meta(pos):set_int("is_powered", 0);
end,
}
end,
update_node_inactive_def = function (self, power_supply, node_def)
end,
update_node_active_def = function (self, power_supply, node_def)
end,
after_place_node = function (self, power_supply, pos, meta)
minetest.get_meta(pos):set_int("is_powered", 0);
end,
};
appliances.add_power_supply("mesecons", power_supply)
end
-- technic
if appliances.have_technic then
-- LV
local power_supply =
{
is_powered = function (self, power_data, pos, meta)
local eu_input = meta:get_int("LV_EU_input");
if (eu_input>=power_data.demand) then
return power_data.run_speed;
end
return 0;
end,
power_need = function (self, power_data, pos, meta)
meta:set_int("LV_EU_demand", power_data.demand)
end,
power_idle = function (self, power_data, pos, meta)
meta:set_int("LV_EU_demand", 0)
end,
activate = function(self, power_data, pos, meta)
meta:set_string("infotext", meta:get_string("technic_info"));
end,
deactivate = function(self, power_data, pos, meta)
meta:set_string("infotext", meta:get_string("technic_info"));
end,
running = function(self, power_data, pos, meta)
meta:set_string("infotext", meta:get_string("technic_info"));
end,
waiting = function(self, power_data, pos, meta)
meta:set_string("infotext", meta:get_string("technic_info"));
end,
no_power = function(self, power_data, pos, meta)
meta:set_string("infotext", meta:get_string("technic_info"));
end,
update_node_def = function (self, power_data, node_def)
self.meta_infotext = "technic_info";
node_def.groups.technic_machine = 1;
node_def.groups.technic_lv = 1;
node_def.connect_sides = self.power_connect_sides;
node_def.technic_run = function (pos, node)
local meta = minetest.get_meta(pos);
meta:set_string("infotext", meta:get_string("technic_info"));
end
node_def.technic_no_network = function (pos, node)
end
end,
after_register_node = function (self, power_data)
technic.register_machine("LV", self.node_name_inactive, technic.receiver)
technic.register_machine("LV", self.node_name_active, technic.receiver)
end,
on_construct = function (self, power_data, pos, meta)
local meta = minetest.get_meta(pos);
meta:set_string("infotext", meta:get_string("technic_info"));
end,
};
appliances.add_power_supply("LV", power_supply)
-- MV
local power_supply =
{
is_powered = function (self, power_data, pos, meta)
local eu_input = meta:get_int("MV_EU_input");
if (eu_input>=power_data.demand) then
return power_data.run_speed;
end
return 0;
end,
power_need = function (self, power_data, pos, meta)
meta:set_int("MV_EU_demand", power_data.demand)
end,
power_idle = function (self, power_data, pos, meta)
meta:set_int("MV_EU_demand", 0)
end,
activate = function(self, power_data, pos, meta)
meta:set_string("infotext", meta:get_string("technic_info"));
end,
deactivate = function(self, power_data, pos, meta)
meta:set_string("infotext", meta:get_string("technic_info"));
end,
running = function(self, power_data, pos, meta)
meta:set_string("infotext", meta:get_string("technic_info"));
end,
waiting = function(self, power_data, pos, meta)
meta:set_string("infotext", meta:get_string("technic_info"));
end,
no_power = function(self, power_data, pos, meta)
meta:set_string("infotext", meta:get_string("technic_info"));
end,
update_node_def = function (self, power_data, node_def)
self.meta_infotext = "technic_info";
node_def.groups.technic_machine = 1;
node_def.groups.technic_mv = 1;
node_def.connect_sides = self.power_connect_sides;
node_def.technic_run = function (pos, node)
local meta = minetest.get_meta(pos);
meta:set_string("infotext", meta:get_string("technic_info"));
end
node_def.technic_no_network = function (pos, node)
end
end,
after_register_node = function (self, power_data)
technic.register_machine("MV", self.node_name_inactive, technic.receiver)
technic.register_machine("MV", self.node_name_active, technic.receiver)
end,
on_construct = function (self, power_data, pos, meta)
local meta = minetest.get_meta(pos);
meta:set_string("infotext", meta:get_string("technic_info"));
end,
};
appliances.add_power_supply("MV", power_supply)
-- HV
local power_supply =
{
is_powered = function (self, power_data, pos, meta)
local eu_input = meta:get_int("HV_EU_input");
if (eu_input>=power_data.demand) then
return power_data.run_speed;
end
return 0;
end,
power_need = function (self, power_data, pos, meta)
meta:set_int("HV_EU_demand", power_data.demand)
end,
power_idle = function (self, power_data, pos, meta)
meta:set_int("HV_EU_demand", 0)
end,
activate = function(self, power_data, pos, meta)
meta:set_string("infotext", meta:get_string("technic_info"));
end,
deactivate = function(self, power_data, pos, meta)
meta:set_string("infotext", meta:get_string("technic_info"));
end,
running = function(self, power_data, pos, meta)
meta:set_string("infotext", meta:get_string("technic_info"));
end,
waiting = function(self, power_data, pos, meta)
meta:set_string("infotext", meta:get_string("technic_info"));
end,
no_power = function(self, power_data, pos, meta)
meta:set_string("infotext", meta:get_string("technic_info"));
end,
update_node_def = function (self, power_data, node_def)
self.meta_infotext = "technic_info";
node_def.groups.technic_machine = 1;
node_def.groups.technic_hv = 1;
node_def.connect_sides = self.power_connect_sides;
node_def.technic_run = function (pos, node)
local meta = minetest.get_meta(pos);
meta:set_string("infotext", meta:get_string("technic_info"));
end
node_def.technic_no_network = function (pos, node)
end
end,
after_register_node = function (self, power_data)
technic.register_machine("HV", self.node_name_inactive, technic.receiver)
technic.register_machine("HV", self.node_name_active, technic.receiver)
end,
on_construct = function (self, power_data, pos, meta)
local meta = minetest.get_meta(pos);
meta:set_string("infotext", meta:get_string("technic_info"));
end,
};
appliances.add_power_supply("HV", power_supply)
end