forked from mad-star-studio/Voxelis
More work being done. And... bugs.
This commit is contained in:
parent
0242488c9e
commit
a260c4a33a
20 changed files with 1102 additions and 80 deletions
152
mods/ITEMS/vox_coloring/README.md
Normal file
152
mods/ITEMS/vox_coloring/README.md
Normal file
|
@ -0,0 +1,152 @@
|
|||
# Vox Coloring Mod
|
||||
|
||||
The `vox_coloring` mod is a dynamic and robust system for adding colorable items, blocks, and decorations to your Minetest game. It enables automatic registration of dyeable variants, recipes for applying and removing dyes, and integration with other mods.
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
- **Dynamic Dye Registration**:
|
||||
- Automatically generates colorable variants of nodes and items.
|
||||
- Uses a neutral "template" texture for consistent colorization.
|
||||
|
||||
- **Custom Recipes**:
|
||||
- Recipes for dyeing nodes and items.
|
||||
- Recipes for reverting dyed objects to their original state.
|
||||
|
||||
- **Spraygun Tool**:
|
||||
- Dye objects directly in the world with a spraygun.
|
||||
|
||||
- **Cleaning Station**:
|
||||
- Revert dyed objects in bulk using the cleaning station.
|
||||
|
||||
- **Mod Integration**:
|
||||
- Other mods can easily register their own dyeable items.
|
||||
|
||||
---
|
||||
|
||||
## How to Use
|
||||
|
||||
### Registering Dyeable Items/Blocks
|
||||
|
||||
To register a dyeable item or block, call the `register_dyeable` function in your mod:
|
||||
|
||||
```lua
|
||||
-- List of dyeable things
|
||||
local dyeable_blocks = {"sand", "terracotta", "marble", "cobblestone", "sandstone"}
|
||||
|
||||
-- Register base things their dyeable variants
|
||||
for _, base_block in ipairs(dyeable_blocks) do
|
||||
vox_coloring.register_dyeable("vox_worldblocks", base_block)
|
||||
end
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
||||
```plaintext
|
||||
modname: The name of your mod (e.g., vox_worldblocks).
|
||||
base_item: The name of the base item/block to make dyeable.
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```lua
|
||||
vox_coloring.register_dyeable("vox_worldblocks", "sand")
|
||||
```
|
||||
|
||||
### Objects Added
|
||||
|
||||
#### Cleaning Solvent
|
||||
|
||||
```plaintext
|
||||
Soap | Bucket of Water | Salt
|
||||
Ash
|
||||
```
|
||||
|
||||
#### Cleaning Station
|
||||
|
||||
```plaintext
|
||||
Iron Ingot | Bucket of Water | Iron Ingot
|
||||
Stone | Soap | Stone
|
||||
Stone | Empty | Stone
|
||||
```
|
||||
|
||||
Our recipe expects these to exist, but you can edit things to suit your game.
|
||||
|
||||
```lua
|
||||
-- Ash
|
||||
minetest.register_craftitem("vox_mats:ash", {
|
||||
description = "Ash",
|
||||
inventory_image = "ash.png",
|
||||
groups = {crumbly = 3},
|
||||
})
|
||||
|
||||
-- Salt
|
||||
minetest.register_craftitem("vox_mats:salt", {
|
||||
description = "Salt",
|
||||
inventory_image = "salt.png",
|
||||
})
|
||||
|
||||
-- Lye
|
||||
minetest.register_craftitem("vox_mats:lye", {
|
||||
description = "Lye",
|
||||
inventory_image = "lye.png",
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "vox_mats:lye",
|
||||
recipe = {
|
||||
{"vox_mats:ash", "bucket:water_bucket"},
|
||||
},
|
||||
replacements = {{"bucket:water_bucket", "bucket:bucket"}},
|
||||
})
|
||||
|
||||
-- Soap
|
||||
minetest.register_craftitem("vox_mats:soap", {
|
||||
description = "Soap",
|
||||
inventory_image = "soap.png",
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "vox_mats:soap",
|
||||
recipe = {
|
||||
{"vox_mobdrops:fat", "vox_mats:lye", "vox_mats:salt"},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
We also expect colors to be registered somewhere. Our personal example:
|
||||
Not full file, but vox_colors contains this part vox_coloring needs...
|
||||
|
||||
```lua
|
||||
vox_colors = {
|
||||
WHITE = "#FFFFFF",
|
||||
LIGHTGREY = "#D3D3D3",
|
||||
SILVER = "#C0C0C0",
|
||||
GREY = "#808080",
|
||||
BLACK = "#000000",
|
||||
RED = "#FF0000",
|
||||
DARK_RED = "#8B0000",
|
||||
YELLOW = "#FFFF00",
|
||||
GOLD = "#FFD700",
|
||||
ORANGE = "#FFA500",
|
||||
PUMPKIN = "#FF7518",
|
||||
CREAM = "#FFFDD0",
|
||||
TAN = "#D2B48C",
|
||||
BROWN = "#A52A2A",
|
||||
DARK_BROWN = "#8B4513",
|
||||
LIME = "#00FF00",
|
||||
MINT = "#98FF98",
|
||||
EMERALD = "#50C878",
|
||||
DARK_GREEN = "#006400",
|
||||
TURQUOISE = "#40E0D0",
|
||||
TEAL = "#008080",
|
||||
CYAN = "#00FFFF",
|
||||
BLUE = "#0000FF",
|
||||
NAVY = "#000080",
|
||||
MAGENTA = "#FF00FF",
|
||||
VIOLET = "#EE82EE",
|
||||
PURPLE = "#800080",
|
||||
INDIGO = "#4B0082",
|
||||
PINK = "#FF69B4",
|
||||
FLAMINGO = "#FC8EAC",
|
||||
}
|
||||
```
|
212
mods/ITEMS/vox_coloring/init.lua
Normal file
212
mods/ITEMS/vox_coloring/init.lua
Normal file
|
@ -0,0 +1,212 @@
|
|||
-- Vox Coloring System
|
||||
|
||||
-- Register dyes dynamically based on vox_colors
|
||||
for color_name, color_hex in pairs(vox_colors) do
|
||||
if type(color_hex) == "string" and vox_colors.validate(color_hex) then
|
||||
minetest.register_craftitem("vox_coloring:dye_" .. color_name:lower(), {
|
||||
description = color_name .. " Dye",
|
||||
inventory_image = "dye_template.png^[multiply:" .. color_hex,
|
||||
groups = {dye = 1},
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- Table to hold registered dyeable items
|
||||
local dyeable_registry = {}
|
||||
|
||||
-- Function for other mods to register colorable items or blocks
|
||||
function vox_coloring.register_dyeable(modname, base_item)
|
||||
dyeable_registry[modname] = dyeable_registry[modname] or {}
|
||||
table.insert(dyeable_registry[modname], base_item)
|
||||
|
||||
-- Get the original node definition
|
||||
local base_item_full = modname .. ":" .. base_item
|
||||
local base_def = minetest.registered_nodes[base_item_full]
|
||||
|
||||
if not base_def then
|
||||
minetest.log("error", "[vox_coloring] Failed to register dyeable item: " .. base_item_full .. " does not exist.")
|
||||
return
|
||||
end
|
||||
|
||||
-- Derive the template texture by appending `_colorize` to the base texture filename
|
||||
local base_texture = base_def.tiles and base_def.tiles[1]
|
||||
if not base_texture then
|
||||
minetest.log("error", "[vox_coloring] No texture found for " .. base_item_full)
|
||||
return
|
||||
end
|
||||
local colorize_texture = base_texture:gsub("%.png$", "_colorize.png")
|
||||
|
||||
-- Iterate over all colors and register dyeable variants
|
||||
for color_name, color_hex in pairs(vox_colors) do
|
||||
if type(color_hex) == "string" then
|
||||
local colored_item = modname .. ":" .. base_item .. "_" .. color_name:lower()
|
||||
|
||||
-- Register the colored version of the item/block
|
||||
minetest.register_node(colored_item, {
|
||||
description = base_def.description .. " (" .. color_name .. ")",
|
||||
tiles = {colorize_texture .. "^[multiply:" .. color_hex},
|
||||
groups = base_def.groups or {},
|
||||
})
|
||||
|
||||
-- Register recipe to dye the item/block
|
||||
minetest.register_craft({
|
||||
output = colored_item,
|
||||
recipe = {
|
||||
{base_item_full, "vox_coloring:dye_" .. color_name:lower()},
|
||||
},
|
||||
})
|
||||
|
||||
-- Register recipe to undye the item/block
|
||||
minetest.register_craft({
|
||||
output = base_item_full,
|
||||
recipe = {
|
||||
{colored_item, "vox_coloring:cleaning_solvent"},
|
||||
},
|
||||
replacements = {{"vox_coloring:cleaning_solvent", "bucket:bucket"}},
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Function to unregister a dyeable item or block
|
||||
function vox_coloring.unregister_dyeable(modname, base_item)
|
||||
if not dyeable_registry[modname] then return end
|
||||
for i, item in ipairs(dyeable_registry[modname]) do
|
||||
if item == base_item then
|
||||
table.remove(dyeable_registry[modname], i)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- Remove all colored variants and recipes
|
||||
for color_name, _ in pairs(vox_colors) do
|
||||
local colored_item = modname .. ":" .. base_item .. "_" .. color_name:lower()
|
||||
minetest.unregister_item(colored_item)
|
||||
end
|
||||
end
|
||||
|
||||
-- Spraygun Tool
|
||||
minetest.register_tool("vox_coloring:spraygun", {
|
||||
description = "Spraygun",
|
||||
inventory_image = "spraygun.png",
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
if pointed_thing.type == "node" then
|
||||
local node = minetest.get_node(pointed_thing.under)
|
||||
local meta = itemstack:get_meta()
|
||||
local dye_color = meta:get_string("dye_color")
|
||||
|
||||
if dye_color and vox_colors[dye_color:upper()] then
|
||||
local modname, item_base = node.name:match("^(.-):(.*)")
|
||||
if modname and item_base then
|
||||
local colored_item = modname .. ":" .. item_base .. "_" .. dye_color:lower()
|
||||
if minetest.registered_nodes[colored_item] then
|
||||
minetest.swap_node(pointed_thing.under, {name = colored_item})
|
||||
itemstack:add_wear(65535 / 100) -- Simulate durability loss
|
||||
minetest.chat_send_player(user:get_player_name(), "Dyed with " .. dye_color .. "!")
|
||||
else
|
||||
minetest.chat_send_player(user:get_player_name(), "Cannot dye this object.")
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(user:get_player_name(), "No valid target for dye.")
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(user:get_player_name(), "No valid dye loaded in the spraygun.")
|
||||
end
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
|
||||
-- Add dye to the spraygun
|
||||
minetest.register_craftitem("vox_coloring:dye_cartridge", {
|
||||
description = "Dye Cartridge",
|
||||
inventory_image = "dye_cartridge.png",
|
||||
on_place = function(itemstack, user, pointed_thing)
|
||||
local wielded = user:get_wielded_item()
|
||||
if wielded:get_name() == "vox_coloring:spraygun" then
|
||||
local meta = wielded:get_meta()
|
||||
local dye_color = itemstack:get_name():match("vox_coloring:dye_(%w+)")
|
||||
if dye_color then
|
||||
meta:set_string("dye_color", dye_color)
|
||||
minetest.chat_send_player(user:get_player_name(), "Spraygun loaded with " .. dye_color .. " dye!")
|
||||
return itemstack:take_item()
|
||||
else
|
||||
minetest.chat_send_player(user:get_player_name(), "Failed to load dye into the spraygun.")
|
||||
end
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
|
||||
-- Cleaning Solvent
|
||||
minetest.register_craftitem("vox_coloring:cleaning_solvent", {
|
||||
description = "Cleaning Solvent",
|
||||
inventory_image = "cleaning_solvent.png",
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
if pointed_thing.type == "node" then
|
||||
local node = minetest.get_node(pointed_thing.under)
|
||||
local modname, item_base = node.name:match("^(.-):(.*)")
|
||||
if modname and item_base then
|
||||
local base_item = item_base:match("^(.-)_")
|
||||
if base_item then
|
||||
local original_item = modname .. ":" .. base_item
|
||||
if minetest.registered_nodes[original_item] then
|
||||
minetest.swap_node(pointed_thing.under, {name = original_item})
|
||||
itemstack:take_item()
|
||||
minetest.chat_send_player(user:get_player_name(), "Reverted to original state.")
|
||||
else
|
||||
minetest.chat_send_player(user:get_player_name(), "This block cannot be cleaned.")
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(user:get_player_name(), "No dye detected on this block.")
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(user:get_player_name(), "No dye detected on this block.")
|
||||
end
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
|
||||
-- Recipe for Cleaning Solvent
|
||||
minetest.register_craft({
|
||||
output = "vox_coloring:cleaning_solvent",
|
||||
recipe = {
|
||||
{"vox_mats:soap", "bucket:water_bucket", "vox_mats:salt"},
|
||||
{"vox_mats:ash", "", ""},
|
||||
},
|
||||
replacements = {{"bucket:water_bucket", "bucket:bucket"}},
|
||||
})
|
||||
|
||||
-- Cleaning Station
|
||||
minetest.register_node("vox_coloring:cleaning_station", {
|
||||
description = "Cleaning Station",
|
||||
tiles = {"cleaning_station_top.png", "cleaning_station_side.png"},
|
||||
groups = {cracky = 2},
|
||||
on_rightclick = function(pos, node, player, itemstack, pointed_thing)
|
||||
local inv = player:get_inventory()
|
||||
if inv:contains_item("main", "vox_coloring:cleaning_solvent") then
|
||||
local node_name = minetest.get_node(pointed_thing.under).name
|
||||
local modname, item_base = node_name:match("^(.-):(.*)")
|
||||
if modname and item_base then
|
||||
local base_item = item_base:match("^(.-)_")
|
||||
if base_item then
|
||||
local original_item = modname .. ":" .. base_item
|
||||
if minetest.registered_nodes[original_item] then
|
||||
minetest.swap_node(pointed_thing.under, {name = original_item})
|
||||
inv:remove_item("main", "vox_coloring:cleaning_solvent")
|
||||
minetest.chat_send_player(player:get_player_name(), "Reverted to original state.")
|
||||
else
|
||||
minetest.chat_send_player(player:get_player_name(), "This block cannot be cleaned.")
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(player:get_player_name(), "No dye detected on this block.")
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(player:get_player_name(), "No dye detected on this block.")
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(player:get_player_name(), "You need cleaning solvent to clean blocks.")
|
||||
end
|
||||
end,
|
||||
})
|
2
mods/ITEMS/vox_coloring/mod.conf
Normal file
2
mods/ITEMS/vox_coloring/mod.conf
Normal file
|
@ -0,0 +1,2 @@
|
|||
name = vox_coloring
|
||||
description = Voxelis - coloring. Adds dynamic dyes, dynamically adds dyed (fill in the blanks) from mods that call upon the function, adds other things that are helpful.
|
Loading…
Add table
Add a link
Reference in a new issue