Compare commits
6 Commits
dd3137bb89
...
633d5082c2
Author | SHA1 | Date |
---|---|---|
ThePython | 633d5082c2 | |
ThePython | 336c0ae56c | |
ThePython | d64337aaf3 | |
ThePython | 8e808c8343 | |
ThePython | bd934c691b | |
ThePython | e3c51c517e |
54
README.md
54
README.md
|
@ -61,46 +61,56 @@ Dependencies: Minetest Game or MineClone.
|
|||
* Originally started as a fork of Enchant97's mod [Element Exchange](https://github.com/enchant97/minetest_element_exchange) (GPLv3+).
|
||||
* Some code copied/modified from MineClone2 and Minetest Game (both GPLv3+)
|
||||
* Textures:
|
||||
* Constructor and Deconstructor: Unmodified from Element Exchange (GPLv3+)
|
||||
* Armor (not the inventory image): Modified versions of diamond armor from 3D Armor in MTG and `mcl_armor` in MCL (both CC-BY-SA-3.0)
|
||||
* Upgrader and Upgrades: Created by me (CC-BY-SA-3.0)
|
||||
* Energy Collectors:
|
||||
* Base: Glowstone block from MineClone2 (CC-BY-SA-3.0)
|
||||
* Overlay: Created by me (CC-BY-SA-3.0)
|
||||
* Armor (not the inventory image): Slightly modified from ProjectE (just moved stuff around so it fit onto Minetest player models correctly).
|
||||
* Alchemical Chest: Modified version of EE2/ProjectE's textures, extended to 16x16 instead of 14x14 (MIT)
|
||||
* Advanced Alchemical Chests: Modified version of ProjectExpansion's textures, extended to 16x16 instead of 14x14 (MIT)
|
||||
* Magnum Stars: Directly from ProjectExpansion (MIT)
|
||||
* Magnum Stars and EMC Link: Directly from ProjectExpansion (MIT)
|
||||
* All other textures and sounds: Directly from EE2/ProjectE (MIT)
|
||||
|
||||
You can find the old textures and sounds by going back to previous commits in GitHub.
|
||||
|
||||
-----
|
||||
|
||||
## To-to for v8.0:
|
||||
[x] Deprecate (De)Constructors
|
||||
[x] Remove fuel crafting recipes for stars and upgrades
|
||||
[x] Add ProjectE armor textures
|
||||
[ ] Add EMC Link
|
||||
[ ] Add Energy Condensers
|
||||
[ ] Add Divining Rods
|
||||
[ ] Add Alchemical Books
|
||||
[ ] Add Knowledge Sharing Book
|
||||
[ ] Add function for getting player's learned items
|
||||
[ ] Add Evertide Amulet
|
||||
[ ] Add Volcanite Amulet
|
||||
[ ] Add Zero Ring
|
||||
[ ] Add Ring of Ignition
|
||||
[ ] Add Black Hole Band (without bag functionality)
|
||||
[ ] Add Void Ring
|
||||
[ ] Add DM Pedestal
|
||||
[ ] Functions for passive stones, talisman, evertide/volcanite, zero/ignition
|
||||
## To-do for v8.0:
|
||||
- [x] Deprecate (De)Constructors
|
||||
- [x] Remove fuel crafting recipes for stars and upgrades
|
||||
- [x] Add ProjectE armor textures
|
||||
- [x] Add EMC Link
|
||||
- [ ] ~~Add Divining Rods~~
|
||||
- [ ] Add Alchemical Books
|
||||
- [ ] Add Knowledge Sharing Book
|
||||
- [ ] Add function for getting player's learned items
|
||||
- [ ] Add Evertide Amulet
|
||||
- [ ] Add Volcanite Amulet
|
||||
- [ ] Add Zero Ring
|
||||
- [ ] Add Ring of Ignition
|
||||
- [ ] Add Black Hole Band (without bag functionality)
|
||||
- [ ] Add Void Ring
|
||||
- [x] Add DM Pedestal
|
||||
- [ ] Add Pedestal abilities
|
||||
- [ ] Passive Stones
|
||||
- [x] Soul
|
||||
- [x] Body
|
||||
- [x] Life
|
||||
- [ ] Mind
|
||||
- [ ] Talisman
|
||||
- [ ] Evertide
|
||||
- [ ] Volcanite
|
||||
- [ ] Zero
|
||||
- [ ] Ignition
|
||||
- [ ] Black Hole/Void
|
||||
- [ ] Functions for passive stones, talisman, evertide/volcanite, zero/ignition
|
||||
|
||||
## Changelog
|
||||
<details><summary>Look at this fancy expanding changelog</summary>
|
||||
|
||||
### v8.0
|
||||
* New Features:
|
||||
*
|
||||
* Added the EMC Link to replace both the Constructor and Deconstructor.
|
||||
* Changes:
|
||||
* The Constructor and Deconstructor are now deprecated. Element Exchange is no more.
|
||||
* Upgrades and Stars can no longer be used as fuel.
|
||||
|
|
|
@ -0,0 +1,216 @@
|
|||
local particle_positions = {
|
||||
{x = -0.2, y=-0.2, z=-0.2},
|
||||
{x = 0, y=-0.2, z=-0.2},
|
||||
{x = 0.2, y=-0.2, z=-0.2},
|
||||
{x = 0.2, y=-0.2, z=0},
|
||||
{x = 0.2, y=-0.2, z=0.2},
|
||||
{x = 0, y=-0.2, z=0.2},
|
||||
{x = -0.2, y=-0.2, z=0.2},
|
||||
{x = -0.2, y=-0.2, z=0},
|
||||
}
|
||||
|
||||
local function add_particles(pos)
|
||||
for _, offset in pairs(particle_positions) do
|
||||
minetest.add_particle({
|
||||
pos = vector.add(pos, offset),
|
||||
expirationtime = 1.1,
|
||||
size = 1,
|
||||
texture = "exchangeclone_flame_particle.png",
|
||||
glow = 14,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_entity("exchangeclone:item", {
|
||||
initial_properties = {
|
||||
hp_max = 1,
|
||||
pointable = false,
|
||||
visual = "wielditem",
|
||||
visual_size = {x=0.25,y=0.25,z=0.25},
|
||||
wield_item = "air",
|
||||
automatic_rotate = 1,
|
||||
static_save = false,
|
||||
},
|
||||
on_activate = function(self, staticdata)
|
||||
if staticdata and staticdata ~= "" then
|
||||
local split_data = staticdata:split(";")
|
||||
self._itemstring = split_data[1]
|
||||
if self._itemstring and minetest.registered_items[self._itemstring] then
|
||||
self.object:set_properties({wield_item = split_data[1], is_visible = true})
|
||||
else
|
||||
self.object:set_properties({is_visible = false})
|
||||
end
|
||||
self._pedestal_pos = minetest.string_to_pos(split_data[2])
|
||||
end
|
||||
end,
|
||||
get_staticdata = function(self)
|
||||
if self._itemstring and self._pedestal_pos then
|
||||
return self._itemstring..";"..minetest.pos_to_string(self._pedestal_pos)
|
||||
else
|
||||
return ""
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
exchangeclone.pedestal_offset = {x=0,y=0.4,z=0}
|
||||
|
||||
-- Copied from Mineclonia enchanting table book
|
||||
local function spawn_pedestal_entity(pos, itemstring, respawn)
|
||||
if respawn then
|
||||
-- Check if we already have an entity
|
||||
local objs = minetest.get_objects_inside_radius(pos, 1)
|
||||
for o=1, #objs do
|
||||
local obj = objs[o]
|
||||
local lua = obj:get_luaentity()
|
||||
if lua and lua.name == "exchangeclone:item" then
|
||||
if lua._pedestal_pos and vector.equals(pos, lua._pedestal_pos) then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
minetest.add_entity(vector.add(pos, exchangeclone.pedestal_offset), "exchangeclone:item", (itemstring or "")..";"..minetest.pos_to_string(pos))
|
||||
end
|
||||
|
||||
local function update_pedestal_entity(pos)
|
||||
local objs = minetest.get_objects_inside_radius(pos, 1)
|
||||
local stack = minetest.get_meta(pos):get_inventory():get_stack("main", 1)
|
||||
local itemstring
|
||||
if stack:is_known() then
|
||||
itemstring = stack:get_name()
|
||||
end
|
||||
if itemstring == "" then
|
||||
itemstring = nil
|
||||
end
|
||||
local found
|
||||
for o=1, #objs do
|
||||
local obj = objs[o]
|
||||
local lua = obj:get_luaentity()
|
||||
if lua and lua.name == "exchangeclone:item" then
|
||||
if lua._pedestal_pos and vector.equals(pos, lua._pedestal_pos) then
|
||||
found = true
|
||||
if itemstring then
|
||||
lua._itemstring = itemstring
|
||||
obj:set_properties({wield_item = itemstring, is_visible = true})
|
||||
else
|
||||
obj:set_properties({is_visible = false})
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if not found then
|
||||
spawn_pedestal_entity(pos, itemstring)
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_lbm({
|
||||
label = "(Re-)spawn item entity above DM pedestal",
|
||||
name = "exchangeclone:spawn_pedestal_entity",
|
||||
nodenames = {"exchangeclone:dark_matter_pedestal"},
|
||||
run_at_every_load = true,
|
||||
action = update_pedestal_entity
|
||||
})
|
||||
|
||||
local function pedestal_action(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local stack = inv:get_stack("main", 1)
|
||||
local def = stack:get_definition()
|
||||
local func = def._exchangeclone_pedestal
|
||||
add_particles(pos)
|
||||
if func then
|
||||
inv:set_stack("main", 1, func(pos, stack) or stack)
|
||||
update_pedestal_entity(pos)
|
||||
local new_stack = inv:get_stack("main", 1)
|
||||
if new_stack:is_known() and new_stack:get_definition()._exchangeclone_pedestal then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("exchangeclone:dark_matter_pedestal", {
|
||||
description = "Dark Matter Pedestal",
|
||||
drawtype = "nodebox",
|
||||
tiles = {"exchangeclone_dark_matter_block.png"},
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.3125, -0.5000, -0.3125, 0.3125, -0.3750, 0.3125},
|
||||
{-0.1250, -0.3750, -0.1250, 0.1250, 0.06250, 0.1250},
|
||||
{-0.1875, 0.06250, -0.1875, 0.1875, 0.1250, 0.1875}
|
||||
}
|
||||
},
|
||||
on_punch = function(pos, node, player, pointed_thing)
|
||||
local wielded_item = player:get_wielded_item()
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
if not inv:is_empty("main") and wielded_item:is_empty() then
|
||||
minetest.add_item(vector.add(pos, exchangeclone.pedestal_offset), inv:get_stack("main", 1))
|
||||
inv:set_stack("main", 1, ItemStack(""))
|
||||
update_pedestal_entity(pos)
|
||||
if minetest.get_node_timer(pos):is_started() then
|
||||
minetest.sound_play("exchangeclone_charge_down", {pos = pos, max_hear_distance = 20})
|
||||
minetest.get_node_timer(pos):stop()
|
||||
end
|
||||
end
|
||||
end,
|
||||
on_rightclick = function(pos, node, player, pointed_thing)
|
||||
local wielded_item = player:get_wielded_item()
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
if not inv:is_empty("main") and wielded_item:is_empty() then
|
||||
local stack = inv:get_stack("main", 1)
|
||||
local pedestal_data = stack:get_definition()._exchangeclone_pedestal
|
||||
if pedestal_data then
|
||||
if minetest.get_node_timer(pos):is_started() then
|
||||
minetest.sound_play("exchangeclone_charge_down", {pos = pos, max_hear_distance = 20})
|
||||
minetest.get_node_timer(pos):stop()
|
||||
else
|
||||
minetest.sound_play("exchangeclone_enable", {pos = pos, max_hear_distance = 20})
|
||||
minetest.get_node_timer(pos):start(1,0)
|
||||
add_particles(pos)
|
||||
end
|
||||
end
|
||||
elseif inv:is_empty("main") and not wielded_item:is_empty() and wielded_item:get_stack_max() == 1 then
|
||||
inv:set_stack("main", 1, wielded_item:take_item())
|
||||
update_pedestal_entity(pos)
|
||||
if wielded_item:get_count() <= 0 then wielded_item = ItemStack("") end
|
||||
return wielded_item
|
||||
end
|
||||
end,
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("main", 1)
|
||||
end,
|
||||
on_timer = pedestal_action,
|
||||
is_ground_content = false,
|
||||
sounds = exchangeclone.sound_mod.node_sound_stone_defaults(),
|
||||
groups = {pickaxey=5, material_stone=1, cracky = 3, building_block = 1, level = exchangeclone.mtg and 4 or 0},
|
||||
_mcl_blast_resistance = 1500,
|
||||
_mcl_hardness = 12,
|
||||
after_dig_node = exchangeclone.drop_after_dig({"main"}),
|
||||
on_blast = exchangeclone.on_blast({"main"}),
|
||||
after_destruct = function(pos)
|
||||
local objs = minetest.get_objects_inside_radius(pos, 1)
|
||||
for o=1, #objs do
|
||||
local obj = objs[o]
|
||||
local lua = obj:get_luaentity()
|
||||
if lua and lua.name == "exchangeclone:item" then
|
||||
if lua._pedestal_pos and vector.equals(pos, lua._pedestal_pos) then
|
||||
obj:remove()
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "exchangeclone:dark_matter_pedestal",
|
||||
recipe = {
|
||||
{"exchangeclone:red_matter", "exchangeclone:dark_matter_block", "exchangeclone:red_matter"},
|
||||
{"exchangeclone:red_matter", "exchangeclone:dark_matter_block", "exchangeclone:red_matter"},
|
||||
{"exchangeclone:dark_matter_block", "exchangeclone:dark_matter_block", "exchangeclone:dark_matter_block"},
|
||||
}
|
||||
})
|
|
@ -36,7 +36,7 @@ local function link_action(pos)
|
|||
local stored_emc
|
||||
local target = inv:get_stack("target", 1):get_name()
|
||||
local output_stack = inv:get_stack("dst", 1)
|
||||
local in_indiv_emc = exchangeclone.get_item_emc(input_stack:peek_item(1)) or 0
|
||||
local in_indiv_emc = exchangeclone.get_item_emc(input_stack:peek_item()) or 0
|
||||
local target_emc = exchangeclone.get_item_emc(target)
|
||||
local stack_max = ItemStack(target):get_stack_max()
|
||||
|
||||
|
@ -81,12 +81,10 @@ local function link_action(pos)
|
|||
local timer = minetest.get_node_timer(pos)
|
||||
if inv:get_stack("src", 1):is_empty() and inv:get_stack("target", 1):is_empty() then
|
||||
timer:stop()
|
||||
else
|
||||
if not timer:is_started() then
|
||||
elseif not timer:is_started() then
|
||||
timer:start(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
|
||||
if player and player.get_player_name and minetest.is_protected(pos, player:get_player_name()) then
|
||||
|
@ -102,7 +100,7 @@ local function allow_metadata_inventory_put(pos, listname, index, stack, player)
|
|||
return stack:get_count()
|
||||
end
|
||||
elseif listname == "target" then
|
||||
local single_item = stack:peek_item(1)
|
||||
local single_item = stack:peek_item()
|
||||
local emc = exchangeclone.get_item_emc(single_item)
|
||||
if emc and emc > 0 then
|
||||
minetest.get_meta(pos):get_inventory():set_stack("target", 1, ItemStack(exchangeclone.handle_alias(single_item)))
|
||||
|
@ -211,3 +209,12 @@ if exchangeclone.pipeworks then
|
|||
on_rotate = pipeworks.on_rotate,
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_craft({
|
||||
output = "exchangeclone:emc_link",
|
||||
recipe = {
|
||||
{exchangeclone.itemstrings.obsidian, exchangeclone.itemstrings.diamond, exchangeclone.itemstrings.obsidian},
|
||||
{exchangeclone.itemstrings.diamond, "exchangeclone:alchemical_chest", exchangeclone.itemstrings.diamond},
|
||||
{exchangeclone.itemstrings.obsidian, exchangeclone.itemstrings.diamond, exchangeclone.itemstrings.obsidian},
|
||||
}
|
||||
})
|
|
@ -131,6 +131,7 @@ local files = {
|
|||
"talisman_of_repair",
|
||||
"passive_stones",
|
||||
"emc_link",
|
||||
"dark_matter_pedestal",
|
||||
}
|
||||
|
||||
if exchangeclone.mcl or minetest.get_modpath("3d_armor") then
|
||||
|
|
|
@ -42,6 +42,11 @@ minetest.register_tool("exchangeclone:soul_stone", {
|
|||
active_image = "exchangeclone_soul_stone_active.png",
|
||||
exclude = {"exchangeclone:life_stone"}
|
||||
},
|
||||
_exchangeclone_pedestal = function(pos)
|
||||
for _, player in minetest.get_objects_inside_radius(pos, 5) do
|
||||
heal(player, 2)
|
||||
end
|
||||
end,
|
||||
on_secondary_use = exchangeclone.toggle_active,
|
||||
on_place = exchangeclone.toggle_active,
|
||||
groups = {exchangeclone_passive = 1, disable_repair = 1}
|
||||
|
@ -71,6 +76,13 @@ if (exchangeclone.mcl and mcl_hunger.active) or (exchangeclone.mtg and minetest.
|
|||
active_image = "exchangeclone_body_stone_active.png",
|
||||
exclude = {"exchangeclone:life_stone"}
|
||||
},
|
||||
_exchangeclone_pedestal = function(pos)
|
||||
for _, object in pairs(minetest.get_objects_inside_radius(pos, 5)) do
|
||||
if object:is_player() then
|
||||
heal(object, 2)
|
||||
end
|
||||
end
|
||||
end,
|
||||
on_secondary_use = exchangeclone.toggle_active,
|
||||
on_place = exchangeclone.toggle_active,
|
||||
groups = {exchangeclone_passive = 1, disable_repair = 1}
|
||||
|
@ -108,6 +120,14 @@ if (exchangeclone.mcl and mcl_hunger.active) or (exchangeclone.mtg and minetest.
|
|||
active_image = "exchangeclone_life_stone_active.png",
|
||||
exclude = {"exchangeclone:body_stone", "exchangeclone:soul_stone"}
|
||||
},
|
||||
_exchangeclone_pedestal = function(pos)
|
||||
for _, object in pairs(minetest.get_objects_inside_radius(pos, 5)) do
|
||||
if object:is_player() then
|
||||
heal(object, 2)
|
||||
satiate(object, 2)
|
||||
end
|
||||
end
|
||||
end,
|
||||
on_secondary_use = exchangeclone.toggle_active,
|
||||
on_place = exchangeclone.toggle_active,
|
||||
groups = {exchangeclone_passive = 1, disable_repair = 1},
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 145 B |
|
@ -116,7 +116,7 @@ end
|
|||
local function handle_inventory(player, inventory, to_list)
|
||||
local stack = inventory:get_stack(to_list, 1)
|
||||
local itemstring = stack:get_name()
|
||||
local single_item = stack:peek_item(1)
|
||||
local single_item = stack:peek_item()
|
||||
itemstring = exchangeclone.emc_aliases[itemstring] or itemstring
|
||||
if to_list == "learn" then
|
||||
local list = minetest.deserialize(player:get_meta():get_string("exchangeclone_transmutation_learned_items")) or {}
|
||||
|
|
|
@ -236,18 +236,6 @@ function exchangeclone.format_number(number)
|
|||
return minus .. int:reverse():gsub("^,", "") .. fraction
|
||||
end
|
||||
|
||||
-- Splits a string into a table using a delimiter (copied from somewhere, I don't remember)
|
||||
function exchangeclone.split (input, sep)
|
||||
if sep == nil then
|
||||
sep = "%s"
|
||||
end
|
||||
local result={}
|
||||
for str in string.gmatch(input, "([^"..sep.."]+)") do
|
||||
table.insert(result, str)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
-- Returns a table of all items in the specified group(s).
|
||||
function exchangeclone.get_group_items(groups, allow_duplicates, include_no_group)
|
||||
if type(groups) ~= "table" then
|
||||
|
@ -276,10 +264,10 @@ function exchangeclone.get_group_items(groups, allow_duplicates, include_no_grou
|
|||
in_group = false
|
||||
for i = 1, num_groups do
|
||||
local grp = groups[i]
|
||||
local subgroups = exchangeclone.split(grp, ",")
|
||||
local subgroups = grp:split(",")
|
||||
local success = true
|
||||
for _, subgroup in pairs(subgroups) do
|
||||
local group_info = exchangeclone.split(subgroup, "=")
|
||||
local group_info = subgroup:split("=")
|
||||
if #group_info == 1 then
|
||||
if minetest.get_item_group(name, subgroup) <= 0 then
|
||||
success = false
|
||||
|
@ -631,7 +619,7 @@ minetest.register_chatcommand("add_player_emc", {
|
|||
description = "Add to a player's personal EMC (player is self if not included, value can be negative to subtract)",
|
||||
privs = {privs = true},
|
||||
func = function(name, param)
|
||||
local split_param = exchangeclone.split(param, " ")
|
||||
local split_param = param:split(" ")
|
||||
local target_player
|
||||
local target_name
|
||||
local value
|
||||
|
@ -685,7 +673,7 @@ minetest.register_chatcommand("set_player_emc", {
|
|||
description = "Set a player's personal EMC (player is self if not included; use 'limit' as value to set it to maximum)",
|
||||
privs = {privs = true},
|
||||
func = function(name, param)
|
||||
local split_param = exchangeclone.split(param, " ")
|
||||
local split_param = param:split(" ")
|
||||
local target_player
|
||||
local target_name
|
||||
local value
|
||||
|
|
Loading…
Reference in New Issue