This commit is contained in:
ThePython 2023-08-07 13:56:29 -07:00
parent d2760c91f3
commit 5645cc4ae4
44 changed files with 1414 additions and 794 deletions

View File

@ -20,30 +20,37 @@ Dependencies: Minetest Game or MineClone.
- Constructor that can create items from energy
## Config
All energy values are in `energy.lua`. You can also change the speed at which the Energy Collector collects energy (default: every 5 seconds) in `minetest.conf` or the Minetest settings.
All energy values are in `energy.lua`. You can also change the speed at which the Energy Collector collects energy (default: 5 energy/second) in `minetest.conf` or the Minetest settings.
## New features added by ThePython10110
*More information in `changelog.txt`.*
* Support for MineClone
* COMPLETELY redone energy values (originally, you could convert a single diamond into a diamond block... incredibly OP).
* Shift-clicking works (`listring`s)
* COMPLETELY redone energy values (originally, you could convert a single diamond into a diamond node... incredibly OP).
* Shift-clicking works with the Constructor/Deconstructor/Collector (`listring`s)
* Fixed a bug where items could be placed in the output slot of the Element Constructor
* Added the ability to add energy values by group
* Damaged tools now give less energy (based on wear)
* Added Philosopher's Stone
* Right-click and sneak-right-click to increase and decrease transmutation range (0-4 blocks away from the block you are currently standing on)
* Left-click and sneak-left-click to transmute blocks in range (two different modes with minor differences)
* Right-click and sneak-right-click to increase and decrease transmutation range (0-4 nodes away from the node you are currently standing on)
* Left-click and sneak-left-click to transmute nodes in range (two different modes with minor differences)
* Aux1-left-click to open enchanting table (MineClone only)
* Aux1-right-click to open crafting table (MineClone only)
* Ability to exchange charcoal/coal/iron/copper/tin/gold/mese/emerald/diamond by crafting (the Philosopher's Stone is always returned)
* Alchemical Coal, Mobius Fuel, and Aeternalis Fuel
* Dark and Red Matter Orbs, Blocks, and tools
* 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:
* When items are inserted into the Energy Collector, Deconstructor, or Constructor with MineClone hoppers, it does not trigger the machines to start.
* When machines are exploded, they (and the items inside) do not drop.
* Dark/Red matter shears will sometimes be treated as normal shears when used by MineClone dispensers.
* Blocks destroyed by special abilities will not update surrounding blocks (so you may end up with floating gravel, flowers, torches, etc.)
* 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.
* In MineClone, it is impossible to heal past 20 health (10 hearts) without potions of healing (or the soul/life stones, which I haven't added yet)
* 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.
* 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).
@ -51,7 +58,12 @@ If you have a suggestion or notice a bug, visit the [GitHub issues page](https:/
![Minetest Game Screenshot](screenshot_mtg.png)
## Sources/license:
This mod is inspired by the "Equivalent Exchange" mod for MineCraft, and forked and modified from Enchant97's mod [Element Exchange](https://github.com/enchant97/minetest_element_exchange). Both this mod and Element Exchange are licensed under GPLv3+. The textures for the Constructor, Deconstructor, Collector, and Orb are from Element Exchange and have the same license.The Alchemical Coal, Mobius Fuel, and Aeternalis Fuel textures are modified versions of MineClone's coal texture (CC-BY-SA-3.0). All other textures are my own (inspired by Equivalent Exchange) and licensed under GPLv3+ just to make it match Element Exchange.
* Code: Forked and *heavily* modified from Enchant97's mod [Element Exchange](https://github.com/enchant97/minetest_element_exchange). Both this mod ane Element Exchange are licenced under GPLv3+. Based on Equivalent Exchange and ProjectE, mods for MineCraft.
* Textures:
* Energy Collector, Element Deconstructor, Element Constructor, and Exchange Orb: Directly from Element Exchange, GPLv3+.
* Alchemical Coal, Mobius Fuel, and Aeternalis Fuel: modified versions of MineClone's coal texture (CC-BY-SA-3.0).
* Dark and Red Matter Armor (and eventually Gem Armor): modified versions of diamond armor from 3D Armor (CC-BY-SA-3.0) and `mcl_armor` (CC-BY-SA-3.0).
* All other textures (and sounds): Created by me, inspired by Equivalent Exchange and licensed under CC-BY-SA-3.0.
Copyright (C) 2023 ThePython10110

346
armor.lua Normal file
View File

@ -0,0 +1,346 @@
local blocked_damage_types = {
drown = true,
lava = true,
in_fire = true,
on_fire = true,
hot_floor = true,
}
local function get_armor_texture(type, matter, preview)
local modifier = ""
-- hsl only works in 5.8 which hasn't been released yet
if matter == "dark" then
modifier = "^[multiply:#222222"
--modifier = "^[hsl:0:-100:-100^[hsl:0:-100:-100"
else
modifier = "^[multiply:#990000"
--modifier = "^[hsl:-180:100:-100"
end
local result
if exchangeclone.mineclone then
result = "exchangeclone_mcl_"..type.."_base.png"..modifier
else
result = "exchangeclone_mtg_"..type.."_base"
if preview then result = result.."_preview" end
result = result..".png"..modifier
end
--minetest.log(result)
return result
end
function exchangeclone.check_armor_health(obj)
local max_armor = 5
local armor_pieces = 0
if exchangeclone.mineclone then
max_armor = 4
local inv = mcl_util.get_inventory(obj)
if inv then
for name, element in pairs(mcl_armor.elements) do
local itemstack = inv:get_stack("armor", element.index)
if not itemstack:is_empty() then
if minetest.get_item_group(itemstack:get_name(), "red_matter_armor") > 0 then
armor_pieces = armor_pieces + 1
end
end
end
end
else
local name, armor_inv = armor:get_valid_player(obj, "[checking for red matter]")
if not armor_inv then minetest.log("Inventory is nil") return end
local list = armor_inv:get_list("armor")
if type(list) ~= "table" then
return
end
for i, stack in ipairs(list) do
if stack:get_count() == 1 then
if minetest.get_item_group(stack:get_name(), "red_matter_armor") > 0 then
armor_pieces = armor_pieces + 1
end
end
end
end
local already_has_health = 0
if obj:is_player() then
already_has_health = obj:get_meta():get_int("exchangeclone_red_matter_armor") or 0
end
if armor_pieces >= max_armor then
if already_has_health == 0 then
obj:set_properties({hp_max = 2000})
-- fix this if MineCraft changes to max_hp instead of hardcoding 20
obj:set_hp(2000-math.max(20-obj:get_hp(), 0))
obj:get_meta():set_int("exchangeclone_red_matter_armor", 1)
end
else
if already_has_health == 1 then
obj:set_hp(math.min(obj:get_hp(), 20))
obj:set_properties({hp_max = 20})
obj:get_meta():set_int("exchangeclone_red_matter_armor", 0)
end
end
end
minetest.register_on_joinplayer(function(ObjectRef, last_login)
exchangeclone.check_armor_health(ObjectRef)
end)
minetest.register_on_respawnplayer(function(ObjectRef)
exchangeclone.check_armor_health(ObjectRef)
end)
if exchangeclone.mineclone then
mcl_armor.register_set({
name = "dark_matter",
description = "Dark Matter",
durability = -1,
enchantability = 0,
points = {
head = 5,
torso = 8,
legs = 7,
feet = 4,
},
textures = {
head = get_armor_texture("helmet","dark"),
torso = get_armor_texture("chestplate","dark"),
legs = get_armor_texture("leggings","dark"),
feet = get_armor_texture("boots","dark"),
},
toughness = 4,
groups = {dark_matter_armor = 1, fire_immune = 1},
craft_material = "exchangeclone:dark_matter",
cook_material = "mcl_core:diamondblock",
})
mcl_armor.register_set({
name = "red_matter",
description = "Red Matter",
durability = -1,
enchantability = 0,
points = {
head = 7,
torso = 12,
legs = 8,
feet = 5,
},
textures = {
head = get_armor_texture("helmet","red"),
torso = get_armor_texture("chestplate","red"),
legs = get_armor_texture("leggings","red"),
feet = get_armor_texture("boots","red"),
},
toughness = 5,
groups = {red_matter_armor = 1, fire_immune = 1},
craft_material = "exchangeclone:red_matter",
cook_material = "exchangeclone:dark_matter",
on_equip_callbacks = {
head=exchangeclone.check_armor_health,
torso=exchangeclone.check_armor_health,
legs=exchangeclone.check_armor_health,
feet=exchangeclone.check_armor_health
},
on_unequip_callbacks = {
head=exchangeclone.check_armor_health,
torso=exchangeclone.check_armor_health,
legs=exchangeclone.check_armor_health,
feet=exchangeclone.check_armor_health
}
})
for _, matter in ipairs({"dark", "red"}) do
for _, type in ipairs({"helmet", "chestplate", "leggings", "boots"}) do
minetest.override_item("exchangeclone:"..type.."_"..matter.."_matter", {
inventory_image = get_armor_texture("inv_"..type, matter),
wield_image = get_armor_texture("inv_"..type, matter),
})
end
end
mcl_damage.register_modifier(function(obj, damage, reason)
if reason.type == "fall" then
return damage/5
elseif not blocked_damage_types[reason.type] then return end
local inv = mcl_util.get_inventory(obj)
if inv then
local armor_pieces = 0
for name, element in pairs(mcl_armor.elements) do
local itemstack = inv:get_stack("armor", element.index)
if not itemstack:is_empty() then
if minetest.get_item_group(itemstack:get_name(), "dark_matter_armor") > 0
or minetest.get_item_group(itemstack:get_name(), "red_matter_armor") > 0 then
armor_pieces = armor_pieces + 1
end
end
end
if armor_pieces >= 4 then
return 0
end
end
end, 0)
else
armor:register_armor("exchangeclone:helmet_dark_matter", {
description = "Dark Matter Helmet",
texture = get_armor_texture("helmet","dark"),
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}
})
armor:register_armor("exchangeclone:chestplate_dark_matter", {
description = "Dark Matter Chestplate",
texture = get_armor_texture("chestplate","dark"),
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}
})
armor:register_armor("exchangeclone:leggings_dark_matter", {
description = "Dark Matter Leggings",
texture = get_armor_texture("leggings","dark"),
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}
})
armor:register_armor("exchangeclone:boots_dark_matter", {
description = "Dark Matter Boots",
texture = get_armor_texture("boots","dark"),
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}
})
armor:register_armor("exchangeclone:shield_dark_matter", {
description = "Dark Matter Shield",
texture = get_armor_texture("shield","dark"),
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}
})
armor:register_armor("exchangeclone:helmet_red_matter", {
description = "Red Matter Helmet",
texture = get_armor_texture("helmet","red"),
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}
})
armor:register_armor("exchangeclone:chestplate_red_matter", {
description = "Red Matter Chestplate",
texture = get_armor_texture("chestplate","red"),
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}
})
armor:register_armor("exchangeclone:leggings_red_matter", {
description = "Red Matter Leggings",
texture = get_armor_texture("leggings","red"),
inventory_image = get_armor_texture("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}
})
armor:register_armor("exchangeclone:boots_red_matter", {
description = "Red Matter Boots",
texture = get_armor_texture("boots","red"),
inventory_image = get_armor_texture("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}
})
armor:register_armor("exchangeclone:shield_red_matter", {
description = "Red Matter Shield",
texture = get_armor_texture("shield","red"),
inventory_image = get_armor_texture("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}
})
armor:register_on_equip(function(player, index, stack)
exchangeclone.check_armor_health(player)
end)
armor:register_on_unequip(function(player, index, stack)
exchangeclone.check_armor_health(player)
end)
end
local d = "exchangeclone:dark_matter"
local r = "exchangeclone:red_matter"
minetest.register_craft({
output = "exchangeclone:helmet_dark_matter",
recipe = {
{d,d,d},
{d,"",d}
}
})
minetest.register_craft({
output = "exchangeclone:chestplate_dark_matter",
recipe = {
{d,"",d},
{d,d,d},
{d,d,d},
}
})
minetest.register_craft({
output = "exchangeclone:leggings_dark_matter",
recipe = {
{d,d,d},
{d,"",d},
{d,"",d},
}
})
minetest.register_craft({
output = "exchangeclone:boots_dark_matter",
recipe = {
{d,"",d},
{d,"",d},
}
})
minetest.register_craft({
output = "exchangeclone:helmet_red_matter",
recipe = {
{r,r,r},
{r,"exchangeclone:helmet_dark_matter",r}
}
})
minetest.register_craft({
output = "exchangeclone:chestplate_red_matter",
recipe = {
{r,"exchangeclone:chestplate_dark_matter",r},
{r,r,r},
{r,r,r},
}
})
minetest.register_craft({
output = "exchangeclone:leggings_red_matter",
recipe = {
{r,r,r},
{r,"exchangeclone:leggings_dark_matter",r},
{r,"",r},
}
})
minetest.register_craft({
output = "exchangeclone:boots_red_matter",
recipe = {
{r,"exchangeclone:boots_dark_matter",r},
{r,"",r},
}
})
if minetest.get_modpath("3d_armor") then
minetest.register_craft({
output = "exchangeclone:shield_dark_matter",
recipe = {
{d,d,d},
{d,d,d},
{"",d,""},
}
})
minetest.register_craft({
output = "exchangeclone:shield_red_matter",
recipe = {
{d,d,d},
{d,d,d},
{"exchangeclone:shield_dark_matter",d,""},
}
})
end

View File

@ -1,51 +1,46 @@
local axe_break_cube = function(player, center, distance, strip)
if distance > 0 then
exchangeclone.play_ability_sound(player)
end
local player_pos = player:get_pos()
local player_energy = exchangeclone.get_player_energy(player)
local energy_cost = 0
local pos = center
pos.x = exchangeclone.round(pos.x)
pos.y = math.floor(pos.y) --make sure y is node BELOW player's feet
pos.z = exchangeclone.round(pos.z)
for x = pos.x-distance, pos.x+distance do
if energy_cost + 8 > player_energy then
break
exchangeclone.axe_action = {
start_action = function(player, center, range)
if exchangeclone.check_cooldown(player, "axe") then return end
local data = {}
data.player_energy = exchangeclone.get_player_energy(player)
data.energy_cost = 0
if exchangeclone.mineclone then
data.strip = not player:get_player_control().sneak
end
for y = pos.y-distance, pos.y+distance do
if energy_cost + 8 > player_energy then
break
if range > 0 or not data.strip then
exchangeclone.play_ability_sound(player)
end
for z = pos.z-distance, pos.z+distance do
if energy_cost + 8 > player_energy then
break
end
local new_pos = {x=x,y=y,z=z}
local node = minetest.get_node(new_pos) or {name="air"}
return data
end,
action = function(player, pos, node, data)
if data.energy_cost + 8 > data.player_energy then return end
local node_def = minetest.registered_items[node.name]
if (node_def.groups.tree or node_def.groups.leaves) then
if minetest.is_protected(new_pos, player:get_player_name()) then
minetest.record_protection_violation(new_pos, player:get_player_name())
if minetest.is_protected(pos, player:get_player_name()) then
minetest.record_protection_violation(pos, player:get_player_name())
else
energy_cost = energy_cost + 8
if strip then
if data.strip then
if node_def._mcl_stripped_variant ~= nil then
minetest.swap_node(new_pos, {name=node_def._mcl_stripped_variant, param2=node.param2})
data.energy_cost = data.energy_cost + 4
minetest.swap_node(pos, {name=node_def._mcl_stripped_variant, param2=node.param2})
end
else
data.energy_cost = data.energy_cost + 8
local drops = minetest.get_node_drops(node.name, "exchangeclone:red_matter_axe")
exchangeclone.drop_items_on_player(new_pos, drops, player)
minetest.set_node(new_pos, {name = "air"})
exchangeclone.drop_items_on_player(pos, drops, player)
minetest.set_node(pos, {name = "air"})
end
end
end
return data
end,
end_action = function(player, center, range, data)
if range > 0 or not data.strip then
exchangeclone.set_player_energy(player, data.player_energy - data.energy_cost)
exchangeclone.start_cooldown(player, "axe", range/6)
end
end
end
end
exchangeclone.set_player_energy(player, player_energy - energy_cost)
end
}
local function axe_on_place(itemstack, player, pointed_thing)
local click_test = exchangeclone.check_on_rightclick(itemstack, player, pointed_thing)
@ -63,27 +58,9 @@ local function axe_on_place(itemstack, player, pointed_thing)
local range = itemstack:get_meta():get_int("exchangeclone_item_range")
if pointed_thing.type == "node" then
local node = minetest.get_node(pointed_thing.under)
local node_def = minetest.registered_nodes[node.name]
if range == 0 then
if node_def._mcl_stripped_variant ~= nil then
minetest.swap_node(pointed_thing.under, {name=node_def._mcl_stripped_variant, param2=node.param2})
return itemstack
end
end
end
local center = player:get_pos()
if pointed_thing.type == "node" then
center = pointed_thing.under
end
if player:get_player_control().sneak and exchangeclone.mineclone then
axe_break_cube(player, center, range, true) -- strip when holding shift
else
axe_break_cube(player, center, range)
end
if pointed_thing.type == "node" then center = pointed_thing.under end
exchangeclone.node_radius_action(player, center, range, exchangeclone.axe_action)
return itemstack
end

View File

@ -18,8 +18,8 @@
Left click to increase range (minimum = 0, maximum = 4).
Shift+left click to decrease range.
Aux1+left click to open enchanting table (MineClone only).
Right click to transmute blocks in range (mode 1).
Shift+right click to transmute blocks in range (mode 2, has some differences).
Right click to transmute nodes in range (mode 1).
Shift+right click to transmute nodes in range (mode 2, has some differences).
Aux1+right click to open crafting table (MineClone only).
Can use to craft coal into iron, mese into diamonds, etc.
Changes:
@ -40,27 +40,27 @@
A single inventory slot in which an orb can be placed. Energy from the orb is used for special abilities.
Added Dark and Red Matter tools
Faster than any other tools (in unmodded MTG/MCL), each has an ability
Special abilities that break blocks (as well as shearing) drop items directly on the player.
Special abilities that break nodes (as well as shearing) drop items directly on the player.
Swords:
Can damage all mobs within a radius (Red Matter sword can toggle between hostile/all mobs), costing 384 energy.
Pickaxes:
Has 3x1 modes (long, tall, and wide, all slightly slower)
Can mine a full vein of ores, dropping items and experience on the player
Axes:
Can break all wood and leaves within a radius, costing 8 energy per block broken.
Can break all wood and leaves within a radius, costing 8 energy per node broken.
Shovels:
Can break all shovely blocks within a radius, costing 8 energy per block broken
Can create paths in a radius, costing 8 energy per block
Can break all shovely nodes within a radius, costing 8 energy per node broken
Can create paths in a radius, costing 8 energy per node
Hoes:
Breaks dirt incredibly quickly (and unfortunately all other shovely blocks because I can't figure out how to avoid it)
Breaks dirt incredibly quickly (and unfortunately all other shovely nodes because I can't figure out how to avoid it)
Has a 3x3 mode for digging dirt (slightly slower)
Can till all dirt within a radius, costs 2 energy per block
Can till all dirt within a radius, costs 2 energy per node
Hammers:
Breaks pickaxey blocks in a 3x3 area
Can break all pickaxey blocks within a radius, costing 8 energy per block broken
Breaks pickaxey nodes in a 3x3 area
Can break all pickaxey nodes within a radius, costing 8 energy per node broken
Shears:
More wool/mushrooms dropped when shearing, chance of cloning sheep/mooshrooms
Can shear all shearable plants/cobwebs within a radius, costing 8 energy per block broken.
Can shear all shearable plants/cobwebs within a radius, costing 8 energy per node broken.
Changes:
Added a mod whitelist in energy.lua, any item from a mod NOT in the whitelist (exchangeclone.whitelisted_mods) will have an energy value of 0
@ -92,4 +92,48 @@
Added mcl_blackstone to the mod whitelist
3.2
Changes:
Set MineClone mod namespace
Set MineClone mod namespace to exchangeclone
4.0
New features:
The "Features that I plan on adding eventually" list below
Cooldowns for tool abilities to limit lag
Red Katar (combination of sword, axe, hoe, and shears)
Red Morningstar (combination of hammer, pickaxe, and shovel)
Dark Matter Armor (full set gives immunity to lava/fire and drowning)
Red Matter Armor (full set gives lava/fire/drowning immunity PLUS 2000 health, although you may want HUD Bars to see it)
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 (hammer, pickaxe, hoe, katar, and morningstar) will be 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.
Plans for 4.1
New features:
New items from the next version of Why (I'm planning on doing that next)
Plans for 5.0
New features:
Exchangeclone guidebook (maybe depend on doc mod?)
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
Features that I plan on adding eventually:
Something that places nodes in a square (with varying range), possibly with a low energy cost
As soon as Minetest 5.8 comes out, better textures for armor...
Dark/Red Matter Furnaces
Energy Condenser
Upgraded Energy Collectors
Transmutation Tablet (including portable version)
Divining Rods
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)
Zero Ring
Ring of Arcana (minus the Harvest band)
Gem Armor

View File

@ -44,7 +44,7 @@ local function on_timer(pos, elapsed)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
-- get block above
-- get node above
pos.y = pos.y + 1
if inv:is_empty("main") then

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -0,0 +1,23 @@
-- next update?
local pages = {}
function exchangeclone.show_guidebook(player)
end
minetest.register_tool("exchangeclone:exchangeclone_guidebook", {
description = "Exchange Guidebook",
inventory_image = "exchangeclone_guidebook.png",
wield_image = "exchangeclone_guidebook.png",
on_place = function(itemstack, player, pointed_thing) exchangeclone.show_guidebook(player) end,
on_secondary_use = function(itemstack, player, pointed_thing) exchangeclone.show_guidebook(player) end,
})
minetest.register_chatcommand("exchangeclone_guidebook", function(name, param) exchangeclone.show_guidebook(minetest.get_player_by_name(name)) end)
minetest.register_craft{
output = "exchangeclone:exchangeclone_guidebook",
recipe = "exchangeclone:philosophers_stone",
replacements = {{"exchangeclone:philosophers_stone", "exchangeclone:philosophers_stone"}}
}

View File

@ -3,49 +3,36 @@ if exchangeclone.mineclone then
stone_group = "pickaxey"
end
local players_digging = {}
local hammer_break_cube = function(player, center, distance)
players_digging[player:get_player_name()] = true -- to prevent doing 3x3 as well as AOE
exchangeclone.play_ability_sound(player)
local player_pos = player:get_pos()
local player_energy = exchangeclone.get_player_energy(player)
local energy_cost = 0
local pos = center
pos.x = exchangeclone.round(pos.x)
pos.y = math.floor(pos.y) --make sure y is node BELOW player's feet
pos.z = exchangeclone.round(pos.z)
for x = pos.x-distance, pos.x+distance do
if energy_cost + 8 > player_energy then
break
end
for y = pos.y-distance, pos.y+distance do
if energy_cost + 8 > player_energy then
break
end
for z = pos.z-distance, pos.z+distance do
if energy_cost + 8 > player_energy then
break
end
local new_pos = {x=x,y=y,z=z}
local node = minetest.get_node(new_pos) or {name="air"}
if minetest.get_item_group(node.name, stone_group) ~= 0 then
if minetest.is_protected(new_pos, player:get_player_name()) then
minetest.record_protection_violation(new_pos, player:get_player_name())
else
energy_cost = energy_cost + 8
local drops = minetest.get_node_drops(node.name, "exchangeclone:red_matter_hammer")
exchangeclone.drop_items_on_player(new_pos, drops, player)
minetest.set_node(new_pos, {name = "air"})
end
end
end
end
end
exchangeclone.set_player_energy(player, player_energy - energy_cost)
players_digging[player:get_player_name()] = nil
end
exchangeclone.hammer_action = {
start_action = function(player, center, range)
if exchangeclone.check_cooldown(player, "hammer") then return end
local data = {}
exchangeclone.multidig[player:get_player_name()] = true -- to prevent doing 3x3 as well as AOE
exchangeclone.play_ability_sound(player)
data.player_energy = exchangeclone.get_player_energy(player)
data.energy_cost = 0
return data
end,
action = function(player, pos, node, data)
if data.energy_cost + 8 > data.player_energy then return end
if minetest.get_item_group(node.name, stone_group) ~= 0 then
if minetest.is_protected(pos, player:get_player_name()) then
minetest.record_protection_violation(pos, player:get_player_name())
else
data.energy_cost = data.energy_cost + 8
local drops = minetest.get_node_drops(node.name, "exchangeclone:red_matter_hammer")
exchangeclone.drop_items_on_player(pos, drops, player)
minetest.set_node(pos, {name = "air"})
end
end
return data
end,
end_action = function(player, center, range, data)
exchangeclone.set_player_energy(player, data.player_energy - data.energy_cost)
exchangeclone.multidig[player:get_player_name()] = nil
exchangeclone.start_cooldown(player, "hammer", range/2) -- The hammer has by far the most lag potential and therefore a long cooldown.
end
}
local function hammer_on_place(itemstack, player, pointed_thing)
local click_test = exchangeclone.check_on_rightclick(itemstack, player, pointed_thing)
@ -65,7 +52,7 @@ local function hammer_on_place(itemstack, player, pointed_thing)
local current_name = itemstack:get_name()
if string.sub(current_name, -4, -1) == "_3x3" then
itemstack:set_name(string.sub(current_name, 1, -5))
minetest.chat_send_player(player:get_player_name(), "Single block mode")
minetest.chat_send_player(player:get_player_name(), "Single node mode")
else
itemstack:set_name(current_name.."_3x3")
minetest.chat_send_player(player:get_player_name(), "3x3 mode")
@ -78,7 +65,7 @@ local function hammer_on_place(itemstack, player, pointed_thing)
if pointed_thing.type == "node" then
center = pointed_thing.under
end
hammer_break_cube(player, center, range)
exchangeclone.node_radius_action(player, center, range, exchangeclone.hammer_action)
end
minetest.register_tool("exchangeclone:dark_matter_hammer", {
@ -181,73 +168,6 @@ minetest.register_tool("exchangeclone:red_matter_hammer_3x3", {
on_secondary_use = hammer_on_place,
})
-- adapted from https://github.com/cultom/hammermod/blob/master/init.lua
local function dig_if_stone(pos, player)
local node = minetest.get_node(pos)
if minetest.get_item_group(node.name, stone_group) ~= 0 then
minetest.node_dig(pos, minetest.get_node(pos), player)
end
end
minetest.register_on_dignode(
function(pos, oldnode, player)
if player == nil or (player:get_wielded_item():get_name() ~= "exchangeclone:dark_matter_hammer_3x3"
and player:get_wielded_item():get_name() ~= "exchangeclone:red_matter_hammer_3x3") then
return
end
local playerName = player:get_player_name()
if(playerName == "" or players_digging[playerName]) then
return
end
players_digging[playerName] = true
local player_rotation = exchangeclone.get_face_direction(player)
local dir1
local dir2
if player_rotation.y ~= 0 then
dir1 = "x"
dir2 = "z"
elseif player_rotation.x ~= 0 then
dir1 = "y"
dir2 = "z"
elseif player_rotation.z ~= 0 then
dir1 = "x"
dir2 = "y"
end
--[[
123
4 5
678
]]
pos[dir1] = pos[dir1] - 1 --7
dig_if_stone(pos, player)
pos[dir2] = pos[dir2] - 1 --6
dig_if_stone(pos, player)
pos[dir1] = pos[dir1] + 1 --4
dig_if_stone(pos, player)
pos[dir1] = pos[dir1] + 1 --1
dig_if_stone(pos, player)
pos[dir2] = pos[dir2] + 1 --2
dig_if_stone(pos, player)
pos[dir2] = pos[dir2] + 1 --3
dig_if_stone(pos, player)
pos[dir1] = pos[dir1] - 1 --5
dig_if_stone(pos, player)
pos[dir1] = pos[dir1] - 1 --8
dig_if_stone(pos, player)
players_digging[playerName] = nil
end
)
-- end copied code
minetest.register_craft({
output = "exchangeclone:dark_matter_hammer",
recipe = {

233
hoes.lua
View File

@ -33,6 +33,32 @@ else
hoe_function = farming.hoe_on_use -- assuming farming exists
end
exchangeclone.hoe_action = {
start_action = function(player, center, range, itemstack)
if exchangeclone.check_cooldown(player, "hoe") then return end
local data = {}
if range > 0 then
exchangeclone.play_ability_sound(player)
end
data.player_energy = exchangeclone.get_player_energy(player)
data.energy_cost = 0
data.itemstack = itemstack
return data
end,
action = function(player, pos, node, data)
local new_pointed_thing = {type = "node", under = pos, above = {x=pos.x,y=pos.y+1,z=pos.z}}
data.energy_cost = data.energy_cost + 4
hoe_function(data.itemstack, player, new_pointed_thing)
return data
end,
end_action = function(player, center, range, data)
if range > 0 then
exchangeclone.set_player_energy(player, data.player_energy - data.energy_cost)
exchangeclone.start_cooldown(player, "hoe", range/4)
end
end
}
local hoe_on_place = function(itemstack, player, pointed_thing)
local click_test = exchangeclone.check_on_rightclick(itemstack, player, pointed_thing)
@ -47,56 +73,25 @@ local hoe_on_place = function(itemstack, player, pointed_thing)
return exchangeclone.range_update(itemstack, player, 4)
end
end
if player:get_player_control().sneak then
local current_name = itemstack:get_name()
if string.sub(current_name, -4, -1) == "_3x3" then
itemstack:set_name(string.sub(current_name, 1, -5))
minetest.chat_send_player(player:get_player_name(), "Single block mode")
minetest.chat_send_player(player:get_player_name(), "Single node mode")
else
itemstack:set_name(current_name.."_3x3")
minetest.chat_send_player(player:get_player_name(), "3x3 mode")
end
return itemstack
end
local range = itemstack:get_meta():get_int("exchangeclone_item_range")
if range == 0 and pointed_thing.type == "node" and pointed_thing.under and pointed_thing.under.x then
--minetest.log(dump(pointed_thing))
hoe_function(itemstack, player, pointed_thing)
return itemstack
end
exchangeclone.play_ability_sound(player)
local start_pos = player:get_pos()
local player_energy = exchangeclone.get_player_energy(player)
local energy_cost = 0
if pointed_thing.type == "node" and pointed_thing.under and pointed_thing.under.x then
start_pos = pointed_thing.under
end
--minetest.log(dump(start_pos))
start_pos.x = exchangeclone.round(start_pos.x)
start_pos.y = math.floor(start_pos.y) --make sure y is node BELOW player's feet
start_pos.z = exchangeclone.round(start_pos.z)
for x = start_pos.x - range, start_pos.x + range do
if energy_cost + 2 > player_energy then
break
end
for y = start_pos.y - range, start_pos.y + range do
if energy_cost + 2 > player_energy then
break
end
for z = start_pos.z - range, start_pos.z + range do
if energy_cost + 2 > player_energy then
break
end
local new_pos = {x=x,y=y,z=z}
local new_pointed_thing = {type = "node", under = new_pos, above = {x=x,y=x+1,z=z}}
energy_cost = energy_cost + 2
hoe_function(itemstack, player, new_pointed_thing)
local range = itemstack:get_meta():get_int("exchangeclone_item_range")
local center = player:get_pos()
if pointed_thing.type == "node" then
center = pointed_thing.under
end
end
end
exchangeclone.set_player_energy(player, player_energy - energy_cost)
return itemstack
exchangeclone.node_radius_action(player, center, range, exchangeclone.hoe_action, itemstack)
end
if exchangeclone.mineclone then
@ -113,7 +108,7 @@ for name, def in pairs(minetest.registered_nodes) do
end
end
minetest.register_tool("exchangeclone:dark_matter_hoe", {
local hoe_def = {
description = "Dark Matter Hoe",
wield_image = "exchangeclone_dark_matter_hoe.png",
inventory_image = "exchangeclone_dark_matter_hoe.png",
@ -133,141 +128,41 @@ minetest.register_tool("exchangeclone:dark_matter_hoe", {
exchangeclone_dirt = { speed = 12, level = 7, uses = 0 },
hoey = { speed = 12, level = 7, uses = 0 }
},
})
}
minetest.register_tool("exchangeclone:dark_matter_hoe_3x3", {
description = "Dark Matter Hoe",
wield_image = "exchangeclone_dark_matter_hoe.png",
inventory_image = "exchangeclone_dark_matter_hoe.png",
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, not_in_creative_inventory = 1 },
tool_capabilities = {
full_punch_interval = 0.25,
damage_groups = { fleshy = 7, },
groupcaps={
exchangeclone_dirt = {times={[1]=0.4, [2]=0.4, [3]=0.4}, uses=0, maxlevel=4},
},
minetest.register_tool("exchangeclone:dark_matter_hoe", table.copy(hoe_def))
local hoe_3x3_def = table.copy(hoe_def)
hoe_3x3_def.groups.not_in_creative_inventory = 1
hoe_3x3_def.tool_capabilities.groupcaps.exchangeclone_dirt.times = {[1]=0.4, [2]=0.4, [3]=0.4}
hoe_3x3_def._mcl_diggroups.exchangeclone_dirt = { speed = 8, level = 7, uses = 0 }
minetest.register_tool("exchangeclone:dark_matter_hoe_3x3", table.copy(hoe_3x3_def))
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.tool_capabilities = {
full_punch_interval = 0.25,
damage_groups = { fleshy = 8, },
groupcaps={
exchangeclone_dirt = {times={[1]=0.15, [2]=0.15, [3]=0.15}, uses=0, maxlevel=4},
},
_mcl_toollike_wield = true,
_mcl_diggroups = {
exchangeclone_dirt = { speed = 8, level = 7, uses = 0 },
hoey = { speed = 8, level = 7, uses = 0 }
},
})
}
hoe_def._mcl_diggroups = {
exchangeclone_dirt = { speed = 13, level = 8, uses = 0 },
hoey = { speed = 13, level = 8, uses = 0 }
}
minetest.register_tool("exchangeclone:red_matter_hoe", {
description = "Red Matter Hoe",
wield_image = "exchangeclone_red_matter_hoe.png",
inventory_image = "exchangeclone_red_matter_hoe.png",
wield_scale = exchangeclone.wield_scale,
on_place = hoe_on_place,
on_secondary_use = hoe_on_place,
groups = { tool=1, hoe=1, enchantability=0, red_matter_hoe = 1 },
tool_capabilities = {
full_punch_interval = 0.25,
damage_groups = { fleshy = 8, },
groupcaps={
exchangeclone_dirt = {times={[1]=0.15, [2]=0.15, [3]=0.15}, uses=0, maxlevel=4},
},
},
_mcl_toollike_wield = true,
_mcl_diggroups = {
exchangeclone_dirt = { speed = 13, level = 8, uses = 0 },
hoey = { speed = 13, level = 8, uses = 0 }
},
})
minetest.register_tool("exchangeclone:red_matter_hoe", table.copy(hoe_def))
minetest.register_tool("exchangeclone:red_matter_hoe_3x3", {
description = "Red Matter Hoe",
wield_image = "exchangeclone_red_matter_hoe.png",
inventory_image = "exchangeclone_red_matter_hoe.png",
wield_scale = exchangeclone.wield_scale,
on_place = hoe_on_place,
on_secondary_use = hoe_on_place,
groups = { tool=1, hoe=1, enchantability=0, red_matter_hoe = 1, not_in_creative_inventory = 1 },
tool_capabilities = {
full_punch_interval = 0.25,
damage_groups = { fleshy = 8, },
groupcaps={
exchangeclone_dirt = {times={[1]=0.25, [2]=0.25, [3]=0.25}, uses=0, maxlevel=4},
},
},
_mcl_toollike_wield = true,
_mcl_diggroups = {
exchangeclone_dirt = { speed = 9, level = 8, uses = 0 },
hoey = { speed = 9, level = 8, uses = 0 }
},
})
hoe_3x3_def = table.copy(hoe_def)
hoe_3x3_def.groups.not_in_creative_inventory = 1
hoe_3x3_def.tool_capabilities.groupcaps.exchangeclone_dirt.times = {[1]=0.25, [2]=0.25, [3]=0.25}
hoe_3x3_def._mcl_diggroups.exchangeclone_dirt = { speed = 9, level = 8, uses = 0 }
-- adapted from https://github.com/cultom/hammermod/blob/master/init.lua
local players_digging = {}
local function dig_if_dirt(pos, player)
local node = minetest.get_node(pos)
if minetest.get_item_group(node.name, "exchangeclone_dirt") ~= 0 then
minetest.node_dig(pos, minetest.get_node(pos), player)
end
end
minetest.register_on_dignode(
function(pos, oldnode, player)
if player == nil or (player:get_wielded_item():get_name() ~= "exchangeclone:dark_matter_hoe_3x3"
and player:get_wielded_item():get_name() ~= "exchangeclone:red_matter_hoe_3x3") then
return
end
local playerName = player:get_player_name()
if (playerName == "" or players_digging[playerName]) then
return
end
players_digging[playerName] = true
local player_rotation = exchangeclone.get_face_direction(player)
local dir1
local dir2
if player_rotation.y ~= 0 then
dir1 = "x"
dir2 = "z"
elseif player_rotation.x ~= 0 then
dir1 = "y"
dir2 = "z"
elseif player_rotation.z ~= 0 then
dir1 = "x"
dir2 = "y"
end
--[[
123
4 5
678
]]
pos[dir1] = pos[dir1] - 1 --7
dig_if_dirt(pos, player)
pos[dir2] = pos[dir2] - 1 --6
dig_if_dirt(pos, player)
pos[dir1] = pos[dir1] + 1 --4
dig_if_dirt(pos, player)
pos[dir1] = pos[dir1] + 1 --1
dig_if_dirt(pos, player)
pos[dir2] = pos[dir2] + 1 --2
dig_if_dirt(pos, player)
pos[dir2] = pos[dir2] + 1 --3
dig_if_dirt(pos, player)
pos[dir1] = pos[dir1] - 1 --5
dig_if_dirt(pos, player)
pos[dir1] = pos[dir1] - 1 --8
dig_if_dirt(pos, player)
players_digging[playerName] = nil
end
)
-- end copied code
minetest.register_tool("exchangeclone:red_matter_hoe_3x3", table.copy(hoe_3x3_def))
minetest.register_craft({
output = "exchangeclone:dark_matter_hoe",

View File

@ -15,6 +15,10 @@ dofile(default_path.."/deconstructor.lua")
dofile(default_path.."/energy_collector.lua")
dofile(default_path.."/orb.lua")
dofile(default_path.."/craftitems.lua")
if exchangeclone.mineclone or minetest.get_modpath("3d_armor") then
dofile(default_path.."/armor.lua")
end
dofile(default_path.."/multidig.lua")
if exchangeclone.mineclone then
mcl_item_id.set_mod_namespace("exchangeclone")
dofile(default_path.."/shears.lua")
@ -25,6 +29,7 @@ dofile(default_path.."/hoes.lua")
dofile(default_path.."/pickaxes.lua")
dofile(default_path.."/hammers.lua")
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.."/energy.lua")

140
lib.lua
View File

@ -137,6 +137,8 @@ if exchangeclone.mineclone then
exchangeclone.wield_scale = mcl_vars.tool_wield_scale
end
exchangeclone.wield_scale = vector.multiply(exchangeclone.wield_scale, 1.5)
exchangeclone.diamond_itemstring = "default:diamond"
if exchangeclone.mineclone then
exchangeclone.diamond_itemstring = "mcl_core:diamond"
@ -144,6 +146,45 @@ end
local doTileDrops = minetest.settings:get_bool("mcl_doTileDrops", true)
local function get_fortune_drops(fortune_drops, fortune_level)
local drop
local i = fortune_level
repeat
drop = fortune_drops[i]
i = i - 1
until drop or i < 1
return drop or {}
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
local new_item = ItemStack(item)
local multiplier = math.random(min_count, max_count)
if cap then
multiplier = math.min(cap, multiplier)
end
new_item:set_count(multiplier * new_item:get_count())
new_drops[i] = new_item
end
return new_drops
end
local tmp_id = 0
local function get_drops(drop, toolname, param2, paramtype2)
tmp_id = tmp_id + 1
local tmp_node_name = "mcl_item_entity:" .. tmp_id
minetest.registered_nodes[tmp_node_name] = {
name = tmp_node_name,
drop = drop,
paramtype2 = paramtype2
}
local drops = minetest.get_node_drops({ name = tmp_node_name, param2 = param2 }, toolname)
minetest.registered_nodes[tmp_node_name] = nil
return drops
end
function exchangeclone.drop_items_on_player(pos, drops, player) --copied from MineClone's code
if not exchangeclone.mineclone then
return minetest.handle_node_drops(pos, drops, player)
@ -207,30 +248,31 @@ function exchangeclone.drop_items_on_player(pos, drops, player) --copied from Mi
end
end
-- if tool and nodedef._mcl_fortune_drop and enchantments.fortune then
-- local fortune_level = enchantments.fortune
-- local fortune_drop = nodedef._mcl_fortune_drop
-- if fortune_drop.discrete_uniform_distribution then
-- local min_count = fortune_drop.min_count
-- local max_count = fortune_drop.max_count + fortune_level * (fortune_drop.factor or 1)
-- local chance = fortune_drop.chance or fortune_drop.get_chance and fortune_drop.get_chance(fortune_level)
-- if not chance or math.random() < chance then
-- drops = discrete_uniform_distribution(fortune_drop.multiply and drops or fortune_drop.items, min_count, max_count,
-- fortune_drop.cap)
-- elseif fortune_drop.override then
-- drops = {}
-- end
-- else
-- -- Fixed Behavior
-- local drop = get_fortune_drops(fortune_drop, fortune_level)
-- drops = get_drops(drop, tool:get_name(), dug_node.param2, nodedef.paramtype2)
-- end
-- end
--[[]] if tool and nodedef._mcl_fortune_drop and enchantments.fortune then
local fortune_level = enchantments.fortune
local fortune_drop = nodedef._mcl_fortune_drop
if fortune_drop.discrete_uniform_distribution then
local min_count = fortune_drop.min_count
local max_count = fortune_drop.max_count + fortune_level * (fortune_drop.factor or 1)
local chance = fortune_drop.chance or fortune_drop.get_chance and fortune_drop.get_chance(fortune_level)
if not chance or math.random() < chance then
drops = discrete_uniform_distribution(fortune_drop.multiply and drops or fortune_drop.items, min_count, max_count,
fortune_drop.cap)
elseif fortune_drop.override then
drops = {}
end
else
-- Fixed Behavior
local drop = get_fortune_drops(fortune_drop, fortune_level)
drops = get_drops(drop, tool:get_name(), dug_node.param2, nodedef.paramtype2)
end
end
--]]
if player and mcl_experience.throw_xp and not silk_touch_drop then
local experience_amount = minetest.get_item_group(dug_node.name, "xp")
if experience_amount > 0 then
mcl_experience.throw_xp(pos, experience_amount)
mcl_experience.throw_xp(player:get_pos(), experience_amount)
end
end
@ -278,4 +320,62 @@ function exchangeclone.get_face_direction(player)
end
return result
end
function exchangeclone.node_radius_action(player, center, range, functions, extra_info)
if not functions.action then return end
local data
local stop = false
if functions.start_action then
data = functions.start_action(player, center, range, extra_info)
if not data then return end
end
if not center then center = player:get_pos() end
center.x = exchangeclone.round(center.x)
center.y = math.floor(center.y) --make sure y is node BELOW player's feet
center.z = exchangeclone.round(center.z)
for x = center.x-range,center.x+range do
for y = center.y-range,center.y+range do
for z = center.z-range,center.z+range do
local pos = {x=x,y=y,z=z}
local node = minetest.get_node(pos)
local result = functions.action(player, pos, node, data)
if not result then stop = true break end
if result ~= true then data = result end
end
if stop then break end
end
if stop then break end
end
if functions.end_action then
data = functions.end_action(player, center, range, data)
end
return data
end
exchangeclone.cooldowns = {}
minetest.register_on_joinplayer(function(player, last_login)
exchangeclone.cooldowns[player:get_player_name()] = {}
end)
minetest.register_on_leaveplayer(function(player, timed_out)
exchangeclone.cooldowns[player:get_player_name()] = nil
end)
function exchangeclone.start_cooldown(player, name, time)
local player_name = player:get_player_name()
exchangeclone.cooldowns[player_name][name] = time
minetest.after(time, function()
if exchangeclone.cooldowns[player_name] then
exchangeclone.cooldowns[player_name][name] = nil
end
end)
end
function exchangeclone.check_cooldown(player, name)
local player_name = player:get_player_name()
if exchangeclone.cooldowns[player_name] then
return exchangeclone.cooldowns[player_name][name]
end
end

View File

@ -1,6 +1,6 @@
name = exchangeclone
title = ExchangeClone
description = Equivalent Exchange for Minetest Game and MineClone! Turn items into energy and energy into items, transmute blocks into other blocks, and craft Dark and Red Matter tools!
description = Equivalent Exchange for Minetest Game and MineClone! Turn items into energy and energy into items, transmute nodes into other nodes, and craft Dark and Red Matter tools!
min_minetest_version = 5.5
optional_depends = mcl_item_id, mcl_core, default, moreswords, mcl_stairs, meat_blocks, ghost_blocks, sticky_things, fake_liquids, sound_machine, stairs, mcl_dispensers, farming
optional_depends = mcl_item_id, mcl_core, default, moreswords, mcl_stairs, meat_blocks, ghost_blocks, sticky_things, fake_liquids, sound_machine, stairs, mcl_dispensers, farming, mcl_blackstone
author = ThePython10110

146
multidig.lua Normal file
View File

@ -0,0 +1,146 @@
exchangeclone.multidig = {}
local stone_group = "cracky"
if exchangeclone.mineclone then
stone_group = "pickaxey"
end
local dirt_group = "crumbly"
if exchangeclone.mineclone then
dirt_group = "shovely"
end
local function dig_if_group(pos, player, groups)
local node = minetest.get_node(pos)
for _, group in ipairs(groups) do
if minetest.get_item_group(node.name, group) ~= 0 then
minetest.node_dig(pos, minetest.get_node(pos), player)
end
end
end
local special_dig = {
["exchangeclone:dark_matter_pickaxe_3x1"] = {groups={stone_group}, mode="3x1"},
["exchangeclone:red_matter_pickaxe_3x1"] = {groups={stone_group}, mode="3x1"},
["exchangeclone:dark_matter_hammer_3x3"] = {groups={stone_group}, mode="3x3"},
["exchangeclone:red_matter_hammer_3x3"] = {groups={stone_group}, mode="3x3"},
["exchangeclone:dark_matter_hoe_3x3"] = {groups={"exchangeclone_dirt"}, mode="3x3"},
["exchangeclone:red_matter_hoe_3x3"] = {groups={"exchangeclone_dirt"}, mode="3x3"},
["exchangeclone:red_katar_3x3"] = {groups={"exchangeclone_dirt"}, mode="3x3"},
["exchangeclone:red_morningstar_3x1"] = {groups={stone_group, dirt_group},mode="3x1"},
["exchangeclone:red_morningstar_3x3"] = {groups={stone_group, dirt_group},mode="3x3"},
}
minetest.register_on_dignode(
function(pos, oldnode, player)
if not player then return end
local itemname = player:get_wielded_item():get_name()
local dig_data = special_dig[itemname]
if not dig_data then return end
local playername = player:get_player_name()
if(playername == "" or exchangeclone.multidig[playername]) then
return
end
exchangeclone.multidig[playername] = true
local player_rotation = exchangeclone.get_face_direction(player)
if dig_data.mode == "3x3" then
local dir1
local dir2
if player_rotation.y ~= 0 then
dir1 = "x"
dir2 = "z"
elseif player_rotation.x ~= 0 then
dir1 = "y"
dir2 = "z"
elseif player_rotation.z ~= 0 then
dir1 = "x"
dir2 = "y"
end
--[[
123
4 5
678
]]
pos[dir1] = pos[dir1] - 1 --7
dig_if_group(pos, player, dig_data.groups)
pos[dir2] = pos[dir2] - 1 --6
dig_if_group(pos, player, dig_data.groups)
pos[dir1] = pos[dir1] + 1 --4
dig_if_group(pos, player, dig_data.groups)
pos[dir1] = pos[dir1] + 1 --1
dig_if_group(pos, player, dig_data.groups)
pos[dir2] = pos[dir2] + 1 --2
dig_if_group(pos, player, dig_data.groups)
pos[dir2] = pos[dir2] + 1 --3
dig_if_group(pos, player, dig_data.groups)
pos[dir1] = pos[dir1] - 1 --5
dig_if_group(pos, player, dig_data.groups)
pos[dir1] = pos[dir1] - 1 --8
dig_if_group(pos, player, dig_data.groups)
elseif dig_data.mode == "3x1" then
local current_mode = player:get_wielded_item():get_meta():get_string("exchangeclone_pick_mode")
if current_mode == "" or not current_mode then current_mode = "tall" end
local new_pos = table.copy(pos)
if current_mode == "long" then
if player_rotation.y ~= 0 then
new_pos.y = new_pos.y + player_rotation.y
dig_if_group(new_pos, player, dig_data.groups)
new_pos.y = new_pos.y + player_rotation.y
dig_if_group(new_pos, player, dig_data.groups)
elseif player_rotation.z ~= 0 then
new_pos.z = new_pos.z + player_rotation.z
dig_if_group(new_pos, player, dig_data.groups)
new_pos.z = new_pos.z + player_rotation.z
dig_if_group(new_pos, player, dig_data.groups)
else
new_pos.x = new_pos.x + player_rotation.x
dig_if_group(new_pos, player, dig_data.groups)
new_pos.x = new_pos.x + player_rotation.x
dig_if_group(new_pos, player, dig_data.groups)
end
elseif current_mode == "tall" then
if player_rotation.y ~= 0 then
if player_rotation.x ~= 0 then
new_pos.x = pos.x - 1
dig_if_group(new_pos, player, dig_data.groups)
new_pos.x = pos.x + 1
dig_if_group(new_pos, player, dig_data.groups)
else
new_pos.z = pos.z - 1
dig_if_group(new_pos, player, dig_data.groups)
new_pos.z = pos.z + 1
dig_if_group(new_pos, player, dig_data.groups)
end
else
new_pos.y = pos.y - 1
dig_if_group(new_pos, player, dig_data.groups)
new_pos.y = pos.y + 1
dig_if_group(new_pos, player, dig_data.groups)
end
elseif current_mode == "wide" then
if player_rotation.x ~= 0 then
new_pos.z = pos.z - 1
dig_if_group(new_pos, player, dig_data.groups)
new_pos.z = pos.z + 1
dig_if_group(new_pos, player, dig_data.groups)
else
new_pos.x = pos.x - 1
dig_if_group(new_pos, player, dig_data.groups)
new_pos.x = pos.x + 1
dig_if_group(new_pos, player, dig_data.groups)
end
end
end
exchangeclone.multidig[playername] = nil
end
)

View File

@ -192,33 +192,31 @@ exchangeclone.node_transmutations = {
}
}
local function transmute_nodes(player, center, distance, mode)
exchangeclone.play_ability_sound(player)
local pos = center
pos.x = exchangeclone.round(pos.x)
pos.y = math.floor(pos.y) --make sure y is node BELOW player's feet
pos.z = exchangeclone.round(pos.z)
for x = pos.x-distance, pos.x+distance do
for y = pos.y-distance, pos.y+distance do
for z = pos.z-distance, pos.z+distance do
local new_pos = {x=x,y=y,z=z}
local node = minetest.get_node(new_pos)
exchangeclone.stone_action = {
start_action = function(player, center, range, mode)
if exchangeclone.check_cooldown(player, "phil") then return end
exchangeclone.play_ability_sound(player)
return mode
end,
action = function(player, pos, node, mode)
local new_node = exchangeclone.node_transmutations[mode][node.name]
if not new_node and mode == 2 then
new_node = exchangeclone.node_transmutations[1][node.name]
end
if new_node then
if minetest.is_protected(new_pos, player:get_player_name()) then
minetest.record_protection_violation(new_pos, player:get_player_name())
if minetest.is_protected(pos, player:get_player_name()) then
minetest.record_protection_violation(pos, player:get_player_name())
else
node.name = new_node
minetest.swap_node(new_pos, node)
minetest.swap_node(pos, node)
end
end
return true
end,
end_action = function(player, center, range, data)
exchangeclone.start_cooldown(player, "phil", 0.3)
end
end
end
end
}
local on_left_click = nil
if exchangeclone.mineclone then
@ -245,14 +243,14 @@ local function on_right_click(itemstack, player, pointed_thing)
end
if player:get_player_control().sneak then
local range = tonumber(itemstack:get_meta():get_int("exchangeclone_item_range"))
transmute_nodes(player, center, range, 2)
exchangeclone.node_radius_action(player, center, range, exchangeclone.stone_action, 2)
else
local range = itemstack:get_meta():get_int("exchangeclone_item_range")
transmute_nodes(player, center, range, 1)
exchangeclone.node_radius_action(player, center, range, exchangeclone.stone_action, 1)
end
end
local tt_help = "(Shift)-right-click: transmute blocks. (Shift)-Aux1-right-click: Change range"
local tt_help = "(Shift)-right-click: transmute nodes. (Shift)-Aux1-right-click: Change range"
local item1 = "mese crystals"
if exchangeclone.mineclone then
@ -260,17 +258,17 @@ if exchangeclone.mineclone then
end
local longdesc = "A mysterious device discovered by alchemists millenia ago. The crafting recipe was recently rediscovered by ThePython.\n\n"..
"It has the ability to transmute nearby blocks into other blocks. The range can be increased or decreased from 0 to 4 by (shift-)aux1-right-clicking.\n"..
"Transmute blocks by (shift-)right-clicking (holding shift causes a few differences in transmutation). They are changed in a cube centered on "..
"the block directly below you, with a radius equal to the range.\n"..
"It has the ability to transmute nearby nodes into other nodes. The range can be increased or decreased from 0 to 4 by (shift-)aux1-right-clicking.\n"..
"Transmute nodes by (shift-)right-clicking (holding shift causes a few differences in transmutation). They are changed in a cube centered on "..
"the node directly below you, with a radius equal to the range.\n"..
"The ancient tome (entitled the \"Tekkit Wiki\") vaguely mentioned a \"cooldown\" when used to transmute large areas, "..
"but ThePython was far to lazy to implement such a thing (maybe just have the charge level/radius reset every time?).\n\n"..
"The Philosopher's Stone is also useful in converting various resources, such as turning coal into iron, or gold into "..item1..".\n"..
"See the crafting guide for recipes. The Philosopher's Stone is NEVER used up in crafting recipes (if it is, it's a bug). The transmutation "..
"range is reset when used in a crafting recipe."
local usagehelp = "The range can be increased or decreased from 0 to 4 by (shift-)aux1-right-clicking. Transmute blocks by (shift-)right-clicking (holding shift causes a few differences in transmutation). They are changed in a cube centered on "..
"the block directly below you, with a radius equal to the range.\n\n"..
local usagehelp = "The range can be increased or decreased from 0 to 4 by (shift-)aux1-right-clicking. Transmute nodes by (shift-)right-clicking (holding shift causes a few differences in transmutation). They are changed in a cube centered on "..
"the node directly below you, with a radius equal to the range.\n\n"..
"The Philosopher's Stone is also useful in converting various resources, such as turning coal into iron, or gold into "..item1..".\n"..
"See the crafting guide for recipes. The Philosopher's Stone is NEVER used up in crafting recipes (if it is, it's a bug). The transmutation "..
"range is reset when used in a crafting recipe."

View File

@ -1,6 +1,6 @@
local players_digging = {}
local multidig = {}
local function mine_vein(player, player_energy, start_pos, node_name, pos)
function exchangeclone.mine_vein(player, player_energy, start_pos, node_name, pos)
-- Not very efficient, but it SHOULD work.
if not player then return 0 end
if not start_pos then return 0 end
@ -15,7 +15,7 @@ local function mine_vein(player, player_energy, start_pos, node_name, pos)
exchangeclone.drop_items_on_player(pos, minetest.get_node_drops(node.name, "exchangeclone:red_matter_pickaxe"), player)
minetest.set_node(pos, {name = "air"})
for x = pos.x-1,pos.x+1 do for y = pos.y-1,pos.y+1 do for z = pos.z-1,pos.z+1 do
local cost = mine_vein(player, player_energy, start_pos, node_name, {x=x,y=y,z=z})
local cost = exchangeclone.mine_vein(player, player_energy, start_pos, node_name, {x=x,y=y,z=z})
if cost and cost > 0 then
energy_cost = energy_cost + cost
end
@ -56,18 +56,19 @@ local function pickaxe_on_use(itemstack, player, pointed_thing)
elseif current_mode == "long" then
itemstack:set_name(string.sub(current_name, 1, -5)) -- set to 1x1 pick
meta:set_string("exchangeclone_pick_mode", "1x1")
minetest.chat_send_player(player:get_player_name(), "Single block mode")
minetest.chat_send_player(player:get_player_name(), "Single node mode")
end
return itemstack
end
if pointed_thing.type == "node" then
if exchangeclone.check_cooldown(player, "pickaxe") then return itemstack end
if (minetest.get_item_group(minetest.get_node(pointed_thing.under).name, "exchangeclone_ore") > 0) then
local player_energy = exchangeclone.get_player_energy(player)
exchangeclone.play_ability_sound(player)
players_digging[player:get_player_name()] = true
local energy_cost = mine_vein(player, player_energy, pointed_thing.under)
players_digging[player:get_player_name()] = nil
exchangeclone.multidig[player:get_player_name()] = true
local energy_cost = exchangeclone.mine_vein(player, player_energy, pointed_thing.under)
exchangeclone.multidig[player:get_player_name()] = nil
if energy_cost then
exchangeclone.set_player_energy(player, player_energy - energy_cost)
end
@ -77,20 +78,21 @@ local function pickaxe_on_use(itemstack, player, pointed_thing)
exchangeclone.set_player_energy(player, player_energy - exchangeclone.get_item_energy(torch_itemstring))
-- 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)
end
end
for name, def in pairs(minetest.registered_nodes) do
if name:find("_ore") or name:find("stone_with") or name:find("deepslate_with")
or name:find("diorite_with") or name:find("andesite_with") or name:find("granite_with")
or name:find("tuff_with") then
or name:find("tuff_with") or (name == "mcl_blackstone:nether_gold") then
local groups = table.copy(def.groups)
groups.exchangeclone_ore = 1
minetest.override_item(name, {groups = groups})
end
end
minetest.register_tool("exchangeclone:dark_matter_pickaxe", {
local pick_def = {
description = "Dark Matter Pickaxe",
wield_image = "exchangeclone_dark_matter_pickaxe.png",
inventory_image = "exchangeclone_dark_matter_pickaxe.png",
@ -114,174 +116,44 @@ minetest.register_tool("exchangeclone:dark_matter_pickaxe", {
},
on_secondary_use = pickaxe_on_use,
on_place = pickaxe_on_use,
})
}
minetest.register_tool("exchangeclone:dark_matter_pickaxe_3x1", {
description = "Dark Matter Pickaxe",
wield_image = "exchangeclone_dark_matter_pickaxe.png",
inventory_image = "exchangeclone_dark_matter_pickaxe.png",
exchangeclone_pick_mode = "tall",
groups = { tool=1, pickaxe=1, dig_speed_class=7, enchantability=0, dark_matter_pickaxe=1, not_in_creative_inventory=1 },
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
-- 1/1.2
full_punch_interval = 0.5,
max_drop_level=5,
damage_groups = {fleshy=7},
punch_attack_uses = 0,
groupcaps={
cracky = {times={[1]=1.8, [2]=0.9, [3]=0.5}, uses=0, maxlevel=4},
},
},
sound = { breaks = "default_tool_breaks" },
_mcl_toollike_wield = true,
_mcl_diggroups = {
pickaxey = { speed = 12, level = 7, uses = 0 }
},
on_secondary_use = pickaxe_on_use,
on_place = pickaxe_on_use,
})
minetest.register_tool("exchangeclone:dark_matter_pickaxe", table.copy(pick_def))
minetest.register_tool("exchangeclone:red_matter_pickaxe", {
description = "Red Matter Pickaxe",
wield_image = "exchangeclone_red_matter_pickaxe.png",
inventory_image = "exchangeclone_red_matter_pickaxe.png",
exchangeclone_pick_mode = "1x1",
groups = { tool=1, pickaxe=1, dig_speed_class=7, red_matter_pickaxe=1, enchantability=0 },
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
-- 1/1.2
full_punch_interval = 0.5,
max_drop_level=5,
damage_groups = {fleshy=9},
punch_attack_uses = 0,
groupcaps={
cracky = {times={[1]=1, [2]=0.5, [3]=0.25}, uses=0, maxlevel=5},
},
},
sound = { breaks = "default_tool_breaks" },
_mcl_toollike_wield = true,
_mcl_diggroups = {
pickaxey = { speed = 20, level = 8, uses = 0 }
},
on_secondary_use = pickaxe_on_use,
on_place = pickaxe_on_use,
})
local pick_def_3x1 = table.copy(pick_def)
pick_def_3x1.exchangeclone_pick_mode = "tall"
pick_def_3x1.groups.not_in_creative_inventory = 1
pick_def_3x1.tool_capabilities.groupcaps.cracky.times = {[1]=1.8, [2]=0.9, [3]=0.5}
pick_def_3x1._mcl_diggroups.pickaxey.speed = 12
minetest.register_tool("exchangeclone:red_matter_pickaxe_3x1", {
description = "Red Matter Pickaxe",
wield_image = "exchangeclone_red_matter_pickaxe.png",
inventory_image = "exchangeclone_red_matter_pickaxe.png",
exchangeclone_pick_mode = "tall",
groups = { tool=1, pickaxe=1, dig_speed_class=7, enchantability=0, red_matter_pickaxe=1, not_in_creative_inventory=1 },
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
-- 1/1.2
full_punch_interval = 0.5,
max_drop_level=5,
damage_groups = {fleshy=9},
punch_attack_uses = 0,
groupcaps={
cracky = {times={[1]=1.2, [2]=0.7, [3]=0.4}, uses=0, maxlevel=5},
},
},
sound = { breaks = "default_tool_breaks" },
_mcl_toollike_wield = true,
_mcl_diggroups = {
pickaxey = { speed = 20, level = 8, uses = 0 }
},
on_secondary_use = pickaxe_on_use,
on_place = pickaxe_on_use,
})
minetest.register_tool("exchangeclone:dark_matter_pickaxe_3x1", table.copy(pick_def_3x1))
-- adapted from https://github.com/cultom/hammermod/blob/master/init.lua
pick_def.description = "Red Matter Pickaxe"
pick_def.wield_image = "exchangeclone_red_matter_pickaxe.png"
pick_def.inventory_image = "exchangeclone_red_matter_pickaxe.png"
pick_def.groups.dark_matter_pickaxe = nil
pick_def.groups.red_matter_pickaxe = 1
pick_def.groups.dig_speed_class = 8
pick_def.tool_capabilities = {
full_punch_interval = 0.5,
max_drop_level=5,
damage_groups = {fleshy=9},
punch_attack_uses = 0,
groupcaps={
cracky = {times={[1]=1.2, [2]=0.7, [3]=0.4}, uses=0, maxlevel=5},
},
}
pick_def._mcl_diggroups.pickaxey = { speed = 20, level = 8, uses = 0 }
local stone_group = "cracky"
if exchangeclone.mineclone then
stone_group = "pickaxey"
end
minetest.register_tool("exchangeclone:red_matter_pickaxe", table.copy(pick_def))
local function dig_if_stone(pos, player)
local node = minetest.get_node(pos)
if minetest.get_item_group(node.name, stone_group) ~= 0 then
minetest.node_dig(pos, minetest.get_node(pos), player)
end
end
local pick_def_3x1 = table.copy(pick_def)
pick_def_3x1.exchangeclone_pick_mode = "tall"
pick_def_3x1.groups.not_in_creative_inventory = 1
pick_def_3x1.tool_capabilities.groupcaps.cracky.times = {[1]=1.2, [2]=0.7, [3]=0.4}
pick_def_3x1._mcl_diggroups.pickaxey.speed = 16
minetest.register_on_dignode(
function(pos, oldnode, player)
if player == nil or (player:get_wielded_item():get_name() ~= "exchangeclone:dark_matter_pickaxe_3x1"
and player:get_wielded_item():get_name() ~= "exchangeclone:red_matter_pickaxe_3x1") then
return
end
local playerName = player:get_player_name()
if (playerName == "" or players_digging[playerName]) then
return
end
players_digging[playerName] = true
local current_mode = player:get_wielded_item():get_meta():get_string("exchangeclone_pick_mode")
if current_mode == "" or not current_mode then current_mode = "tall" end
local player_rotation = exchangeclone.get_face_direction(player)
local new_pos = table.copy(pos)
if current_mode == "long" then
if player_rotation.y ~= 0 then
new_pos.y = new_pos.y + player_rotation.y
dig_if_stone(new_pos, player)
new_pos.y = new_pos.y + player_rotation.y
dig_if_stone(new_pos, player)
elseif player_rotation.z ~= 0 then
new_pos.z = new_pos.z + player_rotation.z
dig_if_stone(new_pos, player)
new_pos.z = new_pos.z + player_rotation.z
dig_if_stone(new_pos, player)
else
new_pos.x = new_pos.x + player_rotation.x
dig_if_stone(new_pos, player)
new_pos.x = new_pos.x + player_rotation.x
dig_if_stone(new_pos, player)
end
elseif current_mode == "tall" then
if player_rotation.y ~= 0 then
if player_rotation.x ~= 0 then
new_pos.x = pos.x - 1
dig_if_stone(new_pos, player)
new_pos.x = pos.x + 1
dig_if_stone(new_pos, player)
else
new_pos.z = pos.z - 1
dig_if_stone(new_pos, player)
new_pos.z = pos.z + 1
dig_if_stone(new_pos, player)
end
else
new_pos.y = pos.y - 1
dig_if_stone(new_pos, player)
new_pos.y = pos.y + 1
dig_if_stone(new_pos, player)
end
elseif current_mode == "wide" then
if player_rotation.x ~= 0 then
new_pos.z = pos.z - 1
dig_if_stone(new_pos, player)
new_pos.z = pos.z + 1
dig_if_stone(new_pos, player)
else
new_pos.x = pos.x - 1
dig_if_stone(new_pos, player)
new_pos.x = pos.x + 1
dig_if_stone(new_pos, player)
end
end
players_digging[playerName] = nil
end
)
-- end copied code
minetest.register_tool("exchangeclone:red_matter_pickaxe_3x1", table.copy(pick_def_3x1))
minetest.register_craft({
output = "exchangeclone:dark_matter_pickaxe",

291
red_matter_multitools.lua Normal file
View File

@ -0,0 +1,291 @@
--------------------------------------RED KATAR--------------------------------------
local katar_on_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
if player:get_player_control().aux1 then
return exchangeclone.range_update(itemstack, player, 5)
end
if pointed_thing.type == "object" then
local name = pointed_thing.ref:get_entity_name()
if name == "mobs_mc:sheep" or name == "mobs_mc:mooshroom" then
return -- Don't do AOE when pointed at sheep/mooshroom, shear instead.
end
end
if pointed_thing.type == "node" then
local node = minetest.get_node(pointed_thing.under)
local range = itemstack:get_meta():get_int("exchangeclone_item_range")
local center = player:get_pos()
if pointed_thing.type == "node" then
center = pointed_thing.under
end
if minetest.get_item_group(node.name, "exchangeclone_dirt") > 0 then
if player:get_player_control().sneak then
local current_name = itemstack:get_name()
if string.sub(current_name, -4, -1) == "_3x3" then
itemstack:set_name(string.sub(current_name, 1, -5))
minetest.chat_send_player(player:get_player_name(), "Single node mode")
else
itemstack:set_name(current_name.."_3x3")
minetest.chat_send_player(player:get_player_name(), "3x3 mode")
end
return itemstack
else
exchangeclone.node_radius_action(player, center, range, exchangeclone.hoe_action, itemstack)
end
elseif minetest.get_item_group(node.name, "tree") > 0 then
exchangeclone.node_radius_action(player, center, range, exchangeclone.axe_action)
elseif minetest.get_item_group(node.name, "shearsy") > 0 or minetest.get_item_group(node.name, "shearsy_cobweb") > 0 then
exchangeclone.node_radius_action(player, center, range, exchangeclone.shear_action)
end
else
local damage_all = itemstack:get_meta():get_int("exchangeclone_damage_all")
exchangeclone.aoe_attack{max_damage = 2}
if not damage_all == 0 then damage_all = 1 end
if player:get_player_control().sneak then
if damage_all == 0 then
damage_all = 1
minetest.chat_send_player(player:get_player_name(), "Damage all mobs")
else
damage_all = 0
minetest.chat_send_player(player:get_player_name(), "Damage hostile mobs")
end
itemstack:get_meta():set_int("exchangeclone_damage_all", damage_all)
return itemstack
end
local aoe_function = exchangeclone.aoe_attack({max_damage = 16, knockback = 20, radius = 9, damage_all = damage_all, cooldown = 0.2})
aoe_function(itemstack, player, pointed_thing)
end
end
local katar_def = {
description = "Red Katar",
wield_image = "exchangeclone_red_katar.png",
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 },
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
full_punch_interval = 0.3,
max_drop_level=5,
damage_groups = {fleshy=21},
punch_attack_uses = 0,
groupcaps={
exchangeclone_dirt = {times={[1]=0.15, [2]=0.15, [3]=0.15}, uses=0, maxlevel=4},
snappy = {times={[1]=0.5, [2]=0.3, [3]=0.15}, uses=0, maxlevel=5},
choppy = {times={[1]=0.5, [2]=0.3, [3]=0.15}, uses=0, maxlevel=5},
},
},
sound = { breaks = "default_tool_breaks" },
_mcl_toollike_wield = true,
_mcl_diggroups = {
exchangeclone_dirt = { speed = 10, level = 8, uses = 0 },
shearsy = { speed = 10, level = 3, uses = 0 },
shearsy_wool = { speed = 16, level = 3, uses = 0 },
shearsy_cobweb = { speed = 36, level = 3, uses = 0 },
hoey = { speed = 9, level = 8, uses = 0 },
swordy = { speed = 20, level = 8, uses = 0 },
axey = { speed = 20, level = 8, uses = 0 }
},
}
minetest.register_tool("exchangeclone:red_katar", table.copy(katar_def))
katar_def.groups.not_in_creative_inventory = 1
katar_def._mcl_diggroups.exchangeclone_dirt = {speed = 8, level = 8, uses = 0}
katar_def.tool_capabilities.groupcaps.exchangeclone_dirt = {times={[1]=0.25,[2]=0.25,[3]=0.25}}
minetest.register_tool("exchangeclone:red_katar_3x3", table.copy(katar_def))
minetest.register_craft({
output = "exchangeclone:red_katar",
type = "shapeless",
recipe = {
"exchangeclone:red_matter_sword",
"exchangeclone:red_matter_shears",
"exchangeclone:red_matter_axe",
"group:red_matter_hoe",
"exchangeclone:red_matter",
"exchangeclone:red_matter",
"exchangeclone:red_matter",
"exchangeclone:red_matter",
"exchangeclone:red_matter"
}
})
--------------------------------------RED MORNINGSTAR--------------------------------------
exchangeclone.morningstar_action = {
start_action = function(player, center, range)
if exchangeclone.check_cooldown(player, "shovel") then return end
if exchangeclone.check_cooldown(player, "hammer") then return end
local data = {}
data.player_energy = exchangeclone.get_player_energy(player)
data.energy_cost = 0
exchangeclone.play_ability_sound(player)
return data
end,
action = function(player, pos, node, data)
if data.energy_cost + 8 > data.player_energy then return end
if ((minetest.get_item_group(node.name, "crumbly") > 0) or (minetest.get_item_group(node.name, "shovely") > 0))
or ((minetest.get_item_group(node.name, "cracky") > 0) or (minetest.get_item_group(node.name, "pickaxey") > 0)) then
if minetest.is_protected(pos, player:get_player_name()) then
minetest.record_protection_violation(pos, player:get_player_name())
else
data.energy_cost = data.energy_cost + 8
local drops = minetest.get_node_drops(node.name, "exchangeclone:red_morningstar")
exchangeclone.drop_items_on_player(pos, drops, player)
minetest.set_node(pos, {name = "air"})
end
end
return data
end,
end_action = function(player, center, range, data)
exchangeclone.set_player_energy(player, data.player_energy - data.energy_cost)
exchangeclone.start_cooldown(player, "shovel", range/4) -- Longish cooldown
exchangeclone.start_cooldown(player, "hammer", range/2)
end
}
local torch_itemstring = "default:torch"
if exchangeclone.mineclone then
torch_itemstring = "mcl_torches:torch"
end
local torch_on_place = minetest.registered_items[torch_itemstring].on_place
local function morningstar_on_use(itemstack, player, pointed_thing)
local click_test = exchangeclone.check_on_rightclick(itemstack, player, pointed_thing)
if click_test ~= false then
return click_test
end
if player:get_player_control().aux1 then
return exchangeclone.range_update(itemstack, player, 5)
end
local range = itemstack:get_meta():get_int("exchangeclone_item_range")
local center = player:get_pos()
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 exchangeclone.check_cooldown(player, "pickaxe") then return itemstack end
local player_energy = exchangeclone.get_player_energy(player)
exchangeclone.play_ability_sound(player)
exchangeclone.multidig[player:get_player_name()] = true
local energy_cost = exchangeclone.mine_vein(player, player_energy, pointed_thing.under)
exchangeclone.multidig[player:get_player_name()] = nil
if energy_cost then
exchangeclone.set_player_energy(player, player_energy - energy_cost)
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)
exchangeclone.set_player_energy(player, player_energy - exchangeclone.get_item_energy(torch_itemstring))
-- If the torch could not be placed, it still costs energy... not sure how to fix that
exchangeclone.start_cooldown(player, "pickaxe", 0.3)
return
end
elseif player:get_player_control().sneak then
local current_name = itemstack:get_name()
local meta = itemstack:get_meta()
local current_mode = itemstack:get_meta():get_string("exchangeclone_pick_mode")
if current_mode == "" or not current_mode then current_mode = "1x1" end
if current_mode == "1x1" then
itemstack:set_name(current_name.."_3x3") -- set to 3x3 pick
meta:set_string("exchangeclone_pick_mode", "3x3")
minetest.chat_send_player(player:get_player_name(), "3x3 mode")
elseif current_mode == "3x3" then
itemstack:set_name(string.sub(current_name, 1, -5).."_3x1") -- set to 3x1 pick
meta:set_string("exchangeclone_pick_mode", "tall")
minetest.chat_send_player(player:get_player_name(), "3x1 tall mode")
elseif current_mode == "tall" then
meta:set_string("exchangeclone_pick_mode", "wide")
minetest.chat_send_player(player:get_player_name(), "3x1 wide mode")
elseif current_mode == "wide" then
meta:set_string("exchangeclone_pick_mode", "long")
minetest.chat_send_player(player:get_player_name(), "3x1 long mode")
elseif current_mode == "long" then
itemstack:set_name(string.sub(current_name, 1, -5)) -- set to 1x1 pick
meta:set_string("exchangeclone_pick_mode", "1x1")
minetest.chat_send_player(player:get_player_name(), "Single node mode")
end
return itemstack
else
exchangeclone.node_radius_action(player, center, range, exchangeclone.morningstar_action)
end
end
local morningstar_def = {
description = "Red Morningstar",
wield_image = "exchangeclone_red_morningstar.png",
inventory_image = "exchangeclone_red_morningstar.png",
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 },
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
full_punch_interval = 0.3,
max_drop_level=5,
damage_groups = {fleshy=20},
punch_attack_uses = 0,
groupcaps={
cracky = {times={[1]=0.5, [2]=0.3, [3]=0.15}, uses=0, maxlevel=5},
crumbly = {times={[1]=0.5, [2]=0.3, [3]=0.15}, uses=0, maxlevel=5},
choppy = {times={[1]=0.5, [2]=0.3, [3]=0.15}, uses=0, maxlevel=5},
},
},
sound = { breaks = "default_tool_breaks" },
_mcl_toollike_wield = true,
_mcl_diggroups = {
pickaxey = {speed = 22, level = 8, uses = 0},
shovely = {speed = 22, level = 8, uses = 0},
axey = { speed = 22, level = 8, uses = 0 }
},
}
minetest.register_tool("exchangeclone:red_morningstar", table.copy(morningstar_def))
for k, v in pairs({cracky = "pickaxey", crumbly = "shovely"}) do
morningstar_def.tool_capabilities.groupcaps[k].times = {[1]=0.7,[2]=0.5,[3]=0.25}
morningstar_def._mcl_diggroups[v].speed = 18
end
morningstar_def.groups.not_in_creative_inventory = 1
morningstar_def.exchangeclone_pick_mode = "3x3"
minetest.register_tool("exchangeclone:red_morningstar_3x3", table.copy(morningstar_def))
for k, v in pairs({cracky = "pickaxey", crumbly = "shovely"}) do
morningstar_def.tool_capabilities.groupcaps[k].times = {[1]=0.6,[2]=0.4,[3]=0.20}
morningstar_def._mcl_diggroups[v].speed = 20
end
morningstar_def.exchangeclone_pick_mode = "tall"
minetest.register_tool("exchangeclone:red_morningstar_3x1", table.copy(morningstar_def))
minetest.register_craft({
output = "exchangeclone:red_morningstar",
type = "shapeless",
recipe = {
"group:red_matter_hammer",
"exchangeclone:red_matter_shovel",
"group:red_matter_pickaxe",
"exchangeclone:red_matter",
"exchangeclone:red_matter",
"exchangeclone:red_matter",
"exchangeclone:red_matter",
"exchangeclone:red_matter",
"exchangeclone:red_matter"
}
})

View File

@ -1,44 +1,38 @@
local shear_cube = function(player, center, distance)
exchangeclone.play_ability_sound(player)
local player_pos = player:get_pos()
local pos = center
local node_positions = {}
local player_energy = exchangeclone.get_player_energy(player)
local energy_cost = 0
pos.x = exchangeclone.round(pos.x)
pos.y = math.floor(pos.y) --make sure y is node BELOW player's feet
pos.z = exchangeclone.round(pos.z)
for x = pos.x-distance, pos.x+distance do
if energy_cost + 8 > player_energy then
break
end
for y = pos.y-distance, pos.y+distance do
if energy_cost + 8 > player_energy then
break
end
for z = pos.z-distance, pos.z+distance do
if energy_cost + 8 > player_energy then
break
end
local new_pos = {x=x,y=y,z=z}
local node = minetest.get_node(new_pos) or "air"
exchangeclone.shear_action = {
start_action = function(player, center, range)
if exchangeclone.check_cooldown(player, "shears") then return end
local data = {}
data.player_energy = exchangeclone.get_player_energy(player)
if data.player_energy < 8 then return end
exchangeclone.play_ability_sound(player)
data.energy_cost = 0
return data
end,
action = function(player, pos, node, data)
if data.energy_cost + 8 > data.player_energy then return end
local node_def = minetest.registered_items[node.name]
if (node_def.groups.shearsy or node_def.groups.shearsy_cobweb) and node.name ~= "mcl_flowers:double_grass_top" then
if minetest.is_protected(new_pos, player:get_player_name()) then
minetest.record_protection_violation(new_pos, player:get_player_name())
if minetest.is_protected(pos, player:get_player_name()) then
minetest.record_protection_violation(pos, player:get_player_name())
else
energy_cost = energy_cost + 8
data.energy_cost = data.energy_cost + 8
local drops = minetest.get_node_drops(node.name, "exchangeclone:red_matter_shears")
exchangeclone.drop_items_on_player(new_pos, drops, player)
minetest.set_node(new_pos, {name = "air"})
exchangeclone.drop_items_on_player(pos, drops, player)
if node.name:sub(1,18) == "mcl_ocean:seagrass" then
minetest.set_node(pos, {name="sand"})
else
minetest.set_node(pos, {name="air"})
end
end
end
return data
end,
end_action = function(player, center, range, data)
exchangeclone.set_player_energy(player, data.player_energy - data.energy_cost)
exchangeclone.start_cooldown(player, "shears", (range+1)/7)
return data
end
end
end
exchangeclone.set_player_energy(player, player_energy - energy_cost)
end
}
local shears_rightclick = function(itemstack, player, pointed_thing)
-- Use pointed node's on_rightclick function first, if present
@ -72,7 +66,7 @@ local shears_rightclick = function(itemstack, player, pointed_thing)
center = pointed_thing.under
end
local range = tonumber(itemstack:get_meta():get_int("exchangeclone_item_range"))
shear_cube(player, center, range)
exchangeclone.node_radius_action(player, center, range, exchangeclone.shear_action)
return itemstack
end
@ -120,6 +114,12 @@ minetest.register_tool("exchangeclone:red_matter_shears", {
},
})
local special_shears = {
["exchangeclone:dark_matter_shears"] = true,
["exchangeclone:red_matter_shears"] = true,
["exchangeclone:red_katar"] = true
}
local colors = {
-- group = { wool, textures }
unicolor_white = { "mcl_wool:white", "#FFFFFF00" },
@ -144,12 +144,11 @@ local gotten_texture = { "blank.png", "mobs_mc_sheep.png" }
local old_sheep_function = minetest.registered_entities["mobs_mc:sheep"].on_rightclick
minetest.registered_entities["mobs_mc:sheep"].on_rightclick = function(self, clicker)
local item = clicker:get_wielded_item()
if (item:get_name() == "exchangeclone:dark_matter_shears" or item:get_name() == "exchangeclone:red_matter_shears")
and not self.gotten and not self.child then
local item_name = item:get_name()
if special_shears[item_name] and not self.gotten and not self.child then
local pos = self.object:get_pos()
local chance = 30 --percent
if item:get_name() == "exchangeclone:red_matter_shears" then chance = 60 end
if item_name == "exchangeclone:red_matter_shears" or item_name == "exchangeclone:red_katar" then chance = 60 end
if math.random(1, 100) <= chance then
local new_sheep = minetest.add_entity(pos, "mobs_mc:sheep"):get_luaentity() --clone the sheep
for attribute, value in pairs(self) do
@ -169,7 +168,7 @@ minetest.registered_entities["mobs_mc:sheep"].on_rightclick = function(self, cli
self.color = "unicolor_white"
end
local max_wool = 8
if item:get_name() == "exchangeclone:red_matter_shears" then max_wool = 12 end
if item_name == "exchangeclone:red_matter_shears" or item_name == "exchangeclone:red_katar" then max_wool = 12 end
minetest.add_item(pos, ItemStack(colors[self.color][1].." "..math.random(1,max_wool))) --normally 3
self.base_texture = gotten_texture
@ -197,13 +196,14 @@ minetest.registered_entities["mobs_mc:mooshroom"].on_rightclick = function(self,
return
end
local item = clicker:get_wielded_item()
local item_name = item:get_name()
-- Use shears to get mushrooms and turn mooshroom into cow
if item:get_name() == "exchangeclone:dark_matter_shears" or item:get_name() == "exchangeclone:red_matter_shears" then
if special_shears[item_name] then
local pos = self.object:get_pos()
local player_pos = clicker:get_pos()
minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true)
local amount = 8
if item:get_name() == "exchangeclone:red_matter_shears" then
if item_name == "exchangeclone:red_matter_shears" or item_name == "exchangeclone:red_katar" then
amount = 12
end
if self.base_texture[1] == "mobs_mc_mooshroom_brown.png" then
@ -213,7 +213,7 @@ minetest.registered_entities["mobs_mc:mooshroom"].on_rightclick = function(self,
end
local chance = 30 --percent
if item:get_name() == "exchangeclone:red_matter_shears" then chance = 60 end
if item_name == "exchangeclone:red_matter_shears" or item_name == "exchangeclone:red_katar" then chance = 60 end
if math.random(1, 100) <= chance then
local new_mooshroom = minetest.add_entity(pos, "mobs_mc:mooshroom"):get_luaentity() --clone the mooshroom
for attribute, value in pairs(self) do
@ -240,8 +240,8 @@ local old_honey_harvest = minetest.registered_items["mcl_beehives:bee_nest_5"].o
for _, itemstring in ipairs({"mcl_beehives:bee_nest_5", "mcl_beehives:beehive_5"}) do
minetest.registered_items[itemstring].on_rightclick = function(pos, node, player, itemstack, pointed_thing)
local inv = player:get_inventory()
local shears = player:get_wielded_item():get_name() == "exchangeclone:dark_matter_shears"
or player:get_wielded_item():get_name() == "exchangeclone:red_matter_shears"
local held_name = player:get_wielded_item():get_name()
local shears = special_shears[held_name]
local beehive = "mcl_beehives:beehive"
local campfire_area = vector.offset(pos, 0, -5, 0)
local campfire = minetest.find_nodes_in_area(pos, campfire_area, "group:lit_campfire")
@ -260,136 +260,137 @@ for _, itemstring in ipairs({"mcl_beehives:bee_nest_5", "mcl_beehives:beehive_5"
old_honey_harvest()
end
end
end
local old_dispenser_function = minetest.registered_items["mcl_dispensers:dispenser"].mesecons.effector.action_on
local new_dispenser_function = function(pos, node)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local droppos, dropdir
if node.name == "mcl_dispensers:dispenser" then
dropdir = vector.multiply(minetest.facedir_to_dir(node.param2), -1)
droppos = vector.add(pos, dropdir)
elseif node.name == "mcl_dispensers:dispenser_up" then
dropdir = {x=0, y=1, z=0}
droppos = {x=pos.x, y=pos.y+1, z=pos.z}
elseif node.name == "mcl_dispensers:dispenser_down" then
dropdir = {x=0, y=-1, z=0}
droppos = {x=pos.x, y=pos.y-1, z=pos.z}
local old_dispenser_function = minetest.registered_items["mcl_dispensers:dispenser"].mesecons.effector.action_on
local new_dispenser_function = function(pos, node)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local droppos, dropdir
if node.name == "mcl_dispensers:dispenser" then
dropdir = vector.multiply(minetest.facedir_to_dir(node.param2), -1)
droppos = vector.add(pos, dropdir)
elseif node.name == "mcl_dispensers:dispenser_up" then
dropdir = {x=0, y=1, z=0}
droppos = {x=pos.x, y=pos.y+1, z=pos.z}
elseif node.name == "mcl_dispensers:dispenser_down" then
dropdir = {x=0, y=-1, z=0}
droppos = {x=pos.x, y=pos.y-1, z=pos.z}
end
local dropnode = minetest.get_node(droppos)
local dropnodedef = minetest.registered_nodes[dropnode.name]
local stacks = {}
for i=1,inv:get_size("main") do
local stack = inv:get_stack("main", i)
if not stack:is_empty() then
table.insert(stacks, {stack = stack, stackpos = i})
end
local dropnode = minetest.get_node(droppos)
local dropnodedef = minetest.registered_nodes[dropnode.name]
local stacks = {}
for i=1,inv:get_size("main") do
local stack = inv:get_stack("main", i)
if not stack:is_empty() then
table.insert(stacks, {stack = stack, stackpos = i})
end
end
if #stacks >= 1 then
local r = math.random(1, #stacks)
local stack = stacks[r].stack
local dropitem = ItemStack(stack)
dropitem:set_count(1)
local stack_id = stacks[r].stackpos
local stackdef = stack:get_definition()
if not stackdef then
return
end
if #stacks >= 1 then
local r = math.random(1, #stacks)
local stack = stacks[r].stack
local dropitem = ItemStack(stack)
dropitem:set_count(1)
local stack_id = stacks[r].stackpos
local stackdef = stack:get_definition()
if not stackdef then
return
end
local iname = stack:get_name()
local igroups = stackdef.groups
local iname = stack:get_name()
local igroups = stackdef.groups
if iname == "exchangeclone:dark_matter_shears" or iname == "exchangeclone:red_matter_shears" then
for _, obj in pairs(minetest.get_objects_inside_radius(droppos, 1)) do
local entity = obj:get_luaentity()
if entity and not entity.child and not entity.gotten then
local entname = entity.name
local pos = obj:get_pos()
local used = false
local texture
if entname == "mobs_mc:sheep" then
local max_wool = 8
if iname == "exchangeclone:red_matter_shears" then max_wool = 12 end
minetest.add_item(pos, entity.drops[2].name.." "..math.random(1,max_wool)) --normally 3
if not entity.color then
entity.color = "unicolor_white"
end
local chance = 30 --percent
if iname == "exchangeclone:red_matter_shears" then chance = 60 end
if math.random(1, 100) <= chance then
local new_sheep = minetest.add_entity(pos, "mobs_mc:sheep"):get_luaentity() --clone the sheep
for attribute, value in pairs(entity) do
if attribute ~= "object" then
new_sheep[attribute] = value
end
end
new_sheep.object:set_properties({
nametag = entity.nametag,
textures = entity.base_texture
})
end
entity.base_texture = { "blank.png", "mobs_mc_sheep.png" }
texture = entity.base_texture
entity.drops = {
{ name = "mcl_mobitems:mutton", chance = 1, min = 1, max = 2 },
}
used = true
elseif entname == "mobs_mc:snowman" then
texture = {
"mobs_mc_snowman.png",
"blank.png", "blank.png",
"blank.png", "blank.png",
"blank.png", "blank.png",
}
used = true
elseif entname == "mobs_mc:mooshroom" then
local amount = 8
if iname == "exchangeclone:red_matter_shears" then
amount = 12
end
if entity.base_texture[1] == "mobs_mc_mooshroom_brown.png" then
minetest.add_item(droppos, "mcl_mushrooms:mushroom_brown "..amount)
else
minetest.add_item(droppos, "mcl_mushrooms:mushroom_red "..amount)
end
local chance = 30 --percent
if iname == "exchangeclone:red_matter_shears" then chance = 60 end
if math.random(1, 100) <= chance then
local new_mooshroom = minetest.add_entity(pos, "mobs_mc:mooshroom"):get_luaentity() --clone the mooshroom
for attribute, value in pairs(entity) do
if attribute ~= "object" then
new_mooshroom[attribute] = value
end
end
new_mooshroom.object:set_properties({
nametag = entity.nametag,
textures = entity.base_texture
})
end
obj = mcl_util.replace_mob(obj, "mobs_mc:cow")
entity = obj:get_luaentity()
used = true
if special_shears[iname] then
for _, obj in pairs(minetest.get_objects_inside_radius(droppos, 1)) do
local entity = obj:get_luaentity()
if entity and not entity.child and not entity.gotten then
local entname = entity.name
local pos = obj:get_pos()
local used = false
local texture
if entname == "mobs_mc:sheep" then
local max_wool = 8
if iname == "exchangeclone:red_matter_shears" or iname == "exchangeclone:red_katar" then max_wool = 12 end
minetest.add_item(pos, entity.drops[2].name.." "..math.random(1,max_wool)) --normally 3
if not entity.color then
entity.color = "unicolor_white"
end
if used then
obj:set_properties({ textures = texture })
entity.gotten = true
minetest.sound_play("mcl_tools_shears_cut", { pos = pos }, true)
inv:set_stack("main", stack_id, stack)
break
local chance = 30 --percent
if iname == "exchangeclone:red_matter_shears" or iname == "exchangeclone:red_katar" then chance = 60 end
if math.random(1, 100) <= chance then
local new_sheep = minetest.add_entity(pos, "mobs_mc:sheep"):get_luaentity() --clone the sheep
for attribute, value in pairs(entity) do
if attribute ~= "object" then
new_sheep[attribute] = value
end
end
new_sheep.object:set_properties({
nametag = entity.nametag,
textures = entity.base_texture
})
end
entity.base_texture = { "blank.png", "mobs_mc_sheep.png" }
texture = entity.base_texture
entity.drops = {
{ name = "mcl_mobitems:mutton", chance = 1, min = 1, max = 2 },
}
used = true
elseif entname == "mobs_mc:snowman" then
texture = {
"mobs_mc_snowman.png",
"blank.png", "blank.png",
"blank.png", "blank.png",
"blank.png", "blank.png",
}
used = true
elseif entname == "mobs_mc:mooshroom" then
local amount = 8
if iname == "exchangeclone:red_matter_shears" or iname == "exchangeclone:red_katar" then
amount = 12
end
if entity.base_texture[1] == "mobs_mc_mooshroom_brown.png" then
minetest.add_item(droppos, "mcl_mushrooms:mushroom_brown "..amount)
else
minetest.add_item(droppos, "mcl_mushrooms:mushroom_red "..amount)
end
local chance = 30 --percent
if iname == "exchangeclone:red_matter_shears" or iname == "exchangeclone:red_katar" then chance = 60 end
if math.random(1, 100) <= chance then
local new_mooshroom = minetest.add_entity(pos, "mobs_mc:mooshroom"):get_luaentity() --clone the mooshroom
for attribute, value in pairs(entity) do
if attribute ~= "object" then
new_mooshroom[attribute] = value
end
end
new_mooshroom.object:set_properties({
nametag = entity.nametag,
textures = entity.base_texture
})
end
obj = mcl_util.replace_mob(obj, "mobs_mc:cow")
entity = obj:get_luaentity()
used = true
end
if used then
obj:set_properties({ textures = texture })
entity.gotten = true
minetest.sound_play("mcl_tools_shears_cut", { pos = pos }, true)
inv:set_stack("main", stack_id, stack)
break
end
end
end
else
old_dispenser_function(pos, node)
return
end
end
for _, itemstring in ipairs({"mcl_dispensers:dispenser", "mcl_dispensers:dispenser_up", "mcl_dispensers:dispenser_down"}) do
minetest.registered_items[itemstring].mesecons.effector.action_on = new_dispenser_function
end
old_dispenser_function(pos, node)
end
for _, itemstring in ipairs({"mcl_dispensers:dispenser", "mcl_dispensers:dispenser_up", "mcl_dispensers:dispenser_down"}) do
minetest.registered_items[itemstring].mesecons.effector.action_on = new_dispenser_function
end
local gotten_texture = {
@ -405,7 +406,8 @@ local gotten_texture = {
local old_snowman_function = minetest.registered_entities["mobs_mc:snowman"].on_rightclick
minetest.registered_entities["mobs_mc:snowman"].on_rightclick = function(self, clicker)
local item = clicker:get_wielded_item()
if self.gotten ~= true and (item:get_name() == "exchangeclone:dark_matter_shears" or item:get_name() == "exchangeclone:red_matter_shears") then
local item_name = item:get_name()
if self.gotten ~= true and special_shears[item_name] then
-- Remove pumpkin
self.gotten = true
self.object:set_properties({

View File

@ -1,55 +1,46 @@
local shovel_cube = function(player, center, distance, path)
if distance > 0 then
exchangeclone.play_ability_sound(player)
end
local player_pos = player:get_pos()
local player_energy = exchangeclone.get_player_energy(player)
local energy_cost = 0
local pos = center
pos.x = exchangeclone.round(pos.x)
pos.y = math.floor(pos.y) --make sure y is node BELOW player's feet
pos.z = exchangeclone.round(pos.z)
for x = pos.x-distance, pos.x+distance do
if energy_cost + 8 > player_energy then
break
exchangeclone.shovel_action = {
start_action = function(player, center, range)
if exchangeclone.check_cooldown(player, "shovel") then return end
local data = {}
data.player_energy = exchangeclone.get_player_energy(player)
data.energy_cost = 0
if exchangeclone.mineclone then
data.path = not player:get_player_control().sneak
end
for y = pos.y-distance, pos.y+distance do
if energy_cost + 8 > player_energy then
break
if range > 0 or not data.path then
exchangeclone.play_ability_sound(player)
end
for z = pos.z-distance, pos.z+distance do
if energy_cost + 8 > player_energy then
break
end
local new_pos = {x=x,y=y,z=z}
local node = minetest.get_node(new_pos) or {name="air"}
return data
end,
action = function(player, pos, node, data)
if data.energy_cost + 8 > data.player_energy then return end
if ((minetest.get_item_group(node.name, "crumbly") > 0) or (minetest.get_item_group(node.name, "shovely") > 0)) then
if minetest.is_protected(new_pos, player:get_player_name()) then
minetest.record_protection_violation(new_pos, player:get_player_name())
if minetest.is_protected(pos, player:get_player_name()) then
minetest.record_protection_violation(pos, player:get_player_name())
else
if distance > 0 then
energy_cost = energy_cost + 8
end
if path then
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 = new_pos}, true)
minetest.swap_node(new_pos, {name="mcl_core:grass_path"})
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
else
data.energy_cost = data.energy_cost + 8
local drops = minetest.get_node_drops(node.name, "exchangeclone:red_matter_shovel")
exchangeclone.drop_items_on_player(new_pos, drops, player)
minetest.set_node(new_pos, {name = "air"})
exchangeclone.drop_items_on_player(pos, drops, player)
minetest.set_node(pos, {name = "air"})
end
end
end
return data
end,
end_action = function(player, center, range, data)
if range > 0 or not data.path then
exchangeclone.set_player_energy(player, data.player_energy - data.energy_cost)
exchangeclone.start_cooldown(player, "shovel", range/4) -- Longish cooldown
end
end
end
end
if distance > 0 then
exchangeclone.set_player_energy(player, player_energy - energy_cost)
end
end
}
local function shovel_on_place(itemstack, player, pointed_thing)
@ -73,11 +64,7 @@ local function shovel_on_place(itemstack, player, pointed_thing)
center = pointed_thing.under
end
if player:get_player_control().sneak then
shovel_cube(player, center, range, false)
else
shovel_cube(player, center, range, true)
end
exchangeclone.node_radius_action(player, center, range, exchangeclone.shovel_action)
return itemstack
end

View File

@ -55,12 +55,13 @@ minetest.register_on_mods_loaded(function()
end
end)
local sword_aoe = function(info)
exchangeclone.aoe_attack = function(info)
if not info then return end
local max_damage = info.max_damage
local knockback = info.knockback
local radius = info.radius
local damage_all = info.damage_all --damage all mobs/players or just hostile ones
local cooldown = info.cooldown or 0
if not max_damage or not knockback or not radius then return end
if damage_all == nil then damage_all = 1 end
@ -71,6 +72,8 @@ local sword_aoe = function(info)
return click_test
end
if exchangeclone.check_cooldown(player, "sword") then return end
local player_energy = exchangeclone.get_player_energy(player)
if player_energy >= 384 then
exchangeclone.set_player_energy(player, player_energy - 384)
@ -97,16 +100,14 @@ local sword_aoe = function(info)
local opos = obj:get_pos()
local distance = vector.distance(pos, opos)
local distance = math.max(1, vector.distance(pos, opos))
-- Punch entity with damage depending on explosion exposure and
-- distance to explosion
local punch_vec = vector.subtract(opos, pos)
local punch_dir = vector.normalize(punch_vec)
punch_dir = {x=punch_dir.x, y=punch_dir.y+0.3, z=punch_dir.z} -- knockback should be more upward
if distance < 1 then distance = 1 end --to prevent huge amounts of damage and dividing by zero
local damage = max_damage/distance
local damage = math.min(max_damage, max_damage-distance)
--minetest.log(dump({name=ent.name, distance=distance, damage=damage}))
local sleep_formspec_doesnt_close_mt53 = false
@ -144,6 +145,7 @@ local sword_aoe = function(info)
end
end
end
exchangeclone.start_cooldown(player, "sword", cooldown)
end
end
@ -163,7 +165,7 @@ local red_matter_sword_action = function(itemstack, player, pointed_thing)
return itemstack
end
local aoe_function = sword_aoe({max_damage = 12, knockback = 20, radius = 7, damage_all = damage_all})
local aoe_function = exchangeclone.aoe_attack({max_damage = 12, knockback = 20, radius = 7, damage_all = damage_all, cooldown = 0.2})
aoe_function(itemstack, player, pointed_thing)
end
@ -183,8 +185,8 @@ minetest.register_tool("exchangeclone:dark_matter_sword", {
snappy = {times={[1]=0.95, [2]=0.45, [3]=0.15}, uses=0, maxlevel=4},
},
},
on_secondary_use = sword_aoe({max_damage = 10, knockback = 12, radius = 5}),
on_place = sword_aoe({max_damage = 10, knockback = 12, radius = 5}),
on_secondary_use = exchangeclone.aoe_attack({max_damage = 10, knockback = 12, radius = 5, cooldown = 0.5}),
on_place = exchangeclone.aoe_attack({max_damage = 10, knockback = 12, radius = 5, cooldown = 0.5}),
sound = { breaks = "default_tool_breaks" },
_mcl_toollike_wield = true,
_mcl_diggroups = {

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 896 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 787 B