Transmutation, DM/RM Furnaces

No furnace textures yet.
Philosopher's Stone smelting started.
This commit is contained in:
ThePython 2023-09-25 07:41:23 -07:00
parent 915e4cadbe
commit 4bebb3c543
28 changed files with 1521 additions and 128 deletions

View File

@ -41,9 +41,6 @@ All energy values are in `energy.lua`. You can also change the speed at which th
* Alchemical Coal, Mobius Fuel, and Aeternalis Fuel
* Dark and Red Matter Orbs, Blocks, tools, and armor
I don't actually own MineCraft, meaning I don't know exactly how the original mod (Equivalent Exchange) works. I will probably make some minor mistakes, since all I have to go on is the internet.
## Known issues:
* Dark and Red Matter armor look kind of terrible in MineClone. I might fix this eventually...
* There is an error reported in MineClone related to Red Matter armor setting health.
@ -51,7 +48,7 @@ I don't actually own MineCraft, meaning I don't know exactly how the original mo
* With a full set of red matter armor, you can almost instantly go back to 2000 health (1000 hearts), no matter what you health is, by removing one piece of red matter armor and putting it back on. I don't really know what to do about this, because of the previous issue. Normally, I would simply make 2000 the maximum health, and leave the player's health how it is, but that doesn't really work because the extra maximum health would be useless because it's unreachable.
* When items are inserted into the Energy Collector, Deconstructor, or Constructor with MineClone hoppers, it does not trigger the machines to start. I could probably fix this just by looking at the hopper API, so this could be fixed eventually.
* When machines are exploded, they (and the items inside) do not drop. I can't figure out why.
* Dark/Red matter shears will sometimes be treated as normal shears when used by MineClone dispensers. This will not be fixed.
* Dark/Red matter shears will sometimes (randomly) be treated as normal shears when used by MineClone dispensers. This will not be fixed.
* Nodes destroyed by special abilities will not usually update surrounding nodes (so you may end up with floating gravel, flowers, torches, etc.). This will *probably* not be fixed, unless a change to Minetest makes it easier.
If you have a suggestion or notice a bug, visit the [GitHub issues page](https://github.com/thepython10110/exchangeclone/issues).
@ -175,7 +172,7 @@ If you have a suggestion or notice a bug, visit the [GitHub issues page](https:/
* Added energy values for MineClone's new items.
* Changes:
* Changed the amount of damage done by Dark/Red Matter Sword special abilities (used to be `max_damage/distance`, now is `max_damage-distance`)
* A whole bunch of things that won't be noticible when playing, mostly code reorganization. It's *possible* that tools that mine multiple nodes at a time (hammer, pickaxe, hoe, katar, and morningstar) will be less laggy
* A whole bunch of things that won't be noticible when playing, mostly code reorganization. It's *possible* that tools that mine multiple nodes at a time (hammer, pickaxe, hoe, katar, and morningstar) will be slightly less laggy
* Texture/sound license changed to CC-BY-SA-3.0 (because GPLv3+ isn't really meant as a media license).
* Bugfixes:
* Fixed an issue where MineClone dispensers could ONLY be used with Dark/Red Matter Shears (whoops).
@ -186,36 +183,80 @@ If you have a suggestion or notice a bug, visit the [GitHub issues page](https:/
* Removed unnecessary chestplate image (not only is it unused, but I put it in the wrong folder for some reason)
### 4.2
* Bugfixes:
* Fixed a dependency error (thanks, @opfromthestart!)
### 4.3
* New features:
* New items from Why (flying sausage, useful green potatoes, etc.)
* Changes:
* The changelog now lives here!
* Exchange Orbs now change color based on the amount of energy (black->red->green->blue->magenta)
* Exchange Orbs now change color based on the amount of energy (black->red->green->blue->magenta).
* Exchange Orbs now have a maximum energy of 51,200,000 (to match Equivalent Exchange's Klein Star Omegas).
* Water is now worth 0 instead of 1 (since it's infinite)
* Bugfixes:
* Exchange Orbs will now correctly display their energy value (I typed `orb` instead of `exchange_orb` in the energy value list)
### Plans for 5.0
### 5.0 (another *huge* release)
* New features:
* Transmutation Table(t)
* A much better (and cheaper) way to manage energy than the Constructor and Deconstructor.
* Teach items to the table by putting them in the Learn slot.
* Recreate learned items by clicking on them, then the "+1," "+5," "+10," and "+Stack" buttons to add them to the Output slots of the Table(t)
* The Table(t) will not show items that cost more energy than the player has.
* Charge orbs by putting them in the Charge slot.
* The Transmutation Tablet is the portable version of the Transmutation Table, and does exactly the same thing.
* All data (learned items, stored energy, etc.) is stored with the player, and will not be lost upon death or breaking/destroying the Transmutation Table(t).
* Mod developers can now add energy values to their own mods! Just set `exchangeclone_custom_energy` in the item/node definition.
* Alchemical Tome
* Feed this item to a Transmutation Table to teach it *all items* with energy. The Tome will NOT turn into energy, and will be completely lost.
* This is mostly so you can't just use it, then make a new one for no real cost and give it to someone else.
* Dark/Red Matter Furnaces
* Transmutation Tablet (including portable version)
* Much faster than normal furnaces
* The Dark Matter Furnace has a 50% chance to duplicate when smelting ores (raw or otherwise).
* The Red Matter Furnace ALWAYS duplicates ores.
* Can be powered by placing next to an Energy Collector.
* Personal Energy Link
* An item copied from Project Expansion
* Allows you to use hoppers to get items into/out of your Personal Energy (MineClone)
* Upgraded Energy Collectors
* Energy Collector MK1-5
* The ability to upgrade dark/red matter tools to give them fortune, looting, fire aspect, and silk touch
* The ability to upgrade dark/red matter armor to give it thorns and frost walker
* Ability to smelt with the Philosopher's Stone and coal/charcoal
* Mind, Life, Body, and Soul Stones
* Custom Energy Values
* Mod developers can now set their own energy values by setting `exchangeclone_custom_energy` in the item/node definition.
* Added a [wiki](https://github.com/ThePython10110/ExchangeClone/wiki)!
* Changes
* Energy for Dark/Red Matter tool abilities (as well as the Transmutation Table) is no longer stored in an orb, but inside the player.
* The amount of energy you currently have stored is visible in the top right of the screen.
* Because of this, the PESA is now useless and deprecated. It will be removed after a few releases (so probably a couple months at least). Remove any Exchange Orbs from your personal storage.
* A lot of items (including DM/RM tools and armor) will not burn in lava in MineClone2.
* Energy Collectors now send their energy to the placer's personal energy by default.
* Placing an orb into an Energy Collector causes energy to go into the orb instead.
* If the Collector is near a DM/RM Furnace, all energy will be used to fuel the furnace.
* Red Matter Armor now sets your maximum health to 200 instead of 2000
* Energy Collectors now require less light to work (15->14)
* Exchange Orbs are now 18x better as fuel than they used to be
* DM/RM Shovels will now only create paths on blocks below air.
* Bugfixes:
* I must have skipped a row while going through MineClone's mod list. Several mods starting with `mcl_b` or `mcl_c` have been added to the whitelist.
* Removed unnecessary tool repair recipes from dark/red matter tools/armor
* Fixed a couple of armor texture issues in Minetest Game (though it still looks like diamond armor; 3D Armor doesn't support texture modifiers)
* The Red Katar is now actually craftable in Minetest Game (I just forgot that shears were only in MCL2)
### Features that I plan on adding eventually:
* Something that places nodes in a square (with varying range), possibly with a low energy cost
* Ability to smelt with the Philosopher's Stone and coal/charcoal (maybe?)
* Exchangeclone guidebook (maybe depend on doc mod?)
* As soon as Minetest 5.8 comes out, better textures for armor...
* Energy Condenser
* Upgraded Energy Collectors
* Divining Rods
* Rings (I'll probably add a new PESA-like item for holding rings, or just add more slots to the PESA)
* Rings (I'll probably add a new PESA-like item for holding rings)
* Archangel's Smite (though arrows will not track targets)
* Ring of Ignition
* Swiftwolf's Rending Gale (though without the force field)
* Swiftwolf's Rending Gale (but without the force field)
* Zero Ring
* Harvest Band?
* Ring of Arcana (possibly without the Harvest Band)

View File

@ -24,7 +24,7 @@ local function get_armor_texture(type, matter, preview)
if preview then result = result.."_preview" end
result = result..".png"..modifier
end
--minetest.log(result)
minetest.log(result)
return result
end
@ -64,10 +64,10 @@ function exchangeclone.check_armor_health(obj)
already_has_health = obj:get_meta():get_int("exchangeclone_red_matter_armor") or 0
end
if armor_pieces >= max_armor then
obj:set_properties({hp_max = 2000})
obj:set_properties({hp_max = 200})
if already_has_health == 0 then
-- fix this if MineCraft changes to max_hp instead of hardcoding 20
obj:set_hp(2000-math.max(20-obj:get_hp(), 0))
-- TODO: fix this if MineCraft changes to max_hp instead of hardcoding 20
obj:set_hp(200-math.max(20-obj:get_hp(), 0))
obj:get_meta():set_int("exchangeclone_red_matter_armor", 1)
end
else
@ -128,7 +128,7 @@ if exchangeclone.mineclone then
feet = get_armor_texture("boots","red"),
},
toughness = 5,
groups = {red_matter_armor = 1, fire_immune = 1},
groups = {red_matter_armor = 1, disable_repair = 1, fire_immune = 1},
craft_material = "exchangeclone:red_matter",
cook_material = "exchangeclone:dark_matter",
on_equip_callbacks = {
@ -182,7 +182,7 @@ else
inventory_image = get_armor_texture("inv_helmet","dark"),
preview = get_armor_texture("helmet","dark", true),
armor_groups = {fleshy = 13},
groups = {["armor_head"] = 1, ["dark_matter_armor"] = 1, armor_heal = 5, armor_fire = 1, armor_water = 1}
groups = {["armor_head"] = 1, ["dark_matter_armor"] = 1, armor_heal = 5, armor_fire = 1, armor_water = 1, disable_repair = 1,}
})
armor:register_armor("exchangeclone:chestplate_dark_matter", {
description = "Dark Matter Chestplate",
@ -190,7 +190,7 @@ else
inventory_image = get_armor_texture("inv_chestplate","dark"),
preview = get_armor_texture("chestplate","dark", true),
armor_groups = {fleshy = 21},
groups = {["armor_torso"] = 1, ["dark_matter_armor"] = 1, armor_heal = 8, armor_fire = 2, armor_water = 1}
groups = {["armor_torso"] = 1, ["dark_matter_armor"] = 1, armor_heal = 8, armor_fire = 2, armor_water = 1, disable_repair = 1}
})
armor:register_armor("exchangeclone:leggings_dark_matter", {
description = "Dark Matter Leggings",
@ -198,7 +198,7 @@ else
inventory_image = get_armor_texture("inv_leggings","dark"),
preview = get_armor_texture("leggings","dark", true),
armor_groups = {fleshy = 18},
groups = {["armor_legs"] = 1, ["dark_matter_armor"] = 1, armor_heal = 7, armor_fire = 1, armor_water = 1}
groups = {["armor_legs"] = 1, ["dark_matter_armor"] = 1, armor_heal = 7, armor_fire = 1, armor_water = 1, disable_repair = 1}
})
armor:register_armor("exchangeclone:boots_dark_matter", {
description = "Dark Matter Boots",
@ -206,7 +206,7 @@ else
inventory_image = get_armor_texture("inv_boots","dark"),
preview = get_armor_texture("boots","dark", true),
armor_groups = {fleshy = 10},
groups = {["armor_feet"] = 1, ["dark_matter_armor"] = 1, armor_heal = 4, armor_fire = 1, armor_water = 1, armor_feather = 1}
groups = {["armor_feet"] = 1, ["dark_matter_armor"] = 1, armor_heal = 4, armor_fire = 1, armor_water = 1, armor_feather = 1, disable_repair = 1}
})
armor:register_armor("exchangeclone:shield_dark_matter", {
description = "Dark Matter Shield",
@ -214,7 +214,7 @@ else
inventory_image = get_armor_texture("inv_shield","dark"),
preview = get_armor_texture("shield","dark", true),
armor_groups = {fleshy = 18},
groups = {["armor_shield"] = 1, ["dark_matter_armor"] = 1, armor_heal = 7, armor_fire = 1, armor_water = 1}
groups = {["armor_shield"] = 1, ["dark_matter_armor"] = 1, armor_heal = 7, armor_fire = 1, armor_water = 1, disable_repair = 1}
})
armor:register_armor("exchangeclone:helmet_red_matter", {
description = "Red Matter Helmet",
@ -222,7 +222,7 @@ else
inventory_image = get_armor_texture("inv_helmet","red"),
preview = get_armor_texture("helmet","red", true),
armor_groups = {fleshy = 15},
groups = {["armor_head"] = 1, ["red_matter_armor"] = 1, armor_heal = 10, armor_fire = 2, armor_water = 1}
groups = {["armor_head"] = 1, ["red_matter_armor"] = 1, armor_heal = 10, armor_fire = 2, armor_water = 1, disable_repair = 1}
})
armor:register_armor("exchangeclone:chestplate_red_matter", {
description = "Red Matter Chestplate",
@ -230,31 +230,31 @@ else
inventory_image = get_armor_texture("inv_chestplate","red"),
preview = get_armor_texture("chestplate","red", true),
armor_groups = {fleshy = 23},
groups = {["armor_torso"] = 1, ["red_matter_armor"] = 1, armor_heal = 16, armor_fire = 2, armor_water = 1}
groups = {["armor_torso"] = 1, ["red_matter_armor"] = 1, armor_heal = 16, armor_fire = 2, armor_water = 1, disable_repair = 1}
})
armor:register_armor("exchangeclone:leggings_red_matter", {
description = "Red Matter Leggings",
texture = get_armor_texture("leggings","red"),
inventory_image = get_armor_texture("leggings","red"),
inventory_image = get_armor_texture("inv_leggings","red"),
preview = get_armor_texture("leggings","red", true),
armor_groups = {fleshy = 20},
groups = {["armor_legs"] = 1, ["red_matter_armor"] = 1, armor_heal = 14, armor_fire = 2, armor_water = 1, armor_feather = 1}
groups = {["armor_legs"] = 1, ["red_matter_armor"] = 1, armor_heal = 14, armor_fire = 2, armor_water = 1, armor_feather = 1, disable_repair = 1}
})
armor:register_armor("exchangeclone:boots_red_matter", {
description = "Red Matter Boots",
texture = get_armor_texture("boots","red"),
inventory_image = get_armor_texture("boots","red"),
inventory_image = get_armor_texture("inv_boots","red"),
preview = get_armor_texture("boots","red", true),
armor_groups = {fleshy = 12},
groups = {["armor_feet"] = 1, ["red_matter_armor"] = 1, armor_heal = 8, armor_fire = 2, armor_water = 1, armor_feather = 1}
groups = {["armor_feet"] = 1, ["red_matter_armor"] = 1, armor_heal = 8, armor_fire = 2, armor_water = 1, armor_feather = 1, disable_repair = 1}
})
armor:register_armor("exchangeclone:shield_red_matter", {
description = "Red Matter Shield",
texture = get_armor_texture("shield","red"),
inventory_image = get_armor_texture("shield","red"),
inventory_image = get_armor_texture("inv_shield","red"),
preview = get_armor_texture("shield","red", true),
armor_groups = {fleshy = 20},
groups = {["armor_shield"] = 1, ["red_matter_armor"] = 1, armor_heal = 14, armor_fire = 2, armor_water = 1}
groups = {["armor_shield"] = 1, ["red_matter_armor"] = 1, armor_heal = 14, armor_fire = 2, armor_water = 1, disable_repair = 1}
})
armor:register_on_equip(function(player, index, stack)
exchangeclone.check_armor_health(player)

View File

@ -68,7 +68,7 @@ minetest.register_tool("exchangeclone:dark_matter_axe", {
description = "Dark Matter Axe",
wield_image = "exchangeclone_dark_matter_axe.png",
inventory_image = "exchangeclone_dark_matter_axe.png",
groups = { tool=1, axe=1, dig_speed_class=7, enchantability=0 },
groups = { tool=1, axe=1, dig_speed_class=7, enchantability=0, disable_repair = 1 },
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
-- 1/1.2
@ -93,7 +93,7 @@ minetest.register_tool("exchangeclone:red_matter_axe", {
description = "Red Matter Axe",
wield_image = "exchangeclone_red_matter_axe.png",
inventory_image = "exchangeclone_red_matter_axe.png",
groups = { tool=1, axe=1, dig_speed_class=8, enchantability=0 },
groups = { tool=1, axe=1, dig_speed_class=8, enchantability=0, disable_repair = 1 },
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
-- 1/1.2

View File

@ -1,10 +1,3 @@
local sound_mod
if mcl_sounds then
sound_mod = mcl_sounds
else
sound_mod = default
end
local function get_element_constructor_formspec()
if not exchangeclone.mineclone then
local formspec = {
@ -184,7 +177,7 @@ minetest.register_node("exchangeclone:element_constructor", {
groups = {cracky = 2, container = 4, pickaxey = 2},
_mcl_hardness = 3,
_mcl_blast_resistance = 6,
sounds = sound_mod.node_sound_metal_defaults(),
sounds = exchangeclone.sound_mod.node_sound_metal_defaults(),
is_ground_content = false,
can_dig = can_dig,
after_dig_node = function(pos, oldnode, oldmetadata, player)

View File

@ -1,10 +1,3 @@
local sound_mod
if mcl_sounds then
sound_mod = mcl_sounds
else
sound_mod = default
end
local function get_level(level)
if exchangeclone.mineclone then
return nil
@ -70,8 +63,7 @@ minetest.register_node("exchangeclone:dark_matter_block", {
description = "Dark Matter Block",
tiles = {"exchangeclone_dark_matter_block.png"},
is_ground_content = false,
light_source = 10,
sounds = sound_mod.node_sound_stone_defaults(),
sounds = exchangeclone.sound_mod.node_sound_stone_defaults(),
groups = {pickaxey=5, material_stone=1, cracky = 3, level = get_level(4)}, --ridiculous workaround
_mcl_blast_resistance = 1500,
_mcl_hardness = 75,
@ -82,9 +74,8 @@ minetest.register_node("exchangeclone:red_matter_block", {
tiles = {"exchangeclone_red_matter_block.png"},
is_ground_content = false,
light_source = 14,
sounds = sound_mod.node_sound_stone_defaults(),
-- TODO: Change level to 5 when adding Red Matter tools
groups = {pickaxey=5, material_stone=1, cracky = 3, level = get_level(4)},
sounds = exchangeclone.sound_mod.node_sound_stone_defaults(),
groups = {pickaxey=5, material_stone=1, cracky = 3, level = get_level(5)},
_mcl_blast_resistance = 1500,
_mcl_hardness = 100,
})

View File

@ -1,10 +1,3 @@
local sound_mod
if mcl_sounds then
sound_mod = mcl_sounds
else
sound_mod = default
end
--Renamed "fuel" inventory to "main" to (almost) work with hoppers
local function get_element_deconstructor_formspec()
@ -66,7 +59,7 @@ local function on_timer(pos, elapsed)
else
energy_value = exchangeclone.get_item_energy(fuel_stack:get_name())
end
if energy_value == 0 then
if energy_value <= 0 then
break
else
local wear = fuel_stack:get_wear()
@ -154,7 +147,7 @@ minetest.register_node("exchangeclone:element_deconstructor", {
groups = {cracky = 2, container = 3, pickaxey = 2},
_mcl_hardness = 3,
_mcl_blast_resistance = 6,
sounds = sound_mod.node_sound_metal_defaults(),
sounds = exchangeclone.sound_mod.node_sound_metal_defaults(),
is_ground_content = false,
can_dig = can_dig,
after_dig_node = function(pos, oldnode, oldmetadata, player)

View File

@ -47,6 +47,9 @@ exchangeclone.mtg_energy_values = {
leggings_red_matter = (139264+466944)*7,
boots_red_matter = (139264+466944)*4,
pesa = 64,
transmutation_table = (64*4)+4,
transmutation_tablet = (64*4)+4+(139264*4)+4,
alchemical_tome = 0
},
["beds"] = {
bed_bottom = 168,
@ -435,8 +438,26 @@ exchangeclone.mcl_energy_values = {
leggings_red_matter = (139264+466944)*7,
boots_red_matter = (139264+466944)*4,
pesa = 64,
transmutation_table = (64*4)+4,
transmutation_tablet = (64*4)+4+(139264*4)+4,
alchemical_tome = 0
},
["mcl_core"] = {
light_0 = 0,
light_1 = 0,
light_2 = 0,
light_3 = 0,
light_4 = 0,
light_5 = 0,
light_6 = 0,
light_7 = 0,
light_8 = 0,
light_9 = 0,
light_10 = 0,
light_11 = 0,
light_12 = 0,
light_13 = 0,
light_14 = 0,
stonebrickmossy = 9,
bedrock = 0,
deadbush = 4,
@ -688,6 +709,7 @@ exchangeclone.mcl_energy_values = {
furnace = 8
},
["mcl_farming"] = {
soil = 0,
hoe_stone = 10,
hoe_wood = 24,
hoe_iron = 520,
@ -827,6 +849,7 @@ exchangeclone.mcl_energy_values = {
["mcl_end"] = {
chorus_flower = 32,
chorus_fruit = 16,
chorus_plant = 0,
chorus_fruit_popped = 16,
crystal = 4293,
ender_eye = 1792,
@ -1453,10 +1476,20 @@ exchangeclone.whitelisted_mods = {
mcl_barrels = true,
mcl_beacons = true,
mcl_beds = true,
mcl_beehives = true,
mcl_bells = true,
mcl_blackstone = true,
mcl_blast_furnace = true,
mcl_boats = true,
mcl_bone_meal = true,
mcl_books = true,
mcl_bows = true,
mcl_buckets = true,
mcl_brewing = true,
mcl_cake = true,
mcl_campfires = true,
mcl_cauldrons = true,
mcl_cherry_blossom = true,
mcl_chests = true,
mcl_clock = true,
mcl_cocoas = true,
@ -1500,6 +1533,7 @@ exchangeclone.whitelisted_mods = {
mcl_mangrove = true,
mcl_maps = true,
mcl_minecarts = true,
mcl_mobs = true,
mcl_mobitems = true,
mcl_mud = true,
mcl_mushrooms = true,
@ -1509,7 +1543,7 @@ exchangeclone.whitelisted_mods = {
mcl_paintings = true,
mcl_potions = true,
mcl_raw_ores = true,
mcl_sculk = true,
--mcl_sculk = true, TODO
mcl_shields = true,
mcl_signs = true,
mcl_smithing_table = true,
@ -1596,6 +1630,9 @@ local function set_item_energy(itemstring, energy_value)
end
description = description.."Energy Value: "..(energy_value)
end
if def.exchangeclone_custom_energy then
energy_value = def.exchangeclone_custom_energy
end
minetest.override_item(itemstring, {
description = description,
energy_value = energy_value,

View File

@ -1,10 +1,3 @@
local sound_mod
if mcl_sounds then
sound_mod = mcl_sounds
else
sound_mod = default
end
local function get_energy_collector_formspec()
local formspec
if not exchangeclone.mineclone then
@ -53,11 +46,13 @@ local function on_timer(pos, elapsed)
return false
end
if minetest.get_natural_light(pos) == 15 then
if minetest.get_artificial_light(pos) >= 14 then
local dest_orb = inv:get_stack("main", 1)
local stored = exchangeclone.get_orb_energy(inv, "main", 1)
stored = stored + exchangeclone.collector_speed
exchangeclone.set_orb_energy(inv, "main", 1, stored)
if stored + exchangeclone.collector_speed > exchangeclone.energy_max then
stored = stored + exchangeclone.collector_speed
exchangeclone.set_orb_energy(inv, "main", 1, stored)
end
end
return true
end
@ -139,7 +134,7 @@ minetest.register_node("exchangeclone:energy_collector", {
groups = {cracky = 2, container = 2, pickaxey = 2},
_mcl_hardness = 3,
_mcl_blast_resistance = 6,
sounds = sound_mod.node_sound_metal_defaults(),
sounds = exchangeclone.sound_mod.node_sound_metal_defaults(),
is_ground_content = false,
can_dig = can_dig,
on_timer = on_timer,

698
furnaces.lua Normal file
View File

@ -0,0 +1,698 @@
-- Everything with the exchangeclone_ore group is also included (see pickaxes.lua)
local ores = {
["mcl_raw_ores:raw_gold"] = true,
["mcl_raw_ores:raw_iron"] = true,
["mcl_copper:raw_copper"] = true
}
local furnace_itemstring = "default:furnace"
if exchangeclone.mineclone then
furnace_itemstring = "mcl_furnaces:furnace"
end
local function get_level(level)
if exchangeclone.mineclone then
return nil
else
return level
end
end
local function is_ore(itemstring)
if ores[itemstring] then return true end
local exchangeclone_ore = minetest.get_item_group(itemstring, "exchangeclone_ore")
minetest.log(tostring(exchangeclone_ore))
if exchangeclone_ore and exchangeclone_ore ~= 0 then return true end
return false
end
local LIGHT_ACTIVE_FURNACE = 13
--90% of the code is copied from MineClone's blast furnaces.
--
-- Formspecs
--
local function active_formspec(fuel_percent, item_percent, type)
return "size[9,8.75]"..
"label[0,4;Inventory]"..
"list[current_player;main;0,4.5;9,3;9]"..
"list[current_player;main;0,7.74;9,1;]"..
"label[2.75,0;"..type.." Matter Furnace]"..
"list[context;src;2.75,0.5;1,1;]"..
"list[context;fuel;2.75,2.5;1,1;]"..
"list[context;dst;5.75,1.5;1,1;]"..
"image[2.75,1.5;1,1;default_furnace_fire_bg.png^[lowpart:"..
(100-fuel_percent)..":default_furnace_fire_fg.png]"..
"image[4.1,1.5;1.5,1;gui_furnace_arrow_bg.png^[lowpart:"..
(item_percent)..":gui_furnace_arrow_fg.png^[transformR270]"..
-- Craft guide button temporarily removed due to Minetest bug.
-- TODO: Add it back when the Minetest bug is fixed.
--"image_button[8,0;1,1;craftguide_book.png;craftguide;]"..
--"tooltip[craftguide;"..minetest.formspec_escape("Recipe book").."]"..
"listring[context;dst]"..
"listring[current_player;main]"..
"listring[context;src]"..
"listring[current_player;main]"..
"listring[context;fuel]"..
"listring[current_player;main]"
end
local function inactive_formspec(type)
return "size[9,8.75]"..
"label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", "Inventory")).."]"..
"list[current_player;main;0,4.5;9,3;9]"..
mcl_formspec.get_itemslot_bg(0,4.5,9,3)..
"list[current_player;main;0,7.74;9,1;]"..
mcl_formspec.get_itemslot_bg(0,7.74,9,1)..
"label[2.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", type.." Matter Furnace")).."]"..
"list[context;src;2.75,0.5;1,1;]"..
mcl_formspec.get_itemslot_bg(2.75,0.5,1,1)..
"list[context;fuel;2.75,2.5;1,1;]"..
mcl_formspec.get_itemslot_bg(2.75,2.5,1,1)..
"list[context;dst;5.75,1.5;1,1;]"..
mcl_formspec.get_itemslot_bg(5.75,1.5,1,1)..
"image[2.75,1.5;1,1;default_furnace_fire_bg.png]"..
"image[4.1,1.5;1.5,1;gui_furnace_arrow_bg.png^[transformR270]"..
-- Craft guide button temporarily removed due to Minetest bug.
-- TODO: Add it back when the Minetest bug is fixed.
--"image_button[8,0;1,1;craftguide_book.png;craftguide;]"..
--"tooltip[craftguide;"..minetest.formspec_escape("Recipe book").."]"..
"listring[context;dst]"..
"listring[current_player;main]"..
"listring[context;src]"..
"listring[current_player;main]"..
"listring[context;fuel]"..
"listring[current_player;main]"
end
if exchangeclone.mineclone then
active_formspec = active_formspec..
mcl_formspec.get_itemslot_bg(0,4.5,9,3)..
mcl_formspec.get_itemslot_bg(0,7.74,9,1)..
mcl_formspec.get_itemslot_bg(2.75,0.5,1,1)..
mcl_formspec.get_itemslot_bg(2.75,2.5,1,1)..
mcl_formspec.get_itemslot_bg(5.75,1.5,1,1)
--currently adding mtg compatibility
end
local receive_fields = function(pos, formname, fields, sender)
if fields.craftguide then
mcl_craftguide.show(sender:get_player_name())
end
end
--[[local function give_xp(pos, player)
local meta = minetest.get_meta(pos)
local dir = vector.divide(minetest.facedir_to_dir(minetest.get_node(pos).param2),-1.95)
local xp = meta:get_int("xp")
if xp > 0 then
if player then
mcl_experience.add_xp(player, xp)
else
mcl_experience.throw_xp(vector.add(pos, dir), xp)
end
meta:set_int("xp", 0)
end
end]]
--
-- Node callback functions that are the same for active and inactive furnace
--
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
local name = player:get_player_name()
if minetest.is_protected(pos, name) then
minetest.record_protection_violation(pos, name)
return 0
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if listname == "fuel" then
-- Test stack with size 1 because we burn one fuel at a time
local teststack = ItemStack(stack)
teststack:set_count(1)
local output, decremented_input = minetest.get_craft_result({method="fuel", width=1, items={teststack}})
if output.time ~= 0 then
-- Only allow to place 1 item if fuel get replaced by recipe.
-- This is the case for lava buckets.
local replace_item = decremented_input.items[1]
if replace_item:is_empty() then
-- For most fuels, just allow to place everything
return stack:get_count()
else
if inv:get_stack(listname, index):get_count() == 0 then
return 1
else
return 0
end
end
else
return 0
end
elseif listname == "src" then
return stack:get_count()
elseif listname == "dst" then
return 0
end
end
local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack(from_list, from_index)
return allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
end
local function allow_metadata_inventory_take(pos, listname, index, stack, player)
local name = player:get_player_name()
if minetest.is_protected(pos, name) then
minetest.record_protection_violation(pos, name)
return 0
end
return stack:get_count()
end
local function on_metadata_inventory_take(pos, listname, index, stack, player)
-- Award smelting achievements
if listname == "dst" then
if stack:get_name() == "mcl_core:iron_ingot" then
awards.unlock(player:get_player_name(), "mcl:acquireIron")
end
--give_xp(pos, player)
end
end
local function on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
if from_list == "dst" then
--give_xp(pos, player)
end
end
local function spawn_flames(pos, param2)
local minrelpos, maxrelpos
local dir = minetest.facedir_to_dir(param2)
if dir.x > 0 then
minrelpos = { x = -0.6, y = -0.05, z = -0.25 }
maxrelpos = { x = -0.55, y = -0.45, z = 0.25 }
elseif dir.x < 0 then
minrelpos = { x = 0.55, y = -0.05, z = -0.25 }
maxrelpos = { x = 0.6, y = -0.45, z = 0.25 }
elseif dir.z > 0 then
minrelpos = { x = -0.25, y = -0.05, z = -0.6 }
maxrelpos = { x = 0.25, y = -0.45, z = -0.55 }
elseif dir.z < 0 then
minrelpos = { x = -0.25, y = -0.05, z = 0.55 }
maxrelpos = { x = 0.25, y = -0.45, z = 0.6 }
else
return
end
mcl_particles.add_node_particlespawner(pos, {
amount = 4,
time = 0,
minpos = vector.add(pos, minrelpos),
maxpos = vector.add(pos, maxrelpos),
minvel = { x = -0.01, y = 0, z = -0.01 },
maxvel = { x = 0.01, y = 0.1, z = 0.01 },
minexptime = 0.3,
maxexptime = 0.6,
minsize = 0.4,
maxsize = 0.8,
texture = "mcl_particles_flame.png",
glow = LIGHT_ACTIVE_FURNACE,
}, "low")
end
local function swap_node(pos, name)
local node = minetest.get_node(pos)
if node.name == name then
return
end
node.name = name
minetest.swap_node(pos, node)
if name == "exchangeclone:dark_matter_furnace_active" or name == "exchangeclone:red_matter_furnace_active" then
spawn_flames(pos, node.param2)
else
mcl_particles.delete_node_particlespawners(pos)
end
end
local function furnace_reset_delta_time(pos)
local meta = minetest.get_meta(pos)
local time_speed = tonumber(minetest.settings:get("time_speed") or 72)
if (time_speed < 0.1) then
return
end
local time_multiplier = 86400 / time_speed
local current_game_time = .0 + ((minetest.get_day_count() + minetest.get_timeofday()) * time_multiplier)
-- TODO: Change meta:get/set_string() to get/set_float() for "last_gametime".
-- In Windows *_float() works OK but under Linux it returns rounded unusable values like 449540.000000000
local last_game_time = meta:get_string("last_gametime")
if last_game_time then
last_game_time = tonumber(last_game_time)
end
if not last_game_time or last_game_time < 1 or math.abs(last_game_time - current_game_time) <= 1.5 then
return
end
meta:set_string("last_gametime", tostring(current_game_time))
end
local function furnace_get_delta_time(pos, elapsed)
local meta = minetest.get_meta(pos)
local time_speed = tonumber(minetest.settings:get("time_speed") or 72)
local current_game_time
if (time_speed < 0.1) then
return meta, elapsed
else
local time_multiplier = 86400 / time_speed
current_game_time = .0 + ((minetest.get_day_count() + minetest.get_timeofday()) * time_multiplier)
end
local last_game_time = meta:get_string("last_gametime")
if last_game_time then
last_game_time = tonumber(last_game_time)
end
if not last_game_time or last_game_time < 1 then
last_game_time = current_game_time - 0.1
elseif last_game_time == current_game_time then
current_game_time = current_game_time + 1.0
end
local elapsed_game_time = .0 + current_game_time - last_game_time
meta:set_string("last_gametime", tostring(current_game_time))
return meta, elapsed_game_time
end
local check_positions = {
{x=0,y=0,z=1},
{x=0,y=0,z=-1},
{x=0,y=1,z=0},
{x=0,y=-1,z=0},
{x=1,y=0, z=0},
{x=-1,y=0,z=0},
}
local function check_for_collector(pos, set_furnace)
local collector_found = false
for _, check_pos in ipairs(check_positions) do
local check_node = minetest.get_node(vector.add(pos, check_pos))
if minetest.get_node_group(check_node.name, "energy_collector") > 0 then
collector_found = true
if set_furnace ~= nil then
minetest.get_meta(check_pos):set_bool("connected_to_furnace", set_furnace)
end
end
end
return collector_found
end
local function furnace_node_timer(pos, elapsed)
--
-- Inizialize metadata
--
local meta, elapsed_game_time = furnace_get_delta_time(pos, elapsed)
local fuel_time = meta:get_float("fuel_time") or 0
local src_time = meta:get_float("src_time") or 0
local src_item = meta:get_string("src_item") or ""
local fuel_totaltime = meta:get_float("fuel_totaltime") or 0
local inv = meta:get_inventory()
local srclist, fuellist
local cookable, cooked
local active = true
local fuel
local type = "Dark"
local speed = 22 -- /10 to get items/second
if minetest.get_node(pos).name:find("red_matter") then
type = "Red"
speed = 66
end
srclist = inv:get_list("src")
fuellist = inv:get_list("fuel")
-- Check if src item has been changed
if srclist[1]:get_name() ~= src_item then
-- Reset cooking progress in this case
src_time = 0
src_item = srclist[1]:get_name()
end
local update = true
while elapsed_game_time > 0.00001 and update do
--
-- Cooking
--
-- Run the furnace <speed> times faster than a normal furnace.
local el = elapsed_game_time * speed
-- Check if we have cookable content: cookable
local aftercooked
cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
cookable = cooked.item ~= ItemStack("") --minetest.get_item_group(inv:get_stack("src", 1):get_name(), "furnace_smeltable") == 1
if cookable then
-- Successful cooking requires space in dst slot and time
if not inv:room_for_item("dst", cooked.item) then
cookable = false
end
end
if cookable then -- fuel lasts long enough, adjust el to cooking duration
el = math.min(el, cooked.time - src_time)
end
local using_collector = check_for_collector(pos, true)
-- Check if we have enough fuel to burn
active = (fuel_time < fuel_totaltime) or using_collector
if cookable and not active then
-- We need to get new fuel
local afterfuel
fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
if fuel.time == 0 then
-- No valid fuel in fuel list -- stop
fuel_totaltime = 0
src_time = 0
update = false
else
-- Take fuel from fuel list
inv:set_stack("fuel", 1, afterfuel.items[1])
fuel_time = 0
fuel_totaltime = fuel.time*5.5 -- 5.5x more fuel efficient for DM/RM furnaces
el = math.min(el, fuel_totaltime)
active = true
fuellist = inv:get_list("fuel")
end
elseif active then
el = math.min(el, fuel_totaltime - fuel_time)
-- The furnace is currently active and has enough fuel
fuel_time = fuel_time + el
end
-- If there is a cookable item then check if it is ready yet
if cookable and active then
src_time = src_time + el
-- Place result in dst list if done
if src_time >= cooked.time then
local count = cooked.item:get_count()
if is_ore(srclist[1]:get_name()) and (count * 2 <= cooked.item:get_stack_max()) then
if type == "Red" or (type == "Dark" and math.random(1,2) == 1) then
cooked.item:set_count(count*2)
else
minetest.log(type)
end
else
minetest.log(tostring(is_ore(cooked.item:get_name())))
end
inv:add_item("dst", cooked.item)
inv:set_stack("src", 1, aftercooked.items[1])
srclist = inv:get_list("src")
src_time = 0
--meta:set_int("xp", meta:get_int("xp") + 1) -- ToDo give each recipe an idividial XP count
end
end
elapsed_game_time = elapsed_game_time - el
end
if fuel and fuel_totaltime > fuel.time * 5.5 then
fuel_totaltime = fuel.time * 5.5
end
if srclist and srclist[1]:is_empty() then
src_time = 0
end
--
-- Update formspec and node
--
local formspec = inactive_formspec(type)
local item_percent = 0
if cookable then
item_percent = math.floor(src_time / cooked.time * 100)
end
local result = false
if active then
local fuel_percent = 0
if fuel_totaltime > 0 then
fuel_percent = math.floor(fuel_time / fuel_totaltime * 100)
end
formspec = active_formspec(fuel_percent, item_percent, type)
swap_node(pos, "exchangeclone:"..type:lower().."_matter_furnace_active")
-- make sure timer restarts automatically
result = true
else
swap_node(pos, "exchangeclone:"..type:lower().."_matter_furnace")
-- stop timer on the inactive furnace
minetest.get_node_timer(pos):stop()
end
--
-- Set meta values
--
meta:set_float("fuel_totaltime", fuel_totaltime)
meta:set_float("fuel_time", fuel_time)
meta:set_float("src_time", src_time)
if srclist then
meta:set_string("src_item", src_item)
else
meta:set_string("src_item", "")
end
meta:set_string("formspec", formspec)
return result
end
local on_rotate, after_rotate_active
if minetest.get_modpath("screwdriver") then
on_rotate = screwdriver.rotate_simple
after_rotate_active = function(pos)
local node = minetest.get_node(pos)
mcl_particles.delete_node_particlespawners(pos)
if node.name == "exchangeclone:dark_matter_furnace" or node.name == "exchangeclone:red_matter_furnace" then
return
end
spawn_flames(pos, node.param2)
end
end
local inactive_def = {
description = "Dark Matter Furnace",
tiles = {
"exchangeclone_dark_matter_block.png"
},
paramtype2 = "facedir",
groups = {pickaxey=5, cracky = 3, container=4, deco_block=1, material_stone=1, level = get_level(4)},
is_ground_content = false,
sounds = exchangeclone.sound_mod.node_sound_stone_defaults(),
on_timer = furnace_node_timer,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
local meta = minetest.get_meta(pos)
local meta2 = meta:to_table()
meta:from_table(oldmetadata)
local inv = meta:get_inventory()
for _, listname in ipairs({"src", "dst", "fuel"}) do
local stack = inv:get_stack(listname, 1)
if not stack:is_empty() then
local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5}
minetest.add_item(p, stack)
end
end
meta:from_table(meta2)
end,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", inactive_formspec("Dark"))
local inv = meta:get_inventory()
inv:set_size("src", 1)
inv:set_size("fuel", 1)
inv:set_size("dst", 1)
end,
on_destruct = function(pos)
mcl_particles.delete_node_particlespawners(pos)
check_for_collector(pos, false)
--give_xp(pos)
end,
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
-- Reset accumulated game time when player works with furnace:
furnace_reset_delta_time(pos)
minetest.get_node_timer(pos):start(0.45)
on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
end,
on_metadata_inventory_put = function(pos)
-- Reset accumulated game time when player works with furnace:
furnace_reset_delta_time(pos)
-- start timer function, it will sort out whether furnace can burn or not.
minetest.get_node_timer(pos):start(0.45)
end,
on_metadata_inventory_take = function(pos, listname, index, stack, player)
-- Reset accumulated game time when player works with furnace:
furnace_reset_delta_time(pos)
-- start timer function, it will helpful if player clears dst slot
minetest.get_node_timer(pos):start(0.45)
on_metadata_inventory_take(pos, listname, index, stack, player)
end,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_move = allow_metadata_inventory_move,
allow_metadata_inventory_take = allow_metadata_inventory_take,
on_receive_fields = receive_fields,
_mcl_blast_resistance = 1500,
_mcl_hardness = 75,
on_rotate = on_rotate,
}
local active_def = {
description = "Active Dark Matter Furnace",
tiles = {
"exchangeclone_dark_matter_block.png",
},
paramtype2 = "facedir",
paramtype = "light",
light_source = LIGHT_ACTIVE_FURNACE,
drop = "exchangeclone:dark_matter_furnace",
groups = {pickaxey=5, not_in_creative_inventory = 1, container = 4, material_stone=1, cracky = 3, level = get_level(4)},
is_ground_content = false,
sounds = exchangeclone.sound_mod.node_sound_stone_defaults(),
on_timer = furnace_node_timer,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
local meta = minetest.get_meta(pos)
local meta2 = meta
meta:from_table(oldmetadata)
local inv = meta:get_inventory()
for _, listname in ipairs({"src", "dst", "fuel"}) do
local stack = inv:get_stack(listname, 1)
if not stack:is_empty() then
local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5}
minetest.add_item(p, stack)
end
end
meta:from_table(meta2:to_table())
end,
on_construct = function(pos)
local node = minetest.get_node(pos)
spawn_flames(pos, node.param2)
end,
on_destruct = function(pos)
mcl_particles.delete_node_particlespawners(pos)
check_for_collector(pos, false)
--give_xp(pos)
end,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_move = allow_metadata_inventory_move,
allow_metadata_inventory_take = allow_metadata_inventory_take,
on_metadata_inventory_move = on_metadata_inventory_move,
on_metadata_inventory_take = on_metadata_inventory_take,
on_receive_fields = receive_fields,
_mcl_blast_resistance = 1500,
_mcl_hardness = 75,
on_rotate = on_rotate,
after_rotate = after_rotate_active,
}
minetest.register_node("exchangeclone:dark_matter_furnace", table.copy(inactive_def))
minetest.register_node("exchangeclone:red_matter_furnace", table.copy(inactive_def))
minetest.register_node("exchangeclone:dark_matter_furnace_active", table.copy(active_def))
minetest.register_node("exchangeclone:red_matter_furnace_active", table.copy(active_def))
minetest.override_item("exchangeclone:red_matter_furnace", {
description = "Red Matter Furnace",
tiles = {
"exchangeclone_red_matter_block.png"
},
groups = {pickaxey=5, cracky = 3, container=4, deco_block=1, material_stone=1, level = get_level(5)},
_mcl_hardness = 100,
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
-- Reset accumulated game time when player works with furnace:
furnace_reset_delta_time(pos)
minetest.get_node_timer(pos):start(0.16)
on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
end,
on_metadata_inventory_put = function(pos)
-- Reset accumulated game time when player works with furnace:
furnace_reset_delta_time(pos)
-- start timer function, it will sort out whether furnace can burn or not.
minetest.get_node_timer(pos):start(0.16)
end,
on_metadata_inventory_take = function(pos, listname, index, stack, player)
-- Reset accumulated game time when player works with furnace:
furnace_reset_delta_time(pos)
-- start timer function, it will helpful if player clears dst slot
minetest.get_node_timer(pos):start(0.16)
on_metadata_inventory_take(pos, listname, index, stack, player)
end,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", inactive_formspec("Red"))
local inv = meta:get_inventory()
inv:set_size("src", 1)
inv:set_size("fuel", 1)
inv:set_size("dst", 1)
end,
})
minetest.override_item("exchangeclone:red_matter_furnace_active", {
description = "Active Red Matter Furnace",
tiles = {
"exchangeclone_red_matter_block.png"
},
drop = "exchangeclone:red_matter_furnace",
groups = {pickaxey=5, cracky = 3, container=4, deco_block=1, material_stone=1, level = get_level(5)},
_mcl_hardness = 100,
})
minetest.register_craft({
output = "exchangeclone:dark_matter_furnace",
recipe = {
{ "exchangeclone:dark_matter_block", "exchangeclone:dark_matter_block", "exchangeclone:dark_matter_block" },
{ "exchangeclone:dark_matter_block", "mcl_core:furnace", "exchangeclone:dark_matter_block" },
{ "exchangeclone:dark_matter_block", "exchangeclone:dark_matter_block", "exchangeclone:dark_matter_block" },
}
})
minetest.register_craft({
output = "exchangeclone:red_matter_furnace",
recipe = {
{ "", "exchangeclone:red_matter_block", "" },
{ "exchangeclone:red_matter_block", "mcl_core:furnace", "exchangeclone:red_matter_block" },
}
})
minetest.register_lbm({
label = "Active furnace flame particles",
name = "exchangeclone:furnace_flames",
nodenames = {"exchangeclone:dark_matter_furnace_active","exchangeclone:red_matter_furnace_active"},
run_at_every_load = true,
action = function(pos, node)
spawn_flames(pos, node.param2)
end,
})

View File

@ -72,7 +72,7 @@ minetest.register_tool("exchangeclone:dark_matter_hammer", {
description = "Dark Matter Hammer",
wield_image = "exchangeclone_dark_matter_hammer.png",
inventory_image = "exchangeclone_dark_matter_hammer.png",
groups = { tool=1, hammer=1, dig_speed_class=7, enchantability=0, dark_matter_hammer = 1 },
groups = { tool=1, hammer=1, dig_speed_class=7, enchantability=0, dark_matter_hammer = 1, disable_repair = 1, fire_immune = 1 },
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
-- 1/1.2
@ -97,7 +97,7 @@ minetest.register_tool("exchangeclone:dark_matter_hammer_3x3", {
description = "Dark Matter Hammer",
wield_image = "exchangeclone_dark_matter_hammer.png",
inventory_image = "exchangeclone_dark_matter_hammer.png",
groups = { tool=1, hammer=1, dig_speed_class=7, enchantability=0, dark_matter_hammer = 1, not_in_creative_inventory = 1 },
groups = { tool=1, hammer=1, dig_speed_class=7, enchantability=0, dark_matter_hammer = 1, not_in_creative_inventory = 1, disable_repair = 1, fire_immune = 1 },
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
-- 1/1.2
@ -122,7 +122,7 @@ minetest.register_tool("exchangeclone:red_matter_hammer", {
description = "Red Matter Hammer",
wield_image = "exchangeclone_red_matter_hammer.png",
inventory_image = "exchangeclone_red_matter_hammer.png",
groups = { tool=1, hammer=1, dig_speed_class=7, enchantability=0, red_matter_hammer = 1 },
groups = { tool=1, hammer=1, dig_speed_class=7, enchantability=0, red_matter_hammer = 1, disable_repair = 1, fire_immune = 1 },
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
-- 1/1.2
@ -147,7 +147,7 @@ minetest.register_tool("exchangeclone:red_matter_hammer_3x3", {
description = "Red Matter Hammer",
wield_image = "exchangeclone_red_matter_hammer.png",
inventory_image = "exchangeclone_red_matter_hammer.png",
groups = { tool=1, hammer=1, dig_speed_class=7, enchantability=0, red_matter_hammer = 1, not_in_creative_inventory = 1 },
groups = { tool=1, hammer=1, dig_speed_class=7, enchantability=0, red_matter_hammer = 1, not_in_creative_inventory = 1, disable_repair = 1, fire_immune = 1 },
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
-- 1/1.2

View File

@ -115,7 +115,7 @@ local hoe_def = {
wield_scale = exchangeclone.wield_scale,
on_place = hoe_on_place,
on_secondary_use = hoe_on_place,
groups = { tool=1, hoe=1, enchantability=0, dark_matter_hoe = 1 },
groups = { tool=1, hoe=1, enchantability=0, dark_matter_hoe = 1, disable_repair = 1, fire_immune = 1 },
tool_capabilities = {
full_punch_interval = 0.25,
damage_groups = { fleshy = 7, },
@ -142,7 +142,7 @@ minetest.register_tool("exchangeclone:dark_matter_hoe_3x3", table.copy(hoe_3x3_d
hoe_def.description = "Red Matter Hoe"
hoe_def.wield_image = "exchangeclone_red_matter_hoe.png"
hoe_def.inventory_image = "exchangeclone_red_matter_hoe.png"
hoe_def.groups = { tool=1, hoe=1, enchantability=0, red_matter_hoe = 1 }
hoe_def.groups = { tool=1, hoe=1, enchantability=0, red_matter_hoe = 1, disable_repair = 1, fire_immune = 1 }
hoe_def.tool_capabilities = {
full_punch_interval = 0.25,
damage_groups = { fleshy = 8, },

View File

@ -34,5 +34,6 @@ dofile(default_path.."/shovels.lua")
dofile(default_path.."/red_matter_multitools.lua")
dofile(default_path.."/philosophers_stone.lua")
dofile(default_path.."/pesa.lua")
dofile(default_path.."/transmutation_tablet.lua")
dofile(default_path.."/transmutation_table.lua")
dofile(default_path.."/furnaces.lua")
dofile(default_path.."/energy.lua")

69
lib.lua
View File

@ -11,7 +11,7 @@ function exchangeclone.get_inventory_drops(pos, inventory, drops) --removes defa
end
function exchangeclone.get_item_energy(name)
return minetest.registered_items[name].energy_value
return minetest.registered_items[name].energy_value or -1
end
function exchangeclone.round(num)
@ -27,23 +27,31 @@ function exchangeclone.map(input, min1, max1, min2, max2)
return (input - min1) / (max1 - min1) * (max2 - min2) + min2
end
function exchangeclone.get_orb_itemstack_energy(itemstack)
if not itemstack then return -1 end
if itemstack:get_name() ~= "exchangeclone:exchange_orb" then return -1 end
return itemstack:get_meta():get_float("stored_energy") or 0
end
function exchangeclone.get_orb_energy(inventory, listname, index)
if not inventory then return end
if not inventory then return -1 end
if not listname then listname = "main" end
if not index then index = 1 end
local itemstack = inventory:get_stack(listname, index)
if not itemstack then return 0 end
if not itemstack:get_name() then return 0 end
return itemstack:get_meta():get_float("stored_energy")
return exchangeclone.get_orb_itemstack_energy(itemstack)
end
if default then exchangeclone.sound_mod = default else exchangeclone.sound_mod = mcl_sounds end
function exchangeclone.set_orb_energy(inventory, listname, index, amount)
if (not inventory) or (not amount) or (amount < 0) or (amount > exchangeclone.energy_max) then return end
if not inventory or amount < 0 then return end
if not listname then listname = "main" end
if not index then index = 1 end
local itemstack = inventory:get_stack(listname, index)
if not itemstack then return end
if not itemstack:get_name() then return end
if not (itemstack:get_name() and itemstack:get_name() == "exchangeclone:exchange_orb") then return end
local old_energy = exchangeclone.get_orb_itemstack_energy(itemstack)
if amount > old_energy and old_energy > exchangeclone.energy_max then return end -- don't allow more energy to be put into an over-filled orb
-- Square roots will hopefully make it less linear
-- And if they don't, I don't really care and I don't want to think about math anymore.
@ -62,8 +70,7 @@ function exchangeclone.set_orb_energy(inventory, listname, index, amount)
b = exchangeclone.map(sqrt_amount, sqrt_max/2, 3*sqrt_max/4, 0, 255)
g = 255 - b
else
r = exchangeclone.map(sqrt_amount, 3*sqrt_max/4, sqrt_max, 0, 255)
minetest.log(dump(r))
r = math.min(exchangeclone.map(sqrt_amount, 3*sqrt_max/4, sqrt_max, 0, 255), 255)
b = 255
end
@ -76,12 +83,38 @@ function exchangeclone.set_orb_energy(inventory, listname, index, amount)
inventory:set_stack(listname, index, itemstack)
end
local hud_elements = {}
function exchangeclone.update_hud(player)
local hud_text = hud_elements[player:get_player_name()]
if not hud_text then minetest.log("!!!") return end
player:hud_change(hud_text, "text", "Stored Energy: "..tostring(exchangeclone.get_player_energy(player)))
end
minetest.register_on_joinplayer(function(player, last_login)
hud_elements[player:get_player_name()] = player:hud_add({
hud_elem_type = "text",
position = {x = 1, y = 0.01},
offset = {x = 0, y = 0},
text = "Stored Energy: 0",
alignment = {x = -1, y = 0},
scale = {x = 100, y = 100},
number = 0xFFFFFF
})
exchangeclone.update_hud(player)
end)
minetest.register_on_leaveplayer(function(player, timed_out)
hud_elements[player:get_player_name()] = nil
end)
function exchangeclone.get_player_energy(player)
return exchangeclone.get_orb_energy(player:get_inventory(), "exchangeclone_pesa", 1)
return player:get_meta():get_int("exchangeclone_stored_energy") or 0
end
function exchangeclone.set_player_energy(player, amount)
exchangeclone.set_orb_energy(player:get_inventory(), "exchangeclone_pesa", 1, amount)
player:get_meta():set_int("exchangeclone_stored_energy", amount)
exchangeclone.update_hud(player)
end
function exchangeclone.get_group_items(groups, allow_duplicates, include_no_group)
@ -188,6 +221,20 @@ local function get_fortune_drops(fortune_drops, fortune_level)
return drop or {}
end
function exchangeclone.inventory_formspec(x,y)
local formspec = ""
if why.mineclone then
formspec = "list[current_player;main;"..tostring(x)..","..tostring(y)..";9,3;9]"..
mcl_formspec.get_itemslot_bg(x,y,9,3)..
"list[current_player;main;"..tostring(x)..","..tostring(y+3.25)..";9,1]"..
mcl_formspec.get_itemslot_bg(x,y+3.25,9,1)
else
formspec = "list[current_player;main;"..tostring(x)..","..tostring(y)..";8,1]"..
"list[current_player;main;"..tostring(x)..","..tostring(y+1.25)..";8,3;8]"
end
return formspec
end
local function discrete_uniform_distribution(drops, min_count, max_count, cap)
local new_drops = table.copy(drops)
for i, item in ipairs(drops) do

View File

@ -16,7 +16,7 @@ minetest.register_tool("exchangeclone:exchange_orb", {
color = "#000000",
on_secondary_use = read_orb_charge,
on_place = read_orb_charge,
groups = {exchange_orb = 1, disable_repair = 1}
groups = {exchange_orb = 1, disable_repair = 1, fire_immune = 1}
})
local recipe_item_1 = "default:steel_ingot"
@ -41,5 +41,5 @@ minetest.register_craft({
minetest.register_craft({ --Making it fuel so hopper will work with constructor better
type = "fuel",
recipe = "exchangeclone:exchange_orb",
burntime = 1600 --Basically 2 coal blocks
burntime = 24000 --Basically 30 coal blocks... it should be worth it.
})

View File

@ -13,7 +13,7 @@ if not exchangeclone.mineclone then
else
formspec = {
"size[9,10]",
"label[0.5,0.5;Personal Energy Storage Accessor (PESA)]",
"label[0.5,0.5;Personal Energy Storage Accessor (PESA)\nWARNING: THIS ITEM IS DEPRECATED AND WILL BE REMOVED SOON.\nREMOVE ANY ORB INSIDE IT.]",
"list[current_player;exchangeclone_pesa;4,2;1,1;]",
mcl_formspec.get_itemslot_bg(4,2,1,1),
"list[current_player;main;0,5;9,3;9]",
@ -35,11 +35,12 @@ local function on_rightclick(itemstack, player, pointed_thing)
end
minetest.register_tool("exchangeclone:pesa", {
description = "Personal Energy Storage Accessor (PESA)",
description = "Personal Energy Storage Accessor (PESA)\nWARNING: DEPRECATED/USELESS, REMOVE ANY ORB INSIDE",
wield_image = "exchangeclone_pesa.png",
inventory_image = "exchangeclone_pesa.png",
on_secondary_use = on_rightclick,
on_place = on_rightclick,
groups = {disable_repair = 1, fire_immune = 1}
})
minetest.register_on_joinplayer(function(player)
@ -59,7 +60,7 @@ minetest.register_allow_player_inventory_action(function(player, action, inv, in
else
stack = player:get_inventory():get_stack("main", info.from_index)
end
if stack:get_name() == "exchangeclone:exchange_orb" or action == "take" then
if (action == "move" and stack:get_name() == "exchangeclone:exchange_orb") or action == "take" then
return stack:get_count()
else
return 0

View File

@ -5,14 +5,40 @@ local function show_enchanting(player)
mcl_enchanting.show_enchanting_formspec(player)
end
local width = (exchangeclone.mineclone and 9) or 8
local smelting_formspec =
"size["..width..",8]"..
"label[0.25,0.25;Smelting]"..
"label["..(width/3)..",0.75;Input]"..
"list[current_player;exchangeclone_smelting_input;"..(width/3)..",1;1,1]"..
"label["..(width/3)..",2.25;Coal"..((exchangeclone.mineclone and "/charcoal]") or "]")..
"list[current_player;exchangeclone_smelting_fuel;"..(width/3)..",2.5;1,1]"..
"label["..(2*width/3)..",0.75;Output]"..
"list[current_player;exchangeclone_smelting_output;"..(2*width/3)..",1.5;1,1]"..
exchangeclone.inventory_formspec(0,4)..
"listring[current_player;main]"..
"listring[current_player;exchangeclone_smelting_input]"..
"listring[current_player;main]"..
"listring[current_player;exchangeclone_smelting_output]"..
"listring[current_player;main]"..
"listring[current_player;exchangeclone_smelting_fuel]"..
"listring[current_player;main]"
if exchangeclone.mineclone then
smelting_formspec = smelting_formspec..
mcl_formspec.get_itemslot_bg(width/3,1,1,1)..
mcl_formspec.get_itemslot_bg(width/3,2.5,1,1)..
mcl_formspec.get_itemslot_bg(2*width/3,1.5,1,1)
end
exchangeclone.node_transmutations = {
{ --use
["mcl_core:stone"] = "mcl_core:cobble",
["mcl_core:cobble"] = "mcl_core:stone",
["mcl_core:dirt_with_grass"] = "mcl_core:sand",
["mcl_core:podzol"] = "mcl_core:redsand",
["mcl_core:dirt"] = "mcl_core:sand",
["mcl_core:sand"] = "mcl_core:dirt_with_grass",
["mcl_core:podzol"] = "mcl_core:redsand",
["mcl_core:redsand"] = "mcl_core:podzol",
["mcl_flowers:tallgrass"] = "mcl_core:deadbush",
["mcl_nether:netherrack"] = "mcl_core:cobble",
@ -83,12 +109,15 @@ exchangeclone.node_transmutations = {
["mcl_core:bedrock"] = "mcl_core:barrier",
["mcl_core:barrier"] = "mcl_core:bedrock",
["mcl_end:end_stone"] = "mcl_nether:netherrack",
["mcl_nether:soul_sand"] = "mcl_blackstone:soul_soil",
["mcl_blackstone:soul_soil"] = "mcl_nether:soul_sand",
["default:stone"] = "default:cobble",
["default:desert_stone"] = "default:desert_cobble",
["default:cobble"] = "default:stone",
["default:desert_cobble"] = "default:desert_stone",
["default:dirt_with_grass"] = "default:sand",
["default:dirt_with_snow"] = "default:sand",
["default:dirt_with_dry_grass"] = "default:sand",
["default:dry_dirt_with_dry_grass"] = "default:desert_sand",
["default:dirt"] = "default:sand",
@ -104,6 +133,9 @@ exchangeclone.node_transmutations = {
["default:grass_4"] = "default:dry_shrub",
["default:grass_5"] = "default:dry_shrub",
["default:gravel"] = "default:sandstone",
["default:sandstone"] = "default:gravel",
["default:desert_sandstone"] = "default:gravel",
["default:silver_sandstone"] = "default:gravel",
["default:water_source"] = "default:ice",
["default:river_water_source"] = "default:ice",
["default:lava_source"] = "default:obsidian",
@ -137,7 +169,12 @@ exchangeclone.node_transmutations = {
["mcl_core:sand"] = "mcl_core:cobble",
["mcl_core:redsand"] = "mcl_core:cobble",
["mcl_core:dirt_with_grass"] = "mcl_core:cobble",
["mcl_core:dirt"] = "mcl_core:cobble",
["mcl_core:podzol"] = "mcl_deepslate:deepslate_cobbled",
["mcl_deepslate:tuff"] = "mcl_core:granite",
["mcl_core:granite"] = "mcl_core:diorite",
["mcl_core:diorite"] = "mcl_core:andesite",
["mcl_core:andesite"] = "mcl_deepslate:tuff",
["mcl_core:acacialeaves"] = "mcl_core:spruceleaves",
["mcl_core:birchleaves"] = "mcl_core:acacialeaves",
["mcl_core:darkleaves"] = "mcl_core:birchleaves",
@ -153,8 +190,6 @@ exchangeclone.node_transmutations = {
["mcl_core:tree"] = "mcl_mangrove:mangrove_tree",
["mcl_core:sprucetree"] = "mcl_core:tree",
["mcl_nether:netherrack"] = "mcl_end:end_stone",
["mcl_nether:soul_sand"] = "mcl_blackstone:soul_soil",
["mcl_blackstone:soul_soil"] = "mcl_nether:soul_sand",
["default:stone"] = "default:dirt_with_grass",
["default:cobble"] = "default:dirt_with_grass",
@ -163,16 +198,14 @@ exchangeclone.node_transmutations = {
["default:dry_dirt_with_dry_grass"] = "default:desert_cobble",
["default:dirt_with_dry_grass"] = "default:cobble",
["default:dirt_with_grass"] = "default:cobble",
["default:dirt_with_snow"] = "default:cobble",
["default:dirt"] = "default:cobble",
["default:dry_dirt"] = "default:desert_cobble",
["default:dirt_with_coniferous_litter"] = "default:cobble",
["default:dirt_with_rainforest_litter"] = "default:cobble",
["default:sand"] = "default:cobble",
["default:desert_sand"] = "default:desert_cobble",
["default:silver_sand"] = "default:cobble",
["default:sandstone"] = "default:gravel",
["default:desert_sandstone"] = "default:gravel",
["default:silver_sandstone"] = "default:gravel",
["mcl_core:diorite"] = "mcl_core:andesite",
["mcl_core:andesite"] = "mcl_deepslate:tuff",
["mcl_deepslate:tuff"] = "mcl_core:granite",
["mcl_core:granite"] = "mcl_core:diorite",
["default:acacia_tree"] = "default:pine_tree",
["default:tree"] = "default:acacia_tree",
["default:aspen_tree"] = "default:tree",
@ -224,11 +257,66 @@ if exchangeclone.mineclone then
if player:get_player_control().sneak then
show_enchanting(player)
else
mcl_crafting_table.show_crafting_form(player)
if player:get_player_control().aux1 then
minetest.show_formspec(player:get_player_name(), "exchangeclone_smelting", smelting_formspec)
else
mcl_crafting_table.show_crafting_form(player)
end
end
end
end
local fuel_items = {
["mcl_core:charcoal_lump"] = true,
["mcl_core:coal_lump"] = true,
["default:coal_lump"] = true,
}
minetest.register_on_joinplayer(function(player, last_login)
local inv = player:get_inventory()
inv:set_size("exchangeclone_smelting_input", 1)
inv:set_size("exchangeclone_smelting_output", 1)
inv:set_size("exchangeclone_smelting_fuel", 1)
end)
minetest.register_allow_player_inventory_action(function(player, action, inventory, info)
if action == "put" then
if info.listname == "exchangeclone_smelting_output" then
return 0
elseif info.listname == "exchangeclone_smelting_fuel" then
if not fuel_items[info.stack:get_name()] then
return 0
end
end
elseif action == "move" then
if info.to_list == "exchangeclone_smelting_output" then
return 0
elseif info.to_list == "exchangeclone_smelting_fuel" then
if not fuel_items[inventory:get_stack(info.from_list, info.from_index):get_name()] then
return 0
end
end
end
end)
local function set_smelting_output(player)
end
minetest.register_on_player_inventory_action(function(player, action, inventory, info)
if action == "put" then
if info.listname == "exchangeclone_smelting_input" or info.listname == "exchangeclone_smelting_fuel" then
set_smelting_output(player)
end
elseif action == "take" then
if info.listname == "exchangeclone_smelting_input"
or info.listname == "exchangeclone_smelting_fuel" then
set_smelting_output(player)
elseif info.listname == "exchangeclone_smelting_output" then
end
end
end)
local function on_right_click(itemstack, player, pointed_thing)
local click_test = exchangeclone.check_on_rightclick(itemstack, player, pointed_thing)
if click_test ~= false then
@ -281,6 +369,114 @@ if exchangeclone.mineclone then
usagehelp = usagehelp..extra_stuff
end
--[[ Could NOT figure out how to make this work.
for name, def in pairs(minetest.registered_nodes) do
local result, _ = minetest.get_craft_result({
method = "cooking",
width = 1,
items = {ItemStack(name)}
})
local name = result.item:get_name()
if minetest.registered_items[name] then
minetest.registered_items[name].groups.exchangeclone_cookable = true
end
end
local recipe_table = {"exchangeclone:philosophers_stone"}
minetest.register_craftitem("exchangeclone:cooked_item", {description = "Cooked Item"})
for i = 1,7 do
table.insert(recipe_table, "group:exchangeclone_cookable")
for fuel, _ in pairs(fuel_items) do
recipe_table[2] = fuel
minetest.register_craft({
output = "exchangeclone:cooked_item "..tostring(i),
type = "shapeless",
recipe = table.copy(recipe_table)
})
end
end
minetest.register_craft_predict(function(itemstack, player, old_craft_grid, craft_inv)
if itemstack == ItemStack("exchangeclone:cooked_item") then
local phil = 0 -- yes, I'm calling it Phil.
local fuel = 0
local item_type = false
local item_count = 0
for _, item in ipairs(old_craft_grid) do
local name = item:get_name()
if name == "" then
-- do nothing
elseif name == "exchangeclone:philosophers_stone" then
phil = phil + 1
elseif fuel_items[name] then
fuel = fuel + 1
else
if item_type and item_type ~= name then
minetest.log(dump({item_type, name}))
return
else
item_type = name
item_count = item_count + 1
end
end
end
minetest.log(dump({phil=phil,fuel=fuel,item_type=item_type,item_count=item_count}))
if not (item_type and (phil == 1) and (fuel == 1)) then return end
local result, _ = minetest.get_craft_result({
method = "cooking",
width = 1,
items = {ItemStack(item_type)}
})
result = result.item
if result:get_name() ~= "" then
result:set_count(item_count)
return result
end
end
end)
minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv)
if itemstack == ItemStack("exchangeclone:cooked_item") then
local phil = 0 -- yes, I'm calling it Phil.
local fuel = 0
local item_type = false
local item_count = 0
for _, item in ipairs(old_craft_grid) do
local name = item:get_name()
if name == "" then
-- do nothing
elseif name == "exchangeclone:philosophers_stone" then
phil = phil + 1
elseif fuel_items[name] then
fuel = fuel + 1
else
if item_type and item_type ~= name then
minetest.log(dump({item_type, name}))
return
else
item_type = name
item_count = item_count + 1
end
end
end
minetest.log(dump({phil=phil,fuel=fuel,item_type=item_type,item_count=item_count}))
if not (item_type and (phil == 1) and (fuel == 1)) then return end
local result, _ = minetest.get_craft_result({
method = "cooking",
width = 1,
items = {ItemStack(item_type)}
})
result = result.item
if result:get_name() ~= "" then
result:set_count(item_count)
return result
end
end
end) --]]
minetest.register_tool("exchangeclone:philosophers_stone", {
description = "Philosopher's Stone",
inventory_image = "exchangeclone_philosophers_stone.png",
@ -292,7 +488,7 @@ minetest.register_tool("exchangeclone:philosophers_stone", {
on_use = on_left_click,
on_place = on_right_click,
on_secondary_use = on_right_click,
groups = {philosophers_stone = 1, disable_repair = 1}
groups = {philosophers_stone = 1, disable_repair = 1, fire_immune = 1}
})
local diamond = "default:diamond"
@ -416,6 +612,21 @@ minetest.register_craft({
replacements = {{"exchangeclone:philosophers_stone", "exchangeclone:philosophers_stone"}}
})
minetest.register_craft({
output = "mcl_core:iron_ingot 2",
type = "shapeless",
recipe = {
"exchangeclone:philosophers_stone",
"mcl_copper:copper_ingot",
"mcl_copper:copper_ingot",
"mcl_copper:copper_ingot",
"mcl_copper:copper_ingot",
"mcl_copper:copper_ingot",
"mcl_copper:copper_ingot",
},
replacements = {{"exchangeclone:philosophers_stone", "exchangeclone:philosophers_stone"}}
})
minetest.register_craft({
output = "default:steel_ingot 5",
type = "shapeless",
@ -675,7 +886,7 @@ minetest.register_craft({
replacements = {{"exchangeclone:philosophers_stone", "exchangeclone:philosophers_stone"}}
})
if exchangeclone.mineclone then -- no idea why both recipes show up in the craft guide, so added if/else
if exchangeclone.mineclone then
minetest.register_craft({
output = "exchangeclone:alchemical_coal",
type = "shapeless",

View File

@ -75,7 +75,7 @@ local function pickaxe_on_use(itemstack, player, pointed_thing)
elseif itemstack:get_name():find("red") then
local player_energy = exchangeclone.get_player_energy(player)
torch_on_place(ItemStack(torch_itemstring), player, pointed_thing)
exchangeclone.set_player_energy(player, player_energy - exchangeclone.get_item_energy(torch_itemstring))
exchangeclone.set_player_energy(player, player_energy - math.max(exchangeclone.get_item_energy(torch_itemstring), 8))
-- If the torch could not be placed, it still costs energy... not sure how to fix that
end
exchangeclone.start_cooldown(player, "pickaxe", 0.3)
@ -97,7 +97,7 @@ local pick_def = {
wield_image = "exchangeclone_dark_matter_pickaxe.png",
inventory_image = "exchangeclone_dark_matter_pickaxe.png",
exchangeclone_pick_mode = "1x1",
groups = { tool=1, pickaxe=1, dig_speed_class=7, enchantability=0, dark_matter_pickaxe=1 },
groups = { tool=1, pickaxe=1, dig_speed_class=7, enchantability=0, dark_matter_pickaxe=1, disable_repair = 1, fire_immune = 1 },
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
-- 1/1.2

View File

@ -69,7 +69,7 @@ local katar_def = {
inventory_image = "exchangeclone_red_katar.png",
on_secondary_use = katar_on_use,
on_place = katar_on_use,
groups = { tool=1, red_katar = 1, sword = 1, axe=1, hoe = 1, shears = 1, dig_speed_class=8, enchantability=0 },
groups = { tool=1, red_katar = 1, sword = 1, axe=1, hoe = 1, shears = 1, dig_speed_class=8, enchantability=0, disable_repair = 1, fire_immune = 1 },
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
full_punch_interval = 0.3,
@ -106,9 +106,9 @@ minetest.register_craft({
type = "shapeless",
recipe = {
"exchangeclone:red_matter_sword",
"exchangeclone:red_matter_shears",
"exchangeclone:red_matter_axe",
"group:red_matter_hoe",
(exchangeclone.mineclone and "exchangeclone:red_matter_shears") or "exchangeclone:red_matter",
"exchangeclone:red_matter",
"exchangeclone:red_matter",
"exchangeclone:red_matter",
@ -173,7 +173,10 @@ local function morningstar_on_use(itemstack, player, pointed_thing)
if pointed_thing.type == "node" then
local node = minetest.get_node(pointed_thing.under)
center = pointed_thing.under
if (minetest.get_item_group(minetest.get_node(pointed_thing.under).name, "exchangeclone_ore") > 0) then
if player:get_player_control().sneak then
exchangeclone.node_radius_action(player, center, range, exchangeclone.morningstar_action)
return
elseif (minetest.get_item_group(minetest.get_node(pointed_thing.under).name, "exchangeclone_ore") > 0) then
if exchangeclone.check_cooldown(player, "pickaxe") then return itemstack end
local player_energy = exchangeclone.get_player_energy(player)
exchangeclone.play_ability_sound(player)
@ -185,9 +188,6 @@ local function morningstar_on_use(itemstack, player, pointed_thing)
end
exchangeclone.start_cooldown(player, "pickaxe", 0.3)
return
elseif player:get_player_control().sneak then
exchangeclone.node_radius_action(player, center, range, exchangeclone.morningstar_action)
return
else
local player_energy = exchangeclone.get_player_energy(player)
torch_on_place(ItemStack(torch_itemstring), player, pointed_thing)
@ -233,7 +233,7 @@ local morningstar_def = {
on_secondary_use = morningstar_on_use,
exchangeclone_pick_mode = "1x1",
on_place = morningstar_on_use,
groups = { tool=1, red_morningstar = 1, shovel = 1, hammer=1, pickaxe = 1, dig_speed_class=8, enchantability=0 },
groups = { tool=1, red_morningstar = 1, shovel = 1, hammer=1, pickaxe = 1, dig_speed_class=8, enchantability=0, disable_repair = 1, fire_immune = 1 },
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
full_punch_interval = 0.3,

View File

@ -75,7 +75,7 @@ minetest.register_tool("exchangeclone:dark_matter_shears", {
wield_image = "exchangeclone_dark_matter_shears.png",
inventory_image = "exchangeclone_dark_matter_shears.png",
stack_max = 1,
groups = { tool=1, shears=1, dig_speed_class=7, },
groups = { tool=1, shears=1, dig_speed_class=7, disable_repair = 1, fire_immune = 1 },
tool_capabilities = {
full_punch_interval = 0.4,
max_drop_level=1,
@ -97,7 +97,7 @@ minetest.register_tool("exchangeclone:red_matter_shears", {
wield_image = "exchangeclone_red_matter_shears.png",
inventory_image = "exchangeclone_red_matter_shears.png",
stack_max = 1,
groups = { tool=1, shears=1, dig_speed_class=8, },
groups = { tool=1, shears=1, dig_speed_class=8, disable_repair = 1, fire_immune = 1 },
tool_capabilities = {
full_punch_interval = 0.3,
max_drop_level=1,

View File

@ -20,9 +20,11 @@ exchangeclone.shovel_action = {
else
if data.path then
if (minetest.get_item_group(node.name, "path_creation_possible") == 1) then
minetest.sound_play({name="default_grass_footstep", gain=1}, {pos = pos}, true)
data.energy_cost = data.energy_cost + 4
minetest.swap_node(pos, {name="mcl_core:grass_path"})
if minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}).name == "air" then
minetest.sound_play({name="default_grass_footstep", gain=1}, {pos = pos}, true)
data.energy_cost = data.energy_cost + 4
minetest.swap_node(pos, {name="mcl_core:grass_path"})
end
end
else
data.energy_cost = data.energy_cost + 8
@ -73,7 +75,7 @@ minetest.register_tool("exchangeclone:dark_matter_shovel", {
description = "Dark Matter Shovel",
wield_image = "exchangeclone_dark_matter_shovel.png",
inventory_image = "exchangeclone_dark_matter_shovel.png",
groups = { tool=1, shovel=1, dig_speed_class=7, enchantability=0 },
groups = { tool=1, shovel=1, dig_speed_class=7, enchantability=0, disable_repair = 1, fire_immune = 1 },
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
-- 1/1.2
@ -98,7 +100,7 @@ minetest.register_tool("exchangeclone:red_matter_shovel", {
description = "Red Matter Shovel",
wield_image = "exchangeclone_red_matter_shovel.png",
inventory_image = "exchangeclone_red_matter_shovel.png",
groups = { tool=1, shovel=1, dig_speed_class=8, enchantability=0 },
groups = { tool=1, shovel=1, dig_speed_class=8, enchantability=0, disable_repair = 1, fire_immune = 1 },
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
-- 1/1.2

View File

@ -173,7 +173,7 @@ minetest.register_tool("exchangeclone:dark_matter_sword", {
description = "Dark Matter Sword",
wield_image = "exchangeclone_dark_matter_sword.png",
inventory_image = "exchangeclone_dark_matter_sword.png",
groups = { tool=1, sword=1, dig_speed_class=7, enchantability=0 },
groups = { tool=1, sword=1, dig_speed_class=7, enchantability=0, disable_repair = 1, fire_immune = 1 },
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
-- 1/1.2
@ -198,7 +198,7 @@ minetest.register_tool("exchangeclone:red_matter_sword", {
description = "Red Matter Sword",
wield_image = "exchangeclone_red_matter_sword.png",
inventory_image = "exchangeclone_red_matter_sword.png",
groups = { tool=1, sword=1, dig_speed_class=8, enchantability=0 },
groups = { tool=1, sword=1, dig_speed_class=8, enchantability=0, disable_repair = 1, fire_immune = 1 },
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
-- 1/1.2

BIN
textures/blank.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 731 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 965 B

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 559 B

384
transmutation_table.lua Normal file
View File

@ -0,0 +1,384 @@
local function get_transmutation_buttons(player, page, x, y)
local pages = minetest.deserialize(player:get_meta():get_string("exchangeclone_transmutation")) or {}
if page > #pages then page = #pages end
if page < 1 then page = 1 end
if not pages[page] and page == 1 then
pages[page] = {}
end
local buttons = ""
for i = 0, 15 do
local itemstring = pages[page][i+1]
local column = (i%4)
local row = math.floor(i/4)
if itemstring then
buttons = buttons.."item_image_button["..tostring(x+column)..","..tostring(y+row)..";1,1;"..itemstring..";"..itemstring..";]"
else
buttons = buttons.."image_button["..tostring(x+column)..","..tostring(y+row)..";1,1;blank.png;empty_button"..tostring(i)..";]"
end
end
buttons = buttons.."label[5.75,5.25;"..tostring(page).."/"..tostring(#pages).."]"
player:get_meta():set_int("exchangeclone_transmutation_page", page)
return buttons
end
--<copied from MineClone>
local function filter_item(name, description, lang, filter)
local desc
if not lang then
desc = string.lower(description)
else
desc = string.lower(minetest.get_translated_string(lang, description))
end
return string.find(name, filter, nil, true) or string.find(desc, filter, nil, true)
end
function exchangeclone.reload_transmutation_list(player, search)
local meta = player:get_meta()
local player_energy = exchangeclone.get_player_energy(player)
local items_to_show = minetest.deserialize(meta:get_string("exchangeclone_transmutation_learned_items")) or {}
local lang = minetest.get_player_information(player:get_player_name()).lang_code
local pages = {}
local page_num = 1
local i = 0
if not search or search == "" then search = player:get_meta():get_string("exchangeclone_transmutation_search") or "" end
if search and search ~= "" then
local filtered_items = {}
for _,name in ipairs(items_to_show) do
local def = minetest.registered_items[name]
if def and (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) and def.description and def.description ~= "" then
if filter_item(string.lower(def.name), def.description, lang, search) then
table.insert(filtered_items, name)
end
end
items_to_show = table.copy(filtered_items)
end
end
for _, item in ipairs(items_to_show) do
local energy_value = exchangeclone.get_item_energy(item)
if energy_value <= player_energy and energy_value > 0 then
page_num = math.floor(i/16) + 1
if not pages[page_num] then pages[page_num] = {} end
pages[page_num][(i % 16) + 1] = item
i = i + 1
end
end
player:get_meta():set_string("exchangeclone_transmutation", minetest.serialize(pages))
return pages
end
local function add_to_output(player, amount, show)
local item = player:get_meta():get_string("exchangeclone_transmutation_selection")
if minetest.registered_items[item] then
local energy_value = exchangeclone.get_item_energy(item)
local player_energy = exchangeclone.get_player_energy(player)
local stack_max = ItemStack(item):get_stack_max()
if amount == true then amount = stack_max end
local max_amount = math.min(amount, stack_max, math.floor(player_energy/energy_value))
local inventory = minetest.get_inventory({type = "detached", name = "exchangeclone_transmutation_"..player:get_player_name()})
local added_amount = max_amount - inventory:add_item("output", ItemStack(item.." "..max_amount)):get_count()
exchangeclone.set_player_energy(player, player_energy - (energy_value * added_amount))
if show then exchangeclone.show_transmutation_table_formspec(player) end
end
end
local function handle_inventory(player, inventory, to_list, to_index, stack)
if to_list == "learn" then
local list = minetest.deserialize(player:get_meta():get_string("exchangeclone_transmutation_learned_items")) or {}
if stack:get_name() == "exchangeclone:alchemical_tome" then
list = {}
local i = 0
for name, def in pairs(minetest.registered_items) do
if exchangeclone.get_item_energy(name) > 0 and not def.groups.not_in_creative_inventory then
i = i + 1
list[i] = name
end
end
table.sort(list)
player:get_meta():set_string("exchangeclone_transmutation_learned_items", minetest.serialize(list))
else
local individual_energy_value = exchangeclone.get_item_energy(stack:get_name())
if individual_energy_value <= 0 then return end
local energy_value = individual_energy_value * stack:get_count()
if stack:get_name() == "exchangeclone:exchange_orb" then
energy_value = energy_value + exchangeclone.get_orb_itemstack_energy(stack)
end
local player_energy = exchangeclone.get_player_energy(player)
local result = player_energy + energy_value
if result < 0 or result > 2147483647 then return end
exchangeclone.set_player_energy(player, exchangeclone.get_player_energy(player) + energy_value)
local item_index = table.indexof(list, stack:get_name())
if item_index == -1 then
list[#list+1] = stack:get_name()
table.sort(list)
player:get_meta():set_string("exchangeclone_transmutation_learned_items", minetest.serialize(list))
end
end
inventory:set_stack(to_list, to_index, nil)
exchangeclone.show_transmutation_table_formspec(player)
elseif to_list == "forget" then
-- end
elseif to_list == "charge" then
local player_energy = exchangeclone.get_player_energy(player)
local orb_energy = exchangeclone.get_orb_itemstack_energy(stack)
local charge_amount = math.min(exchangeclone.energy_max - orb_energy, player_energy)
if charge_amount > 0 then
exchangeclone.set_player_energy(player, player_energy - charge_amount)
exchangeclone.set_orb_energy(inventory, to_list, to_index, orb_energy + charge_amount)
exchangeclone.show_transmutation_table_formspec(player)
end
end
end
local function check_for_table(player, inv)
if minetest.is_creative_enabled(player:get_player_name()) then return true end
if inv and inv:get_location().name ~= "exchangeclone_transmutation_"..player:get_player_name() then return false end
local def = player:get_wielded_item():get_definition()
local range = def and def.range
if not range then range = player:get_inventory():get_stack("hand", 1):get_definition().range end
if range then range = range + 1 else range = 5 end
if player:get_wielded_item():get_name() ~= "exchangeclone:transmutation_tablet"
and not minetest.find_node_near(player:get_pos(), range, "exchangeclone:transmutation_table", true) then return false end
return true
end
local function allow_inventory_action(player, stack, to_list, count, move, inventory)
if not check_for_table(player, inventory) then return 0 end
if to_list == "output" then
return 0
elseif to_list == "charge" and stack:get_name() ~= "exchangeclone:exchange_orb" then
return 0
elseif to_list == "learn" then
if stack:get_name() == "exchangeclone:alchemical_tome" then return count end
local name = stack:get_name()
local energy_value = exchangeclone.get_item_energy(stack:get_name())
local def = minetest.registered_items[name]
if energy_value <= 0 or def.groups.not_in_creative_inventory == 1 then
return 0
else
return count
end
elseif to_list == "forget" then
-- Kind of a weird way of doing this, but I couldn't make it work in the "on_inventory_* functions"
local list = minetest.deserialize(player:get_meta():get_string("exchangeclone_transmutation_learned_items")) or {}
local item_index = table.indexof(list, stack:get_name())
if item_index > -1 then
list[item_index] = list[#list]
list[#list] = nil
table.sort(list)
player:get_meta():set_string("exchangeclone_transmutation_learned_items", minetest.serialize(list))
local selection = player:get_meta():get_string("exchangeclone_transmutation_selection")
if selection == stack:get_name() then
player:get_meta():set_string("exchangeclone_transmutation_selection", "")
end
end
exchangeclone.show_transmutation_table_formspec(player)
return 0
else
return count
end
end
function exchangeclone.show_transmutation_table_formspec(player, data)
exchangeclone.reload_transmutation_list(player, data and data.search)
if not data then data = {} end
local player_energy = exchangeclone.get_player_energy(player)
local selection = data.selection or player:get_meta():get_string("exchangeclone_transmutation_selection")
local player_name = player:get_player_name()
local inventory_name = "detached:exchangeclone_transmutation_"..player_name
local label = "Transmutation\n"..tostring(player_energy).." energy"
local formspec =
"size[9,11]"..
"label[0,0;"..label.."]"..
"list["..inventory_name..";charge;0,1;1,1]"..
"label[0,2;Charge]"..
"list["..inventory_name..";forget;1,1;1,1]"..
"label[1,2;Forget]"..
"list["..inventory_name..";learn;2,1;1,1]"..
"label[2,2;Learn]"..
"list["..inventory_name..";output;2,3.5;2,2]"..
"label[2.5,3;Output]"..
get_transmutation_buttons(player, (data.page or player:get_meta():get_int("exchangeclone_transmutation_page")), 4, 1)..
"button[4,5;1,1;left_arrow;<]"..
"button[7,5;1,1;right_arrow;>]"..
"button[0,3.5;1,1;plus1;+1]"..
"button[1,3.5;1,1;plus5;+5]"..
"button[0,4.5;1,1;plus10;+10]"..
"button[1,4.5;1,1;plusstack;+Stack]"..
"field[4.25,0.25;4,1;search_box;;"..(data.search or player:get_meta():get_string("exchangeclone_transmutation_search") or "").."]"..
"field_close_on_enter[search_box;false]"..
"button[8,0;1,1;search_button;Search]"..
exchangeclone.inventory_formspec(0,6.25)..
"listring["..inventory_name..";output]"..
"listring[current_player;main]"..
"listring["..inventory_name..";learn]"..
"listring[current_player;main]"
if minetest.registered_items[selection] then
formspec = formspec.."item_image[0.5,2.5;0.8,0.8;"..selection.."]"
end
if exchangeclone.mineclone then
formspec = formspec..
mcl_formspec.get_itemslot_bg(0,1,1,1)..
mcl_formspec.get_itemslot_bg(1,1,1,1)..
mcl_formspec.get_itemslot_bg(2,1,1,1)..
mcl_formspec.get_itemslot_bg(2,3.5,2,2)
end
minetest.show_formspec(player_name, "exchangeclone_transmutation_table", formspec)
end
minetest.register_on_joinplayer(function(player, last_login)
local playername = player:get_player_name()
minetest.create_detached_inventory("exchangeclone_transmutation_"..playername, {
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
local stack = inv:get_stack(from_list, from_index)
stack:set_count(count)
return allow_inventory_action(player, stack, to_list, count, true, inv)
end,
on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
local stack = inv:get_stack(to_list, to_index)
handle_inventory(player, inv, to_list, to_index, stack)
end,
allow_put = function(inv, listname, index, stack, player)
local count = stack:get_count()
return allow_inventory_action(player, stack, listname, count, false, inv)
end,
on_put = function(inv, listname, index, stack, player)
handle_inventory(player, inv, listname, index, stack)
end
}, playername)
local inventory = minetest.get_inventory({type = "detached", name = "exchangeclone_transmutation_"..playername})
inventory:set_size("charge", 1)
inventory:set_size("output", 4)
inventory:set_width("output", 2)
inventory:set_size("learn", 1)
inventory:set_size("forget", 1)
exchangeclone.reload_transmutation_list(player)
end)
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname == "exchangeclone_transmutation_table" then
if not check_for_table(player) then return end
for field, value in pairs(fields) do
if field == "search_box" or field == "quit" then
-- do nothing
elseif field == "right_arrow" then
exchangeclone.show_transmutation_table_formspec(player, {page = player:get_meta():get_int("exchangeclone_transmutation_page") + 1})
elseif field == "left_arrow" then
exchangeclone.show_transmutation_table_formspec(player, {page = player:get_meta():get_int("exchangeclone_transmutation_page") - 1})
elseif field == "search_button" or (field == "key_enter_field" and value == "search_box") then
local search = fields.search_box or ""
player:get_meta():set_string("exchangeclone_transmutation_search", search)
exchangeclone.show_transmutation_table_formspec(player)
elseif field == "plus1" then
add_to_output(player, 1, true)
elseif field == "plus5" then
add_to_output(player, 5, true)
elseif field == "plus10" then
add_to_output(player, 10, true)
elseif field == "plusstack" then
add_to_output(player, true, true)
elseif minetest.registered_items[field] then
player:get_meta():set_string("exchangeclone_transmutation_selection", field)
exchangeclone.show_transmutation_table_formspec(player, {selection = field})
end
end
end
end)
minetest.register_tool("exchangeclone:transmutation_tablet", {
description = "Transmutation Tablet",
groups = {disable_repair = 1, fire_immune = 1},
wield_image = "exchangeclone_transmutation_table.png",
inventory_image = "exchangeclone_transmutation_table.png",
on_secondary_use = function(itemstack, player, pointed_thing)
local click_test = exchangeclone.check_on_rightclick(itemstack, player, pointed_thing)
if click_test ~= false then
return click_test
end
exchangeclone.show_transmutation_table_formspec(player)
end,
on_place = function(itemstack, player, pointed_thing)
local click_test = exchangeclone.check_on_rightclick(itemstack, player, pointed_thing)
if click_test ~= false then
return click_test
end
exchangeclone.show_transmutation_table_formspec(player)
end
})
minetest.register_node("exchangeclone:transmutation_table", {
description = "Transmutation Table",
paramtype2 = "wallmounted",
tiles = {"exchangeclone_transmutation_table.png", "exchangeclone_transmutation_table.png", "exchangeclone_transmutation_table_side.png"},
groups = {oddly_breakable_by_hand = 3, handy = 1},
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, -0.3, 0.5},
},
sounds = exchangeclone.sound_mod.node_sound_stone_defaults(),
on_rightclick = function(pos, node, player, itemstack, pointed_thing)
exchangeclone.show_transmutation_table_formspec(player)
end,
_mcl_hardness = 0.6,
_mcl_blast_resistance = 6,
})
minetest.register_tool("exchangeclone:alchemical_tome", {
description = "Alchemical Tome",
inventory_image = "exchangeclone_alchemical_tome.png",
wield_image = "exchangeclone_alchemical_tome.png",
groups = {disable_repair = 1, fire_immune = 1}
})
local book = "default:book"
local obsidian = "default:obsidian"
local stone = "default:stone"
if exchangeclone.mineclone then
book = "mcl_books:book"
obsidian = "mcl_core:obsidian"
stone = "mcl_core:stone"
end
minetest.register_craft({
output = "exchangeclone:transmutation_table",
recipe = {
{obsidian, stone, obsidian},
{stone, "exchangeclone:philosophers_stone", stone},
{obsidian, stone, obsidian}
},
replacements = {{"exchangeclone:philosophers_stone", "exchangeclone:philosophers_stone"}}
})
minetest.register_craft({
output = "exchangeclone:transmutation_tablet",
recipe = {
{"exchangeclone:dark_matter_block", stone, "exchangeclone:dark_matter_block"},
{stone, "exchangeclone:transmutation_table", stone},
{"exchangeclone:dark_matter_block", stone, "exchangeclone:dark_matter_block"}
},
})
minetest.register_craft({
output = "exchangeclone:alchemical_tome",
recipe = {
{"", book, ""},
{"exchangeclone:exchange_orb", "exchangeclone:philosophers_stone", "exchangeclone:exchange_orb"},
{"", "exchangeclone:red_matter", ""}
},
replacements = {{"exchangeclone:philosophers_stone", "exchangeclone:philosophers_stone"}}
})
minetest.register_craft_predict(function(itemstack, player, old_craft_grid, craft_inv)
if itemstack == ItemStack("exchangeclone:alchemical_tome") then
if exchangeclone.get_orb_itemstack_energy(old_craft_grid[4]) >= exchangeclone.energy_max
and exchangeclone.get_orb_itemstack_energy(old_craft_grid[6]) >= exchangeclone.energy_max then
return
else
return ItemStack("")
end
end
end)

View File

@ -1 +0,0 @@
-- Not until 5.0