-- Licenses of media (3D Meshes and textures) -- --------------------------------------- -- Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) -- Copyright (C) 2019 - 2020 Steamed_Punk steamedpunk.mt at gmail.com -- Load support for intllib. local MP = minetest.get_modpath(minetest.get_current_modname()) local S, NS = dofile(MP.."/intllib.lua") -- Original Campfire by Pavel Litvinoff -- Wild Buffalo Code, models and textures by Steamed_Punk -- VARIABLES indianvillage_campfire_cooking = 1; -- nil - not cooked, 1 - cooked indianvillage_campfire_limit = 3; -- nil - unlimited campfire, 1 - limited indianvillage_campfire_ttl = 120; -- Time in sec indianvillage_campfire_stick_time = indianvillage_campfire_ttl/2; -- How long does the stick increase. In sec. indianvillage_campfire = {} -- FUNCTIONS local function fire_particles_on(pos) -- 3 layers of fire local meta = minetest.get_meta(pos) local id = minetest.add_particlespawner({ -- 1 layer big particles fire amount = 9, time = 1.3, minpos = {x = pos.x - 0.2, y = pos.y - 0.4, z = pos.z - 0.2}, maxpos = {x = pos.x + 0.2, y = pos.y - 0.1, z = pos.z + 0.2}, minvel = {x= 0, y= 0, z= 0}, maxvel = {x= 0, y= 0.1, z= 0}, minacc = {x= 0, y= 0, z= 0}, maxacc = {x= 0, y= 0.7, z= 0}, minexptime = 0.5, maxexptime = 0.7, minsize = 2, maxsize = 5, collisiondetection = false, vertical = true, texture = "indianvillage_flame_animated.png", animation = {type="vertical_frames", aspect_w=65, aspect_h=64, length = 0.8,}, -- playername = "singleplayer" }) meta:set_int("layer_1", id) local id = minetest.add_particlespawner({ -- 2 layer smol particles fire amount = 1, time = 1.3, minpos = {x = pos.x - 0.1, y = pos.y, z = pos.z - 0.1}, maxpos = {x = pos.x + 0.1, y = pos.y + 0.4, z = pos.z + 0.1}, minvel = {x= 0, y= 0, z= 0}, maxvel = {x= 0, y= 0.1, z= 0}, minacc = {x= 0, y= 0, z= 0}, maxacc = {x= 0, y= 1, z= 0}, minexptime = 0.4, maxexptime = 0.6, minsize = 0.5, maxsize = 0.7, collisiondetection = false, vertical = true, texture = "indianvillage_flame_animated.png", animation = {type="vertical_frames", aspect_w=64, aspect_h=64, length = 0.7,}, -- playername = "singleplayer" }) meta:set_int("layer_2", id) local id = minetest.add_particlespawner({ --3 layer smoke amount = 1, time = 1.3, minpos = {x = pos.x - 0.1, y = pos.y - 0.2, z = pos.z - 0.1}, maxpos = {x = pos.x + 0.2, y = pos.y + 0.4, z = pos.z + 0.2}, minvel = {x= 0, y= 0, z= 0}, maxvel = {x= 0, y= 0.1, z= 0}, minacc = {x= 0, y= 0, z= 0}, maxacc = {x= 0, y= 1, z= 0}, minexptime = 0.6, maxexptime = 0.8, minsize = 2, maxsize = 4, collisiondetection = true, vertical = true, texture = "indianvillage_smoke_animated.png", animation = {type="vertical_frames", aspect_w=32, aspect_h=32, length = 0.9,}, -- playername = "singleplayer" }) meta:set_int("layer_3", id) end local function fire_particles_off(pos) local meta = minetest.get_meta(pos) local id_1 = meta:get_int("layer_1"); local id_2 = meta:get_int("layer_2"); local id_3 = meta:get_int("layer_3"); minetest.delete_particlespawner(id_1) minetest.delete_particlespawner(id_2) minetest.delete_particlespawner(id_3) end local function indicator(maxVal, curVal) local percent_val = math.floor(curVal / maxVal * 100) local progress = "" local v = percent_val / 10 for k=1,10 do if v > 0 then progress = progress.."▓" else progress = progress.."▒" end v = v - 1 end return "\n"..progress.." "..percent_val.."%" end local function effect(pos, texture, vlc, acc, time, size) local id = minetest.add_particle({ pos = pos, velocity = vlc, acceleration = acc, expirationtime = time, size = size, collisiondetection = true, vertical = true, texture = texture, }) end local function infotext_edit(meta) local infotext = S("Active campfire") if indianvillage_campfire_limit and indianvillage_campfire_ttl > 0 then local it_val = meta:get_int("it_val"); infotext = infotext..indicator(indianvillage_campfire_ttl, it_val) end local cooked_time = meta:get_int('cooked_time'); if indianvillage_campfire_cooking and cooked_time ~= 0 then local cooked_cur_time = meta:get_int('cooked_cur_time'); infotext = infotext.."\n"..S("Cooking")..indicator(cooked_time, cooked_cur_time) end meta:set_string('infotext', infotext) end local function cooking(pos, itemstack) local meta = minetest.get_meta(pos) local cooked, _ = minetest.get_craft_result({method = "cooking", width = 1, items = {itemstack}}) local cookable = cooked.time ~= 0 if cookable and indianvillage_campfire_cooking then local eat_y = ItemStack(cooked.item:to_table().name):get_definition().on_use if string.find(minetest.serialize(eat_y), "do_item_eat") and meta:get_int("cooked_time") == 0 then meta:set_int('cooked_time', cooked.time); meta:set_int('cooked_cur_time', 0); local name = itemstack:to_table().name local texture = itemstack:get_definition().inventory_image infotext_edit(meta) effect( {x = pos.x, y = pos.y+0.4, z = pos.z}, texture, {x=0, y=-1/cooked.time, z=0}, {x=0, y=0, z=0}, cooked.time/2, 4 ) minetest.after(cooked.time/2, function() if meta:get_int("it_val") > 0 then effect( {x = pos.x, y = pos.y-0.1, z = pos.z}, texture, {x=0, y=1/cooked.time, z=0}, {x=0, y=0, z=0}, cooked.time/2, 4 ) local item = cooked.item:to_table().name minetest.after(cooked.time/2, function(item) if meta:get_int("it_val") > 0 then minetest.add_item({x=pos.x, y=pos.y+0.5, z=pos.z}, item) meta:set_int('cooked_time', 0); meta:set_int('cooked_cur_time', 0); else minetest.add_item({x=pos.x, y=pos.y+0.5, z=pos.z}, name) end end, item) else minetest.add_item({x=pos.x, y=pos.y+0.5, z=pos.z}, name) end end) if not minetest.setting_getbool("creative_mode") then itemstack:take_item() return itemstack end end end end -- NODES minetest.register_node('nativeamericanvillage:fireplace', { description = S("fireplace"), drawtype = 'mesh', mesh = 'indianvillage_campfireoff.obj', tiles = {name='indianvillage_campfire.png'}, walkable = false, buildable_to = false, sunlight_propagates = false, paramtype = 'light', groups = {dig_immediate=3, flammable=0, not_in_creative_inventory=1}, selection_box = { type = 'fixed', fixed = { -1, -1, -1, 1, -1, 1 }, }, drop = {max_items = 3, items = {{items = {"group:tree 3"}}}}, on_construct = function(pos) local meta = minetest.get_meta(pos) meta:set_string('infotext', S("fireplace")); end, }) minetest.register_node('nativeamericanvillage:campfireoff', { description = S("Campfire"), drawtype = 'mesh', mesh = 'indianvillage_campfireoff.obj', tiles = {name='indianvillage_campfire.png'}, inventory_image = "item_campfire.png", wield_image = "item_campfire.png", walkable = false, buildable_to = false, sunlight_propagates = true, groups = {dig_immediate=3, flammable=0}, paramtype = 'light', selection_box = { type = 'fixed', fixed = { -0.48, -0.5, -0.48, 0.48, -0.4, 0.48 }, }, on_construct = function(pos) local meta = minetest.get_meta(pos) meta:set_string('infotext', S("Campfire")); end, on_rightclick = function(pos, node, player, itemstack, pointed_thing) if itemstack:get_name() == "fire:flint_and_steel" then minetest.sound_play("fire_flint_and_steel",{pos = pos, gain = 0.5, max_hear_distance = 8}) minetest.set_node(pos, {name = 'nativeamericanvillage:campfireon'}) local id = minetest.add_particle({ pos = {x = pos.x, y = pos.y, z = pos.z}, velocity = {x=0, y=0.1, z=0}, acceleration = {x=0, y=0, z=0}, expirationtime = 2, size = 4, collisiondetection = true, vertical = true, texture = "indianvillage_smoke_animated.png", animation = {type="vertical_frames", aspect_w=32, aspect_h=32, length = 2.5,}, -- playername = "singleplayer" }) end end, }) minetest.register_node('nativeamericanvillage:campfireon', { description = S("Campfire lit"), drawtype = 'mesh', mesh = 'indianvillage_campfireon.obj', tiles = {name='indianvillage_campfire.png'}, inventory_image = "item_campfire.png", wield_image = "item_campfire.png", walkable = false, buildable_to = false, sunlight_propagates = true, groups = {oddly_breakable_by_hand=3, flammable=0, not_in_creative_inventory=1, igniter=1}, paramtype = 'none', light_source = 13, damage_per_second = 3, drop = "nativeamericanvillage:campfireoff", selection_box = { type = 'fixed', fixed = { -0.48, -0.5, -0.48, 0.48, -0.4, 0.48 }, }, on_rightclick = function(pos, node, player, itemstack, pointed_thing) local meta = minetest.get_meta(pos) cooking(pos, itemstack) if itemstack:get_definition().groups.tree == 1 then local it_val = meta:get_int("it_val") + (indianvillage_campfire_ttl); meta:set_int('it_val', it_val); effect( {x = pos.x, y = pos.y+0.4, z = pos.z}, "item_tree.png", {x=0, y=-1, z=0}, {x=0, y=0, z=0}, 1, 6 ) infotext_edit(meta) if not minetest.setting_getbool("creative_mode") then itemstack:take_item() return itemstack end end end, on_construct = function(pos) local meta = minetest.get_meta(pos) meta:set_int('it_val', indianvillage_campfire_ttl); infotext_edit(meta) minetest.get_node_timer(pos):start(2) end, on_destruct = function(pos, oldnode, oldmetadata, digger) fire_particles_off(pos) local meta = minetest.get_meta(pos) local handle = meta:get_int("handle") minetest.sound_stop(handle) end, on_timer = function(pos) -- Every 6 seconds play sound fire_small local meta = minetest.get_meta(pos) local handle = minetest.sound_play("fire_small",{pos=pos, max_hear_distance = 18, loop=false, gain=0.1}) meta:set_int("handle", handle) minetest.get_node_timer(pos):start(6) end, }) -- CAMPFIRE_CRAFT minetest.register_craft({ output = "nativeamericanvillage:campfireoff", recipe = { {'', 'default:stick', ''}, {'default:stick','nativeamericanvillage:fat', 'default:stick'}, {'group:tree', 'group:tree', 'group:tree'}, } }) -- CAMPFIRE_ITEM_DROPS minetest.register_craftitem("nativeamericanvillage:ash", { description = S("Ash"), inventory_image = "indianvillage_ash.png" }) minetest.register_craftitem("nativeamericanvillage:bone", { description = S("Bone"), inventory_image = "bonemeal_bone.png" }) -- ABM minetest.register_abm({ nodenames = {"nativeamericanvillage:campfireon"}, -- neighbors = {"group:puts_out_fire"}, interval = 1.0, -- Run every 3 seconds chance = 1, -- Select every 1 in 1 nodes catch_up = false, action = function(pos, node, active_object_count, active_object_count_wider) local fpos, num = minetest.find_nodes_in_area( {x=pos.x-1, y=pos.y, z=pos.z-1}, {x=pos.x+1, y=pos.y+1, z=pos.z+1}, {"group:water"} ) if #fpos > 0 then minetest.set_node(pos, {name = 'nativeamericanvillage:campfireon'}) minetest.sound_play("fire_extinguish_flame",{pos = pos, max_hear_distance = 16, gain = 0.15}) else local meta = minetest.get_meta(pos) local it_val = meta:get_int("it_val") - 1; if indianvillage_campfire_limit and indianvillage_campfire_ttl > 0 then if it_val <= 0 then minetest.remove_node(pos) minetest.set_node(pos, {name = 'nativeamericanvillage:fireplace'}) minetest.add_item(pos, "nativeamericanvillage:ash") minetest.add_item(pos, "bonemeal:bone") return end meta:set_int('it_val', it_val); end if indianvillage_campfire_cooking then if meta:get_int('cooked_cur_time') <= meta:get_int('cooked_time') then meta:set_int('cooked_cur_time', meta:get_int('cooked_cur_time') + 1); else meta:set_int('cooked_time', 0); meta:set_int('cooked_cur_time', 0); end end infotext_edit(meta) fire_particles_on(pos) end end })