commit 99fb8d93ea529afec2060c2a4afdbb47aa33df13 Author: Auke Kok Date: Sat Feb 4 01:30:44 2017 -0800 Initial commit. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1bcb8c6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ + +frame - a minetest mod that adds a lag-free item frame + +See spdx.org/licenses to see what the License Identifiers used below mean. + +=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~ + +All source code (lua): + (C) Auke Kok + LGPL-2.1+ + +All models: + (C) Auke Kok + CC-BY-SA-3.0 + +All Textures: + Public-Domain, see: + https://mods.curse.com/texture-packs/minecraft/227527-isabella-ii + +=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~ diff --git a/api.md b/api.md new file mode 100644 index 0000000..85a85a8 --- /dev/null +++ b/api.md @@ -0,0 +1,7 @@ + +## frame API + +`frame.register(name)` --[[ +^ name = node or item name, e.g. "default:sapling" or "default:sword_diamond" +^ the node must be defined and registered first using `minetest.register_node()`. ]] + diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..86eb706 --- /dev/null +++ b/depends.txt @@ -0,0 +1,13 @@ +default +beds? +boats? +bucket? +carts? +doors? +dye? +farming? +fire? +flowers? +tnt? +vessels? +wool? diff --git a/description.txt b/description.txt new file mode 100644 index 0000000..e19c702 --- /dev/null +++ b/description.txt @@ -0,0 +1 @@ +A stylish item and node frame that causes no lag/server load. diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..357fa49 --- /dev/null +++ b/init.lua @@ -0,0 +1,451 @@ + +--[[ + + Copyright (C) 2015 - Auke Kok + + "frame" is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of + the license, or (at your option) any later version. + +--]] + +frame = {} + +-- handle node removal from frame +local function frame_on_punch(pos, node, puncher, pointed_thing) + if puncher and not minetest.check_player_privs(puncher, "protection_bypass") then + local name = puncher:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return false + end + end + + local def = minetest.registered_nodes[node.name] + local item = ItemStack(def.frame_contents) + + -- preserve itemstack metadata and wear + local meta = minetest.get_meta(pos) + local wear = meta:get_int("wear") + if wear then + item:set_wear(wear) + end + local metadata = meta:get_string("metadata") + if metadata ~= "" then + item:set_metadata(metadata) + end + + --minetest.handle_node_drops(pos, {item}, puncher) + local inv = puncher:get_inventory() + if inv:room_for_item("main", item) then + inv:add_item("main", item) + minetest.sound_play(def.sounds.dug, {pos = pos}) + minetest.swap_node(pos, {name = "frame:empty", param2 = node.param2}) + end +end + +-- handle node insertion into frame +local function frame_on_rightclick(pos, node, clicker, itemstack, pointed_thing) + if clicker and not minetest.check_player_privs(clicker, "protection_bypass") then + local name = clicker:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return false + end + end + + local nodename = itemstack:get_name() + if not nodename then + return false + end + + local wear = itemstack:get_wear() + if wear then + local meta = minetest.get_meta(pos) + meta:set_int("wear", wear) + end + local metadata = itemstack:get_metadata() + if metadata ~= "" then + local meta = minetest.get_meta(pos) + meta:set_string("metadata", metadata) + end + + local name = "frame:" .. nodename:gsub(":", "_") + local def = minetest.registered_nodes[name] + if not def then + return false + end + minetest.sound_play(def.sounds.place, {pos = pos}) + minetest.swap_node(pos, {name = name, param2 = node.param2}) + if not minetest.setting_getbool("creative_mode") then + itemstack:take_item() + end + return itemstack +end + +function frame.register(name) + assert(name, "no content passed") + local tiles + + local def = minetest.registered_nodes[name] + if not def then + -- item? + def = minetest.registered_items[name] + assert(def, "not a thing: ".. name) + assert(def.inventory_image, "no inventory image for " .. name) + + tiles = { + {name = "frame_frame.png"}, + {name = def.inventory_image}, + {name = "doors_blank.png"}, + {name = "doors_blank.png"}, + {name = "doors_blank.png"}, + } + else + -- node + if def.inventory_image ~= "" then + -- custom inventory override image first. + tiles = { + {name = "frame_frame.png"}, + {name = def.inventory_image or "doors_blank.png"}, + {name = "doors_blank.png"}, + {name = "doors_blank.png"}, + {name = "doors_blank.png"}, + } + elseif def.drawtype ~= "normal" then + -- use tiles[1] only, but on frame + tiles = { + {name = "frame_frame.png"}, + {name = def.tiles[1] and def.tiles[1].name or def.tiles[1] or "doors_blank.png"}, + {name = "doors_blank.png"}, + {name = "doors_blank.png"}, + {name = "doors_blank.png"}, + } + else -- type(def.tiles[1]) == "table" then + -- multiple tiles + tiles = { + {name = "frame_frame.png"}, + {name = "doors_blank.png"}, + {name = def.tiles[1] and def.tiles[1].name or def.tiles[1] + or "doors_blank.png"}, + {name = def.tiles[2] and def.tiles[2].name or def.tiles[1] + or def.tiles[1] and def.tiles[1].name or def.tiles[1] + or "doors_blank.png"}, + {name = def.tiles[3] and def.tiles[3].name or def.tiles[3] + or def.tiles[2] and def.tiles[2].name or def.tiles[2] + or def.tiles[1] and def.tiles[1].name or def.tiles[1] + or "doors_blank.png"}, + } + end + end + assert(def, name .. " is not a known node or item") + + local desc = def.description + local nodename = def.name:gsub(":", "_") + + minetest.register_node("frame:" .. nodename, { + description = "Frame with " .. desc, + drawtype = "mesh", + mesh = "frame.obj", + tiles = tiles, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + collision_box = { + type = "fixed", + fixed = {-1/2, -1/2, 3/8, 1/2, 1/2, 1/2}, + }, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, 3/8, 1/2, 1/2, 1/2}, + }, + sounds = default.node_sound_defaults(), + groups = {oddly_breakable_by_hand = 1, snappy = 3, not_in_creative_inventory = 1}, + frame_contents = name, + on_punch = frame_on_punch, + }) +end + +-- empty frame +minetest.register_node("frame:empty", { + description = "Frame", + drawtype = "mesh", + mesh = "frame.obj", + tiles = { + {name = "frame_frame.png"}, + {name = "doors_blank.png"}, + {name = "doors_blank.png"}, + {name = "doors_blank.png"}, + {name = "doors_blank.png"}, + }, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + collision_box = { + type = "fixed", + fixed = {-1/2, -1/2, 3/8, 1/2, 1/2, 1/2}, + }, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, 3/8, 1/2, 1/2, 1/2}, + }, + sounds = default.node_sound_defaults(), + groups = {oddly_breakable_by_hand = 3, cracky = 1}, + on_rightclick = frame_on_rightclick, +}) + +-- craft +minetest.register_craft({ + output = "frame:empty", + recipe = { + {"default:stick", "default:stick", "default:stick"}, + {"default:stick", "default:paper", "default:stick"}, + {"default:stick", "default:stick", "default:stick"}, + } +}) + +-- default farming nodes +for _, node in pairs({ + "flowers:rose", + "flowers:tulip", + "flowers:dandelion_yellow", + "flowers:geranium", + "flowers:viola", + "flowers:dandelion_white", + "flowers:mushroom_red", + "flowers:mushroom_brown", + "flowers:waterlily", + "farming:cotton_1", + "farming:cotton_2", + "farming:cotton_3", + "farming:cotton_4", + "farming:cotton_5", + "farming:cotton_6", + "farming:cotton_7", + "farming:cotton_8", + "farming:wheat_1", + "farming:wheat_2", + "farming:wheat_3", + "farming:wheat_4", + "farming:wheat_5", + "farming:wheat_6", + "farming:wheat_7", + "farming:wheat_8", + "farming:wheat", + "farming:flour", + "farming:bread", + "farming:cotton", + "farming:string", + "fire:basic_flame", + "fire:permanent_flame", + "tnt:gunpowder", + "tnt:tnt", + "farming:straw", + "default:stone", + "default:cobble", + "default:stonebrick", + "default:stone_block", + "default:mossycobble", + "default:desert_stone", + "default:desert_cobble", + "default:desert_stonebrick", + "default:desert_stone_block", + "default:sandstone", + "default:sandstonebrick", + "default:sandstone_block", + "default:obsidian", + "default:obsidianbrick", + "default:obsidian_block", + "default:dirt", + "default:dirt_with_grass", + "default:dirt_with_grass_footsteps", + "default:dirt_with_dry_grass", + "default:dirt_with_snow", + "default:sand", + "default:desert_sand", + "default:silver_sand", + "default:gravel", + "default:clay", + "default:snow", + "default:snowblock", + "default:ice", + "default:tree", + "default:wood", + "default:sapling", + "default:leaves", + "default:apple", + "default:jungletree", + "default:junglewood", + "default:jungleleaves", + "default:junglesapling", + "default:pine_tree", + "default:pine_wood", + "default:pine_needles", + "default:pine_sapling", + "default:acacia_tree", + "default:acacia_wood", + "default:acacia_leaves", + "default:acacia_sapling", + "default:aspen_tree", + "default:aspen_wood", + "default:aspen_leaves", + "default:aspen_sapling", + "default:stone_with_coal", + "default:coalblock", + "default:stone_with_iron", + "default:steelblock", + "default:stone_with_copper", + "default:copperblock", + "default:bronzeblock", + "default:stone_with_mese", + "default:mese", + "default:stone_with_gold", + "default:goldblock", + "default:stone_with_diamond", + "default:diamondblock", + "default:cactus", + "default:papyrus", + "default:dry_shrub", + "default:junglegrass", + "default:grass_1", + "default:grass_2", + "default:grass_3", + "default:grass_4", + "default:grass_5", + "default:dry_grass_1", + "default:dry_grass_2", + "default:dry_grass_3", + "default:dry_grass_4", + "default:dry_grass_5", + "default:bush_stem", + "default:bush_leaves", + "default:acacia_bush_stem", + "default:acacia_bush_leaves", + "default:coral_brown", + "default:coral_orange", + "default:coral_skeleton", + "default:water_source", + "default:water_flowing", + "default:river_water_source", + "default:river_water_flowing", + "default:lava_source", + "default:lava_flowing", + "default:torch", + "default:bookshelf", + "default:sign_wall_wood", + "default:sign_wall_steel", + "default:ladder_wood", + "default:ladder_steel", + "default:glass", + "default:obsidian_glass", + "default:brick", + "default:meselamp", + "default:cloud", + "default:furnace", + "default:pick_wood", + "default:pick_stone", + "default:pick_steel", + "default:pick_bronze", + "default:pick_mese", + "default:pick_diamond", + "default:shovel_wood", + "default:shovel_stone", + "default:shovel_steel", + "default:shovel_bronze", + "default:shovel_mese", + "default:shovel_diamond", + "default:axe_wood", + "default:axe_stone", + "default:axe_steel", + "default:axe_bronze", + "default:axe_mese", + "default:axe_diamond", + "default:sword_wood", + "default:sword_stone", + "default:sword_steel", + "default:sword_bronze", + "default:sword_mese", + "default:sword_diamond", + "default:stick", + "default:paper", + "default:book", + "default:book_written", + "default:coal_lump", + "default:iron_lump", + "default:copper_lump", + "default:mese_crystal", + "default:gold_lump", + "default:diamond", + "default:clay_lump", + "default:steel_ingot", + "default:copper_ingot", + "default:bronze_ingot", + "default:gold_ingot", + "default:mese_crystal_fragment", + "default:clay_brick", + "default:obsidian_shard", + "default:flint", + "nyancat:nyancat", + "nyancat:nyancat_rainbow", + "vessels:shelf", + "vessels:glass_bottle", + "vessels:drinking_glass", + "vessels:steel_bottle", + "vessels:glass_fragments", + "doors:door_wood", + "doors:door_steel", + "doors:door_glass", + "doors:door_obsidian_glass", + "doors:trapdoor", + "doors:trapdoor_steel", + "beds:bed", + "beds:fancy_bed", + "carts:cart", + "carts:rail", + "carts:powerrail", + "carts:brakerail", + "fire:flint_and_steel", + "boats:boat", + "screwdriver:screwdriver", + "bucket:bucket_empty", + "bucket:bucket_water", + "bucket:bucket_river_water", + "bucket:bucket_lava", + "wool:white", + "wool:grey", + "wool:black", + "wool:red", + "wool:yellow", + "wool:green", + "wool:cyan", + "wool:blue", + "wool:magenta", + "wool:orange", + "wool:violet", + "wool:brown", + "wool:pink", + "wool:dark_grey", + "wool:dark_green", + "dye:white", + "dye:grey", + "dye:black", + "dye:red", + "dye:yellow", + "dye:green", + "dye:cyan", + "dye:blue", + "dye:magenta", + "dye:orange", + "dye:violet", + "dye:brown", + "dye:pink", + "dye:dark_grey", + "dye:dark_green", +}) do + frame.register(node) +end + +-- inception! +frame.register("frame:empty") + diff --git a/mod.conf b/mod.conf new file mode 100644 index 0000000..3404d84 --- /dev/null +++ b/mod.conf @@ -0,0 +1 @@ +name = frame diff --git a/models/frame.obj b/models/frame.obj new file mode 100644 index 0000000..3fe3916 --- /dev/null +++ b/models/frame.obj @@ -0,0 +1,176 @@ +# Blender v2.78 (sub 0) OBJ File: 'frame.blend' +# www.blender.org +mtllib frame.mtl +o Cube +v 0.437500 -0.437500 0.500000 +v -0.437500 -0.437500 0.500000 +v -0.437500 -0.437500 0.437500 +v 0.437500 -0.437500 0.437500 +v 0.437500 0.437500 0.500000 +v -0.437500 0.437500 0.500000 +v -0.437500 0.437500 0.437500 +v 0.437500 0.437500 0.437500 +v -0.437500 0.375000 0.500000 +v -0.437500 -0.375000 0.500000 +v 0.375000 0.375000 0.500000 +v 0.375000 -0.375000 0.500000 +v -0.375000 -0.375000 0.497000 +v -0.375000 0.375000 0.497000 +v -0.437500 0.375000 0.437500 +v 0.437500 0.375000 0.437500 +v -0.375000 0.375000 0.437500 +v -0.375000 -0.375000 0.437500 +v 0.375000 -0.375000 0.437500 +v 0.375000 0.375000 0.437500 +v 0.312500 0.312500 0.493750 +v 0.312500 -0.312500 0.493750 +v -0.312500 -0.312500 0.493750 +v -0.312500 0.312500 0.493750 +v -0.250000 -0.250000 0.243125 +v -0.250000 0.250000 0.243125 +v 0.250000 -0.250000 0.243125 +v 0.250000 0.250000 0.243125 +v 0.250000 -0.250000 0.493125 +v 0.250000 0.250000 0.493125 +v -0.250000 -0.250000 0.493125 +v -0.250000 0.250000 0.493125 +v 0.437500 0.375000 0.500000 +v 0.437500 -0.375000 0.500000 +v -0.437500 -0.375000 0.437500 +v 0.437500 -0.375000 0.437500 +v 0.375000 0.375000 0.500000 +v 0.375000 0.375000 0.497000 +v 0.375000 -0.375000 0.500000 +v 0.375000 -0.375000 0.497000 +v -0.375000 -0.375000 0.500000 +v -0.375000 -0.375000 0.500000 +v -0.375000 0.375000 0.500000 +v -0.375000 0.375000 0.500000 +vt 0.0625 0.1250 +vt 0.1250 0.1250 +vt 0.1250 0.8750 +vt 0.0625 0.8750 +vt 0.8750 0.9375 +vt 0.8750 0.5000 +vt 0.8750 0.2812 +vt 0.8750 0.0625 +vt 0.9375 0.0625 +vt 0.9375 0.4688 +vt 0.9375 0.8750 +vt 0.9375 0.9375 +vt 0.1250 0.0625 +vt 0.8750 0.0625 +vt 0.8750 0.1250 +vt 0.0625 0.0625 +vt 0.9375 0.0625 +vt 0.9375 0.1250 +vt 0.0625 0.1250 +vt 0.1250 0.0625 +vt 0.1250 0.1250 +vt 0.1250 0.8750 +vt 0.1250 0.9375 +vt 0.0625 0.9375 +vt 0.0625 0.8750 +vt 0.0625 0.4688 +vt 0.0625 0.0625 +vt 0.0625 0.8750 +vt 0.0625 0.9375 +vt 0.9375 0.9375 +vt 0.9375 0.8750 +vt 0.8750 0.8750 +vt 0.1250 0.8750 +vt 0.1250 0.9375 +vt 0.8750 0.8750 +vt 0.8750 0.9375 +vt 0.9375 0.0625 +vt 0.0625 0.0625 +vt 0.0625 0.1250 +vt 0.1250 0.1250 +vt 0.8750 0.1250 +vt 0.9375 0.1250 +vt 0.9375 0.1250 +vt 0.9375 0.8750 +vt 0.0625 0.9375 +vt 0.0625 0.8750 +vt 0.9375 0.8750 +vt 0.9375 0.9375 +vt 0.1250 0.8750 +vt 0.1250 0.1250 +vt 0.8750 0.1250 +vt 0.8750 0.8750 +vt 0.9375 0.8750 +vt 0.9375 0.9375 +vt 0.0625 0.9375 +vt 0.0625 0.8750 +vt 0.1250 0.8750 +vt 0.8750 0.8750 +vt 0.0625 0.0625 +vt 0.9375 0.0625 +vt 0.9375 0.1250 +vt 0.8750 0.1250 +vt 0.1250 0.1250 +vt 0.0625 0.1250 +vt 0.0000 1.0000 +vt -0.0000 -0.0000 +vt 1.0000 0.0000 +vt 1.0000 1.0000 +vt 0.9999 0.5000 +vt 0.9999 0.0001 +vt 0.0001 0.0001 +vt 0.0001 0.5000 +vt 0.0000 1.0000 +vt -0.0000 0.5000 +vt 1.0000 0.5000 +vt 1.0000 1.0000 +vt 1.0000 1.0000 +vt 1.0000 0.0000 +vt 0.0000 -0.0000 +vt 0.0000 1.0000 +vt 0.5000 0.0001 +vt 0.0001 0.0001 +vt 0.0000 1.0000 +vt 0.5000 1.0000 +vt 1.0000 -0.0000 +vt 0.5000 -0.0000 +vt 0.5000 1.0000 +vt 1.0000 1.0000 +vn -1.0000 -0.0000 -0.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 1.0000 -0.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 -0.0000 -1.0000 +vn 0.0000 0.0000 1.0000 +g Cube_Cube_frame +usemtl frame +s off +f 19/1/1 39/2/1 37/3/1 20/4/1 +f 5/5/2 33/6/2 34/7/2 1/8/2 4/9/2 36/10/2 16/11/2 8/12/2 +f 19/13/3 18/14/3 41/15/3 39/2/3 +f 1/16/4 2/17/4 3/18/4 4/19/4 +f 2/20/1 10/21/1 9/22/1 6/23/1 7/24/1 15/25/1 35/26/1 3/27/1 +f 9/28/5 6/29/5 5/30/5 33/31/5 11/32/5 44/33/5 +f 20/34/4 37/3/4 43/35/4 17/36/4 +f 1/37/5 2/38/5 10/39/5 42/40/5 12/41/5 34/42/5 +f 43/35/2 41/15/2 18/43/2 17/44/2 +f 5/45/3 8/46/3 7/47/3 6/48/3 +f 42/40/5 10/39/5 9/28/5 44/33/5 +f 38/49/5 40/50/5 13/51/5 14/52/5 +f 15/53/5 7/54/5 8/55/5 16/56/5 20/57/5 17/58/5 +f 33/31/5 34/42/5 12/41/5 11/32/5 +f 4/59/5 3/60/5 35/61/5 18/62/5 19/63/5 36/64/5 +f 15/53/5 17/58/5 18/62/5 35/61/5 +f 36/64/5 19/63/5 20/57/5 16/56/5 +g Cube_Cube_image +usemtl image +f 21/65/5 22/66/5 23/67/5 24/68/5 +g Cube_Cube_node.top +usemtl node.top +f 30/69/3 28/70/3 26/71/3 32/72/3 +g Cube_Cube_node.bottom +usemtl node.bottom +f 27/73/4 29/74/4 31/75/4 25/76/4 +g Cube_Cube_node.side +usemtl node.side +f 26/77/6 25/78/6 27/79/6 28/80/6 +f 31/81/2 25/82/2 26/83/2 32/84/2 +f 27/85/1 29/86/1 30/87/1 28/88/1 diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..b10d9df --- /dev/null +++ b/readme.md @@ -0,0 +1,34 @@ + +frame +===== + +This minetest mod adds a lag-free, simple and stylish item and node +frame to minetest. It can contain either nodes or craftitems. + +The player can place these frames in any orientation, just like normal +nodes. Then, with an item or node in hand, the player can place the +item or node into the item frame. If the itemframe is punched, the +item or node is returned to the puncher. + +The concept works through the use of object materials. The empty +frame node has the same model, but part of the mesh is transparent +and therefore not visible. If an item is inserted, the transparent +textures are replaced with the texture of the item or node, and thus +it looks like the node is inserted, while effectively the frame is +a single node without metadata. + +There are no crafting recipes for each variant. The player can craft +a frame and potentially use `/giveme` to give filled versions of the +frame, but the creative inventory does not contain them as they are +easily filled already. + +The model was made in blender from scratch by the author. + +The texture of the frame itself was created from the itemframe texture +of the excellent Isabella II texture pack, which is Public Domain. The +texture has been reworked to allow for a more detailed texturing of +the frame model. + +The frame mod has an API that can be used by other mods to create +new item/node-frame combinations. See api.md for usage information. + diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000..657de34 Binary files /dev/null and b/screenshot.png differ diff --git a/textures/frame_frame.png b/textures/frame_frame.png new file mode 100644 index 0000000..65f881a Binary files /dev/null and b/textures/frame_frame.png differ