From 6463b77e60639f4012b702fef344cc7e201d3e3a Mon Sep 17 00:00:00 2001 From: kpoppel Date: Mon, 6 May 2013 20:00:00 +0200 Subject: [PATCH 1/2] Add milling machine from non cubic to technic mod. Next step is to make sure it only works if powered. --- technic/chainsaw.lua | 304 +++++- technic/cnc.lua | 208 ++++ technic/cnc_api.lua | 970 ++++++++++++++++++ technic/cnc_nodes.lua | 354 +++++++ technic/init.lua | 14 +- technic/textures/technic_cnc_bottom.png | Bin 0 -> 2006 bytes technic/textures/technic_cnc_cylinder.png | Bin 0 -> 456 bytes .../technic_cnc_cylinder_horizontal.png | Bin 0 -> 463 bytes .../textures/technic_cnc_element_cross.png | Bin 0 -> 415 bytes technic/textures/technic_cnc_element_edge.png | Bin 0 -> 409 bytes technic/textures/technic_cnc_element_end.png | Bin 0 -> 391 bytes .../textures/technic_cnc_element_straight.png | Bin 0 -> 412 bytes technic/textures/technic_cnc_element_t.png | Bin 0 -> 389 bytes technic/textures/technic_cnc_front.png | Bin 0 -> 2000 bytes technic/textures/technic_cnc_full.png | Bin 0 -> 372 bytes technic/textures/technic_cnc_half.png | Bin 0 -> 460 bytes .../technic_cnc_milling_background.png | Bin 0 -> 78748 bytes .../textures/technic_cnc_onecurvededge.png | Bin 0 -> 507 bytes technic/textures/technic_cnc_pyramid.png | Bin 0 -> 480 bytes technic/textures/technic_cnc_side.png | Bin 0 -> 1922 bytes technic/textures/technic_cnc_slope.png | Bin 0 -> 437 bytes technic/textures/technic_cnc_slope_edge.png | Bin 0 -> 419 bytes .../technic_cnc_slope_edge_upsdwn.png | Bin 0 -> 486 bytes .../textures/technic_cnc_slope_inner_edge.png | Bin 0 -> 497 bytes .../technic_cnc_slope_inner_edge_upsdwn.png | Bin 0 -> 605 bytes technic/textures/technic_cnc_slope_lying.png | Bin 0 -> 548 bytes technic/textures/technic_cnc_slope_upsdwn.png | Bin 0 -> 440 bytes technic/textures/technic_cnc_sphere.png | Bin 0 -> 532 bytes technic/textures/technic_cnc_spike.png | Bin 0 -> 556 bytes technic/textures/technic_cnc_stick.png | Bin 0 -> 320 bytes technic/textures/technic_cnc_top.png | Bin 0 -> 2137 bytes .../textures/technic_cnc_twocurvededge.png | Bin 0 -> 768 bytes 32 files changed, 1794 insertions(+), 56 deletions(-) create mode 100644 technic/cnc.lua create mode 100644 technic/cnc_api.lua create mode 100644 technic/cnc_nodes.lua create mode 100644 technic/textures/technic_cnc_bottom.png create mode 100644 technic/textures/technic_cnc_cylinder.png create mode 100644 technic/textures/technic_cnc_cylinder_horizontal.png create mode 100644 technic/textures/technic_cnc_element_cross.png create mode 100644 technic/textures/technic_cnc_element_edge.png create mode 100644 technic/textures/technic_cnc_element_end.png create mode 100644 technic/textures/technic_cnc_element_straight.png create mode 100644 technic/textures/technic_cnc_element_t.png create mode 100644 technic/textures/technic_cnc_front.png create mode 100644 technic/textures/technic_cnc_full.png create mode 100644 technic/textures/technic_cnc_half.png create mode 100644 technic/textures/technic_cnc_milling_background.png create mode 100644 technic/textures/technic_cnc_onecurvededge.png create mode 100644 technic/textures/technic_cnc_pyramid.png create mode 100644 technic/textures/technic_cnc_side.png create mode 100644 technic/textures/technic_cnc_slope.png create mode 100644 technic/textures/technic_cnc_slope_edge.png create mode 100644 technic/textures/technic_cnc_slope_edge_upsdwn.png create mode 100644 technic/textures/technic_cnc_slope_inner_edge.png create mode 100644 technic/textures/technic_cnc_slope_inner_edge_upsdwn.png create mode 100644 technic/textures/technic_cnc_slope_lying.png create mode 100644 technic/textures/technic_cnc_slope_upsdwn.png create mode 100644 technic/textures/technic_cnc_sphere.png create mode 100644 technic/textures/technic_cnc_spike.png create mode 100644 technic/textures/technic_cnc_stick.png create mode 100644 technic/textures/technic_cnc_top.png create mode 100644 technic/textures/technic_cnc_twocurvededge.png diff --git a/technic/chainsaw.lua b/technic/chainsaw.lua index 2c3fbf5..c31d9a8 100644 --- a/technic/chainsaw.lua +++ b/technic/chainsaw.lua @@ -1,63 +1,261 @@ -chainsaw_max_charge=30000 +-- Configuration +local chainsaw_max_charge = 30000 -- 30000 - Maximum charge of the saw +local chainsaw_charge_per_node = 12 -- 12 - Gives 2500 nodes on a single charge (about 50 complete normal trees) +local chainsaw_leaves = true -- true - Cut down entire trees, leaves and all + register_power_tool ("technic:chainsaw",chainsaw_max_charge) minetest.register_tool("technic:chainsaw", { - description = "Chainsaw", - inventory_image = "technic_chainsaw.png", - stack_max = 1, - on_use = function(itemstack, user, pointed_thing) - if pointed_thing.type=="node" then - item=itemstack:to_table() - local meta=get_item_meta(item["metadata"]) - if meta==nil then return end --tool not charghed - if meta["charge"]==nil then return end - charge=meta["charge"] - charge_to_take=600; - if charge-charge_to_take>0 then - charge_to_take=chainsaw_dig_it(minetest.get_pointed_thing_position(pointed_thing, above),user,charge_to_take) - charge=charge-charge_to_take; - set_RE_wear(item,charge,chainsaw_max_charge) - meta["charge"]=charge - item["metadata"]=set_item_meta(meta) - itemstack:replace(item) - return itemstack - end - end - end, + description = "Chainsaw", + inventory_image = "technic_chainsaw.png", + stack_max = 1, + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type=="node" then + item=itemstack:to_table() + local meta=get_item_meta(item["metadata"]) + if meta==nil then return end --tool not charged + if meta["charge"]==nil then return end + -- Send current charge to digging function so that the chainsaw will stop after digging a number of nodes. + local charge=meta["charge"] + if charge < chainsaw_charge_per_node then return end -- only cut if charged + + charge=chainsaw_dig_it(minetest.get_pointed_thing_position(pointed_thing, above),user,charge) + set_RE_wear(item,charge,chainsaw_max_charge) + meta["charge"]=charge + item["metadata"]=set_item_meta(meta) + itemstack:replace(item) + return itemstack + end + end, }) minetest.register_craft({ - output = 'technic:chainsaw', - recipe = { - {'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot', 'technic:battery'}, - {'technic:stainless_steel_ingot', 'technic:motor', 'technic:battery'}, - {'','','moreores:copper_ingot'}, - } + output = 'technic:chainsaw', + recipe = { + {'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot', 'technic:battery'}, + {'technic:stainless_steel_ingot', 'technic:motor', 'technic:battery'}, + {'','','moreores:copper_ingot'}, + } }) +-- The default stuff +local timber_nodenames={["default:jungletree"] = true, + ["default:papyrus"] = true, + ["default:cactus"] = true, + ["default:tree"] = true, + ["default:apple"] = true +} - - -timber_nodenames={"default:jungletree", "default:papyrus", "default:cactus", "default:tree"} - -function chainsaw_dig_it (pos, player,charge_to_take) - charge_to_take=0 - local node=minetest.env:get_node(pos) - local i=1 - while timber_nodenames[i]~=nil do - if node.name==timber_nodenames[i] then - charge_to_take=600 - np={x=pos.x, y=pos.y, z=pos.z} - while minetest.env:get_node(np).name==timber_nodenames[i] do - minetest.env:remove_node(np) - minetest.env:add_item(np, timber_nodenames[i]) - np={x=np.x, y=np.y+1, z=np.z} - end - minetest.sound_play("chainsaw", {pos = pos, gain = 1.0, max_hear_distance = 10,}) - return charge_to_take - end - i=i+1 - end - -return charge_to_take +if chainsaw_leaves == true then + timber_nodenames["default:leaves"] = true +end + +-- Support moretrees if it is there +if( minetest.get_modpath("moretrees") ~= nil ) then + timber_nodenames["moretrees:apple_tree_trunk"] = true + timber_nodenames["moretrees:apple_tree_trunk_sideways"] = true + timber_nodenames["moretrees:beech_trunk"] = true + timber_nodenames["moretrees:beech_trunk_sideways"] = true + timber_nodenames["moretrees:birch_trunk"] = true + timber_nodenames["moretrees:birch_trunk_sideways"] = true + timber_nodenames["moretrees:fir_trunk"] = true + timber_nodenames["moretrees:fir_trunk_sideways"] = true + timber_nodenames["moretrees:oak_trunk"] = true + timber_nodenames["moretrees:oak_trunk_sideways"] = true + timber_nodenames["moretrees:palm_trunk"] = true + timber_nodenames["moretrees:palm_trunk_sideways"] = true + timber_nodenames["moretrees:pine_trunk"] = true + timber_nodenames["moretrees:pine_trunk_sideways"] = true + timber_nodenames["moretrees:rubber_tree_trunk"] = true + timber_nodenames["moretrees:rubber_tree_trunk_sideways"] = true + timber_nodenames["moretrees:rubber_tree_trunk_empty"] = true + timber_nodenames["moretrees:rubber_tree_trunk_sideways_empty"] = true + timber_nodenames["moretrees:sequoia_trunk"] = true + timber_nodenames["moretrees:sequoia_trunk_sideways"] = true + timber_nodenames["moretrees:spruce_trunk"] = true + timber_nodenames["moretrees:spruce_trunk_sideways"] = true + timber_nodenames["moretrees:willow_trunk"] = true + timber_nodenames["moretrees:willow_trunk_sideways"] = true + timber_nodenames["moretrees:jungletree_trunk"] = true + timber_nodenames["moretrees:jungletree_trunk_sideways"] = true + + if chainsaw_leaves == true then + timber_nodenames["moretrees:apple_tree_leaves"] = true + timber_nodenames["moretrees:oak_leaves"] = true + timber_nodenames["moretrees:sequoia_leaves"] = true + timber_nodenames["moretrees:birch_leaves"] = true + timber_nodenames["moretrees:birch_leaves"] = true + timber_nodenames["moretrees:palm_leaves"] = true + timber_nodenames["moretrees:spruce_leaves"] = true + timber_nodenames["moretrees:spruce_leaves"] = true + timber_nodenames["moretrees:pine_leaves"] = true + timber_nodenames["moretrees:willow_leaves"] = true + timber_nodenames["moretrees:rubber_tree_leaves"] = true + timber_nodenames["moretrees:jungletree_leaves_green"] = true + timber_nodenames["moretrees:jungletree_leaves_yellow"] = true + timber_nodenames["moretrees:jungletree_leaves_red"] = true + end +end + +-- Support growing_trees if it is there +if( minetest.get_modpath("growing_trees") ~= nil ) then + timber_nodenames["growing_trees:trunk"] = true + timber_nodenames["growing_trees:medium_trunk"] = true + timber_nodenames["growing_trees:big_trunk"] = true + timber_nodenames["growing_trees:trunk_top"] = true + timber_nodenames["growing_trees:trunk_sprout"] = true + timber_nodenames["growing_trees:branch_sprout"] = true + timber_nodenames["growing_trees:branch"] = true + timber_nodenames["growing_trees:branch_xmzm"] = true + timber_nodenames["growing_trees:branch_xpzm"] = true + timber_nodenames["growing_trees:branch_xmzp"] = true + timber_nodenames["growing_trees:branch_xpzp"] = true + timber_nodenames["growing_trees:branch_zz"] = true + timber_nodenames["growing_trees:branch_xx"] = true + + if chainsaw_leaves == true then + timber_nodenames["growing_trees:leaves"] = true + end +end + +-- Support growing_cactus if it is there +if( minetest.get_modpath("growing_cactus") ~= nil ) then + timber_nodenames["growing_cactus:sprout"] = true + timber_nodenames["growing_cactus:branch_sprout_vertical"] = true + timber_nodenames["growing_cactus:branch_sprout_vertical_fixed"] = true + timber_nodenames["growing_cactus:branch_sprout_xp"] = true + timber_nodenames["growing_cactus:branch_sprout_xm"] = true + timber_nodenames["growing_cactus:branch_sprout_zp"] = true + timber_nodenames["growing_cactus:branch_sprout_zm"] = true + timber_nodenames["growing_cactus:trunk"] = true + timber_nodenames["growing_cactus:branch_trunk"] = true + timber_nodenames["growing_cactus:branch"] = true + timber_nodenames["growing_cactus:branch_xp"] = true + timber_nodenames["growing_cactus:branch_xm"] = true + timber_nodenames["growing_cactus:branch_zp"] = true + timber_nodenames["growing_cactus:branch_zm"] = true + timber_nodenames["growing_cactus:branch_zz"] = true + timber_nodenames["growing_cactus:branch_xx"] = true +end + +-- Table for saving what was sawed down +local produced + +-- Saw down trees entry point +chainsaw_dig_it = function(pos, player,current_charge) + local remaining_charge=current_charge + + -- A bit of trickery here: use a different node drop callback + -- and restore the original afterwards. + minetest.handle_node_drops = chainsaw_handle_node_drops + + -- clear result and start sawing things down + produced = {} + remaining_charge = recursive_dig(pos, remaining_charge, player) + minetest.sound_play("chainsaw", {pos = pos, gain = 1.0, max_hear_distance = 10,}) + + -- Restore the original noder drop handler + minetest.handle_node_drops = original_handle_node_drops + + -- Now drop items for the player + local number, produced_item, p + for produced_item,number in pairs(produced) do + --print("ADDING ITEM: " .. produced_item .. " " .. number) + -- Drop stacks of 99 or less + p = { + x = pos.x + math.random()*4, + y = pos.y, + z = pos.z + math.random()*4 + } + while number > 99 do + minetest.env:add_item(p, produced_item .. " 99") + p = { + x = pos.x + math.random()*4, + y = pos.y, + z = pos.z + math.random()*4 + } + number = number - 99 + end + minetest.env:add_item(p, produced_item .. " " .. number) + end + return remaining_charge +end + +-- Override the default handling routine to be able to count up the +-- items sawed down so that we can drop them i an nice single stack +chainsaw_handle_node_drops = function(pos, drops, digger) + -- Add dropped items to list of collected nodes + local _, dropped_item + for _, dropped_item in ipairs(drops) do + if produced[dropped_item] == nil then + produced[dropped_item] = 1 + else + produced[dropped_item] = produced[dropped_item] + 1 + end + end +end + +-- Save the currently installed dropping mechanism so we can restore it. +local original_handle_node_drops = minetest.handle_node_drops + +-- This function does all the hard work. Recursively we dig the node at hand +-- if it is in the table and then search the surroundings for more stuff to dig. +recursive_dig = function(pos, remaining_charge, player) + local node=minetest.env:get_node(pos) + local i=1 + -- Lookup node name in timber table: + if timber_nodenames[node.name] ~= nil then + -- Return if we are out of power + if remaining_charge < chainsaw_charge_per_node then + return 0 + end + local np + -- wood found - cut it. + minetest.env:dig_node(pos) + + remaining_charge=remaining_charge-chainsaw_charge_per_node + -- check surroundings and run recursively if any charge left + np={x=pos.x+1, y=pos.y, z=pos.z} + if timber_nodenames[minetest.env:get_node(np).name] ~= nil then + remaining_charge = recursive_dig(np, remaining_charge) + end + np={x=pos.x+1, y=pos.y, z=pos.z+1} + if timber_nodenames[minetest.env:get_node(np).name] ~= nil then + remaining_charge = recursive_dig(np, remaining_charge) + end + np={x=pos.x+1, y=pos.y, z=pos.z-1} + if timber_nodenames[minetest.env:get_node(np).name] ~= nil then + remaining_charge = recursive_dig(np, remaining_charge) + end + + np={x=pos.x-1, y=pos.y, z=pos.z} + if timber_nodenames[minetest.env:get_node(np).name] ~= nil then + remaining_charge = recursive_dig(np, remaining_charge) + end + np={x=pos.x-1, y=pos.y, z=pos.z+1} + if timber_nodenames[minetest.env:get_node(np).name] ~= nil then + remaining_charge = recursive_dig(np, remaining_charge) + end + np={x=pos.x-1, y=pos.y, z=pos.z-1} + if timber_nodenames[minetest.env:get_node(np).name] ~= nil then + remaining_charge = recursive_dig(np, remaining_charge) + end + + np={x=pos.x, y=pos.y+1, z=pos.z} + if timber_nodenames[minetest.env:get_node(np).name] ~= nil then + remaining_charge = recursive_dig(np, remaining_charge) + end + + np={x=pos.x, y=pos.y, z=pos.z+1} + if timber_nodenames[minetest.env:get_node(np).name] ~= nil then + remaining_charge = recursive_dig(np, remaining_charge) + end + np={x=pos.x, y=pos.y, z=pos.z-1} + if timber_nodenames[minetest.env:get_node(np).name] ~= nil then + remaining_charge = recursive_dig(np, remaining_charge) + end + return remaining_charge + end + -- Nothing sawed down + return remaining_charge end diff --git a/technic/cnc.lua b/technic/cnc.lua new file mode 100644 index 0000000..6e763ef --- /dev/null +++ b/technic/cnc.lua @@ -0,0 +1,208 @@ +-- Technic CNC v1.0 by kpo +-- Based on the NonCubic Blocks MOD v1.4 by yves_de_beck +local shape = {} +local size = 0 +local onesize_products = { + slope = 2, + slope_edge = 1, + slope_inner_edge = 1, + pyramid = 2, + spike = 1, + cylinder = 2, + sphere = 1, + stick = 8, + slope_upsdwn = 2, + slope_edge_upsdwn = 1, + slope_inner_edge_upsdwn = 1, + cylinder_hor = 2, + slope_lying = 2, + onecurvededge = 1, + twocurvededge = 1, +} +local twosize_products = { + element_straight = 4, + element_end = 2, + element_cross = 1, + element_t = 1, + element_edge = 2, +} + +local showbackground = "--" +local max_cncruns = 99 +local max_products = 99 + +--showlabelin = "" +--showlabelout = "label[4.5,5.5;Out:]" + +-- I want the CNC machine to be a two block thing +minetest.register_node("technic:cnc", { + description = "CNC Milling Machine", + tiles = {"technic_cnc_top.png", "technic_cnc_bottom.png", "technic_cnc_side.png", + "technic_cnc_side.png", "technic_cnc_side.png", "technic_cnc_front.png"}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + + }, + }, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + groups = {oddly_breakable_by_hand=2, cracky=3, dig_immediate=1}, + + can_dig = function(pos,player) + local meta = minetest.env:get_meta(pos); + local inv = meta:get_inventory() + if not inv:is_empty("input") or not inv:is_empty("output") then + minetest.chat_send_player(player:get_player_name(), "CNC machine cannot be removed because it is not empty"); + return false + end + return true + end, + + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + if technic_cnc_api.allow_menu_background == true or technic_cnc_api.allow_menu_background == 1 then + showbackground = "background[-0.15,-0.25;8.40,11.75;technic_cnc_background.png]" + end + + meta:set_string("formspec", "invsize[8,11;]".. + "label[0,0;Choose Milling Program:]".. + "image_button[0,0.5;1,1;technic_cnc_slope.png;slope; ]".. + "image_button[1,0.5;1,1;technic_cnc_slope_edge.png;slope_edge; ]".. + "image_button[2,0.5;1,1;technic_cnc_slope_inner_edge.png;slope_inner_edge; ]".. + "image_button[3,0.5;1,1;technic_cnc_pyramid.png;pyramid; ]".. + "image_button[4,0.5;1,1;technic_cnc_spike.png;spike; ]".. + "image_button[5,0.5;1,1;technic_cnc_cylinder.png;cylinder; ]".. + "image_button[6,0.5;1,1;technic_cnc_sphere.png;sphere; ]".. + "image_button[7,0.5;1,1;technic_cnc_stick.png;stick; ]".. + + "image_button[0,1.5;1,1;technic_cnc_slope_upsdwn.png;slope_upsdwn; ]".. + "image_button[1,1.5;1,1;technic_cnc_slope_edge_upsdwn.png;slope_upsdwn_edge; ]".. + "image_button[2,1.5;1,1;technic_cnc_slope_inner_edge_upsdwn.png;slope_upddown_inner_edge; ]".. + "image_button[5,1.5;1,1;technic_cnc_cylinder_horizontal.png;cylinder_horizontal; ]".. + + "image_button[0,2.5;1,1;technic_cnc_slope_lying.png;slope_lying; ]".. + "image_button[1,2.5;1,1;technic_cnc_onecurvededge.png;onecurvededge; ]".. + "image_button[2,2.5;1,1;technic_cnc_twocurvededge.png;twocurvededge; ]".. + + "label[0,3.5;Slim Elements half / normal height:]".. + + "image_button[0,4;1,0.5;technic_cnc_full.png;full; ]".. + "image_button[0,4.5;1,0.5;technic_cnc_half.png;half; ]".. + "image_button[1,4;1,1;technic_cnc_element_straight.png;element_straight; ]".. + "image_button[2,4;1,1;technic_cnc_element_end.png;element_end; ]".. + "image_button[3,4;1,1;technic_cnc_element_cross.png;element_cross; ]".. + "image_button[4,4;1,1;technic_cnc_element_t.png;element_t; ]".. + "image_button[5,4;1,1;technic_cnc_element_edge.png;element_edge; ]".. + + "label[0, 5.5;In:]".. -- showlabelin.. + "list[current_name;input;0.5,5.5;1,1;]".. + "field[3, 6;1,1;num_cncruns;Repeat program:;${num_cncruns}]".. -- Fill default with meta data num_cncruns + "label[4, 5.5;Out:]".. -- showlabelout.. + "list[current_name;output;4.5,5.5;1,1;]".. + + "list[current_player;main;0,7;8,4;]".. + showbackground) + meta:set_string("infotext", "CNC Milling Machine") + meta:set_string("num_cncruns", 1 ); + + local inv = meta:get_inventory() + inv:set_size("input", 1) + inv:set_size("output", 1) + end, + + on_receive_fields = function(pos, formname, fields, sender) + -- REGISTER MILLING PROGRAMMS AND OUTPUTS: + ------------------------------------------ + -- Program for half/full size + if fields["full"] then + size = 1 + return + end + + if fields["half"] then + size = 2 + return + end + + local meta = minetest.env:get_meta(pos) + local inv = meta:get_inventory() + + -- Limit the number entered + if( fields.num_cncruns and tonumber( fields.num_cncruns) > 0 and tonumber(fields.num_cncruns) < 100 ) then + meta:set_string( "num_cncruns", fields.num_cncruns ); + else + minetest.chat_send_player(sender:get_player_name(), "CNC machine runs set to a bad value. Machine resets."); + meta:set_string( "num_cncruns", 1 ); + fields.num_cncruns = 1 + end + + -- Do nothing if the machine is empty + if inv:is_empty("input") then + return + end + + -- Do nothing if the output is not empty and the product used is not the same as what is already there + + -- Resolve the node name and the number of items to make and the number of items to take + local product = "" + local produces = 1 + local input_used = 1 + local inputstack = inv:get_stack("input", 1) + local inputname = inputstack:get_name() + local multiplier = 1 + for k, _ in pairs(fields) do + -- Set a multipier for the half/full size capable blocks + if twosize_products[k] ~= nil then + multiplier = size*twosize_products[k] + else + multiplier = onesize_products[k] + end + + if onesize_products[k] ~= nil or twosize_products[k] ~= nil then + product = inputname .. "_technic_cnc_" .. k + produces = math.min( fields.num_cncruns*multiplier, max_products) -- produce at most max_products + input_used = math.min( math.floor(produces/multiplier), inputstack:get_count()) -- use at most what we got + produces = input_used*multiplier -- final production + print(size) + print(fields.num_cncruns) + print(product) + print(produces) + print(input_used) + print("------------------") + break + end + end + + -- CNC does the transformation + ------------------------------ + if minetest.registered_nodes[product] ~= nil then + inv:add_item("output",product .. " " .. produces) + inputstack:take_item(input_used) + inv:set_stack("input",1,inputstack) + else + minetest.chat_send_player(sender:get_player_name(), "CNC machine does not know how to mill this material. Please remove it."); + end + return; + end, -- callback function + }) +---------- + + +-- Milling Machine Recipe +------------------------- +minetest.register_craft({ + output = 'technic:cnc', + recipe = { + {'default:glass', 'technic:diamond_drill_head', 'default:glass'}, + {'technic:control_logic_unit', 'technic:motor', 'default:steel_ingot'}, + {'default:steel_ingot', 'default:copper_ingot', 'default:steel_ingot'}, + }, + }) +------------------------- \ No newline at end of file diff --git a/technic/cnc_api.lua b/technic/cnc_api.lua new file mode 100644 index 0000000..390a996 --- /dev/null +++ b/technic/cnc_api.lua @@ -0,0 +1,970 @@ +-- API for the technic CNC machine +-- Again code is adapted from the NonCubic Blocks MOD v1.4 by yves_de_beck +technic_cnc_api = {} + +-- HERE YOU CAN CHANGE THE DETAIL-LEVEL: +---------------------------------------- +technic_cnc_api.detail_level = 16 -- 16; 1-32 + +-- HERE YOU CAN DE/ACTIVATE BACKGROUND FOR CNC MENU: +-------------------------------------------------------- +technic_cnc_api.allow_menu_background = false + +-- REGISTER NONCUBIC FORMS, CREATE MODELS AND RECIPES: +------------------------------------------------------ + +-- SLOPE +-------- +function technic_cnc_api.register_slope(recipeitem, groups, images, description) + +local slopebox = {} +local detail = technic_cnc_api.detail_level +for i = 0, detail-1 do + slopebox[i+1]={-0.5, (i/detail)-0.5, (i/detail)-0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5} +end + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = slopebox, + }, + groups = groups, + }) +end + + +-- SLOPE Lying +---------------- +function technic_cnc_api.register_slope_lying(recipeitem, groups, images, description) + +local slopeboxlying = {} +local detail = technic_cnc_api.detail_level +for i = 0, detail-1 do + slopeboxlying[i+1]={(i/detail)-0.5, -0.5, (i/detail)-0.5, (i/detail)-0.5+(1/detail), 0.5 , 0.5} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_lying", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = slopeboxlying, + }, + groups = groups, + }) + minetest.register_craft({ + output = recipeitem .. "_technic_cnc_slope_lying 1", + recipe = { + {"", "", ""}, + {"", recipeitem .. "_technic_cnc_slope", ""}, + {"", "", ""}, + }, + }) + +end + + +-- SLOPE UPSIDE DOWN +-------------------- +function technic_cnc_api.register_slope_upsdown(recipeitem, groups, images, description) + +if subname == "dirt" then +return +end + +local slopeupdwnbox = {} +local detail = technic_cnc_api.detail_level +for i = 0, detail-1 do + slopeupdwnbox[i+1]={-0.5, (i/detail)-0.5, (-1*(i/detail))+0.5-(1/detail), 0.5, (i/detail)-0.5+(1/detail), 0.5} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_upsdown", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = slopeupdwnbox, + }, + groups = groups, + }) +end + + +-- SLOPE EDGE +------------- +function technic_cnc_api.register_slope_edge(recipeitem, groups, images, description) + +local slopeboxedge = {} +local detail = technic_cnc_api.detail_level +for i = 0, detail-1 do + slopeboxedge[i+1]={(i/detail)-0.5, -0.5, (i/detail)-0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_edge", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = slopeboxedge, + }, + groups = groups, + }) +end + + +-- SLOPE INNER EDGE +------------------- +function technic_cnc_api.register_slope_inner_edge(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_inner_edge", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = { + -- PART 1 + {-0.5, -0.5, -0.5, 0.5, -0.45, 0.5}, + {-0.45, -0.5, -0.5, 0.5, -0.4, 0.5}, + {-0.4, -0.5, -0.5, 0.5, -0.35, 0.5}, + {-0.35, -0.5, -0.5, 0.5, -0.3, 0.5}, + {-0.3, -0.5, -0.5, 0.5, -0.25, 0.5}, + {-0.25, -0.5, -0.5, 0.5, -0.2, 0.5}, + {-0.2, -0.5, -0.5, 0.5, -0.15, 0.5}, + {-0.15, -0.5, -0.5, 0.5, -0.1, 0.5}, + {-0.1, -0.5, -0.5, 0.5, -0.05, 0.5}, + {-0.05, -0.5, -0.5, 0.5, 0, 0.5}, + {0, -0.5, -0.5, 0.5, 0.05, 0.5}, + {0.05, -0.5, -0.5, 0.5, 0.1, 0.5}, + {0.1, -0.5, -0.5, 0.5, 0.15, 0.5}, + {0.15, -0.5, -0.5, 0.5, 0.2, 0.5}, + {0.2, -0.5, -0.5, 0.5, 0.25, 0.5}, + {0.25, -0.5, -0.5, 0.5, 0.3, 0.5}, + {0.3, -0.5, -0.5, 0.5, 0.35, 0.5}, + {0.35, -0.5, -0.5, 0.5, 0.4, 0.5}, + {0.4, -0.5, -0.5, 0.5, 0.45, 0.5}, + {0.45, -0.5, -0.5, 0.5, 0.5, 0.5}, + -- PART 2 + {-0.5, -0.5, -0.45, 0.5, -0.45, 0.5}, + {-0.5, -0.5, -0.4, 0.5, -0.4, 0.5}, + {-0.5, -0.5, -0.35, 0.5, -0.35, 0.5}, + {-0.5, -0.5, -0.3, 0.5, -0.3, 0.5}, + {-0.5, -0.5, -0.25, 0.5, -0.25, 0.5}, + {-0.5, -0.5, -0.2, 0.5, -0.2, 0.5}, + {-0.5, -0.5, -0.15, 0.5, -0.15, 0.5}, + {-0.5, -0.5, -0.1, 0.5, -0.1, 0.5}, + {-0.5, -0.5, -0.05, 0.5, -0.05, 0.5}, + {-0.5, -0.5, 0, 0.5, 0, 0.5}, + {-0.5, -0.5, 0.05, 0.5, 0.05, 0.5}, + {-0.5, -0.5, 0.1, 0.5, 0.1, 0.5}, + {-0.5, -0.5, 0.15, 0.5, 0.15, 0.5}, + {-0.5, -0.5, 0.2, 0.5, 0.2, 0.5}, + {-0.5, -0.5, .25, 0.5, 0.25, 0.5}, + {-0.5, -0.5, 0.3, 0.5, 0.3, 0.5}, + {-0.5, -0.5, 0.35, 0.5, 0.35, 0.5}, + {-0.5, -0.5, 0.4, 0.5, 0.4, 0.5}, + {-0.5, -0.5, 0.45, 0.5, 0.45, 0.5}, + {-0.5, -0.5, 0.5, 0.5, 0.5, 0.5}, + }, + }, + groups = groups, + }) +end + + +-- SLOPE EDGE UPSIDE DOWN +------------------------- +function technic_cnc_api.register_slope_upsdown_edge(recipeitem, groups, images, description) + +if recipeitem == "default:dirt" then + return +end + +local slopeupdwnboxedge = {} +local detail = technic_cnc_api.detail_level +for i = 0, detail-1 do + slopeupdwnboxedge[i+1]={(-1*(i/detail))+0.5-(1/detail), (i/detail)-0.5, (-1*(i/detail))+0.5-(1/detail), 0.5, (i/detail)-0.5+(1/detail), 0.5} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_upsdown_edge", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = slopeupdwnboxedge, + }, + groups = groups, + }) +end + + +-- SLOPE INNER EDGE UPSIDE DOWN +------------------------------- +function technic_cnc_api.register_slope_upsdown_inner_edge(recipeitem, groups, images, description) + +if recipename == "default:dirt" then +return +end + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_upsdown_inner_edge", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = { + {0.45, -0.5, -0.5, 0.5, -0.45, 0.5}, + {0.4, -0.45, -0.5, 0.5, -0.4, 0.5}, + {0.35, -0.4, -0.5, 0.5, -0.35, 0.5}, + {0.3, -0.35, -0.5, 0.5, -0.3, 0.5}, + {0.25, -0.3, -0.5, 0.5, -0.25, 0.5}, + {0.2, -0.25, -0.5, 0.5, -0.2, 0.5}, + {0.15, -0.2, -0.5, 0.5, -0.15, 0.5}, + {0.1, -0.15, -0.5, 0.5, -0.1, 0.5}, + {0.05, -0.1, -0.5, 0.5, -0.05, 0.5}, + {0, -0.05, -0.5, 0.5, 0, 0.5}, + {-0.05, 0, -0.5, 0.5, 0.05, 0.5}, + {-0.1, 0.05, -0.5, 0.5, 0.1, 0.5}, + {-0.15, 0.1, -0.5, 0.5, 0.15, 0.5}, + {-0.2, 0.15, -0.5, 0.5, 0.2, 0.5}, + {-0.25, 0.2, -0.5, 0.5, 0.25, 0.5}, + {-0.3, 0.25, -0.5, 0.5, 0.3, 0.5}, + {-0.35, 0.3, -0.5, 0.5, 0.35, 0.5}, + {-0.4, 0.35, -0.5, 0.5, 0.4, 0.5}, + {-0.45, 0.4, -0.5, 0.5, 0.45, 0.5}, + {-0.5, 0.45, -0.5, 0.5, 0.5, 0.5}, + + {-0.5, -0.5, 0.45, 0.5, -0.45, 0.5}, + {-0.5, -0.45, 0.4, 0.5, -0.4, 0.5}, + {-0.5, -0.4, 0.35, 0.5, -0.35, 0.5}, + {-0.5, -0.35, 0.3, 0.5, -0.3, 0.5}, + {-0.5, -0.3, 0.25, 0.5, -0.25, 0.5}, + {-0.5, -0.25, 0.2, 0.5, -0.2, 0.5}, + {-0.5, -0.2, 0.15, 0.5, -0.15, 0.5}, + {-0.5, -0.15, 0.1, 0.5, -0.1, 0.5}, + {-0.5, -0.1, 0.05, 0.5, -0.05, 0.5}, + {-0.5, -0.05, 0, 0.5, 0, 0.5}, + {-0.5, 0, -0.05, 0.5, 0.05, 0.5}, + {-0.5, 0.05, -0.1, 0.5, 0.1, 0.5}, + {-0.5, 0.1, -0.15, 0.5, 0.15, 0.5}, + {-0.5, 0.15, -0.2, 0.5, 0.2, 0.5}, + {-0.5, 0.2, -0.25, 0.5, 0.25, 0.5}, + {-0.5, 0.25, -0.3, 0.5, 0.3, 0.5}, + {-0.5, 0.3, -0.35, 0.5, 0.35, 0.5}, + {-0.5, 0.35, -0.4, 0.5, 0.4, 0.5}, + {-0.5, 0.4, -0.45, 0.5, 0.45, 0.5}, + {-0.5, 0.45, -0.5, 0.5, 0.5, 0.5}, + + }, + }, + groups = groups, + }) +end + + +-- PYRAMID +---------- +function technic_cnc_api.register_pyramid(recipeitem, groups, images, description) + +local pyrabox = {} +local detail = technic_cnc_api.detail_level/2 +for i = 0, detail-1 do + pyrabox[i+1]={(i/detail/2)-0.5, (i/detail/2)-0.5, (i/detail/2)-0.5, 0.5-(i/detail/2), (i/detail/2)-0.5+(1/detail), 0.5-(i/detail/2)} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_pyramid", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + }, + node_box = { + type = "fixed", + fixed = pyrabox, + }, + groups = groups, + }) +end + + +-- SPIKE +-------- +function technic_cnc_api.register_spike(recipeitem, groups, images, description) + +if recipename == "default:dirt" then + return +end + +local spikebox = {} +local detail = technic_cnc_api.detail_level +for i = 0, detail-1 do + spikebox[i+1]={(i/detail/2)-0.5, (i/detail/2)-0.5, (i/detail/2)-0.5, 0.5-(i/detail/2), (i/detail)-0.5+(1/detail), 0.5-(i/detail/2)} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_spike", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = spikebox, + }, + groups = groups, + }) +end + + +-- Block one curved edge +------------------------ +function technic_cnc_api.register_onecurvededge(recipeitem, groups, images, description) + +local quartercyclebox = {} +local detail = technic_cnc_api.detail_level*2 +local sehne +for i = (detail/2)-1, detail-1 do + sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) + quartercyclebox[i]={-0.5, -0.5, -sehne, 0.5, (i/detail)+(1/detail)-0.5, 0.5} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_onecurvededge", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = quartercyclebox, + }, + groups = groups, + }) +end + + +-- Block two curved edges +------------------------- +function technic_cnc_api.register_twocurvededge(recipeitem, groups, images, description) + +local quartercyclebox2 = {} +local detail = technic_cnc_api.detail_level*2 +local sehne +for i = (detail/2)-1, detail-1 do + sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) + quartercyclebox2[i]={-sehne, -0.5, -sehne, 0.5, (i/detail)+(1/detail)-0.5, 0.5} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_twocurvededge", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = quartercyclebox2, + }, + groups = groups, + }) + minetest.register_craft({ + output = recipeitem .. "_technic_cnc_twocurvededge 3", + recipe = { + {"", "", ""}, + {recipeitem .. "_technic_cnc_onecurvededge", "", ""}, + {recipeitem .. "_technic_cnc_onecurvededge", recipeitem .. "_technic_cnc_onecurvededge", ""}, + }, + }) + +end + +-- Cylinder +----------- +function technic_cnc_api.register_cylinder(recipeitem, groups, images, description) + +if recipename == "default:dirt" then +return +end + +local cylbox = {} +local detail = technic_cnc_api.detail_level +local sehne +for i = 1, detail-1 do + sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) + cylbox[i]={(i/detail)-0.5, -0.5, -sehne, (i/detail)+(1/detail)-0.5, 0.5, sehne} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_cylinder", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = cylbox, + }, + groups = groups, + }) + minetest.register_craft({ + output = recipeitem .. "_technic_cnc_cylinder 1", + recipe = { + {"", "", ""}, + {"", recipeitem .. "_technic_cnc_cylinder_horizontal", ""}, + {"", "", ""}, + }, + }) + +end + + +-- Cylinder Horizontal +---------------------- +function technic_cnc_api.register_cylinder_horizontal(recipeitem, groups, images, description) + +if recipename == "default:dirt" then + return +end + +local cylbox_horizontal = {} +local detail = technic_cnc_api.detail_level +local sehne +for i = 1, detail-1 do + sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) + cylbox_horizontal[i]={-0.5, (i/detail)-0.5, -sehne, 0.5, (i/detail)+(1/detail)-0.5, sehne} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_cylinder_horizontal", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = cylbox_horizontal, + }, + groups = groups, + }) + minetest.register_craft({ + output = recipeitem .. "_technic_cnc_cylinder_horizontal 1", + recipe = { + {"", "", ""}, + {"", recipeitem .. "_technic_cnc_cylinder", ""}, + {"", "", ""}, + }, + }) +end + + +-- Sphere +--------- +function technic_cnc_api.register_sphere(recipeitem, groups, images, description) + +if recipename == "default:dirt" then + return +end + +local spherebox = {} +local detail = technic_cnc_api.detail_level +local sehne +for i = 1, detail-1 do + sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) + spherebox[i]={-sehne, (i/detail)-0.5, -sehne, sehne, (i/detail)+(1/detail)-0.5, sehne} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_cylinder_sphere", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = spherebox, + }, + groups = groups, + }) +end + + +-- Element straight +------------------- +function technic_cnc_api.register_element_straight(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_straight", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.5, 0.3, 0, 0.5}, + }, + node_box = { + type = "fixed", + fixed = { + {-0.3, -0.5, -0.5, 0.3, 0, 0.5}, + }, + }, + groups = groups, + }) +end + + +-- Element Edge +--------------- +function technic_cnc_api.register_element_edge(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_edge", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = { + {-0.3, -0.5, -0.5, 0.3, 0, 0.3}, + {-0.5, -0.5, -0.3, -0.3, 0, 0.3}, + }, + }, + node_box = { + type = "fixed", + fixed = { + {-0.3, -0.5, -0.5, 0.3, 0, 0.3}, + {-0.5, -0.5, -0.3, -0.3, 0, 0.3}, + }, + }, + groups = groups, + }) +end + + +-- Element T +------------ +function technic_cnc_api.register_element_t(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_t", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = { + {-0.3, -0.5, -0.5, 0.3, 0, 0.3}, + {-0.5, -0.5, -0.3, -0.3, 0, 0.3}, + {0.3, -0.5, -0.3, 0.5, 0, 0.3}, + }, + }, + node_box = { + type = "fixed", + fixed = { + {-0.3, -0.5, -0.5, 0.3, 0, 0.3}, + {-0.5, -0.5, -0.3, -0.3, 0, 0.3}, + {0.3, -0.5, -0.3, 0.5, 0, 0.3}, + }, + }, + groups = groups, + }) +end + + +-- Element Cross +---------------- +function technic_cnc_api.register_element_cross(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_cross", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = { + {0.3, -0.5, -0.3, 0.5, 0, 0.3}, + {-0.3, -0.5, -0.5, 0.3, 0, 0.5}, + {-0.5, -0.5, -0.3, -0.3, 0, 0.3}, + }, + }, + node_box = { + type = "fixed", + fixed = { + {0.3, -0.5, -0.3, 0.5, 0, 0.3}, + {-0.3, -0.5, -0.5, 0.3, 0, 0.5}, + {-0.5, -0.5, -0.3, -0.3, 0, 0.3}, + }, + }, + groups = groups, + }) +end + + +-- Element End +-------------- +function technic_cnc_api.register_element_end(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_end", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, 0, 0.5}, + }, + node_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, 0, 0.5}, + }, + groups = groups, + }) +end + + +-- Element straight DOUBLE +-------------------------- +function technic_cnc_api.register_element_straight_double(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_straight_double", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.5, 0.3, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = { + {-0.3, -0.5, -0.5, 0.3, 0.5, 0.5}, + }, + }, + groups = groups, + }) + minetest.register_craft({ + output = recipeitem .. "_technic_cnc_element_straight_double 1", + recipe = { + {"", "", ""}, + {"", recipeitem .. "_technic_cnc_element_straight", ""}, + {"", recipeitem .. "_technic_cnc_element_straight", ""}, + }, + }) +end + + +-- Element Edge DOUBLE +---------------------- +function technic_cnc_api.register_element_edge_double(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_edge_double", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = { + {-0.3, -0.5, -0.5, 0.3, 0.5, 0.3}, + {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}, + }, + }, + node_box = { + type = "fixed", + fixed = { + {-0.3, -0.5, -0.5, 0.3, 0.5, 0.3}, + {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}, + }, + }, + groups = groups, + }) + minetest.register_craft({ + output = recipeitem .. "_technic_cnc_element_edge_double 1", + recipe = { + {"", "", ""}, + {"", recipeitem .. "_technic_cnc_element_edge", ""}, + {"", recipeitem .. "_technic_cnc_element_edge", ""}, + }, + }) +end + + +-- Element T DOUBLE +------------------- +function technic_cnc_api.register_element_t_double(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_t_double", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = { + {-0.3, -0.5, -0.5, 0.3, 0.5, 0.3}, + {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}, + {0.3, -0.5, -0.3, 0.5, 0.5, 0.3}, + }, + }, + node_box = { + type = "fixed", + fixed = { + {-0.3, -0.5, -0.5, 0.3, 0.5, 0.3}, + {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}, + {0.3, -0.5, -0.3, 0.5, 0.5, 0.3}, + }, + }, + groups = groups, + }) + minetest.register_craft({ + output = recipeitem .. "_technic_cnc_element_t_double 1", + recipe = { + {"", "", ""}, + {"", recipeitem .. "_technic_cnc_element_t", ""}, + {"", recipeitem .. "_technic_cnc_element_t", ""}, + }, + }) +end + + +-- Element Cross Double +----------------------- +function technic_cnc_api.register_element_cross_double(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_cross_double", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = { + {0.3, -0.5, -0.3, 0.5, 0.5, 0.3}, + {-0.3, -0.5, -0.5, 0.3, 0.5, 0.5}, + {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}, + }, + }, + node_box = { + type = "fixed", + fixed = { + {0.3, -0.5, -0.3, 0.5, 0.5, 0.3}, + {-0.3, -0.5, -0.5, 0.3, 0.5, 0.5}, + {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}, + }, + }, + groups = groups, + }) + minetest.register_craft({ + output = recipeitem .. "_technic_cnc_element_cross_double 1", + recipe = { + {"", "", ""}, + {"", recipeitem .. "_technic_cnc_element_cross", ""}, + {"", recipeitem .. "_technic_cnc_element_cross", ""}, + }, + }) + +end + + +-- Element End Double +--------------------- +function technic_cnc_api.register_element_end_double(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_end_double", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, 0.5, 0.5}, + }, + groups = groups, + }) + minetest.register_craft({ + output = recipeitem .. "_technic_cnc_element_end_double 1", + recipe = { + {"", "", ""}, + {"", recipeitem .. "_technic_cnc_element_end", ""}, + {"", recipeitem .. "_technic_cnc_element_end", ""}, + }, + }) +end + + +-- STICK +-------- +function technic_cnc_api.register_stick(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_stick", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.15, -0.5, -0.15, 0.15, 0.5, 0.15}, + }, + node_box = { + type = "fixed", + fixed = {-0.15, -0.5, -0.15, 0.15, 0.5, 0.15}, + }, + groups = groups, + }) + minetest.register_craft({ + output = recipeitem .. "_technic_cnc_stick 8", + recipe = { + {'default:stick', "", ""}, + {"", "", ""}, + {recipeitem, "", ""}, + }, + }) +end + + + +-- REGISTER NEW TECHNIC_CNC_API's PART 2: technic_cnc_api.register_element_end(subname, recipeitem, groups, images, desc_element_xyz) +----------------------------------------------------------------------------------------------------------------------- +function technic_cnc_api.register_slope_edge_etc(recipeitem, groups, images, desc_slope, desc_slope_lying, desc_slope_upsdown, desc_slope_edge, desc_slope_inner_edge, desc_slope_upsdwn_edge, desc_slope_upsdwn_inner_edge, desc_pyramid, desc_spike, desc_onecurvededge, desc_twocurvededge, desc_cylinder, desc_cylinder_horizontal, desc_sphere, desc_element_straight, desc_element_edge, desc_element_t, desc_element_cross, desc_element_end) + + technic_cnc_api.register_slope(recipeitem, groups, images, desc_slope) + technic_cnc_api.register_slope_lying(recipeitem, groups, images, desc_slope_lying) + technic_cnc_api.register_slope_upsdown(recipeitem, groups, images, desc_slope_upsdown) + technic_cnc_api.register_slope_edge(recipeitem, groups, images, desc_slope_edge) + technic_cnc_api.register_slope_inner_edge(recipeitem, groups, images, desc_slope_inner_edge) + technic_cnc_api.register_slope_upsdown_edge(recipeitem, groups, images, desc_slope_upsdwn_edge) + technic_cnc_api.register_slope_upsdown_inner_edge(recipeitem, groups, images, desc_slope_upsdwn_inner_edge) + technic_cnc_api.register_pyramid(recipeitem, groups, images, desc_pyramid) + technic_cnc_api.register_spike(recipeitem, groups, images, desc_spike) + technic_cnc_api.register_onecurvededge(recipeitem, groups, images, desc_onecurvededge) + technic_cnc_api.register_twocurvededge(recipeitem, groups, images, desc_twocurvededge) + technic_cnc_api.register_cylinder(recipeitem, groups, images, desc_cylinder) + technic_cnc_api.register_cylinder_horizontal(recipeitem, groups, images, desc_cylinder_horizontal) + technic_cnc_api.register_sphere(recipeitem, groups, images, desc_sphere) + technic_cnc_api.register_element_straight(recipeitem, groups, images, desc_element_straight) + technic_cnc_api.register_element_edge(recipeitem, groups, images, desc_element_edge) + technic_cnc_api.register_element_t(recipeitem, groups, images, desc_element_t) + technic_cnc_api.register_element_cross(recipeitem, groups, images, desc_element_cross) + technic_cnc_api.register_element_end(recipeitem, groups, images, desc_element_end) +end + +-- REGISTER STICKS: noncubic.register_xyz(recipeitem, groups, images, desc_element_xyz) +------------------------------------------------------------------------------------------------------------ +function technic_cnc_api.register_stick_etc(recipeitem, groups, images, desc_stick) + technic_cnc_api.register_stick(recipeitem, groups, images, desc_stick) +end + +function technic_cnc_api.register_elements(recipeitem, groups, images, desc_element_straight_double, desc_element_edge_double, desc_element_t_double, desc_element_cross_double, desc_element_end_double) + technic_cnc_api.register_element_straight_double(recipeitem, groups, images, desc_element_straight_double) + technic_cnc_api.register_element_edge_double(recipeitem, groups, images, desc_element_edge_double) + technic_cnc_api.register_element_t_double(recipeitem, groups, images, desc_element_t_double) + technic_cnc_api.register_element_cross_double(recipeitem, groups, images, desc_element_cross_double) + technic_cnc_api.register_element_end_double(recipeitem, groups, images, desc_element_end_double) +end diff --git a/technic/cnc_nodes.lua b/technic/cnc_nodes.lua new file mode 100644 index 0000000..2f375a5 --- /dev/null +++ b/technic/cnc_nodes.lua @@ -0,0 +1,354 @@ +-- REGISTER MATERIALS AND PROPERTIES FOR NONCUBIC ELEMENTS: +----------------------------------------------------------- + +-- WOOD +------- +technic_cnc_api.register_slope_edge_etc("default:wood", + {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, + {"default_wood.png"}, + "Wooden Slope", + "Wooden Slope Lying", + "Wooden Slope Upside Down", + "Wooden Slope Edge", + "Wooden Slope Inner Edge", + "Wooden Slope Upside Down Edge", + "Wooden Slope Upside Down Inner Edge", + "Wooden Pyramid", + "Wooden Spike", + "Wooden One Curved Edge Block", + "Wooden Two Curved Edge Block", + "Wooden Cylinder", + "Wooden Cylinder Horizontal", + "Wooden Sphere", + "Wooden Element Straight", + "Wooden Element Edge", + "Wooden Element T", + "Wooden Element Cross", + "Wooden Element End") +-- STONE +-------- +technic_cnc_api.register_slope_edge_etc("default:stone", + {cracky=3,not_in_creative_inventory=1}, + {"default_stone.png"}, + "Stone Slope", + "Stone Slope Lying", + "Stone Slope Upside Down", + "Stone Slope Edge", + "Stone Slope Inner Edge", + "Stone Slope Upside Down Edge", + "Stone Slope Upside Down Inner Edge", + "Stone Pyramid", + "Stone Spike", + "Stone One Curved Edge Block", + "Stone Two Curved Edge Block", + "Stone Cylinder", + "Stote Cylinder Horizontal", + "Stone Sphere", + "Stone Element Straight", + "Stone Element Edge", + "Stone Element T", + "Stone Element Cross", + "Stone Element End") +-- COBBLE +--------- +technic_cnc_api.register_slope_edge_etc("default:cobble", + {cracky=3,not_in_creative_inventory=1}, + {"default_cobble.png"}, + "Cobble Slope", + "Cobble Slope Lying", + "Cobble Slope Upside Down", + "Cobble Slope Edge", + "Cobble Slope Inner Edge", + "Cobble Slope Upside Down Edge", + "Cobble Slope Upside Down Inner Edge", + "Cobble Pyramid", + "Cobble Spike", + "Cobble One Curved Edge Block", + "Cobble Two Curved Edge Block", + "Cobble Cylinder", + "Cobble Cylinder Horizontal", + "Cobble Sphere", + "Cobble Element Straight", + "Cobble Element Edge", + "Cobble Element T", + "Cobble Element Cross", + "Cobble Element End") +-- BRICK +-------- +technic_cnc_api.register_slope_edge_etc("default:brick", + {cracky=3,not_in_creative_inventory=1}, + {"default_brick.png"}, + "Brick Slope", + "Brick Slope Upside Down", + "Brick Slope Edge", + "Brick Slope Inner Edge", + "Brick Slope Upside Down Edge", + "Brick Slope Upside Down Inner Edge", + "Brick Pyramid", + "Brick Spike", + "Brick One Curved Edge Block", + "Brick Two Curved Edge Block", + "Brick Cylinder", + "Brick Cylinder Horizontal", + "Brick Sphere", + "Brick Element Straight", + "Brick Element Edge", + "Brick Element T", + "Brick Element Cross", + "Brick Element End") +-- SANDSTONE +------------ +technic_cnc_api.register_slope_edge_etc("default:sandstone", + {crumbly=2,cracky=2,not_in_creative_inventory=1}, + {"default_sandstone.png"}, + "Sandstone Slope", + "Sandstone Slope Lying", + "Sandstone Slope Upside Down", + "Sandstone Slope Edge", + "Sandstone Slope Inner Edge", + "Sandstone Slope Upside Down Edge", + "Sandstone Slope Upside Down Inner Edge", + "Sandstone Pyramid", + "Sandstone Spike", + "Sandstone One Curved Edge Block", + "Sandstone Two Curved Edge Block", + "Sandstone Cylinder", + "Sandstone Cylinder Horizontal", + "Sandstone Sphere", + "Sandstone Element Straight", + "Sandstone Element Edge", + "Sandstone Element T", + "Sandstone Element Cross", + "Sandstone Element End") +-- LEAVES +--------- +technic_cnc_api.register_slope_edge_etc("default:leaves", + {snappy=2,choppy=2,oddly_breakable_by_hand=3,not_in_creative_inventory=1}, + {"bucharest_tree.png"}, + "Leaves Slope", + "Leaves Slope Lying", + "Leaves Slope Upside Down", + "Leaves Slope Edge", + "Leaves Slope Inner Edge", + "Leaves Slope Upside Down Edge", + "Leaves Slope Upside Down Inner Edge", + "Leaves Pyramid", + "Leaves Spike", + "Leaves One Curved Edge Block", + "Leaves Two Curved Edge Block", + "Leaves Cylinder", + "Leaves Cylinder Horizontal", + "Leaves Sphere", + "Leaves Element Straight", + "Leaves Element Edge", + "Leaves Element T", + "Leaves Element Cross", + "Leaves Element End") +-- DIRT +------- +technic_cnc_api.register_slope_edge_etc("default:dirt", + {snappy=2,choppy=2,oddly_breakable_by_hand=3,not_in_creative_inventory=1}, + {"default_grass.png", "default_dirt.png", "default_grass.png"}, + "Dirt Slope", + "Dirt Slope Lying", + "Dirt Slope Upside Down", + "Dirt Slope Edge", + "Dirt Slope Inner Edge", + "Dirt Slope Upside Down Edge", + "Dirt Slope Upside Down Inner Edge", + "Dirt Pyramid", + "Dirt Spike", + "Dirt One Curved Edge Block", + "Dirt Two Curved Edge Block", + "Dirt Cylinder", + "Dirt Cylinder Horizontal", + "Dirt Sphere", + "Dirt Element Straight", + "Dirt Element Edge", + "Dirt Element T", + "Dirt Element Cross", + "Dirt Element End") +-- TREE +------- +technic_cnc_api.register_slope_edge_etc("default:tree", + {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,not_in_creative_inventory=1}, + {"default_tree.png"}, + "Tree Slope", + "Tree Slope Lying", + "Tree Slope Upside Down", + "Tree Slope Edge", + "Tree Slope Inner Edge", + "Tree Slope Upside Down Edge", + "Tree Slope Upside Down Inner Edge", + "Tree Pyramid", + "Tree Spike", + "Tree One Curved Edge Block", + "Tree Two Curved Edge Block", + "Tree Cylinder", + "Tree Cylinder Horizontal", + "Tree Sphere", + "Tree Element Straight", + "Tree Element Edge", + "Tree Element T", + "Tree Element Cross", + "Tree Element End") +-- STEEL +-------- +technic_cnc_api.register_slope_edge_etc("default:steelblock", + {snappy=1,bendy=2,cracky=1,melty=2,level=2,not_in_creative_inventory=1}, + {"default_steel_block.png"}, + "Steel Slope", + "Steel Slope Lying", + "Steel Slope Upside Down", + "Steel Slope Edge", + "Steel Slope Inner Edge", + "Steel Slope Upside Down Edge", + "Steel Slope Upside Down Inner Edge", + "Steel Pyramid", + "Steel Spike", + "Steel One Curved Edge Block", + "Steel Two Curved Edge Block", + "Steel Cylinder", + "Steel Cylinder Horizontal", + "Steel Sphere", + "Steel Element Straight", + "Steel Element Edge", + "Steel Element T", + "Steel Element Cross", + "Steel Element End") + +-- REGISTER MATERIALS AND PROPERTIES FOR STICKS: +------------------------------------------------ + +-- WOOD +------- +technic_cnc_api.register_stick_etc("default:wood", + {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, + {"default_wood.png"}, + "Wooden Stick") +-- STONE +-------- +technic_cnc_api.register_stick_etc("default:stone", + {cracky=3,not_in_creative_inventory=1}, + {"default_stone.png"}, + "Stone Stick") +-- COBBLE +--------- +technic_cnc_api.register_stick_etc("default:cobble", + {cracky=3,not_in_creative_inventory=1}, + {"default_cobble.png"}, + "Cobble Stick") +-- BRICK +-------- +technic_cnc_api.register_stick_etc("default:brick", + {cracky=3,not_in_creative_inventory=1}, + {"default_brick.png"}, + "Brick Stick") +-- SANDSTONE +------------ +technic_cnc_api.register_stick_etc("default:sandstone", + {crumbly=2,cracky=2,not_in_creative_inventory=1}, + {"default_sandstone.png"}, + "Sandstone Stick") +-- LEAVES +--------- +technic_cnc_api.register_stick_etc("default:leaves", + {snappy=2,choppy=2,oddly_breakable_by_hand=3,not_in_creative_inventory=1}, + {"bucharest_tree.png"}, + "Leaves Stick") +-- TREE +------- +technic_cnc_api.register_stick_etc("default:tree", + {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1,not_in_creative_inventory=1}, + {"default_tree.png"}, + "Tree Stick") +-- STEEL +-------- +technic_cnc_api.register_stick_etc("default:steelblock", + {snappy=1,bendy=2,cracky=1,melty=2,level=2,not_in_creative_inventory=1}, + {"default_steel_block.png"}, + "Steel Stick") + +-- REGISTER MATERIALS AND PROPERTIES FOR HALF AND NORMAL HEIGHT ELEMENTS: +------------------------------------------------------------------------- + +-- WOOD +------- +technic_cnc_api.register_elements("default:wood", + {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, + {"default_wood.png"}, + "Wooden Element Straight Double", + "Wooden Element Edge Double", + "Wooden Element T Double", + "Wooden Element Cross Double", + "Wooden Element End Double") +-- STONE +-------- +technic_cnc_api.register_elements("default:stone", + {cracky=3,not_in_creative_inventory=1}, + {"default_stone.png"}, + "Stone Element Straight Double", + "Stone Element Edge Double", + "Stone Element T Double", + "Stone Element Cross Double", + "Stone Element End Double") +-- COBBLE +--------- +technic_cnc_api.register_elements("default:cobble", + {cracky=3,not_in_creative_inventory=1}, + {"default_cobble.png"}, + "Cobble Element Straight Double", + "Cobble Element Edge Double", + "Cobble Element T Double", + "Cobble Element Cross Double", + "Cobble Element End Double") +-- BRICK +-------- +technic_cnc_api.register_elements("default:brick", + {cracky=3,not_in_creative_inventory=1}, + {"default_brick.png"}, + "Brick Element Straight Double", + "Brick Element Edge Double", + "Brick Element T Double", + "Brick Element Cross Double", + "Brick Element End Double") +-- SANDSTONE +------------ +technic_cnc_api.register_elements("default:sandstone", + {crumbly=2,cracky=2,not_in_creative_inventory=1}, + {"default_sandstone.png"}, + "Sandstone Element Straight Double", + "Sandstone Element Edge Double", + "Sandstone Element T Double", + "Sandstone Element Cross Double", + "Sandstone Element End Double") +-- LEAVES +--------- +technic_cnc_api.register_elements("default:leaves", + {snappy=2,choppy=2,oddly_breakable_by_hand=3,not_in_creative_inventory=1}, + {"bucharest_tree.png"}, + "Leaves Element Straight Double", + "Leaves Element Edge Double", + "Leaves Element T Double", + "Leaves Element Cross Double", + "Leaves Element End Double") +-- TREE +------- +technic_cnc_api.register_elements("default:tree", + {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1,not_in_creative_inventory=1}, + {"default_tree.png"}, + "Tree Element Straight Double", + "Tree Element Edge Double", + "Tree Element T Double", + "Tree Element Cross Double", + "Tree Element End Double") +-- STEEL +-------- +technic_cnc_api.register_elements("default:steel", + {snappy=1,bendy=2,cracky=1,melty=2,level=2,not_in_creative_inventory=1}, + {"default_steel_block.png"}, + "Steel Element Straight Double", + "Steel Element Edge Double", + "Steel Element T Double", + "Steel Element Cross Double", + "Steel Element End Double") diff --git a/technic/init.lua b/technic/init.lua index 58e0488..ff904e2 100644 --- a/technic/init.lua +++ b/technic/init.lua @@ -2,6 +2,8 @@ -- namespace: technic -- (c) 2012-2013 by RealBadAngel +technic = {} + modpath=minetest.get_modpath("technic") --Read technic config file @@ -25,6 +27,9 @@ dofile(modpath.."/tool_workshop.lua") dofile(modpath.."/music_player.lua") dofile(modpath.."/generator.lua") dofile(modpath.."/grinder.lua") +dofile(modpath.."/cnc.lua") +dofile(modpath.."/cnc_api.lua") +dofile(modpath.."/cnc_nodes.lua") --MV machines dofile(modpath.."/wires_mv.lua") @@ -34,10 +39,13 @@ dofile(modpath.."/electric_furnace_mv.lua") dofile(modpath.."/alloy_furnace_mv.lua") dofile(modpath.."/forcefield.lua") +--HV machines +dofile(modpath.."/wires_hv.lua") + --Tools -if enable_mining_drill==true then dofile(modpath.."/mining_drill.lua") end -if enable_mining_laser==true then dofile(modpath.."/mining_laser_mk1.lua") end -if enable_flashlight==true then dofile(modpath.."/flashlight.lua") end +if technic.config:getBool("enable_mining_drill") then dofile(modpath.."/mining_drill.lua") end +if technic.config:getBool("enable_mining_laser") then dofile(modpath.."/mining_laser_mk1.lua") end +if technic.config:getBool("enable_flashlight") then dofile(modpath.."/flashlight.lua") end dofile(modpath.."/cans.lua") dofile(modpath.."/chainsaw.lua") dofile(modpath.."/tree_tap.lua") diff --git a/technic/textures/technic_cnc_bottom.png b/technic/textures/technic_cnc_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..e600cb1de24947b81b8bdc0111b8efa44becf544 GIT binary patch literal 2006 zcmV;{2Pyc8P){yZmA))XA8$k7>e}Zi^~&|*Y(24ND_c*?8teR>QtoT5eHo{I8*hEv z_Wtg(TkCnv>^1lEaq&C%Ii7S@53bW2RR^- zjk*#gXfub1e9in`6W>cOnaGzE|D~3`meSjGL>8A-&}0Q*0@`@KwWDVMB*2Wr#QH73 ze`R3hM`4rUZRpc&>N5)ysl4AG&@lFok2_f+ZDe6Tj(%Qyf4jYr3DZCKykrh1LQ-A; zkO5f%Rts4Z1kvV9)MQ6W%yi}Z7XTwJpqk*Y5cyU}c_Dr9beu=%qSYP#=2(}}gdEno zaou#bpk;)%3VlW|t%d8-DVUS&x_3fbW@UJPe*riTxM9N$#CIYrA_qWiXQcduGqbd? zW|`~CiON3G{QT{HD^;_x&&u@`@b3Krz-Fdb zF-_wLLjH+h0Zjg)q@WEVAzSS@p@B3bE;-)!gH6{ss35?u` z%K9Y{tR>7IUjQ}^Rd_282w<9qrwF}nREm` zSR71c6rO7bV5EU8x!*ScPi{1jV&ntqCsheLRBmR2hMBlVg-2CrDu~RKCM$vsXEM1U zxCuH1yOVNj-h-RfuvW_aGdKW$0r0Rw4Y#ZH`+t8&dP9I5rj5$q%9;btEjcrmmZ_iT z6?UD~&!=%o$9ca8s6>TGlhvZ}C}=ad>AZmY0&q~HMpalGY2^S@nBeNVU)<9d^od)) z9%pD^BU8HM?fu3B7 zZ!4CB)9u$4SrCjVHTCMiL#-Iax^Ztt%x1%~ZMzMK%DT;z=@1#q>V*3TmGcE46ZMRX znVJC=S2Mza+YT)U(Zkoa(j|#*rz37;Nox_NdzqDKc|vqV?X$DIziAnd&;NCBg> zJ0)y&p_Ok&q_I#^az*WLp?}kAD*-CiFIj;~BvC=Pg9L z1HvrYoMzVAZ53_BxYShn*^cE7gTZ<=kqeXxr|oB?Dk)OX>v{rkgF{uru}w@HHgf6O z>59@+andj|o_%1?H@v^tv;ebY^a2g9ZfGfCBzCnhp3lL=jV@?VKvB!o_=vLQTKBWe zvcl4);Wn|cbAxu?PQU_Y)Kj#1%*cwcvTVb3>IWKMonz z@I2u0h-!l``?=0&e`wGWDQ9}Jq#pnKO^G>fX~&w4osrUHO`(*1CbR;@t`W?SUZAaN zMpl3+TS2Gas|gKef(lC~(hqtKC9V;%uIXlx6%QaI0@i$V!i%XY_~%}Wy%);!q-T8V zhAYiR3cRU-EX;n2an?4WpxUT7EP6a5TASSwF%k6=>zwtVi6}>m$WNmckOw&@%ur~* z(3q;@9aZ)cA&1PQGq@ol1tHDK*=}^r2IL4J4yNcb0UUHDaJ1R7u+Xr5*Ml>w*XH5BiQ1{qLzq)O{S;wEfx zef;J@#K+rGc)Cr*IUfG)Xx8(}eGiH{C%sln@Xd7XI<4E8(rL;ep$~{;vQ314^xHi%raM*#H0l07*qoM6N<$f@Pk|5dZ)H literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_cylinder.png b/technic/textures/technic_cnc_cylinder.png new file mode 100644 index 0000000000000000000000000000000000000000..06da024b91b5839c9135c2c8b87fb6a53ee01ffd GIT binary patch literal 456 zcmV;(0XP1MP)lv6%>6+Xs-rb=2S|pb%5=fmEZV)>HuoPfj>3C9&qUM7H2wc z^&##F_woIwfX{}iU5J8h1uxce@XC}o2MFQzP}FRNn85+4KH$SE09HE$sG#6ED)~J? zKk3c`at*8m*A?(C=vNB}V8r?;C;`$6&8f%W0Q3M%@(#0*D<~+3VYZ>5IY3^$2Oyo4 zp@NsH_@@fC02V^quSgESaGpwgGr6{hxFOI|@D!Ik{dsT~fOKO(R}Z|$?UYm`pd7Jn z3dU?m2Ph~30@UsSnR?;>Hyzw*qX*Slqo4q$*ZSa)TLHUuw|Fm(=O)cTS{&IXV|<_& y;?jrkIEl~;P)SfqIXI4^-3EGGO$>MVJ=+^lMa9`J4O<-m00003ieY#{#}~Tsofn@i`E593TTW9uUA_69579(*d3>Anj(Pc~bO# zCRVgZE%pU8z+JH240_<8V7dT$;f4T`TS+|UlE=*rme_kR5g+B9Xy;w$5YTFFhhuLu z)c_Uux@4?iP6Dg~S!ge7kS^M;XmPc$M0=V;dul+pO$!`cTLO4>7nb6&04Cr}22<^M zHu?&1a{v-^bnc1$pyq)_EF{UI09S1A)}F`n(*Vc`5g(eYCci4415}u+9x+=)F(gy1 zT@Bu%r;ubB)1=cRV$Bb0ulXIobzSHE1O3yqlIC#2{Wm>>$%zVH-L(J!002ovPDHLk FV1leSym0^k literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_element_cross.png b/technic/textures/technic_cnc_element_cross.png new file mode 100644 index 0000000000000000000000000000000000000000..f2ad0b79ddafba3d275341800bd610a429ff2b4a GIT binary patch literal 415 zcmV;Q0bu@#P)>makflA+Lf$RqS z23QYh7vKyyDLh zBx_hX=%5IUZ2_J$o@Qm~&Zy=UeEcHBTrzTiH8}E32Mp@jO~nQ{TtKTF!C?XhaCm?T z-2Vdl_Pbm>E>F)S5kjkK`HMBK1+WoJ1$Z9D=F|)UZD$hQTxKdWHn&GaBP=f#f002ov JPDHLkV1kXQqt^fc literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_element_edge.png b/technic/textures/technic_cnc_element_edge.png new file mode 100644 index 0000000000000000000000000000000000000000..e6104cf3b258057fe1cb99d52c780222d53540c7 GIT binary patch literal 409 zcmV;K0cQS*P)G}BwEvoe(^A$4Pn4F%< z5!eJa_RLIBJDz8PGeK zD8P*cp23jh#&_{!fq61OVs$-kp=Qk35=R{v#9JMECm|MMEIE_Y%q5gqh&id1U~z&! zjq_0+#g;&1+zmfb{~-Zb;JB!631S~Spv79(0)sZHE+%JQ>U!dIBE^~jr3jN*+!Mh9 luIuXe0{wfj@A!s4+CGrJX;{@Do!9^X002ovPDHLkV1i4boGJhS literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_element_straight.png b/technic/textures/technic_cnc_element_straight.png new file mode 100644 index 0000000000000000000000000000000000000000..1648b7b2a5d4702f3ba5c0dbfa7e834f78f61f8b GIT binary patch literal 412 zcmV;N0b~A&P)P~J!5VsBbS(asU&TTIE_AjG00tV+u z?Hkwx7FK2^XzkB4!I_{n0qga%5B^1hVXCL;UJGtkVnRtr6xsxs!)X$&3PfS)d3R}6 z1D4`)X_|mm6nA}^W)ZLj%)R|xeKP}F;!MEmu$UMnw;x}H30B92$94+zxaWafYB9Nh zdk!eU65KOD1+E|P4n@Dkl2U2=l^DS>rR@Vma6)p!1EmE6G}Xb+!CZo1zx&1Z12Q;d z(b@-Ch&y%!# z`6)$V(WynLM=|mTJCs=wBiBMNP3yXjyMca;55Qw0Wt42BK%rBb1rvgavVH!XCdMm$S!=y9#vAa(H(Cnb@dk|ql%g;DLfi7o?jXZ%tir|VS!TToR%s@wGd-+>oOIeFFs6AEBhHZTtOPh;gI zQp*Xx{?WyNs{va$`0VFE#8E&7PA@Pd2RNO;6HXtnz&#g;i)Z(-Yh;pix;Ebv&nric z->Og!kO>n3<6&(27k8-#ft-g{)?VDY5CtTML}eN2A;rK8CL~DRF#ZT)m+0Y+WAo4! jigQly0s4VVQl<45wk-ZGPM&bL00000NkvXXu0mjflC7KR literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_front.png b/technic/textures/technic_cnc_front.png new file mode 100644 index 0000000000000000000000000000000000000000..6cc049004708b6f0c262a99e1818838300d2efd6 GIT binary patch literal 2000 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 literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_onecurvededge.png b/technic/textures/technic_cnc_onecurvededge.png new file mode 100644 index 0000000000000000000000000000000000000000..46779fd6167b3b844183f90ba4997afbbb192ff6 GIT binary patch literal 507 zcmVPx#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy7<5HgbW?9;ba!ELWdKlNX>N2bPDNB8b~7$AGPjWzeE%1YST7KQjex!t)c`ptY#(l_YG4m89m_$Afg@m&(u;r=I4Vsx&=QxQ zyDmEm=!JuzBya|2bDuJdKw|h`qT6bV8CFs4+S;sh_pSocs z)|NKm+<=nwa-0iLf{XjQ0()`h2}*!5jfKXxj-zrR)T5i*EQX6fDPPhFk6#Q zKm?~+7poE#0@HfBo**##sZDX;xz`4!re{Z=l59CA8bNv;FBB& xmG9FHMDI@kD8&^C?)$!O1N|;@_TOv4?LT5tyL}w(&U*j=002ovPDHLkV1lmk#v%X! literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_pyramid.png b/technic/textures/technic_cnc_pyramid.png new file mode 100644 index 0000000000000000000000000000000000000000..5dc3322e5f729cb43591f4b8a999e7ced0ecbf09 GIT binary patch literal 480 zcmV<60U!Q}P)l3-W5--?a|+v_q)+@9UO^U_W!X5*T0wBBW46A2;BF9 z^h1MyfMNb(Kw54e0l*x`ksR8VrUR(Ka^M$B6U+8Q8-OJk))NL3Ui&<-n3tgyKr4*i z$5X@e9A`rsfi*Y@NSGY>JkrEmPO|{4h4J^JynxXD(jx;ep z(-eRaIGz?y5T6Zb4*OW4d=jroB7joA5egISL&9O-K;B+7d7x6S5spwA>^(UY`4110 zyx;g2)=GOll8vXC{R*}2kpqF^!UMwv8a5)Soz|w85M`SlTJ!V#c1}JkR~!K;M5&I=;id+I|3p W0^oF6IUle90000Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy7<5HgbW?9;ba!ELWdKlNX>N2bPDNB8b~7$AGPjWzeEj=)?2wU^4=(x^fy^o#Z|JjBnb4(boUJZ z`1c;ij z=B2cuA6n*Ko-%ul?6JmonP;9^ShKXLAKT9Q^X)CxChmLoC;v++wPnsNkC_8Xo2IFa zX=>9rw(Ire-rTzHT^l)|l+tDn$gC+j2Y_|k0z};ap6RGZEx3Wn|W>=QyYhg z0Jm0;`UJ48L^n=t*+2@2KJ~5ddNu-#kt}oky|B(q?Z?h$na$1C%H~^}vr!G~u>x`; zN)MXb1Q>%l4%VzoTiJ7*xSsM8z-*fMj7B~Tt^fYLy}iFjv_|zSjoZGoLKenxX#2KD ziZ{xWhMs3rWFcMpcI*eylR@@NBftTY$YvqS0lZSyWqJar>mFrDY!Zvv(DaSN2x?Mp zeMz@Ktlvrrj97kL-%jpvjpt13&~<#1Apj(TS>(-J_!!{8GxuN%S$S|^r_P%fSrpkY z<$c#?4ye27%|V*;IHE+~zI|(|=ih#OE_234IVztAfSiepjW-x>YWCaN&hrRBxez%l z-T*bi4LAAx`SXAN2-;GsvQ6f(_JpC zuN>~W#Kv%fb^Q+rSNP4L%5)F_Tngz%dCj8ozRURmpc36K+cgp*Qf4bz*df)%W=1(v ziiL+J2=@^VNYrr@(2EKRy4(S=RgmWdy4=nyDWpydIv-&3PBs?Y@ON-vgV@8X6Y6xy z^iqb614B9hT8ZA2W$*KV`qt4hdJZcl-Ew2)_k;(`TvwtxV`lw;Ukp6~!3||=nRM3$ z&S+SV5_qwv=GHQk8V}J_RDlQme7kYK3*sI0ht+zr?ux~(a6$(R;QXG3)H>Gcs;<*N zy33!j=W#vS0$CR_yCdnR3UD*Yk|m4HM+*hi!6M6JGue=(hn=_Uhd5w)6QI^tA6SU0 z*82e~>Dgp8ht6D|7apKI=j|5S{T&>L(gNZsLk?F~rfGtqp=D||p$Zi;V9B9-x>-R& zDxu&BE14UU-=v$`?`U7J%2`FJpoJ2q9^>J@*6#BM&a2v90AMVpS*zv2gbi1sKS;Zp zR{LQ{dIIHfKA30B1yDQS{adq15YBH8D=(yTPS6J;pn3;)5b)EAy@BjjSS%3-=L4d- z-t>O6ayOM^^ssw&I3WXt@>mf>(BQW4q&|}>9*12XeN*bIf`0BtwgP!H63efi}t>stg(b&tZ?Q&DG55WR}3T< zh>OGrCaM_Y09F9zEb-(3>?{nT_<>hIKv<(&ufzF%NRc%maz$ zGO>xx%XbFHw~cI7-X~lagDoU0n2a(G*2@vHV{aJ=>|oxIAFAmAAW%`$-mzMDgY}~i z5}_09jz^3%88dMLtc#HyGda%~REshs_1+hpe2|#lw>0;b-UWEGwlY!6gXfEhEt7g4 zOvl}&gY~{(sAFW~Fd_&@WwX+3^n|t4`Y6+KJ`obZdnv@Aa)?#bvM06sF~|Bh$>2HIyn1UV!Z07*qo IM6N<$g7Jiq4gdfE literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_slope.png b/technic/textures/technic_cnc_slope.png new file mode 100644 index 0000000000000000000000000000000000000000..083ae18cead58a9184bd67530aeafe610e9d7298 GIT binary patch literal 437 zcmV;m0ZRUfP)4D zo3T!BIziXKRXD7*@%zu{fAK0@tcw97?sXuA8v(P&c@0uUs5Ajr?rl_6<~7)FM4OreXIS^Ssm1%g%ZJ`M@xCjT*G+9! foXV%WVb%8!Ki5#NA|S~n00000NkvXXu0mjf9OS!A literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_slope_edge.png b/technic/textures/technic_cnc_slope_edge.png new file mode 100644 index 0000000000000000000000000000000000000000..785adf6531fb5a95b387869ed590d354d071666b GIT binary patch literal 419 zcmV;U0bKrxP)=13A3=}IIiuvm3S2Fm2Y?DFyD)N zV3N{y0Y~BhW&(P^YUxp&s>Gf+u49;h-Y^Z0O>hKCTiR+HoC&-tEB>rH%y>g#@P%^? zcb;Zdrk!3$iYxE=PC;jZ!g+BIwv}FeVk!i}MYK?iyB>&J^JXRRSd5VG9I(aueQy9t z)1)0jj>5m}0JfkQXu~-#9^t~DpXuy8SlwFJ)o%g)cpCOT+%M<~`~W~B_g~(faa{la N002ovPDHLkV1jjZu+9Jg literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_slope_edge_upsdwn.png b/technic/textures/technic_cnc_slope_edge_upsdwn.png new file mode 100644 index 0000000000000000000000000000000000000000..5adb788b795553448a74f32234eb12a0b152343b GIT binary patch literal 486 zcmV@P)-G35m*7E zDXP~xv;o+O`wdL#^)j*o*a^e*RG{3O1>hixm$n*t+&?owW1KoLa_NNd=I!sm z6?^kqpjhe;!2wbQ(&;ivGYjOf>I8G+ZvYKQK+#1@I|PhfF?1%t9Bdef$+j|iVx`iW z0b9~U9DJz#IwW~&f;B_Ldkujeb}f*Xox=(PAtIZ$8U0ts{|@ZU5|Wj*h&&C*OOH^g z-%PiemNens3g98dSL-)PE2^}~LsD=`Wd__WKsrd7l7`Ibb>JROh>QAlxGVA=u|e>=5CKlk|uIGXR1piP47y2dEy cT~p(>FB3e%#bcOwwEzGB07*qoM6N<$f*QunI{*Lx literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_slope_inner_edge.png b/technic/textures/technic_cnc_slope_inner_edge.png new file mode 100644 index 0000000000000000000000000000000000000000..906dd2548b63cd146bcb3374293ddb3a7543e1e0 GIT binary patch literal 497 zcmVjl1O?K=K^ASUKmfXf-`}Di^3={f`jk! z^i*ILmIcmmBCv{s>m%t&xFvuZ&K!f4Bs~e*$>CaAS(9Xu7Em8^d=c+lG)1r)P@b*Q z?t&ADmwTYrBkcJov$m0fKqzM+JwS`~`aA)&(&WHcV#zV6{bHWz4Cqg64&3*>zUht7 n=enX^_ul?!+?BuouD7-yOl{;`+yuDy00000NkvXXu0mjfjFa2c literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_slope_inner_edge_upsdwn.png b/technic/textures/technic_cnc_slope_inner_edge_upsdwn.png new file mode 100644 index 0000000000000000000000000000000000000000..0ae0e14ddd6400f190469173534ae2fb8e8f45ee GIT binary patch literal 605 zcmV-j0;2tiP)SC+y6v1=45!R_Tg|K!GA0^zOqx02;X32S?}ONCyy1 z4Fck&2Z12&Hb{``#%T_KNaHil=|elf;7wg6?%k_}w!qYQ^aj!E>r7Cf_XMNJ5b*Z^ z(WU|UTo%Pb^CFd*YmsTXFx{BI8Uz9+6m2p&v&0IJ z<~R=MbpaE|aaww2i3dpSp}-9r;bs7PtA;wLWNH=;28scrjY^qbh4x?wZZ`1NKTlYO zqkYab&B%4pvHVF?bF7Wn-tUL=U;vmB>z3GqbCnnv(YJ}0m6Z~#XcX#7(1YysIT!Bd z__}F(6G#sLIn5(Mdan-#DOG}nfXK9CEMv`5$;&+rXd$gNmZ6%`zY0VL!ddQI@~;93 zR?`gkL2E=i(vzt*$Va1?PvF|>f&yhp*>Ns;7^n>v1USHnMJz#^f4|8^&OVk&T0jlg zztabR;|L}IWvR6U`_qV3p-DiFM1U6S`uqi8JFnriDWkae+$a;go=m*BQkS%C+g5g> rTN=^rAK&pd&pB~cLj@T9qT>30-TN_gAA!CT00000NkvXXu0mjfP2CS$ literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_slope_lying.png b/technic/textures/technic_cnc_slope_lying.png new file mode 100644 index 0000000000000000000000000000000000000000..377769a7f2d0c28cf411134146fb6d5e9d13b89c GIT binary patch literal 548 zcmV+<0^9wGP)Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy7<5HgbW?9;ba!ELWdKlNX>N2bPDNB8b~7$AGPjWzeEE32oCLI7gvtt_B>i;!gOxBfdJV%cg%G9y zzQ;|gMnG`3WQ$-Ou+TFv3eGQDyIzu{9&irh<+sOfCX4H~)Ns77-EkMd7?^!m23p}_ z0{khLdO$J9e-#3HLEg>tL1qH(0hZ_b48SAcwi9Us@JJ|M#wP&n;*vz*9+#>liU4xs zTfxR$`%|%YUFZ{lfP-o@y=ag>=XjN8LSckKIji2c%stEaWyX^{f6gO}?VsugA9Z^L zXWiQYMZH56q00Yzx^`C=Gxlr@YPiDze`mR2u_Wn$o-D3akY$A)@RS$Kb(a|r zpss(|oG}Qv4%iix`k?EdI|iwqEif&+ literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_slope_upsdwn.png b/technic/textures/technic_cnc_slope_upsdwn.png new file mode 100644 index 0000000000000000000000000000000000000000..b802b60db0e329dddc96884da31bd597d8e8c925 GIT binary patch literal 440 zcmV;p0Z0CcP)w5W*3X?{nhyK)`5p zwf!Zi)5T(Zcio+!wILAW;9QS10G43%w{hqokb|mSBf|~=H8^?c1wad!y!1@q3>+`b z25=^dKjI6(t6}Z3I|QCfUn%jb6rXV&f+J5yj{4vW;S#b7{H=y_^Q16#f~6VXikeXP zz@=Rd?7>t(P1$K`wbGgZ^Z4TLfJ-glyi``vDCRzOw3swC0QPXAQ9J@Im6MyCS&4h2 zyoThYHzh#~#$}f#H#I?;s$@{$WFL~1gxd#O*FmBQk@i-Z6Yg>#oj+?pz%2vf`I90s zZYdCV1={aiBv=|qG(9&7(y7U1g0)2153Cl`%=kT+@5SSPplx{r?*z38XxryLxbM5) i59s;j-SHRxXnO-cQtO1vAaX7M00003v?#Bj2nR*28_Y2?M-;+mSo0uB>$2druzw4i1^)78bZP}A1n4DioMaNqZJ|ABr@)inPvc>M{6 W_hHLH!dDsq0000?H^6s{au38*-x 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 Date: Mon, 6 May 2013 23:14:27 +0200 Subject: [PATCH 2/2] Fixes to te machine level of service. --- technic/cnc.lua | 352 ++++++++++++++++++++++++++++---------------- technic/cnc_api.lua | 14 +- 2 files changed, 229 insertions(+), 137 deletions(-) diff --git a/technic/cnc.lua b/technic/cnc.lua index 6e763ef..71b78b0 100644 --- a/technic/cnc.lua +++ b/technic/cnc.lua @@ -1,40 +1,94 @@ -- Technic CNC v1.0 by kpo -- Based on the NonCubic Blocks MOD v1.4 by yves_de_beck local shape = {} -local size = 0 local onesize_products = { - slope = 2, - slope_edge = 1, - slope_inner_edge = 1, - pyramid = 2, - spike = 1, - cylinder = 2, - sphere = 1, - stick = 8, - slope_upsdwn = 2, - slope_edge_upsdwn = 1, - slope_inner_edge_upsdwn = 1, - cylinder_hor = 2, - slope_lying = 2, - onecurvededge = 1, - twocurvededge = 1, + slope = 2, + slope_edge = 1, + slope_inner_edge = 1, + pyramid = 2, + spike = 1, + cylinder = 2, + sphere = 1, + stick = 8, + slope_upsdown = 2, + slope_edge_upsdown = 1, + slope_inner_edge_upsdown = 1, + cylinder_horizontal = 2, + slope_lying = 2, + onecurvededge = 1, + twocurvededge = 1, } local twosize_products = { - element_straight = 4, - element_end = 2, - element_cross = 1, - element_t = 1, - element_edge = 2, + element_straight = 4, + element_end = 2, + element_cross = 1, + element_t = 1, + element_edge = 2, } -local showbackground = "--" -local max_cncruns = 99 -local max_products = 99 +--cnc_recipes ={} +--registered_cnc_recipes_count=1 +-- +--function register_cnc_recipe (string1,string2) +-- cnc_recipes[registered_cnc_recipes_count]={} +-- cnc_recipes[registered_cnc_recipes_count].src_name=string1 +-- cnc_recipes[registered_cnc_recipes_count].dst_name=string2 +-- registered_cnc_recipes_count=registered_cnc_recipes_count+1 +-- if unified_inventory then +-- unified_inventory.register_craft({ +-- type = "cnc milling", +-- output = string2, +-- items = {string1}, +-- width = 0, +-- }) +-- end +--end ---showlabelin = "" ---showlabelout = "label[4.5,5.5;Out:]" +local cnc_formspec = + "invsize[9,11;]".. + "label[1,0;Choose Milling Program:]".. + "image_button[1,0.5;1,1;technic_cnc_slope.png;slope; ]".. + "image_button[2,0.5;1,1;technic_cnc_slope_edge.png;slope_edge; ]".. + "image_button[3,0.5;1,1;technic_cnc_slope_inner_edge.png;slope_inner_edge; ]".. + "image_button[4,0.5;1,1;technic_cnc_pyramid.png;pyramid; ]".. + "image_button[5,0.5;1,1;technic_cnc_spike.png;spike; ]".. + "image_button[6,0.5;1,1;technic_cnc_cylinder.png;cylinder; ]".. + "image_button[7,0.5;1,1;technic_cnc_sphere.png;sphere; ]".. + "image_button[8,0.5;1,1;technic_cnc_stick.png;stick; ]".. + + "image_button[1,1.5;1,1;technic_cnc_slope_upsdwn.png;slope_upsdown; ]".. + "image_button[2,1.5;1,1;technic_cnc_slope_edge_upsdwn.png;slope_edge_upsdown; ]".. + "image_button[3,1.5;1,1;technic_cnc_slope_inner_edge_upsdwn.png;slope_inner_edge_upsdown; ]".. + "image_button[4,1.5;1,1;technic_cnc_cylinder_horizontal.png;cylinder_horizontal; ]".. + + "image_button[1,2.5;1,1;technic_cnc_slope_lying.png;slope_lying; ]".. + "image_button[2,2.5;1,1;technic_cnc_onecurvededge.png;onecurvededge; ]".. + "image_button[3,2.5;1,1;technic_cnc_twocurvededge.png;twocurvededge; ]".. + + "label[1,3.5;Slim Elements half / normal height:]".. + + "image_button[1,4;1,0.5;technic_cnc_full.png;full; ]".. + "image_button[1,4.5;1,0.5;technic_cnc_half.png;half; ]".. + "image_button[2,4;1,1;technic_cnc_element_straight.png;element_straight; ]".. + "image_button[3,4;1,1;technic_cnc_element_end.png;element_end; ]".. + "image_button[4,4;1,1;technic_cnc_element_cross.png;element_cross; ]".. + "image_button[5,4;1,1;technic_cnc_element_t.png;element_t; ]".. + "image_button[6,4;1,1;technic_cnc_element_edge.png;element_edge; ]".. + + "label[0, 5.5;In:]".. + "list[current_name;src;0.5,5.5;1,1;]".. + "label[4, 5.5;Out:]".. + "list[current_name;dst;5,5.5;4,1;]".. + + "list[current_player;main;0,7;8,4;]" + + +local cnc_power_formspec= + "label[0,3;Power]".. + "image[0,1;1,2;technic_power_meter_bg.png]" + +local size = 1; --- I want the CNC machine to be a two block thing minetest.register_node("technic:cnc", { description = "CNC Milling Machine", tiles = {"technic_cnc_top.png", "technic_cnc_bottom.png", "technic_cnc_side.png", @@ -53,72 +107,44 @@ minetest.register_node("technic:cnc", { type = "fixed", fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, }, - groups = {oddly_breakable_by_hand=2, cracky=3, dig_immediate=1}, + groups = {cracky=2}, + legacy_facedir_simple = true, + technic_power_machine=1, + internal_EU_buffer=0; + internal_EU_buffer_size=5000; + cnc_time = 0; + src_time = 0; -- fixme + + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_string("infotext", "CNC machine") + meta:set_float("technic_power_machine", 1) + meta:set_float("internal_EU_buffer", 0) + meta:set_float("internal_EU_buffer_size", 5000) + meta:set_string("formspec", cnc_formspec..cnc_power_formspec) + meta:set_float("cnc_time", 0) + + local inv = meta:get_inventory() + inv:set_size("src", 1) + inv:set_size("dst", 4) + + meta:set_string("formspec", cnc_formspec) + meta:set_string("infotext", "CNC Milling Machine") + end, can_dig = function(pos,player) local meta = minetest.env:get_meta(pos); local inv = meta:get_inventory() - if not inv:is_empty("input") or not inv:is_empty("output") then + if not inv:is_empty("src") or not inv:is_empty("dst") then minetest.chat_send_player(player:get_player_name(), "CNC machine cannot be removed because it is not empty"); return false end return true end, - on_construct = function(pos) - local meta = minetest.env:get_meta(pos) - if technic_cnc_api.allow_menu_background == true or technic_cnc_api.allow_menu_background == 1 then - showbackground = "background[-0.15,-0.25;8.40,11.75;technic_cnc_background.png]" - end - - meta:set_string("formspec", "invsize[8,11;]".. - "label[0,0;Choose Milling Program:]".. - "image_button[0,0.5;1,1;technic_cnc_slope.png;slope; ]".. - "image_button[1,0.5;1,1;technic_cnc_slope_edge.png;slope_edge; ]".. - "image_button[2,0.5;1,1;technic_cnc_slope_inner_edge.png;slope_inner_edge; ]".. - "image_button[3,0.5;1,1;technic_cnc_pyramid.png;pyramid; ]".. - "image_button[4,0.5;1,1;technic_cnc_spike.png;spike; ]".. - "image_button[5,0.5;1,1;technic_cnc_cylinder.png;cylinder; ]".. - "image_button[6,0.5;1,1;technic_cnc_sphere.png;sphere; ]".. - "image_button[7,0.5;1,1;technic_cnc_stick.png;stick; ]".. - "image_button[0,1.5;1,1;technic_cnc_slope_upsdwn.png;slope_upsdwn; ]".. - "image_button[1,1.5;1,1;technic_cnc_slope_edge_upsdwn.png;slope_upsdwn_edge; ]".. - "image_button[2,1.5;1,1;technic_cnc_slope_inner_edge_upsdwn.png;slope_upddown_inner_edge; ]".. - "image_button[5,1.5;1,1;technic_cnc_cylinder_horizontal.png;cylinder_horizontal; ]".. - - "image_button[0,2.5;1,1;technic_cnc_slope_lying.png;slope_lying; ]".. - "image_button[1,2.5;1,1;technic_cnc_onecurvededge.png;onecurvededge; ]".. - "image_button[2,2.5;1,1;technic_cnc_twocurvededge.png;twocurvededge; ]".. - - "label[0,3.5;Slim Elements half / normal height:]".. - - "image_button[0,4;1,0.5;technic_cnc_full.png;full; ]".. - "image_button[0,4.5;1,0.5;technic_cnc_half.png;half; ]".. - "image_button[1,4;1,1;technic_cnc_element_straight.png;element_straight; ]".. - "image_button[2,4;1,1;technic_cnc_element_end.png;element_end; ]".. - "image_button[3,4;1,1;technic_cnc_element_cross.png;element_cross; ]".. - "image_button[4,4;1,1;technic_cnc_element_t.png;element_t; ]".. - "image_button[5,4;1,1;technic_cnc_element_edge.png;element_edge; ]".. - - "label[0, 5.5;In:]".. -- showlabelin.. - "list[current_name;input;0.5,5.5;1,1;]".. - "field[3, 6;1,1;num_cncruns;Repeat program:;${num_cncruns}]".. -- Fill default with meta data num_cncruns - "label[4, 5.5;Out:]".. -- showlabelout.. - "list[current_name;output;4.5,5.5;1,1;]".. - - "list[current_player;main;0,7;8,4;]".. - showbackground) - meta:set_string("infotext", "CNC Milling Machine") - meta:set_string("num_cncruns", 1 ); - - local inv = meta:get_inventory() - inv:set_size("input", 1) - inv:set_size("output", 1) - end, - on_receive_fields = function(pos, formname, fields, sender) - -- REGISTER MILLING PROGRAMMS AND OUTPUTS: + -- REGISTER MILLING PROGRAMS AND OUTPUTS: ------------------------------------------ -- Program for half/full size if fields["full"] then @@ -131,32 +157,12 @@ minetest.register_node("technic:cnc", { return end - local meta = minetest.env:get_meta(pos) - local inv = meta:get_inventory() - - -- Limit the number entered - if( fields.num_cncruns and tonumber( fields.num_cncruns) > 0 and tonumber(fields.num_cncruns) < 100 ) then - meta:set_string( "num_cncruns", fields.num_cncruns ); - else - minetest.chat_send_player(sender:get_player_name(), "CNC machine runs set to a bad value. Machine resets."); - meta:set_string( "num_cncruns", 1 ); - fields.num_cncruns = 1 - end - - -- Do nothing if the machine is empty - if inv:is_empty("input") then - return - end - - -- Do nothing if the output is not empty and the product used is not the same as what is already there - - -- Resolve the node name and the number of items to make and the number of items to take - local product = "" - local produces = 1 - local input_used = 1 - local inputstack = inv:get_stack("input", 1) + -- Resolve the node name and the number of items to make + local meta = minetest.env:get_meta(pos) + local inv = meta:get_inventory() + local inputstack = inv:get_stack("src", 1) local inputname = inputstack:get_name() - local multiplier = 1 + local multiplier = 0 for k, _ in pairs(fields) do -- Set a multipier for the half/full size capable blocks if twosize_products[k] ~= nil then @@ -164,38 +170,124 @@ minetest.register_node("technic:cnc", { else multiplier = onesize_products[k] end - + if onesize_products[k] ~= nil or twosize_products[k] ~= nil then - product = inputname .. "_technic_cnc_" .. k - produces = math.min( fields.num_cncruns*multiplier, max_products) -- produce at most max_products - input_used = math.min( math.floor(produces/multiplier), inputstack:get_count()) -- use at most what we got - produces = input_used*multiplier -- final production - print(size) - print(fields.num_cncruns) - print(product) - print(produces) - print(input_used) - print("------------------") + meta:set_float( "cnc_multiplier", multiplier) + meta:set_string("cnc_user", sender:get_player_name()) + end + + if onesize_products[k] ~= nil or (twosize_products[k] ~= nil and size==2) then + meta:set_string("cnc_product", inputname .. "_technic_cnc_" .. k) + break + end + + if twosize_products[k] ~= nil and size==1 then + meta:set_string("cnc_product", inputname .. "_technic_cnc_" .. k .. "_double") break end end - - -- CNC does the transformation - ------------------------------ - if minetest.registered_nodes[product] ~= nil then - inv:add_item("output",product .. " " .. produces) - inputstack:take_item(input_used) - inv:set_stack("input",1,inputstack) - else - minetest.chat_send_player(sender:get_player_name(), "CNC machine does not know how to mill this material. Please remove it."); - end - return; + return end, -- callback function }) ----------- +minetest.register_node("technic:cnc_active", { + description = "CNC Machine", + tiles = {"technic_cnc_top.png", "technic_cnc_bottom.png", "technic_cnc_side.png", + "technic_cnc_side.png", "technic_cnc_side.png", "technic_cnc_front_active.png"}, + paramtype2 = "facedir", + groups = {cracky=2,not_in_creative_inventory=1}, + legacy_facedir_simple = true, + can_dig = function(pos,player) + local meta = minetest.env:get_meta(pos); + local inv = meta:get_inventory() + if not inv:is_empty("src") or not inv:is_empty("dst") then + minetest.chat_send_player(player:get_player_name(), "CNC machine cannot be removed because it is not empty"); + return false + end + return true + end, +}) --- Milling Machine Recipe +minetest.register_abm( + { + nodenames = {"technic:cnc","technic:cnc_active"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local meta = minetest.env:get_meta(pos) + local charge= meta:get_float("internal_EU_buffer") + local max_charge= meta:get_float("internal_EU_buffer_size") + local cnc_cost=350 + + local load = math.floor((charge/max_charge)*100) + meta:set_string("formspec", cnc_formspec.. + "image[0,1;1,2;technic_power_meter_bg.png^[lowpart:".. + (load)..":technic_power_meter_fg.png]" + ) + + local inv = meta:get_inventory() + local srclist = inv:get_list("src") + if inv:is_empty("src") then + meta:set_float("cnc_on",0) + meta:set_string("cnc_product", "") -- Reset the program + end + + if (meta:get_float("cnc_on") == 1) then + if charge>=cnc_cost then + charge=charge-cnc_cost; + meta:set_float("internal_EU_buffer",charge) + meta:set_float("src_time", meta:get_float("src_time") + 1) + if meta:get_float("src_time") >= meta:get_float("cnc_time") then + local product = meta:get_string("cnc_product") + if inv:room_for_item("dst",product) then + -- CNC does the transformation + ------------------------------ + if minetest.registered_nodes[product] ~= nil then + inv:add_item("dst",product .. " " .. meta:get_float("cnc_multiplier")) + srcstack = inv:get_stack("src", 1) + srcstack:take_item() + inv:set_stack("src",1,srcstack) + if inv:is_empty("src") then + meta:set_float("cnc_on",0) + meta:set_string("cnc_product", "") -- Reset the program +-- print("cnc product reset") + end + else + minetest.chat_send_player(meta:get_string("cnc_user"), "CNC machine does not know how to handle this material. Please remove it."); + end + else + minetest.chat_send_player(meta:get_string("cnc_user"), "CNC inventory full!") + end + meta:set_float("src_time", 0) + end + end + end + + if (meta:get_float("cnc_on")==0) then + if not inv:is_empty("src") then + local product = meta:get_string("cnc_product") + if minetest.registered_nodes[product] ~= nil then + meta:set_float("cnc_on",1) + hacky_swap_node(pos,"technic:cnc_active") + meta:set_string("infotext", "CNC Machine Active") + cnc_time=3 + meta:set_float("cnc_time",cnc_time) + meta:set_float("src_time", 0) + return + end + else + hacky_swap_node(pos,"technic:cnc") + meta:set_string("infotext", "CNC Machine Inactive") + end + end + end + }) + +register_LV_machine ("technic:cnc","RE") +register_LV_machine ("technic:cnc_active","RE") +------------------------- + +-- CNC Machine Recipe ------------------------- minetest.register_craft({ output = 'technic:cnc', diff --git a/technic/cnc_api.lua b/technic/cnc_api.lua index 390a996..2d5dcfe 100644 --- a/technic/cnc_api.lua +++ b/technic/cnc_api.lua @@ -212,7 +212,7 @@ end -- SLOPE EDGE UPSIDE DOWN ------------------------- -function technic_cnc_api.register_slope_upsdown_edge(recipeitem, groups, images, description) +function technic_cnc_api.register_slope_edge_upsdown(recipeitem, groups, images, description) if recipeitem == "default:dirt" then return @@ -223,7 +223,7 @@ local detail = technic_cnc_api.detail_level for i = 0, detail-1 do slopeupdwnboxedge[i+1]={(-1*(i/detail))+0.5-(1/detail), (i/detail)-0.5, (-1*(i/detail))+0.5-(1/detail), 0.5, (i/detail)-0.5+(1/detail), 0.5} end -minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_upsdown_edge", { +minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_edge_upsdown", { description = description, drawtype = "nodebox", tiles = images, @@ -245,13 +245,13 @@ end -- SLOPE INNER EDGE UPSIDE DOWN ------------------------------- -function technic_cnc_api.register_slope_upsdown_inner_edge(recipeitem, groups, images, description) +function technic_cnc_api.register_slope_inner_edge_upsdown(recipeitem, groups, images, description) if recipename == "default:dirt" then return end -minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_upsdown_inner_edge", { +minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_inner_edge_upsdown", { description = description, drawtype = "nodebox", tiles = images, @@ -548,7 +548,7 @@ for i = 1, detail-1 do sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) spherebox[i]={-sehne, (i/detail)-0.5, -sehne, sehne, (i/detail)+(1/detail)-0.5, sehne} end -minetest.register_node(":" .. recipeitem .. "_technic_cnc_cylinder_sphere", { +minetest.register_node(":" .. recipeitem .. "_technic_cnc_sphere", { description = description, drawtype = "nodebox", tiles = images, @@ -939,8 +939,8 @@ function technic_cnc_api.register_slope_edge_etc(recipeitem, groups, images, des technic_cnc_api.register_slope_upsdown(recipeitem, groups, images, desc_slope_upsdown) technic_cnc_api.register_slope_edge(recipeitem, groups, images, desc_slope_edge) technic_cnc_api.register_slope_inner_edge(recipeitem, groups, images, desc_slope_inner_edge) - technic_cnc_api.register_slope_upsdown_edge(recipeitem, groups, images, desc_slope_upsdwn_edge) - technic_cnc_api.register_slope_upsdown_inner_edge(recipeitem, groups, images, desc_slope_upsdwn_inner_edge) + technic_cnc_api.register_slope_edge_upsdown(recipeitem, groups, images, desc_slope_upsdwn_edge) + technic_cnc_api.register_slope_inner_edge_upsdown(recipeitem, groups, images, desc_slope_upsdwn_inner_edge) technic_cnc_api.register_pyramid(recipeitem, groups, images, desc_pyramid) technic_cnc_api.register_spike(recipeitem, groups, images, desc_spike) technic_cnc_api.register_onecurvededge(recipeitem, groups, images, desc_onecurvededge)