Add metatable functions

This commit is contained in:
ThePython 2024-03-03 17:46:39 -08:00
parent 3e820720bc
commit 5c4c42ab58
17 changed files with 134 additions and 88 deletions

View File

@ -44,8 +44,8 @@ Dependencies: Minetest Game or MineClone.
* Dark and Red Matter Armor can make the player invincible. This is an [engine problem](https://github.com/minetest/minetest/issues/14344) that I can't fix. * Dark and Red Matter Armor can make the player invincible. This is an [engine problem](https://github.com/minetest/minetest/issues/14344) that I can't fix.
* Mobs Redo (and mods that use it) don't care that DM/RM tools are supposed to be unbreakable and add wear to them anyway. * Mobs Redo (and mods that use it) don't care that DM/RM tools are supposed to be unbreakable and add wear to them anyway.
* Covalence Dust and the Talisman of Repair cannot repair certain tools. This will not be fixed. * Covalence Dust and the Talisman of Repair cannot repair certain tools. This will not be fixed.
* The recipe for Energy Collectors doesn't include glowstone even though they are very glowstone-y. This will probably not be fixed because glowstone doesn't exist in MTG.
* DM/RM tools are too fast in MTG (can't figure out why) * DM/RM tools are too fast in MTG (can't figure out why)
* When placing torches with a pick/morningstar, if the placement fails, it still costs energy. This will probably not be fixed.
**If you have a suggestion or notice a bug that isn't on this list, visit the [GitHub issues page](https://github.com/thepython10110/exchangeclone/issues).** **If you have a suggestion or notice a bug that isn't on this list, visit the [GitHub issues page](https://github.com/thepython10110/exchangeclone/issues).**
@ -84,8 +84,6 @@ You can find the old textures and sounds by going back to previous commits in Gi
- [x] Add more matter/fuel types - [x] Add more matter/fuel types
- [x] Make collectors less expensive and less effective (gold instead of glowstone) - [x] Make collectors less expensive and less effective (gold instead of glowstone)
- [x] Make collectors use ProjectExpansion's textures - [x] Make collectors use ProjectExpansion's textures
- [ ] Add Knowledge Sharing Book
- [ ] Add function for getting player's learned items
- [ ] Add Evertide Amulet - [ ] Add Evertide Amulet
- [ ] Add Volcanite Amulet - [ ] Add Volcanite Amulet
- [ ] Add Zero Ring - [ ] Add Zero Ring
@ -96,8 +94,8 @@ You can find the old textures and sounds by going back to previous commits in Gi
- [ ] Add Pedestal abilities - [ ] Add Pedestal abilities
- [x] Passive Stones - [x] Passive Stones
- [x] Talisman - [x] Talisman
- [ ] Evertide - [ ] Evertide (MCL)
- [ ] Volcanite - [ ] Volcanite (MCL)
- [ ] Zero - [ ] Zero
- [ ] Ignition - [ ] Ignition
- [ ] Black Hole/Void - [ ] Black Hole/Void
@ -117,13 +115,16 @@ You can find the old textures and sounds by going back to previous commits in Gi
* Added the Dark Matter Pedestal. * Added the Dark Matter Pedestal.
* Added Alchemical Books. * Added Alchemical Books.
* DM/RM armor now use ProjectE's textures. * DM/RM armor now use ProjectE's textures.
* Added Magenta through White Matter (would have added fading matter, but it's over 1 trillion EMC) * Added Magenta through White Fuel/Matter (would have added fading matter, but it's over 1 trillion EMC)
* Added `_get_emc`, `_set_emc`, and `_add_emc` to player metatables. This means you can use `player:_get_emc()` instead of `exchangeclone.get_player_emc(player)`. **WARNING: Do not use these functions in `on_joinplayer` functions.**
* Added the same functions for itemstack metatables, as well as `_<get/set/add>_star_emc` and `_get_star_max`. `_set_emc` and `_add_emc` work by changing the metadata EMC value.
* Changes: * Changes:
* The Constructor and Deconstructor are now deprecated, replaced with the EMC Link. * The Constructor and Deconstructor are now deprecated, replaced with the EMC Link.
* Upgrades and Stars can no longer be used as fuel. * Upgrades and Stars can no longer be used as fuel.
* Dark and Red Matter Armor now uses ProjectE's textures * Dark and Red Matter Armor now uses ProjectE's textures
* Removed the ability to right click with stars to see the charge (it's unnecessary). * Removed the ability to right click with stars to see the charge (it's unnecessary).
* Organized textures into folders * Organized textures into folders
* Collectors now match ProjectExpansion's in every way possible (except MTG doesn't have glowstone so it's replaced with gold in the recipe)
* Bugfixes: * Bugfixes:
* Dark and Red Matter Armor display properly (and identically) in both games, with ProjectE's textures. * Dark and Red Matter Armor display properly (and identically) in both games, with ProjectE's textures.
* `add_star_emc` now correctly works with negative energy values. * `add_star_emc` now correctly works with negative energy values.
@ -501,7 +502,7 @@ I didn't get to everything I wanted to, mostly because the automatic energy valu
* Pedestals\*\* (haven't added all the abilities yet) * Pedestals\*\* (haven't added all the abilities yet)
* Black Hole Band and Void Ring\* * Black Hole Band and Void Ring\*
* Nova Catalyst/Cataclysm? * Nova Catalyst/Cataclysm?
* Knowledge Sharing Book\* * Knowledge Sharing Book
* EMC Link\*\* * EMC Link\*\*
\* Planned for v8.0 \* Planned for v8.0

View File

@ -193,12 +193,12 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
local distance = vector.distance(adjusted_player_pos, adjusted_pos) local distance = vector.distance(adjusted_player_pos, adjusted_pos)
local emc_per_node = stack:get_definition().alchemical_book_data.emc_per_node local emc_per_node = stack:get_definition().alchemical_book_data.emc_per_node
local cost = distance*emc_per_node local cost = distance*emc_per_node
local player_emc = exchangeclone.get_player_emc(player) local player_emc = player:_get_emc()
if player_emc < cost then if player_emc < cost then
minetest.chat_send_player(player:get_player_name(), "Not enough EMC to teleport.") minetest.chat_send_player(player:get_player_name(), "Not enough EMC to teleport.")
else else
player:set_pos(pos) player:set_pos(pos)
exchangeclone.add_player_emc(-cost) player:_add_emc(-cost)
end end
show_formspec(player, index, fields.name, use_stack_data) show_formspec(player, index, fields.name, use_stack_data)
elseif fields.location_list then elseif fields.location_list then
@ -220,12 +220,12 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
local distance = vector.distance(adjusted_player_pos, adjusted_pos) local distance = vector.distance(adjusted_player_pos, adjusted_pos)
local emc_per_node = stack:get_definition().alchemical_book_data.emc_per_node local emc_per_node = stack:get_definition().alchemical_book_data.emc_per_node
local cost = distance*emc_per_node local cost = distance*emc_per_node
local player_emc = exchangeclone.get_player_emc(player) local player_emc = player:_get_emc()
if player_emc < cost then if player_emc < cost then
minetest.chat_send_player(player:get_player_name(), "Not enough EMC to teleport.") minetest.chat_send_player(player:get_player_name(), "Not enough EMC to teleport.")
else else
player:set_pos(pos) player:set_pos(pos)
exchangeclone.add_player_emc(-cost) player:_add_emc(-cost)
end end
end end
show_formspec(player, index, fields.name, use_stack_data) show_formspec(player, index, fields.name, use_stack_data)

View File

@ -80,7 +80,7 @@ local function is_repairable_gear(item)
item = ItemStack(item) item = ItemStack(item)
if item:get_wear() <= 0 then return end if item:get_wear() <= 0 then return end
if minetest.get_item_group(item:get_name(), "disable_repair") > 0 then return end if minetest.get_item_group(item:get_name(), "disable_repair") > 0 then return end
if (exchangeclone.get_item_emc(item) or 0) <= 0 then return end if (item:_get_emc() or 0) <= 0 then return end
local def = item:get_definition() local def = item:get_definition()
if def if def
and def.type == "tool" and def.type == "tool"
@ -129,7 +129,7 @@ minetest.register_on_player_inventory_action(function(player, action, inventory,
if gear_stack:is_empty() or dust_stack:is_empty() then return end if gear_stack:is_empty() or dust_stack:is_empty() then return end
if not inventory:room_for_item("exchangeclone_covalence_output", gear_stack) then return end if not inventory:room_for_item("exchangeclone_covalence_output", gear_stack) then return end
local amount = is_repairable_gear(gear_stack) local amount = is_repairable_gear(gear_stack)
local emc_value = exchangeclone.get_item_emc(gear_stack) local emc_value = gear_stack:_get_emc()
local tier = 3 local tier = 3
if emc_value/amount < 50 then if emc_value/amount < 50 then
tier = 1 tier = 1

View File

@ -36,7 +36,7 @@ local function link_action(pos)
local stored_emc local stored_emc
local target = inv:get_stack("target", 1):get_name() local target = inv:get_stack("target", 1):get_name()
local output_stack = inv:get_stack("dst", 1) local output_stack = inv:get_stack("dst", 1)
local in_indiv_emc = exchangeclone.get_item_emc(input_stack:peek_item()) or 0 local in_indiv_emc = input_stack:peek_item():_get_emc() or 0
local target_emc = exchangeclone.get_item_emc(target) local target_emc = exchangeclone.get_item_emc(target)
local stack_max = ItemStack(target):get_stack_max() local stack_max = ItemStack(target):get_stack_max()
@ -44,12 +44,13 @@ local function link_action(pos)
if minetest.get_item_group(star_stack:get_name(), "klein_star") > 0 then if minetest.get_item_group(star_stack:get_name(), "klein_star") > 0 then
using_star = true using_star = true
limit = exchangeclone.get_star_max(star_stack) limit = exchangeclone.get_star_max(star_stack)
stored_emc = exchangeclone.get_star_itemstack_emc(star_stack) stored_emc = star_stack:get_star_emc()
else else
using_star = false using_star = false
limit = exchangeclone.limit limit = exchangeclone.limit
player = minetest.get_player_by_name(meta:get_string("exchangeclone_placer")) player = minetest.get_player_by_name(meta:get_string("exchangeclone_placer"))
stored_emc = exchangeclone.get_player_emc(player) if not player then return true end
stored_emc = player:_get_emc()
end end
-- Construct -- Construct
if target ~= "" and (output_stack:is_empty() or exchangeclone.handle_alias(output_stack) == target) then if target ~= "" and (output_stack:is_empty() or exchangeclone.handle_alias(output_stack) == target) then
@ -60,7 +61,7 @@ local function link_action(pos)
minetest.log(dump({out_count = out_count, target_emc = target_emc})) minetest.log(dump({out_count = out_count, target_emc = target_emc}))
exchangeclone.add_star_emc(inv, "fuel", 1, -out_count*target_emc) exchangeclone.add_star_emc(inv, "fuel", 1, -out_count*target_emc)
else else
exchangeclone.add_player_emc(player, -out_count*target_emc) player:_add_emc(-out_count*target_emc)
end end
end end
end end
@ -73,7 +74,7 @@ local function link_action(pos)
if using_star then if using_star then
exchangeclone.add_star_emc(inv, "fuel", 1, max_count*in_indiv_emc) exchangeclone.add_star_emc(inv, "fuel", 1, max_count*in_indiv_emc)
else else
exchangeclone.add_player_emc(player, max_count*in_indiv_emc) player:_add_emc(max_count*in_indiv_emc)
end end
end end
end end
@ -95,13 +96,13 @@ local function allow_metadata_inventory_put(pos, listname, index, stack, player)
return stack:get_count() return stack:get_count()
end end
elseif listname == "src" then elseif listname == "src" then
local emc = exchangeclone.get_item_emc(stack) local emc = stack:_get_emc()
if emc and emc > 0 then if emc and emc > 0 then
return stack:get_count() return stack:get_count()
end end
elseif listname == "target" then elseif listname == "target" then
local single_item = stack:peek_item() local single_item = stack:peek_item()
local emc = exchangeclone.get_item_emc(single_item) local emc = single_item:_get_emc()
if emc and emc > 0 then if emc and emc > 0 then
minetest.get_meta(pos):get_inventory():set_stack("target", 1, ItemStack(exchangeclone.handle_alias(single_item))) minetest.get_meta(pos):get_inventory():set_stack("target", 1, ItemStack(exchangeclone.handle_alias(single_item)))
link_action(pos) link_action(pos)

View File

@ -73,7 +73,7 @@ local function on_timer(pos, elapsed)
if placer and placer ~= "" then if placer and placer ~= "" then
local player = minetest.get_player_by_name(placer) local player = minetest.get_player_by_name(placer)
if player then if player then
exchangeclone.add_player_emc(player, amount) player:_add_emc(amount)
end end
end end
end end
@ -240,7 +240,7 @@ for i = 2, #collectors do
local previous = "exchangeclone:"..collectors[i-1]:lower().."_collector" local previous = "exchangeclone:"..collectors[i-1]:lower().."_collector"
exchangeclone.register_energy_collector( exchangeclone.register_energy_collector(
"exchangeclone:"..codified, "exchangeclone:"..codified,
S(collector.." Energy Collector [MK"..i.."]"), S(collector.." Collector [MK"..i.."]"),
4*math.pow(6,i-1), 4*math.pow(6,i-1),
"exchangeclone_"..codified..".png", "exchangeclone_"..codified..".png",
{ {

View File

@ -11,7 +11,7 @@ local function get_gem_description(itemstack)
local current_target = math.max(meta:get_int("density_target"), 1) local current_target = math.max(meta:get_int("density_target"), 1)
local target_message = "Target: "..ItemStack(exchangeclone.density_targets[current_target]):get_short_description() local target_message = "Target: "..ItemStack(exchangeclone.density_targets[current_target]):get_short_description()
local emc = exchangeclone.get_item_emc(itemstack:get_name()) local emc = exchangeclone.get_item_emc(itemstack:get_name())
local stored = exchangeclone.get_item_emc(itemstack) - emc local stored = itemstack:_get_emc() - emc
return "Gem of Eternal Density\n"..target_message.."\nEMC: "..exchangeclone.format_number(emc).."\nStored EMC: "..exchangeclone.format_number(stored) return "Gem of Eternal Density\n"..target_message.."\nEMC: "..exchangeclone.format_number(emc).."\nStored EMC: "..exchangeclone.format_number(stored)
end end
@ -24,7 +24,7 @@ local function condense(player, itemstack)
local min = player:hud_get_hotbar_itemcount() + 1 local min = player:hud_get_hotbar_itemcount() + 1
if player:get_wield_index() >= min then return end if player:get_wield_index() >= min then return end
local total_emc = exchangeclone.get_item_emc(itemstack) - exchangeclone.get_item_emc(itemstack:get_name()) local total_emc = itemstack:_get_emc() - exchangeclone.get_item_emc(itemstack:get_name())
local target = exchangeclone.density_targets[math.max(meta:get_int("density_target"), 1)] local target = exchangeclone.density_targets[math.max(meta:get_int("density_target"), 1)]
local filter local filter
local current_mode = player:get_meta():get_string("exchangeclone_goed_filter_type") local current_mode = player:get_meta():get_string("exchangeclone_goed_filter_type")
@ -45,7 +45,7 @@ local function condense(player, itemstack)
for i = min, #list do for i = min, #list do
local stack = list[i] local stack = list[i]
if filter(stack) and stack:get_name() ~= target then if filter(stack) and stack:get_name() ~= target then
local emc = exchangeclone.get_item_emc(stack) or 0 local emc = stack:_get_emc() or 0
local individual_emc = exchangeclone.get_item_emc(stack:get_name()) or 0 local individual_emc = exchangeclone.get_item_emc(stack:get_name()) or 0
if individual_emc > 0 and individual_emc <= exchangeclone.get_item_emc(target) then if individual_emc > 0 and individual_emc <= exchangeclone.get_item_emc(target) then
total_emc = total_emc + emc total_emc = total_emc + emc
@ -85,7 +85,7 @@ local function condense(player, itemstack)
if meta:get_string("exchangeclone_active") ~= "true" then if meta:get_string("exchangeclone_active") ~= "true" then
exchangeclone.play_sound(player, "exchangeclone_enable") exchangeclone.play_sound(player, "exchangeclone_enable")
end end
meta:set_int("exchangeclone_emc_value", exchangeclone.get_item_emc(itemstack:get_name()) + remainder_emc) meta:set_string("exchangeclone_emc_value", exchangeclone.get_item_emc(itemstack:get_name()) + remainder_emc)
meta:set_string("description", get_gem_description(itemstack)) meta:set_string("description", get_gem_description(itemstack))
return itemstack return itemstack
end end
@ -138,7 +138,7 @@ minetest.register_on_joinplayer(function(joining_player)
minetest.create_detached_inventory(inv_name, { minetest.create_detached_inventory(inv_name, {
allow_put = function(inv, listname, index, stack, player) allow_put = function(inv, listname, index, stack, player)
if player:get_player_name() ~= joining_player:get_player_name() then return 0 end if player:get_player_name() ~= joining_player:get_player_name() then return 0 end
local emc = exchangeclone.get_item_emc(stack) local emc = stack:_get_emc()
if emc <= 0 or not emc then return 0 end if emc <= 0 or not emc then return 0 end
local stack_copy = ItemStack(stack) local stack_copy = ItemStack(stack)
stack_copy:set_count(1) stack_copy:set_count(1)

View File

@ -9,7 +9,7 @@ local function infinite_food_function(itemstack, player, pointed_thing)
if click_test ~= false then if click_test ~= false then
return click_test return click_test
end end
local player_emc = exchangeclone.get_player_emc(player) local player_emc = player:_get_emc()
if player_emc >= 64 then if player_emc >= 64 then
if stamina_exists then if stamina_exists then
if stamina.get_saturation(player) >= stamina_max then if stamina.get_saturation(player) >= stamina_max then
@ -37,9 +37,8 @@ minetest.register_tool("exchangeclone:infinite_food", {
}) })
minetest.register_on_item_eat(function(hp_change, replace_with_item, itemstack, player, pointed_thing) minetest.register_on_item_eat(function(hp_change, replace_with_item, itemstack, player, pointed_thing)
local player_emc = exchangeclone.get_player_emc(player)
if itemstack:get_name() == "exchangeclone:infinite_food" then if itemstack:get_name() == "exchangeclone:infinite_food" then
exchangeclone.set_player_emc(player, player_emc - 64) player:_add_emc(-64)
end end
end) end)

View File

@ -29,7 +29,7 @@ for i, name in ipairs(names) do
_mcl_generate_description = function(itemstack) _mcl_generate_description = function(itemstack)
return name.."\n"..S( return name.."\n"..S(
"Current Charge: @1/@2", "Current Charge: @1/@2",
exchangeclone.format_number(exchangeclone.get_star_itemstack_emc(itemstack)), exchangeclone.format_number(itemstack:_get_star_emc()),
exchangeclone.format_number(capacity) exchangeclone.format_number(capacity)
) )
end end

View File

@ -32,9 +32,9 @@ minetest.register_tool("exchangeclone:soul_stone", {
inventory_image = "exchangeclone_soul_stone.png", inventory_image = "exchangeclone_soul_stone.png",
_exchangeclone_passive = { _exchangeclone_passive = {
func = function(player) func = function(player)
if exchangeclone.get_player_emc(player) >= 64 then if player:_get_emc() >= 64 then
if heal(player, 2) then if heal(player, 2) then
exchangeclone.add_player_emc(player, -64) player:_add_emc(-64)
end end
end end
end, end,
@ -68,9 +68,9 @@ if (exchangeclone.mcl and mcl_hunger.active) or (exchangeclone.mtg and minetest.
inventory_image = "exchangeclone_body_stone.png", inventory_image = "exchangeclone_body_stone.png",
_exchangeclone_passive = { _exchangeclone_passive = {
func = function(player) func = function(player)
if exchangeclone.get_player_emc(player) >= 64 then if player:_get_emc() >= 64 then
if satiate(player, 2) then if satiate(player, 2) then
exchangeclone.add_player_emc(player, -64) player:_add_emc(-64)
end end
end end
end, end,
@ -105,7 +105,7 @@ if (exchangeclone.mcl and mcl_hunger.active) or (exchangeclone.mtg and minetest.
inventory_image = "exchangeclone_life_stone.png", inventory_image = "exchangeclone_life_stone.png",
_exchangeclone_passive = { _exchangeclone_passive = {
func = function(player) func = function(player)
if exchangeclone.get_player_emc(player) >= 64 then if player:_get_emc() >= 64 then
local changed local changed
if heal(player, 2) then if heal(player, 2) then
changed = true changed = true
@ -114,7 +114,7 @@ if (exchangeclone.mcl and mcl_hunger.active) or (exchangeclone.mtg and minetest.
changed = true changed = true
end end
if changed then if changed then
exchangeclone.add_player_emc(player, -64) player:_add_emc(-64)
end end
end end
end, end,
@ -145,7 +145,7 @@ if exchangeclone.mcl then
local function get_mind_description(itemstack) local function get_mind_description(itemstack)
local meta = itemstack:get_meta() local meta = itemstack:get_meta()
local emc = exchangeclone.get_item_emc(itemstack) or 0 local emc = itemstack:_get_emc() or 0
local stored = meta:get_int("exchangeclone_stored_xp") or 0 local stored = meta:get_int("exchangeclone_stored_xp") or 0
return "Mind Stone\nEMC: "..exchangeclone.format_number(emc).."\nStored XP: "..exchangeclone.format_number(stored) return "Mind Stone\nEMC: "..exchangeclone.format_number(emc).."\nStored XP: "..exchangeclone.format_number(stored)
end end

View File

@ -71,7 +71,7 @@ local function pickaxe_on_use(itemstack, player, pointed_thing)
elseif itemstack:get_name():find("red_") then elseif itemstack:get_name():find("red_") then
local result = exchangeclone.place_torch(player, pointed_thing) local result = exchangeclone.place_torch(player, pointed_thing)
if result then if result then
exchangeclone.add_player_emc(player, result) player:_add_emc(result)
-- If the torch could not be placed, it still costs EMC... not sure how to fix that -- If the torch could not be placed, it still costs EMC... not sure how to fix that
end end
end end

View File

@ -179,9 +179,11 @@ local function morningstar_on_use(itemstack, player, pointed_thing)
elseif minetest.get_item_group(name, exchangeclone.pickaxe_group) > 0 and sneaking then elseif minetest.get_item_group(name, exchangeclone.pickaxe_group) > 0 and sneaking then
exchangeclone.hammer_action(itemstack, player, pointed_thing.under) exchangeclone.hammer_action(itemstack, player, pointed_thing.under)
else else
exchangeclone.place_torch(player, pointed_thing) local result = exchangeclone.place_torch(player, pointed_thing)
exchangeclone.add_player_emc(player, -math.max(exchangeclone.get_item_emc(exchangeclone.itemstrings.torch) or 8, 8)) if result then
-- If the torch could not be placed, it still costs EMC... not sure how to fix that player:_add_emc(result)
-- If the torch could not be placed, it still costs EMC... not sure how to fix that
end
return return
end end
elseif sneaking then elseif sneaking then

View File

@ -115,7 +115,7 @@ end
exchangeclone.emc_values = {} exchangeclone.emc_values = {}
-- Sets the EMC value of an item, must be called during load time. -- Sets the EMC value of an item, must be called during load time.
local function set_item_emc(itemstring, emc_value) local function register_emc(itemstring, emc_value)
if not (emc_value and itemstring) then return end if not (emc_value and itemstring) then return end
emc_value = math.floor(emc_value*20)/20 -- floor to nearest .05 emc_value = math.floor(emc_value*20)/20 -- floor to nearest .05
if emc_value < 0 then return end if emc_value < 0 then return end
@ -297,19 +297,19 @@ end
local grouped_items = exchangeclone.get_group_items(groupnames, true, true) local grouped_items = exchangeclone.get_group_items(groupnames, true, true)
for index, group in ipairs(exchangeclone.group_values) do for index, group in ipairs(exchangeclone.group_values) do
for i, item in pairs(grouped_items[group[1]]) do for i, item in pairs(grouped_items[group[1]]) do
set_item_emc(item, group[2]) register_emc(item, group[2])
end end
end end
-- Register base EMC values -- Register base EMC values
for itemstring, emc_value in pairs(exchangeclone.base_emc_values) do for itemstring, emc_value in pairs(exchangeclone.base_emc_values) do
set_item_emc(itemstring, emc_value) register_emc(itemstring, emc_value)
end end
-- Register `exchangeclone_custom_emc` values and decide whether to automatically register EMC values -- Register `exchangeclone_custom_emc` values and decide whether to automatically register EMC values
for itemstring, def in pairs(minetest.registered_items) do for itemstring, def in pairs(minetest.registered_items) do
if def.exchangeclone_custom_emc then if def.exchangeclone_custom_emc then
set_item_emc(itemstring, def.exchangeclone_custom_emc) register_emc(itemstring, def.exchangeclone_custom_emc)
else else
itemstring = exchangeclone.handle_alias(itemstring) or itemstring itemstring = exchangeclone.handle_alias(itemstring) or itemstring
def = minetest.registered_items[itemstring] -- in case itemstring changed def = minetest.registered_items[itemstring] -- in case itemstring changed
@ -364,7 +364,7 @@ while not same do
for itemstring, _ in pairs(auto) do for itemstring, _ in pairs(auto) do
local cheapest = get_cheapest_recipe(itemstring) local cheapest = get_cheapest_recipe(itemstring)
if cheapest then if cheapest then
set_item_emc(itemstring, cheapest) register_emc(itemstring, cheapest)
auto[itemstring] = nil auto[itemstring] = nil
end end
end end
@ -372,8 +372,8 @@ while not same do
end end
if exchangeclone.mcl then if exchangeclone.mcl then
set_item_emc("mcl_campfires:campfire", exchangeclone.get_item_emc("mcl_campfires:campfire_lit")) register_emc("mcl_campfires:campfire", exchangeclone.get_item_emc("mcl_campfires:campfire_lit"))
set_item_emc("mcl_campfires:soul_campfire", exchangeclone.get_item_emc("mcl_campfires:soul_campfire_lit")) register_emc("mcl_campfires:soul_campfire", exchangeclone.get_item_emc("mcl_campfires:soul_campfire_lit"))
-- Recovery compasses use a random compass frame for the crafting recipe... Incredibly irritating. -- Recovery compasses use a random compass frame for the crafting recipe... Incredibly irritating.
for i = 0, 31 do for i = 0, 31 do
if exchangeclone.get_item_emc("mcl_compass:"..i.."_recovery") then if exchangeclone.get_item_emc("mcl_compass:"..i.."_recovery") then
@ -404,12 +404,12 @@ local cheapest_advanced_itemstring = "exchangeclone:advanced_alchemical_chest_".
for color, color_data in pairs(exchangeclone.colors) do for color, color_data in pairs(exchangeclone.colors) do
local advanced_itemstring = "exchangeclone:advanced_alchemical_chest_"..color local advanced_itemstring = "exchangeclone:advanced_alchemical_chest_"..color
set_item_emc(advanced_itemstring, exchangeclone.get_item_emc(cheapest_advanced_itemstring)) register_emc(advanced_itemstring, exchangeclone.get_item_emc(cheapest_advanced_itemstring))
end end
-- Adds EMC values to aliased items, even though they're not used (just so it's displayed) -- Adds EMC values to aliased items, even though they're not used (just so it's displayed)
for alias, itemstring in pairs(exchangeclone.emc_aliases) do for alias, itemstring in pairs(exchangeclone.emc_aliases) do
set_item_emc(itemstring, exchangeclone.get_item_emc(alias)) register_emc(itemstring, exchangeclone.get_item_emc(alias))
end end
-- Delete unnecessary data (waste of memory) -- Delete unnecessary data (waste of memory)

View File

@ -75,9 +75,9 @@ local function upgrader_action(pos)
local new_tool = exchangeclone.enchant(tool, upgrade_def.enchantment, upgrade_def.level) local new_tool = exchangeclone.enchant(tool, upgrade_def.enchantment, upgrade_def.level)
if not new_tool then return end -- If the tool already has that enchantment if not new_tool then return end -- If the tool already has that enchantment
local new_emc = exchangeclone.get_item_emc(new_tool) + exchangeclone.get_item_emc(upgrade:get_name()) local new_emc = new_tool:_get_emc() + exchangeclone.get_item_emc(upgrade:get_name())
new_tool:get_meta():set_int("exchangeclone_emc_value", new_emc) new_tool:get_meta():set_string("exchangeclone_emc_value", new_emc)
inv:set_stack("dst", 1, new_tool) inv:set_stack("dst", 1, new_tool)

View File

@ -16,7 +16,7 @@ local function get_amount_label(itemstring, player_emc)
end end
local function get_transmutation_buttons(player, page, x, y) local function get_transmutation_buttons(player, page, x, y)
local player_emc = exchangeclone.get_player_emc(player) local player_emc = player:_get_emc()
local pages = minetest.deserialize(player:get_meta():get_string("exchangeclone_transmutation")) or {} local pages = minetest.deserialize(player:get_meta():get_string("exchangeclone_transmutation")) or {}
if page < 1 then page = 1 end if page < 1 then page = 1 end
if not pages[1] then if not pages[1] then
@ -52,7 +52,7 @@ end
function exchangeclone.reload_transmutation_list(player, search) function exchangeclone.reload_transmutation_list(player, search)
local meta = player:get_meta() local meta = player:get_meta()
local player_emc = exchangeclone.get_player_emc(player) local player_emc = player:_get_emc()
local items_to_show = minetest.deserialize(meta:get_string("exchangeclone_transmutation_learned_items")) or {} local items_to_show = minetest.deserialize(meta:get_string("exchangeclone_transmutation_learned_items")) or {}
local lang = minetest.get_player_information(player:get_player_name()).lang_code local lang = minetest.get_player_information(player:get_player_name()).lang_code
local pages = {} local pages = {}
@ -102,13 +102,13 @@ local function add_to_output(player, amount, show)
if minetest.registered_items[item] then if minetest.registered_items[item] then
local emc_value = exchangeclone.get_item_emc(item) local emc_value = exchangeclone.get_item_emc(item)
if not emc_value then return end if not emc_value then return end
local player_emc = exchangeclone.get_player_emc(player) local player_emc = player:_get_emc()
local stack_max = ItemStack(item):get_stack_max() local stack_max = ItemStack(item):get_stack_max()
if amount == true then amount = stack_max end if amount == true then amount = stack_max end
local max_amount = math.min(amount, stack_max, math.floor(player_emc/emc_value)) local max_amount = math.min(amount, stack_max, math.floor(player_emc/emc_value))
local inventory = minetest.get_inventory({type = "detached", name = "exchangeclone_transmutation_"..player:get_player_name()}) local inventory = minetest.get_inventory({type = "detached", name = "exchangeclone_transmutation_"..player:get_player_name()})
local added_amount = max_amount - inventory:add_item("output", ItemStack(item.." "..max_amount)):get_count() local added_amount = max_amount - inventory:add_item("output", ItemStack(item.." "..max_amount)):get_count()
exchangeclone.add_player_emc(player, math.min(player_emc, -(emc_value * added_amount))) -- not sure if "math.min()" is necessary player:_add_emc(math.min(player_emc, -(emc_value * added_amount))) -- not sure if "math.min()" is necessary
if show then exchangeclone.show_transmutation_table_formspec(player) end if show then exchangeclone.show_transmutation_table_formspec(player) end
end end
end end
@ -134,16 +134,16 @@ local function handle_inventory(player, inventory, to_list)
player:get_meta():set_string("exchangeclone_transmutation_learned_items", minetest.serialize(list)) player:get_meta():set_string("exchangeclone_transmutation_learned_items", minetest.serialize(list))
inventory:set_stack(to_list, 1, nil) inventory:set_stack(to_list, 1, nil)
else else
local individual_emc_value = exchangeclone.get_item_emc(single_item) local individual_emc_value = single_item:_get_emc()
if not individual_emc_value or individual_emc_value <= 0 then return end if not individual_emc_value or individual_emc_value <= 0 then return end
local player_emc = exchangeclone.get_player_emc(player) local player_emc = player:_get_emc()
-- How many items can be added? -- How many items can be added?
local max_count = math.floor((exchangeclone.limit - player_emc)/individual_emc_value) local max_count = math.floor((exchangeclone.limit - player_emc)/individual_emc_value)
-- How many items will be added? -- How many items will be added?
local add_count = math.min(max_count, stack:get_count()) local add_count = math.min(max_count, stack:get_count())
-- How much EMC is that? -- How much EMC is that?
local emc_value = individual_emc_value * add_count local emc_value = individual_emc_value * add_count
exchangeclone.add_player_emc(player, emc_value) player:_add_emc(emc_value)
local item_index = table.indexof(list, itemstring) local item_index = table.indexof(list, itemstring)
if item_index == -1 then if item_index == -1 then
list[#list+1] = itemstring list[#list+1] = itemstring
@ -158,11 +158,11 @@ local function handle_inventory(player, inventory, to_list)
elseif to_list == "forget" then elseif to_list == "forget" then
return return
elseif to_list == "charge" then elseif to_list == "charge" then
local player_emc = exchangeclone.get_player_emc(player) local player_emc = player:_get_emc()
local star_emc = exchangeclone.get_star_itemstack_emc(stack) local star_emc = stack:_get_star_emc()
local charge_amount = math.min(exchangeclone.get_star_max(stack) - star_emc, player_emc) local charge_amount = math.min(exchangeclone.get_star_max(stack) - star_emc, player_emc)
if charge_amount > 0 then if charge_amount > 0 then
exchangeclone.add_player_emc(player, -charge_amount) player:_add_emc(-charge_amount)
exchangeclone.add_star_emc(inventory, to_list, 1, charge_amount) exchangeclone.add_star_emc(inventory, to_list, 1, charge_amount)
exchangeclone.show_transmutation_table_formspec(player) exchangeclone.show_transmutation_table_formspec(player)
end end
@ -223,7 +223,7 @@ end
function exchangeclone.show_transmutation_table_formspec(player, data) function exchangeclone.show_transmutation_table_formspec(player, data)
exchangeclone.reload_transmutation_list(player, data and data.search) exchangeclone.reload_transmutation_list(player, data and data.search)
if not data then data = {} end if not data then data = {} end
local player_emc = exchangeclone.get_player_emc(player) local player_emc = player:_get_emc()
local selection = data.selection or player:get_meta():get_string("exchangeclone_transmutation_selection") local selection = data.selection or player:get_meta():get_string("exchangeclone_transmutation_selection")
local player_name = player:get_player_name() local player_name = player:get_player_name()
local inventory_name = "detached:exchangeclone_transmutation_"..player_name local inventory_name = "detached:exchangeclone_transmutation_"..player_name
@ -416,7 +416,7 @@ minetest.register_craft_predict(function(itemstack, player, old_craft_grid, craf
if itemstack == ItemStack("exchangeclone:tome_of_knowledge") then if itemstack == ItemStack("exchangeclone:tome_of_knowledge") then
for _, i in pairs({4,6}) do for _, i in pairs({4,6}) do
local stack = old_craft_grid[i] local stack = old_craft_grid[i]
if exchangeclone.get_star_itemstack_emc(stack) < exchangeclone.get_star_max(stack) then if stack:_get_star_emc() < stack:_get_star_max() then
return ItemStack("") return ItemStack("")
end end
end end

View File

@ -1,3 +1,4 @@
name = exchangeclone name = exchangeclone
title = ExchangeClone title = ExchangeClone
description = Equivalent Exchange/ProjectE for Minetest Game and MineClone! Turn items into EMC and EMC into items, craft OP tools and armor, and more! description = Equivalent Exchange/ProjectE for Minetest Game and MineClone! Turn items into EMC and EMC into items, craft OP tools and armor, and more!
optional_depends = default, mcl_core, technic, ethereal, why_init, nether, mobs

View File

@ -1,4 +1,4 @@
Keep unnecessary temporary data (such as the list of recipes) after load time for debugging purposes. # Keep unnecessary temporary data (such as the list of recipes) after load time for debugging purposes.
exchangeclone.keep_data (Keep temporary data after loading) bool false exchangeclone.keep_data (Keep temporary data after loading) bool false
# Allow the crafting recipe for the Tome of Knowledge # Allow the crafting recipe for the Tome of Knowledge

View File

@ -1,7 +1,7 @@
-- A ton of functions with approximately zero organization. At least there are comments now. -- A ton of functions with approximately zero organization. At least there are comments now.
local S = minetest.get_translator() local S = minetest.get_translator()
local exchangeclone = exchangeclone --local exchangeclone = exchangeclone
--- Rounds to the nearest integer --- Rounds to the nearest integer
function exchangeclone.round(num) function exchangeclone.round(num)
@ -71,7 +71,7 @@ function exchangeclone.get_item_emc(item)
end end
-- Only check metadata for ItemStacks -- Only check metadata for ItemStacks
if type(item) == "userdata" then if getmetatable(item) == getmetatable(ItemStack()) then
local meta_emc_value = item:get_meta():get_string("exchangeclone_emc_value") local meta_emc_value = item:get_meta():get_string("exchangeclone_emc_value")
if meta_emc_value == "none" then if meta_emc_value == "none" then
return 0 return 0
@ -89,7 +89,7 @@ function exchangeclone.get_item_emc(item)
if not def then return end if not def then return end
if minetest.get_item_group(item:get_name(), "klein_star") > 0 then if minetest.get_item_group(item:get_name(), "klein_star") > 0 then
if def.emc_value then if def.emc_value then
return def.emc_value + exchangeclone.get_star_itemstack_emc(item) return def.emc_value + item:_get_star_emc()
end end
end end
if def.emc_value then if def.emc_value then
@ -97,6 +97,26 @@ function exchangeclone.get_item_emc(item)
end end
end end
function exchangeclone.set_item_meta_emc(item, value)
if getmetatable(item) ~= getmetatable(ItemStack()) then
return
end
item:get_meta():set_string("exchangeclone_emc_value", value)
end
function exchangeclone.add_item_meta_emc(item, value)
if getmetatable(item) ~= getmetatable(ItemStack()) then
return
end
local current_value = item:get_meta():get_string("exchangeclone_emc_value", value)
if current_value == "" or current_value == "none" then
current_value = 0
else
current_value = tonumber(current_value)
end
item:get_meta():set_string("exchangeclone_emc_value", current_value + value)
end
-- https://forum.unity.com/threads/re-map-a-number-from-one-range-to-another.119437/ -- https://forum.unity.com/threads/re-map-a-number-from-one-range-to-another.119437/
-- Remaps a number from one range to another -- Remaps a number from one range to another
function exchangeclone.map(input, min1, max1, min2, max2) function exchangeclone.map(input, min1, max1, min2, max2)
@ -106,6 +126,9 @@ end
-- Gets the EMC stored in a specified Klein/Magnum Star itemstack. -- Gets the EMC stored in a specified Klein/Magnum Star itemstack.
function exchangeclone.get_star_itemstack_emc(itemstack) function exchangeclone.get_star_itemstack_emc(itemstack)
if not itemstack then return end if not itemstack then return end
if getmetatable(itemstack) ~= getmetatable(ItemStack()) then
return
end
if minetest.get_item_group(itemstack:get_name(), "klein_star") < 1 then return end if minetest.get_item_group(itemstack:get_name(), "klein_star") < 1 then return end
return math.max(itemstack:get_meta():get_float("stored_energy"), 0) return math.max(itemstack:get_meta():get_float("stored_energy"), 0)
end end
@ -116,13 +139,13 @@ function exchangeclone.get_star_emc(inventory, listname, index)
if not listname then listname = "main" end if not listname then listname = "main" end
if not index then index = 1 end if not index then index = 1 end
local itemstack = inventory:get_stack(listname, index) local itemstack = inventory:get_stack(listname, index)
return exchangeclone.get_star_itemstack_emc(itemstack) return itemstack:get_star_emc()
end end
function exchangeclone.set_star_itemstack_emc(itemstack, amount) function exchangeclone.set_star_itemstack_emc(itemstack, amount)
if not itemstack or not amount then return end if not itemstack or not amount then return end
if minetest.get_item_group(itemstack:get_name(), "klein_star") < 1 then return end if minetest.get_item_group(itemstack:get_name(), "klein_star") < 1 then return end
local old_emc = exchangeclone.get_star_itemstack_emc(itemstack) local old_emc = itemstack:get_star_emc()
local max = exchangeclone.get_star_max(itemstack) local max = exchangeclone.get_star_max(itemstack)
if amount > old_emc and old_emc > max then return end -- don't allow more EMC to be put into an over-filled star if amount > old_emc and old_emc > max then return end -- don't allow more EMC to be put into an over-filled star
@ -131,7 +154,6 @@ function exchangeclone.set_star_itemstack_emc(itemstack, amount)
meta:set_string("description", itemstack:get_definition()._mcl_generate_description(itemstack)) meta:set_string("description", itemstack:get_definition()._mcl_generate_description(itemstack))
local wear = math.max(1, math.min(65535, 65535 - 65535*amount/max)) local wear = math.max(1, math.min(65535, 65535 - 65535*amount/max))
itemstack:set_wear(wear) itemstack:set_wear(wear)
return itemstack
end end
-- Sets the amount of EMC in a star in a specific inventory slot -- Sets the amount of EMC in a star in a specific inventory slot
@ -140,16 +162,15 @@ function exchangeclone.set_star_emc(inventory, listname, index, amount)
if not listname then listname = "main" end if not listname then listname = "main" end
if not index then index = 1 end if not index then index = 1 end
local itemstack = inventory:get_stack(listname, index) local itemstack = inventory:get_stack(listname, index)
local new_stack = exchangeclone.set_star_itemstack_emc(itemstack, amount) itemstack:_set_star_emc(amount)
if not new_stack then return end inventory:set_stack(listname, index, itemstack)
inventory:set_stack(listname, index, new_stack)
end end
function exchangeclone.add_star_itemstack_emc(itemstack, amount) function exchangeclone.add_star_itemstack_emc(itemstack, amount)
if itemstack and amount then if itemstack and amount then
local emc = exchangeclone.get_star_itemstack_emc(itemstack) + amount local emc = itemstack:get_star_emc() + amount
if not emc or emc < 0 or emc > exchangeclone.get_star_max(itemstack) then return end if not emc or emc < 0 or emc > exchangeclone.get_star_max(itemstack) then return end
return exchangeclone.set_star_itemstack_emc(itemstack, emc) itemstack:_set_star_emc(itemstack, emc)
end end
end end
@ -159,9 +180,8 @@ function exchangeclone.add_star_emc(inventory, listname, index, amount)
if not listname then listname = "main" end if not listname then listname = "main" end
if not index then index = 1 end if not index then index = 1 end
local itemstack = inventory:get_stack(listname, index) local itemstack = inventory:get_stack(listname, index)
local new_stack = exchangeclone.add_star_itemstack_emc(itemstack, amount) exchangeclone.add_star_itemstack_emc(itemstack, amount)
if not new_stack then return end inventory:set_stack(listname, index, itemstack)
inventory:set_stack(listname, index, new_stack)
end end
function exchangeclone.get_star_max(item) function exchangeclone.get_star_max(item)
@ -212,7 +232,7 @@ end
-- Add to a player's personal EMC (amount can be negative) -- Add to a player's personal EMC (amount can be negative)
function exchangeclone.add_player_emc(player, amount) function exchangeclone.add_player_emc(player, amount)
if not (player and amount) then return end if not (player and amount) then return end
exchangeclone.set_player_emc(player, (exchangeclone.get_player_emc(player) or 0) + amount) player:_set_emc((player:_get_emc() or 0) + amount)
end end
-- Through trial and error, I have found that this number (1 trillion) works the best. -- Through trial and error, I have found that this number (1 trillion) works the best.
@ -641,12 +661,12 @@ minetest.register_chatcommand("add_player_emc", {
minetest.chat_send_player(name, "Bad command. Use /add_player_emc [player] [value] or /add_player_emc [value]") minetest.chat_send_player(name, "Bad command. Use /add_player_emc [player] [value] or /add_player_emc [value]")
return return
end end
local emc = exchangeclone.get_player_emc(target_player) local emc = target_player:_get_emc()
if (emc + value > exchangeclone.limit) or (emc + value < 0) then if (emc + value > exchangeclone.limit) or (emc + value < 0) then
minetest.chat_send_player(name, "Out of bounds; personal EMC must be between 0 and 1 trillion.") minetest.chat_send_player(name, "Out of bounds; personal EMC must be between 0 and 1 trillion.")
return return
end end
exchangeclone.add_player_emc(target_player, tonumber(value)) target_player:_add_emc(tonumber(value))
minetest.chat_send_player(name, "Added "..exchangeclone.format_number(value).." to "..target_name.."'s personal EMC.") minetest.chat_send_player(name, "Added "..exchangeclone.format_number(value).." to "..target_name.."'s personal EMC.")
end end
}) })
@ -669,7 +689,7 @@ minetest.register_chatcommand("get_player_emc", {
minetest.chat_send_player(name, "Bad command. Use /get_player_emc [player] or /get_player_emc") minetest.chat_send_player(name, "Bad command. Use /get_player_emc [player] or /get_player_emc")
return return
end end
local emc = exchangeclone.get_player_emc(target_player) local emc = target_player:_get_emc()
minetest.chat_send_player(name, target_name.."'s personal EMC: "..exchangeclone.format_number(emc)) minetest.chat_send_player(name, target_name.."'s personal EMC: "..exchangeclone.format_number(emc))
end end
}) })
@ -702,7 +722,7 @@ minetest.register_chatcommand("set_player_emc", {
minetest.chat_send_player(name, "Failed to set EMC; must be between 0 and 1 trillion.") minetest.chat_send_player(name, "Failed to set EMC; must be between 0 and 1 trillion.")
return return
end end
exchangeclone.set_player_emc(target_player, tonumber(value)) target_player:_set_emc(tonumber(value))
minetest.chat_send_player(name, "Set "..target_name.."'s personal EMC to "..exchangeclone.format_number(value)) minetest.chat_send_player(name, "Set "..target_name.."'s personal EMC to "..exchangeclone.format_number(value))
end end
}) })
@ -1198,7 +1218,7 @@ end
function exchangeclone.place_torch(player, pointed_thing) function exchangeclone.place_torch(player, pointed_thing)
local torch_cost = math.max(exchangeclone.get_item_emc(exchangeclone.itemstrings.torch) or 0, 8) local torch_cost = math.max(exchangeclone.get_item_emc(exchangeclone.itemstrings.torch) or 0, 8)
if exchangeclone.get_player_emc(player) >= torch_cost then if player:_get_emc() >= torch_cost then
local torch_on_place = minetest.registered_items[exchangeclone.itemstrings.torch].on_place local torch_on_place = minetest.registered_items[exchangeclone.itemstrings.torch].on_place
if torch_on_place then if torch_on_place then
torch_on_place(ItemStack(exchangeclone.itemstrings.torch), player, pointed_thing) torch_on_place(ItemStack(exchangeclone.itemstrings.torch), player, pointed_thing)
@ -1267,4 +1287,26 @@ function exchangeclone.toggle_active(itemstack, player, pointed_thing)
meta:set_string("inventory_image", "") meta:set_string("inventory_image", "")
end end
return itemstack return itemstack
end end
local item_metatable = getmetatable(ItemStack())
item_metatable._get_emc = exchangeclone.get_item_emc
item_metatable._set_emc = exchangeclone.set_item_meta_emc
item_metatable._add_emc = exchangeclone.add_item_meta_emc
item_metatable._get_star_emc = exchangeclone.get_star_itemstack_emc
item_metatable._set_star_emc = exchangeclone.set_star_itemstack_emc
item_metatable._add_star_emc = exchangeclone.add_star_itemstack_emc
item_metatable._get_star_max = exchangeclone.get_star_max
local updated_metatable = false
minetest.register_on_joinplayer(function(player)
if not updated_metatable then
local player_metatable = getmetatable(player)
player_metatable._get_emc = exchangeclone.get_player_emc
player_metatable._set_emc = exchangeclone.set_player_emc
player_metatable._add_emc = exchangeclone.add_player_emc
updated_metatable = true
end
end)