Compare commits

...

3 Commits

Author SHA1 Message Date
ThePython e456cf5c96 Finished BHB (minus pedestal) 2024-03-05 07:49:56 -08:00
ThePython 16f5085932 Fix amulet issues 2024-03-05 07:30:11 -08:00
ThePython a64e38e4af Added amulets, started black hole band 2024-03-04 16:41:27 -08:00
16 changed files with 284 additions and 27 deletions

View File

@ -1,16 +0,0 @@
{
"type": "MOD",
"title": "ExchangeClone",
"name": "exchangeclone",
"tags": [
"magic",
"technology"
],
"license": "GPL-3.0-or-later",
"media_license": "GPL-3.0-or-later",
"short_description": "Exchange nodes into other nodes",
"dev_state": "ACTIVELY_DEVELOPED",
"repo": "https://github.com/thepython10110/exchangeclone",
"website": "https://thepython10110.github.io",
"issue_tracker": "https://github.com/thepython10110/exchangeclone/issues"
}

View File

@ -59,7 +59,7 @@ Dependencies: Minetest Game or MineClone.
* Also includes some features from ProjectExpansion, an expansion to ProjectE (MIT).
* Code: GPLv3+
* 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+)
* Some code copied/modified from other places, of course, but not large amounts and not closed-source projects. Sometimes I remember to give credit, sometimes I don't.
* Textures:
* Upgrader and Upgrades: Created by me (CC-BY-SA-3.0)
* Energy Collectors:
@ -84,8 +84,8 @@ You can find the old textures and sounds by going back to previous commits in Gi
- [x] Add more matter/fuel types
- [x] Make collectors less expensive and less effective (gold instead of glowstone)
- [x] Make collectors use ProjectExpansion's textures
- [ ] Add Evertide Amulet
- [ ] Add Volcanite Amulet
- [x] Add Evertide Amulet
- [x] Add Volcanite Amulet
- [ ] Add Zero Ring
- [ ] Add Ring of Ignition
- [ ] Add Black Hole Band (without bag functionality)
@ -94,8 +94,8 @@ You can find the old textures and sounds by going back to previous commits in Gi
- [ ] Add Pedestal abilities
- [x] Passive Stones
- [x] Talisman
- [ ] Evertide (MCL)
- [ ] Volcanite (MCL)
- [x] Evertide
- [x] Volcanite
- [ ] Zero
- [ ] Ignition
- [ ] Black Hole/Void
@ -118,6 +118,10 @@ You can find the old textures and sounds by going back to previous commits in Gi
* 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.
* Added Evertide/Volcanite Amulets
* Projectiles do not work in Mineclonia.
* The "Buckets use select box" (`mcl_buckets_use_select_box`) setting must be enabled to use projectiles in MineClone2.
* Pedestal abilities use the "Weather" mod (the one by theFox) in Minetest Game
* Changes:
* The Constructor and Deconstructor are now deprecated, replaced with the EMC Link.
* Upgrades and Stars can no longer be used as fuel.

View File

@ -273,6 +273,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end)
local function alchemical_book_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
local use_stack_data = itemstack:get_meta():get_int("exchangeclone_use_stack_data")
if use_stack_data == 0 then
use_stack_data = nil
@ -294,7 +299,7 @@ end
minetest.register_tool("exchangeclone:basic_alchemical_book", {
description = "Basic Alchemical Book\n1000 EMC/node\nCannot travel between dimensions",
inventory_image = "exchangeclone_basic_alchemical_book.png",
groups = {exchangeclone_alchemical_book = 1},
groups = {exchangeclone_alchemical_book = 1, disable_repair = 1},
alchemical_book_data = {emc_per_node = 1000, dimension_lock = true},
on_secondary_use = alchemical_book_function,
on_place = alchemical_book_function
@ -303,7 +308,7 @@ minetest.register_tool("exchangeclone:basic_alchemical_book", {
minetest.register_tool("exchangeclone:advanced_alchemical_book", {
description = "Advanced Alchemical Book\n500 EMC/node",
inventory_image = "exchangeclone_advanced_alchemical_book.png",
groups = {exchangeclone_alchemical_book = 1},
groups = {exchangeclone_alchemical_book = 1, disable_repair = 1},
alchemical_book_data = {emc_per_node = 500},
on_secondary_use = alchemical_book_function,
on_place = alchemical_book_function
@ -312,7 +317,7 @@ minetest.register_tool("exchangeclone:advanced_alchemical_book", {
minetest.register_tool("exchangeclone:master_alchemical_book", {
description = "Master Alchemical Book\n100 EMC/node.",
inventory_image = "exchangeclone_master_alchemical_book.png",
groups = {exchangeclone_alchemical_book = 1},
groups = {exchangeclone_alchemical_book = 1, disable_repair = 1},
alchemical_book_data = {emc_per_node = 100},
on_secondary_use = alchemical_book_function,
on_place = alchemical_book_function
@ -321,7 +326,7 @@ minetest.register_tool("exchangeclone:master_alchemical_book", {
minetest.register_tool("exchangeclone:arcane_alchemical_book", {
description = "Arcane Alchemical Book\n0 EMC/node",
inventory_image = "exchangeclone_arcane_alchemical_book.png",
groups = {exchangeclone_alchemical_book = 1},
groups = {exchangeclone_alchemical_book = 1, disable_repair = 1},
alchemical_book_data = {emc_per_node = 0},
on_secondary_use = alchemical_book_function,
on_place = alchemical_book_function

221
exchangeclone/amulets.lua Normal file
View File

@ -0,0 +1,221 @@
-- This list is copied/modified from 3D Armor.
local fire_nodes = {
["nether:lava_source"] = true,
["default:lava_source"] = true,
["default:lava_flowing"] = true,
["fire:basic_flame"] = true,
["fire:permanent_flame"] = true,
["ethereal:crystal_spike"] = true,
["ethereal:fire_flower"] = true,
["nether:lava_crust"] = true,
["default:torch"] = true,
["default:torch_ceiling"] = true,
["default:torch_wall"] = true,
}
local function place_liquid(itemstack, player, pointed_thing)
local click_test = exchangeclone.check_on_rightclick(itemstack, player, pointed_thing)
if click_test ~= false then
return click_test
end
local liquid = itemstack:get_name() == "exchangeclone:volcanite_amulet" and "lava" or "water"
local cost = liquid == "lava" and 64 or 0
local sound = liquid == "lava" and "exchangeclone_transmute" or "exchangeclone_water"
exchangeclone.play_sound(player, sound)
if pointed_thing and pointed_thing.type == "node" then
local bucket = ItemStack(exchangeclone.itemstrings[liquid.."_bucket"])
bucket:get_definition().on_place(bucket, player, pointed_thing)
else
if (not exchangeclone.mcl) or minetest.settings:get_bool("mcl_buckets_use_select_box", false) then
local velocity = player:get_look_dir()*20
minetest.add_entity(
vector.offset(player:get_pos(), 0, player:get_properties().eye_height, 0),
"exchangeclone:projectile", minetest.serialize({
velocity = vector.to_string(velocity),
player = player:get_player_name(),
itemstring = itemstack:get_name(),
texture = liquid == "lava" and "exchangeclone_lava_projectile.png" or "exchangeclone_water_projectile.png"
})
)
end
player:_add_emc(-cost)
end
end
minetest.register_entity("exchangeclone:projectile", {
initial_properties = {
hp_max = 1,
physical = true,
collide_with_objects = true,
pointable = false,
visual = "sprite",
textures = {"blank.png"},
static_save = false,
},
on_activate = function(self, staticdata)
local table_data = minetest.deserialize(staticdata)
local velocity = vector.from_string(table_data.velocity) or vector.new(0,0,0)
self._itemstring = table_data.itemstring
self._player = table_data.player
self.object:set_velocity(velocity)
self.object:set_properties({textures = {table_data.texture}})
if not self._player then self.object:remove() end
end,
on_step = function(self, dtime, moveresult)
for _, collision in ipairs(moveresult.collisions) do
if collision.type == "node" then
local player = minetest.get_player_by_name(self._player)
if not player then
self.object:remove()
return
end
local above = vector.new(collision.node_pos)
if collision.old_velocity[collision.axis] < 0 then
above[collision.axis] = above[collision.axis] + 1
else
above[collision.axis] = above[collision.axis] - 1
end
place_liquid(ItemStack(self._itemstring), player, {type = "node", under = collision.node_pos, above = above})
elseif collision.type == "object" then
local obj = collision.object
if exchangeclone.mcl then
mcl_util.deal_damage(obj, 5, {type = "on_fire"})
mcl_burning.set_on_fire(obj, 4)
else
obj:set_hp(obj:get_hp() - 5)
if minetest.get_modpath("fire_plus") and obj:is_player() then
fire_plus.burn_player(obj, 4, 1)
end
end
end
self.object:remove()
end
end
})
local change_count = 9 -- numbers of calls before changing, starts at 9 to make it do it the first time (10)
local evertide_pedestal
if exchangeclone.mcl and minetest.settings:get_bool("mcl_doWeatherCycle", true) then
evertide_pedestal = function()
change_count = change_count + 1
if change_count >= 10 then
mcl_weather.change_weather("rain")
change_count = 0
end
end
elseif minetest.get_modpath("weather") then
evertide_pedestal = function()
change_count = change_count + 1
if change_count >= 10 then
weather.type = "weather:rain"
weather_mod.handle_lightning()
weather_mod.handle_weather_change({type = "weather:rain"})
change_count = 0
end
end
end
local volcanite_pedestal
if exchangeclone.mcl and minetest.settings:get_bool("mcl_doWeatherCycle", true) then
volcanite_pedestal = function()
change_count = change_count + 1
if change_count >= 10 then
minetest.log("clearing?")
mcl_weather.change_weather("none")
change_count = 0
end
end
elseif minetest.get_modpath("weather") then
volcanite_pedestal = function()
change_count = change_count + 1
if change_count >= 10 then
weather.type = "none"
weather_mod.handle_lightning()
weather_mod.handle_weather_change({type = "none"})
change_count = 0
end
end
end
minetest.register_tool("exchangeclone:evertide_amulet", {
description = "Evertide Amulet",
inventory_image = "exchangeclone_evertide_amulet.png",
groups = {disable_repair = 1, immune_to_fire = 1},
on_place = place_liquid,
on_secondary_use = place_liquid,
_exchangeclone_pedestal = evertide_pedestal
})
minetest.register_tool("exchangeclone:volcanite_amulet", {
description = "Volcanite Amulet",
inventory_image = "exchangeclone_volcanite_amulet.png",
groups = {disable_repair = 1, immune_to_fire = 1},
on_place = place_liquid,
on_secondary_use = place_liquid,
_exchangeclone_pedestal = volcanite_pedestal
})
-- Drowning damage looks the same in MCL and MTGs
minetest.register_on_player_hpchange(function(player, hp_change, reason)
if hp_change < 0 then
if reason.type == "drown" then
local inv = player:get_inventory()
local hotbar_max = player:hud_get_hotbar_itemcount() + 1
for i = 1, hotbar_max do
local stack = inv:get_stack("main", i)
if stack:get_name() == "exchangeclone:evertide_amulet" then
return 0
end
end
elseif exchangeclone.mtg and reason.type == "node_damage" and reason.node then
if fire_nodes[reason.node] then
local inv = player:get_inventory()
local hotbar_max = player:hud_get_hotbar_itemcount() + 1
for i = 1, hotbar_max do
local stack = inv:get_stack("main", i)
if stack:get_name() == "exchangeclone:volcanite_amulet" then
return 0
end
end
end
end
end
return hp_change
end, true)
-- Fire damage is different (and a lot easier to detect in MCL)
if exchangeclone.mcl then
mcl_damage.register_modifier(function(obj, damage, reason)
if not obj:is_player() then return end
if reason.flags.is_fire then
local inv = obj:get_inventory()
local hotbar_max = obj:hud_get_hotbar_itemcount() + 1
for i = 1, hotbar_max do
local stack = inv:get_stack("main", i)
if stack:get_name() == "exchangeclone:volcanite_amulet" then
return 0
end
end
end
return damage
end)
end
minetest.register_craft({
output = "exchangeclone:evertide_amulet",
recipe = {
{exchangeclone.itemstrings.water_bucket, exchangeclone.itemstrings.water_bucket, exchangeclone.itemstrings.water_bucket},
{"exchangeclone:dark_matter", "exchangeclone:dark_matter", "exchangeclone:dark_matter"},
{exchangeclone.itemstrings.water_bucket, exchangeclone.itemstrings.water_bucket, exchangeclone.itemstrings.water_bucket},
}
})
minetest.register_craft({
output = "exchangeclone:volcanite_amulet",
recipe = {
{exchangeclone.itemstrings.lava_bucket, exchangeclone.itemstrings.lava_bucket, exchangeclone.itemstrings.lava_bucket},
{"exchangeclone:dark_matter", "exchangeclone:dark_matter", "exchangeclone:dark_matter"},
{exchangeclone.itemstrings.lava_bucket, exchangeclone.itemstrings.lava_bucket, exchangeclone.itemstrings.lava_bucket},
}
})

View File

@ -0,0 +1,35 @@
-- Some of this is copied from `sneak_drop` by Krunegan because I was too lazy to do it myself
local function pickup_items(player)
local pos = player:get_pos()
local objs = minetest.get_objects_inside_radius(pos, 5)
for j = 1, #objs do
local obj = objs[j]
if obj:get_luaentity() and obj:get_luaentity().name == "__builtin:item" then
local objpos = obj:get_pos()
local objdir = vector.direction(pos, objpos)
local objdist = vector.distance(pos, objpos)
local itemstack = obj:get_luaentity().itemstring
if player:get_inventory():room_for_item("main", itemstack) then
player:get_inventory():add_item("main", itemstack)
obj:remove()
exchangeclone.play_sound(player, "exchangeclone_pickup")
else
obj:set_pos(vector.offset(player:get_pos(), 0, 1, 0))
end
end
end
end
minetest.register_tool("exchangeclone:black_hole_band", {
description = "Black Hole Band",
inventory_image = "exchangeclone_black_hole_band.png",
on_secondary_use = exchangeclone.toggle_active,
on_place = exchangeclone.toggle_active,
groups = {exchangeclone_passive = 1, disable_repair = 1},
_exchangeclone_passive = {
func = pickup_items,
hotbar = true,
active_image = "exchangeclone_black_hole_band_active.png",
exclude = {"exchangeclone:void_ring"}
},
})

View File

@ -111,6 +111,8 @@ end
local files = {
"fuels",
"matter",
"amulets",
"black_hole_band",
"deprecated_stuff",
"energy_collectors",
"klein_stars",

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

View File

@ -1,4 +1,5 @@
name = 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!
optional_depends = default, mcl_core, technic, ethereal, why_init, nether, mobs
description = Transmute items into other items, create powerful tools and armor, and more! Based on ProjectE/Equivalent Exchange.
supported_games = mineclone2, minetest_game, mineclonia
unsupported_games = nodecore

View File

@ -385,6 +385,11 @@ exchangeclone.itemstrings = {
torch = exchangeclone.mcl and "mcl_torches:torch" or "default:torch",
book = exchangeclone.mcl and "mcl_books:book" or "default:book",
glass = exchangeclone.mcl and "mcl_core:glass" or "default:glass",
water = exchangeclone.mcl and "mcl_core:water_source" or "default:water_source",
lava = exchangeclone.mcl and "mcl_core:lava_source" or "default:lava_source",
water_bucket = exchangeclone.mcl and "mcl_buckets:bucket_water" or "bucket:bucket_water",
lava_bucket = exchangeclone.mcl and "mcl_buckets:bucket_lava" or "bucket:bucket_lava",
empty_bucket = exchangeclone.mcl and "mcl_buckets:bucket_empty" or "bucket:bucket_empty",
}
exchangeclone.emc_aliases = {}