2015-10-19 11:26:09 +02:00
-- rnd 2015, power outlet
-- used to power basic_machines using remaining available power from technic:switching_station. Just place it below mover but within 10 block distance of technich switching station. Each power outlet adds 500 to the power demand. If switching station has not enough unused power ( after technic machines demand), it wont supply power to mover.
2016-03-25 00:16:03 +01:00
-- outlet -> change to battery
2015-10-19 11:26:09 +02:00
2016-03-25 00:16:03 +01:00
-- power plant block: costly to make: 8 diamondblocks, battery in center
-- -upgradeable, each diamondblock+lava_bucket will add ammount of energy cells produced in cycle ( 5 seconds) and increase its internal energy storage capacity
-- initially produces 1 power cell, storage capacity 10, with each level of upgrade it adds 1 power cell, 10 storage capacity
-- when it generates power it will also fill the battery on top of it ( if any), speed of refill equalls speed of power generation, it will put all energy
-- possible in battery until is filled, will make recharge sound - electric discharge like in factorio game?
2015-10-19 11:26:09 +02:00
2016-03-25 00:16:03 +01:00
-- BATTERY
2015-10-19 11:26:09 +02:00
2016-03-25 00:16:03 +01:00
local battery_update_meta = function ( pos )
local meta = minetest.get_meta ( pos ) ;
local list_name = " nodemeta: " .. pos.x .. ' , ' .. pos.y .. ' , ' .. pos.z
local capacity = meta : get_float ( " capacity " ) ;
2016-03-28 20:38:46 +02:00
local maxpower = meta : get_float ( " maxpower " ) ;
2016-03-25 00:16:03 +01:00
local energy = math.ceil ( 10 * meta : get_float ( " energy " ) ) / 10 ;
local form =
2016-03-26 14:03:00 +01:00
" size[8,6.5] " .. -- width, height
2016-03-25 00:16:03 +01:00
" label[0,0;FUEL] " .. " label[6,0;UPGRADE] " ..
2016-03-28 20:38:46 +02:00
" label[1,0;ENERGY " .. energy .. " / " .. capacity .. " , maximum power output " .. maxpower .. " ] " ..
2016-03-25 00:16:03 +01:00
" label[1,1;UPGRADE LEVEL " .. meta : get_int ( " upgrade " ) .. " (mese and diamond block)] " ..
" list[ " .. list_name .. " ;fuel;0.,0.5;1,1;] " .. " list[ " .. list_name .. " ;upgrade;6.,0.5;2,1;] " ..
2016-03-26 14:03:00 +01:00
" list[current_player;main;0,2.5;8,4;] " ..
2016-03-25 00:16:03 +01:00
" button[4.5,0.35;1.5,1;OK;REFRESH] " ;
meta : set_string ( " formspec " , form ) ;
end
--[power crystal name] = energy provided
basic_machines.energy_crystals = {
[ " basic_machines:power_cell " ] = 1 ,
[ " basic_machines:power_block " ] = 10 ,
[ " basic_machines:power_rod " ] = 100 ,
}
battery_recharge = function ( pos )
local meta = minetest.get_meta ( pos ) ;
local energy = meta : get_float ( " energy " ) ;
local capacity = meta : get_float ( " capacity " ) ;
local inv = meta : get_inventory ( ) ;
local stack = inv : get_stack ( " fuel " , 1 ) ; local item = stack : get_name ( ) ;
local crystal = false ;
local add_energy = 0 ;
add_energy = basic_machines.energy_crystals [ item ] or 0 ;
if add_energy > 0 then
crystal = true ;
if energy + add_energy <= capacity then
stack : take_item ( 1 ) ;
inv : set_stack ( " fuel " , 1 , stack )
end
else -- try do determine caloric value
local fuellist = inv : get_list ( " fuel " ) ; if not fuellist then return end
local fueladd , afterfuel = minetest.get_craft_result ( { method = " fuel " , width = 1 , items = fuellist } )
if fueladd.time > 0 then
add_energy = fueladd.time / 40 ;
if energy + add_energy <= capacity then
inv : set_stack ( " fuel " , 1 , afterfuel.items [ 1 ] ) ;
end
end
end
if add_energy > 0 then
if energy + add_energy <= capacity then
energy = energy + add_energy
meta : set_float ( " energy " , energy ) ;
meta : set_string ( " infotext " , " (R) energy: " .. math.ceil ( energy * 10 ) / 10 .. " / " .. capacity ) ;
--TODO2: add entity power status display
minetest.sound_play ( " electric_zap " , { pos = pos , gain = 0.03 , max_hear_distance = 8 , } )
end
end
return energy ; -- new battery energy level
end
battery_upgrade = function ( pos )
local meta = minetest.get_meta ( pos ) ;
local inv = meta : get_inventory ( ) ;
local count1 , count2 ; count1 = 0 ; count2 = 0 ;
local stack , item , count ;
for i = 1 , 2 do
stack = inv : get_stack ( " upgrade " , i ) ; item = stack : get_name ( ) ; count = stack : get_count ( ) ;
if item == " default:mese " then
count1 = count1 + count
elseif item == " default:diamondblock " then
count2 = count2 + count
end
end
if count1 < count2 then count = count1 else count = count2 end
meta : set_int ( " upgrade " , count ) ;
-- adjust capacity
local capacity = 10 + 20 * count ;
2016-03-28 20:38:46 +02:00
--if count == 99 then capacity = 10000 end -- ultimate upgrade for ultimate capacity
local maxpower = capacity * 0.1 ;
2016-03-25 00:16:03 +01:00
capacity = math.ceil ( capacity * 10 ) / 10 ;
local energy = 0 ;
meta : set_float ( " capacity " , capacity )
2016-03-28 20:38:46 +02:00
meta : set_float ( " maxpower " , maxpower )
2016-03-25 00:16:03 +01:00
meta : set_float ( " energy " , 0 )
meta : set_string ( " infotext " , " energy: " .. math.ceil ( energy * 10 ) / 10 .. " / " .. capacity ) ;
end
minetest.register_node ( " basic_machines:battery " , {
2016-03-26 14:03:00 +01:00
description = " battery - stores energy, generates energy from fuel, can power nearby machines, or accelerate/run furnace above it. Its upgradeable. " ,
2016-03-25 00:16:03 +01:00
tiles = { " basic_machine_outlet.png " , " basic_machine_side.png " , " basic_machine_battery.png " } ,
2015-10-19 11:26:09 +02:00
groups = { oddly_breakable_by_hand = 2 , mesecon_effector_on = 1 } ,
sounds = default.node_sound_wood_defaults ( ) ,
after_place_node = function ( pos , placer )
local meta = minetest.get_meta ( pos ) ;
2016-03-26 14:03:00 +01:00
meta : set_string ( " infotext " , " battery - stores energy, generates energy from fuel, can power nearby machines, or accelerate/run furnace above it when activated by keypad " ) ;
2016-03-25 00:16:03 +01:00
meta : set_string ( " owner " , placer : get_player_name ( ) ) ;
local inv = meta : get_inventory ( ) ; inv : set_size ( " fuel " , 1 * 1 ) ; -- place to put crystals
inv : set_size ( " upgrade " , 2 * 1 ) ;
meta : set_int ( " upgrade " , 0 ) ; -- upgrade level determines energy storage capacity and max energy output
2016-03-28 20:38:46 +02:00
meta : set_float ( " capacity " , 10 ) ; meta : set_float ( " maxpower " , 1 ) ;
2016-03-25 00:16:03 +01:00
meta : set_float ( " energy " , 0 ) ;
end ,
2016-02-29 11:35:12 +01:00
2016-03-25 00:16:03 +01:00
mesecons = { effector = {
action_on = function ( pos , node , ttl )
if type ( ttl ) ~= " number " then ttl = 1 end
if ttl < 0 then return end -- machines_TTL prevents infinite recursion
local meta = minetest.get_meta ( pos ) ;
local energy = meta : get_float ( " energy " ) ;
local capacity = meta : get_float ( " capacity " ) ;
-- try to power furnace on top of it
if energy >= 1 then -- need at least 1 energy
pos.y = pos.y + 1 ; local node = minetest.get_node ( pos ) . name ;
if node == " default:furnace " or node == " default:furnace_active " then
local fmeta = minetest.get_meta ( pos ) ;
local fuel_totaltime = fmeta : get_float ( " fuel_totaltime " ) or 0 ;
local fuel_time = fmeta : get_float ( " fuel_time " ) or 0 ;
2016-04-01 14:49:04 +02:00
local t0 = meta : get_int ( " ftime " ) ; -- furnace time
local t1 = minetest.get_gametime ( ) ;
if t1 - t0 < machines_timer then return end -- to prevent too quick furnace acceleration
meta : set_int ( " ftime " , t1 ) ;
2016-03-25 00:16:03 +01:00
if fuel_time > 4 then -- twice as fast cooking
local src_time = fmeta : get_float ( " src_time " ) or 0
fmeta : set_float ( " src_time " , src_time + 5 ) ;
end
if fuel_time > 40 or fuel_totaltime == 0 then -- must burn for at least 40 secs or furnace out of fuel
fmeta : set_float ( " fuel_totaltime " , 60 ) ; fmeta : set_float ( " fuel_time " , 0 ) -- add 60 second burn time to furnace
energy = energy - 1 ; -- use up one energy
meta : set_float ( " energy " , energy ) ;
-- update energy display
meta : set_string ( " infotext " , " energy: " .. math.ceil ( energy * 10 ) / 10 .. " / " .. capacity ) ;
end
if energy >= 1 then -- no need to recharge yet, will still work next time
return
else
local infotext = meta : get_string ( " infotext " ) ;
local new_infotext = " furnace needs at least 1 energy " ;
if new_infotext ~= infotext then -- dont update unnecesarilly
meta : set_string ( " infotext " , new_infotext ) ;
2016-04-01 15:13:54 +02:00
pos.y = pos.y - 1 ; -- so that it points to battery again!
2016-03-25 00:16:03 +01:00
end
end
else
pos.y = pos.y - 1 ;
end
end
-- try to recharge by converting inserted fuel/power cells into energy
if energy < capacity then -- not full, try to recharge
battery_recharge ( pos ) ;
end
end
} } ,
2016-02-29 11:35:12 +01:00
2016-03-25 00:16:03 +01:00
on_rightclick = function ( pos , node , player , itemstack , pointed_thing )
local meta = minetest.get_meta ( pos ) ;
local privs = minetest.get_player_privs ( player : get_player_name ( ) ) ;
if minetest.is_protected ( pos , player : get_player_name ( ) ) and not privs.privs then return end -- only owner can interact with recycler
battery_update_meta ( pos ) ;
end ,
2016-02-29 11:35:12 +01:00
2016-03-25 00:16:03 +01:00
on_receive_fields = function ( pos , formname , fields , sender )
if fields.quit then return end
local meta = minetest.get_meta ( pos ) ;
battery_update_meta ( pos ) ;
end ,
2016-02-29 11:35:12 +01:00
2016-03-25 00:16:03 +01:00
allow_metadata_inventory_put = function ( pos , listname , index , stack , player )
local meta = minetest.get_meta ( pos ) ;
local privs = minetest.get_player_privs ( player : get_player_name ( ) ) ;
if minetest.is_protected ( pos , player : get_player_name ( ) ) and not privs.privs then return 0 end
return stack : get_count ( ) ;
end ,
allow_metadata_inventory_take = function ( pos , listname , index , stack , player )
local meta = minetest.get_meta ( pos ) ;
local privs = minetest.get_player_privs ( player : get_player_name ( ) ) ;
if minetest.is_protected ( pos , player : get_player_name ( ) ) and not privs.privs then return 0 end
return stack : get_count ( ) ;
end ,
on_metadata_inventory_put = function ( pos , listname , index , stack , player )
if listname == " fuel " then
battery_recharge ( pos ) ;
battery_update_meta ( pos ) ;
elseif listname == " upgrade " then
battery_upgrade ( pos ) ;
battery_update_meta ( pos ) ;
end
return stack : get_count ( ) ;
end ,
2016-02-29 11:35:12 +01:00
2016-03-25 00:16:03 +01:00
on_metadata_inventory_take = function ( pos , listname , index , stack , player )
if listname == " upgrade " then
battery_upgrade ( pos ) ;
battery_update_meta ( pos ) ;
end
return stack : get_count ( ) ;
end ,
allow_metadata_inventory_move = function ( pos , from_list , from_index , to_list , to_index , count , player )
return 0 ;
end ,
can_dig = function ( pos )
local meta = minetest.get_meta ( pos ) ;
if meta : get_int ( " upgrade " ) ~= 0 then return false else return true end
2015-10-19 11:26:09 +02:00
end
2016-03-25 00:16:03 +01:00
} )
-- GENERATOR
local generator_update_meta = function ( pos )
local meta = minetest.get_meta ( pos ) ;
local list_name = " nodemeta: " .. pos.x .. ' , ' .. pos.y .. ' , ' .. pos.z
2015-10-19 11:26:09 +02:00
2016-03-25 00:16:03 +01:00
local form =
2016-03-26 14:03:00 +01:00
" size[8,6.5] " .. -- width, height
2016-03-25 00:16:03 +01:00
" label[0,0;POWER CRYSTALS] " .. " label[6,0;UPGRADE] " ..
" label[1,1;UPGRADE LEVEL " .. meta : get_int ( " upgrade " ) .. " (gold and diamond block)] " ..
" list[ " .. list_name .. " ;fuel;0.,0.5;1,1;] " .. " list[ " .. list_name .. " ;upgrade;6.,0.5;2,1;] " ..
2016-03-26 14:03:00 +01:00
" list[current_player;main;0,2.5;8,4;] " ..
2016-03-25 00:16:03 +01:00
" button[4.5,0.35;1.5,1;OK;REFRESH] " ;
meta : set_string ( " formspec " , form ) ;
end
generator_upgrade = function ( pos )
local meta = minetest.get_meta ( pos ) ;
local inv = meta : get_inventory ( ) ;
local count1 , count2 ; count1 = 0 ; count2 = 0 ;
local stack , item , count ;
for i = 1 , 2 do
stack = inv : get_stack ( " upgrade " , i ) ; item = stack : get_name ( ) ; count = stack : get_count ( ) ;
if item == " default:goldblock " then
count1 = count1 + count
elseif item == " default:diamondblock " then
count2 = count2 + count
end
end
if count1 < count2 then count = count1 else count = count2 end
meta : set_int ( " upgrade " , count ) ;
end
minetest.register_node ( " basic_machines:generator " , {
2016-03-26 14:03:00 +01:00
description = " Generator - very expensive, generates power crystals that provide power. Its upgradeable. " ,
2016-03-25 00:16:03 +01:00
tiles = { " basic_machine_side.png " , " basic_machine_side.png " , " basic_machine_generator.png " } ,
groups = { oddly_breakable_by_hand = 2 , mesecon_effector_on = 1 } ,
sounds = default.node_sound_wood_defaults ( ) ,
after_place_node = function ( pos , placer )
local meta = minetest.get_meta ( pos ) ;
meta : set_string ( " infotext " , " generator - generates power crystals that provide power. Upgrade with up to 99 gold/diamond blocks. " ) ;
meta : set_string ( " owner " , placer : get_player_name ( ) ) ;
local inv = meta : get_inventory ( ) ;
inv : set_size ( " fuel " , 1 * 1 ) ; -- here generated power crystals are placed
inv : set_size ( " upgrade " , 2 * 1 ) ;
meta : set_int ( " upgrade " , 0 ) ; -- upgrade level determines quality of produced crystals
2015-10-19 11:26:09 +02:00
end ,
2016-03-25 00:16:03 +01:00
on_rightclick = function ( pos , node , player , itemstack , pointed_thing )
local meta = minetest.get_meta ( pos ) ;
local privs = minetest.get_player_privs ( player : get_player_name ( ) ) ;
if minetest.is_protected ( pos , player : get_player_name ( ) ) and not privs.privs then return end -- only owner can interact with recycler
generator_update_meta ( pos ) ;
end ,
2015-10-19 11:26:09 +02:00
2016-03-25 00:16:03 +01:00
on_receive_fields = function ( pos , formname , fields , sender )
if fields.quit then return end
local meta = minetest.get_meta ( pos ) ;
generator_update_meta ( pos ) ;
end ,
allow_metadata_inventory_put = function ( pos , listname , index , stack , player )
local meta = minetest.get_meta ( pos ) ;
local privs = minetest.get_player_privs ( player : get_player_name ( ) ) ;
if minetest.is_protected ( pos , player : get_player_name ( ) ) and not privs.privs then return 0 end
return stack : get_count ( ) ;
end ,
2016-02-29 13:20:58 +01:00
2016-03-25 00:16:03 +01:00
allow_metadata_inventory_take = function ( pos , listname , index , stack , player )
2016-02-29 13:20:58 +01:00
local meta = minetest.get_meta ( pos ) ;
2016-03-25 00:16:03 +01:00
local privs = minetest.get_player_privs ( player : get_player_name ( ) ) ;
if minetest.is_protected ( pos , player : get_player_name ( ) ) and not privs.privs then return 0 end
return stack : get_count ( ) ;
end ,
on_metadata_inventory_put = function ( pos , listname , index , stack , player )
if listname == " upgrade " then
generator_upgrade ( pos ) ;
generator_update_meta ( pos ) ;
2016-02-29 13:20:58 +01:00
end
2016-03-25 00:16:03 +01:00
return stack : get_count ( ) ;
end ,
on_metadata_inventory_take = function ( pos , listname , index , stack , player )
if listname == " upgrade " then
generator_upgrade ( pos ) ;
generator_update_meta ( pos ) ;
end
return stack : get_count ( ) ;
end ,
allow_metadata_inventory_move = function ( pos , from_list , from_index , to_list , to_index , count , player )
return 0 ;
end ,
can_dig = function ( pos )
local meta = minetest.get_meta ( pos ) ;
if meta : get_int ( " upgrade " ) ~= 0 then return false else return true end
2016-02-29 13:20:58 +01:00
end
2015-10-19 11:26:09 +02:00
} )
2016-03-25 00:16:03 +01:00
minetest.register_abm ( {
nodenames = { " basic_machines:generator " } ,
neighbors = { " " } ,
interval = 20 ,
chance = 1 ,
action = function ( pos , node , active_object_count , active_object_count_wider )
local meta = minetest.get_meta ( pos ) ;
local upgrade = meta : get_int ( " upgrade " ) ;
local inv = meta : get_inventory ( ) ;
local stack = inv : get_stack ( " fuel " , 1 ) ;
local crystal , text ;
if upgrade >= 99 then
crystal = " basic_machines:power_rod "
text = " upgrade level 99: generating power rod " ;
elseif upgrade >= 20 then
crystal = " basic_machines:power_block "
text = " upgrade level 20: generating power block " ;
else
crystal = " basic_machines:power_cell "
text = " upgrade level 0: generating power cell " ;
end
local morecrystal = ItemStack ( crystal )
stack : add_item ( morecrystal ) ;
inv : set_stack ( " fuel " , 1 , stack )
meta : set_string ( " infotext " , text )
end
} )
-- API for power distribution
function basic_machines . check_power ( pos , power_draw ) -- mover checks power source - battery
--minetest.chat_send_all(" battery: check_power " .. minetest.pos_to_string(pos) .. " " .. power_draw)
if minetest.get_node ( pos ) . name ~= " basic_machines:battery "
2015-10-19 11:26:09 +02:00
then return 0
end
2016-03-25 00:16:03 +01:00
local meta = minetest.get_meta ( pos ) ;
local energy = meta : get_float ( " energy " ) ;
local capacity = meta : get_float ( " capacity " ) ;
2016-03-28 20:38:46 +02:00
local maxpower = meta : get_float ( " maxpower " ) ;
if power_draw > maxpower then
meta : set_string ( " infotext " , " Power draw required : " .. power_draw .. " maximum power output " .. maxpower .. " . Please upgrade battery " )
2016-03-25 00:16:03 +01:00
return 0 ;
2015-10-19 11:26:09 +02:00
end
2016-03-25 00:16:03 +01:00
if power_draw > energy then
energy = battery_recharge ( pos ) ; -- try recharge battery and continue operation immidiately
end
energy = energy - power_draw ;
if energy < 0 then
2016-03-26 14:03:00 +01:00
meta : set_string ( " infotext " , " used fuel provides too little power for current power draw " .. power_draw ) ;
2016-03-25 00:16:03 +01:00
return 0
end -- recharge wasnt enough, needs to be repeated manually, return 0 power available
meta : set_float ( " energy " , energy ) ;
-- update energy display
meta : set_string ( " infotext " , " energy: " .. math.ceil ( energy * 10 ) / 10 .. " / " .. capacity ) ;
return power_draw ;
2015-10-19 11:26:09 +02:00
end
2016-03-25 00:16:03 +01:00
------------------------
-- CRAFTS
------------------------
minetest.register_craft ( {
output = " basic_machines:battery " ,
recipe = {
{ " " , " default:steel_ingot " , " " } ,
{ " default:steel_ingot " , " default:mese " , " default:steel_ingot " } ,
{ " " , " default:diamond " , " " } ,
}
} )
2015-10-19 11:26:09 +02:00
minetest.register_craft ( {
2016-03-25 00:16:03 +01:00
output = " basic_machines:generator " ,
2015-10-19 11:26:09 +02:00
recipe = {
2016-03-26 14:03:00 +01:00
{ " " , " " , " " } ,
2016-03-25 00:16:03 +01:00
{ " default:diamondblock " , " basic_machines:battery " , " default:diamondblock " } ,
{ " default:diamondblock " , " default:diamondblock " , " default:diamondblock " }
2015-10-19 11:26:09 +02:00
}
2016-03-25 00:16:03 +01:00
} )
minetest.register_craftitem ( " basic_machines:power_cell " , {
2016-03-26 14:03:00 +01:00
description = " Power cell - provides 1 power " ,
2016-03-25 00:16:03 +01:00
inventory_image = " power_cell.png " ,
2016-03-26 14:03:00 +01:00
stack_max = 25
2016-03-25 00:16:03 +01:00
} )
minetest.register_craftitem ( " basic_machines:power_block " , {
2016-03-26 14:03:00 +01:00
description = " Power block - provides 10 power " ,
2016-03-25 00:16:03 +01:00
inventory_image = " power_block.png " ,
2016-03-26 14:03:00 +01:00
stack_max = 25
2016-03-25 00:16:03 +01:00
} )
minetest.register_craftitem ( " basic_machines:power_rod " , {
2016-03-26 14:03:00 +01:00
description = " Power rod - provides 100 power " ,
2016-03-25 00:16:03 +01:00
inventory_image = " power_rod.png " ,
2016-03-26 14:03:00 +01:00
stack_max = 25
} )