2022-04-30 11:57:03 +03:00
local stereotype_frame = 18
2021-05-29 17:12:33 +03:00
local S = minetest.get_translator ( minetest.get_current_modname ( ) )
2019-03-08 00:40:43 +02:00
2017-02-20 22:14:10 +02:00
mcl_compass = { }
2015-06-29 20:55:56 +03:00
2017-08-17 22:26:09 +03:00
local compass_frames = 32
2022-04-30 11:57:03 +03:00
local function get_far_node ( pos , itemstack ) --code from minetest dev wiki: https://dev.minetest.net/minetest.get_node, some edits have been made to add a cooldown for force loads
local node = minetest.get_node ( pos )
if node.name == " ignore " then
tstamp = tonumber ( itemstack : get_meta ( ) : get_string ( " last_forceload " ) )
if tstamp == nil then --this is only relevant for new lodestone compasses, the ones that have never performes a forceload yet
itemstack : get_meta ( ) : set_string ( " last_forceload " , tostring ( os.time ( os.date ( " !*t " ) ) ) )
tstamp = tonumber ( os.time ( os.date ( " !*t " ) ) )
end
if tonumber ( os.time ( os.date ( " !*t " ) ) ) - tstamp > 180 then --current time in secounds - old time in secounds, if it is over 180 (3 mins): forceload
itemstack : get_meta ( ) : set_string ( " last_forceload " , tostring ( os.time ( os.date ( " !*t " ) ) ) )
minetest.get_voxel_manip ( ) : read_from_map ( pos , pos )
node = minetest.get_node ( pos )
minetest.log ( " forceloaded, cooldown reset! " )
else
minetest.log ( " cooldown not over yet " )
node = { name = " mcl_compass:lodestone " } --cooldown not over yet, pretend like there is something...
end
end
return node
end
2021-05-23 01:17:12 +03:00
--Not sure spawn point should be dymanic (is it in mc?)
--local default_spawn_settings = minetest.settings:get("static_spawnpoint")
2015-06-29 20:55:56 +03:00
2017-08-17 22:26:09 +03:00
-- Timer for random compass spinning
local random_timer = 0
local random_timer_trigger = 0.5 -- random compass spinning tick in seconds. Increase if there are performance problems
local random_frame = math.random ( 0 , compass_frames - 1 )
2022-04-30 11:57:03 +03:00
function mcl_compass . get_compass_image ( pos , dir , itemstack )
if not itemstack then
minetest.log ( " WARNING: mcl_compass.get_compass_image() was called without itemstack, returning random frame! " )
return random_frame
end
local lodestone_pos = minetest.string_to_pos ( itemstack : get_meta ( ) : get_string ( " pointsto " ) )
if lodestone_pos then --lodestone meta present
local _ , dim = mcl_worlds.y_to_layer ( lodestone_pos.y )
local _ , playerdim = mcl_worlds.y_to_layer ( pos.y )
if dim == playerdim then --Check if player and compass target are in the same dimension, above check is just if the diemension is valid for the non lodestone compass
if get_far_node ( lodestone_pos , itemstack ) . name == " mcl_compass:lodestone " then --check if lodestone still exists
local angle_north = math.deg ( math.atan2 ( lodestone_pos.x - pos.x , lodestone_pos.z - pos.z ) )
if angle_north < 0 then angle_north = angle_north + 360 end
local angle_dir = - math.deg ( dir )
local angle_relative = ( angle_north - angle_dir + 180 ) % 360
return math.floor ( ( angle_relative / 11.25 ) + 0.5 ) % compass_frames .. " _lodestone "
else -- lodestone got destroyed
return random_frame .. " _lodestone "
end
else
return random_frame .. " _lodestone "
end
else --no lodestone meta, normal compass....
local spawn = { x = 0 , y = 0 , z = 0 } --before you guys tell me that the normal compass no points to real spawn, it always pointed to 0 0
2021-05-03 12:22:47 +03:00
local ssp = minetest.setting_get_pos ( " static_spawnpoint " )
if ssp then
spawn = ssp
if type ( spawn ) ~= " table " or type ( spawn.x ) ~= " number " or type ( spawn.y ) ~= " number " or type ( spawn.z ) ~= " number " then
spawn = { x = 0 , y = 0 , z = 0 }
end
end
2022-04-30 11:57:03 +03:00
if mcl_worlds.compass_works ( pos ) then --is the player in the overworld?
local angle_north = math.deg ( math.atan2 ( spawn.x - pos.x , spawn.z - pos.z ) )
if angle_north < 0 then angle_north = angle_north + 360 end
local angle_dir = - math.deg ( dir )
local angle_relative = ( angle_north - angle_dir + 180 ) % 360
return math.floor ( ( angle_relative / 11.25 ) + 0.5 ) % compass_frames
else
return random_frame
end
2021-05-03 12:22:47 +03:00
end
end
2015-06-29 20:55:56 +03:00
minetest.register_globalstep ( function ( dtime )
2017-08-17 22:26:09 +03:00
random_timer = random_timer + dtime
if random_timer >= random_timer_trigger then
random_frame = ( random_frame + math.random ( - 1 , 1 ) ) % compass_frames
random_timer = 0
end
2022-04-30 11:57:03 +03:00
for _ , player in pairs ( minetest.get_connected_players ( ) ) do
2015-06-29 20:55:56 +03:00
local function has_compass ( player )
2021-03-16 18:35:46 +02:00
for _ , stack in pairs ( player : get_inventory ( ) : get_list ( " main " ) ) do
2015-06-29 20:55:56 +03:00
if minetest.get_item_group ( stack : get_name ( ) , " compass " ) ~= 0 then
return true
end
end
return false
end
if has_compass ( player ) then
2019-02-01 07:33:07 +02:00
local pos = player : get_pos ( )
2015-06-29 20:55:56 +03:00
2021-03-16 18:43:32 +02:00
for j , stack in pairs ( player : get_inventory ( ) : get_list ( " main " ) ) do
2022-04-30 11:57:03 +03:00
if minetest.get_item_group ( stack : get_name ( ) , " compass " ) ~= 0 then
local compass_image = mcl_compass.get_compass_image ( pos , player : get_look_horizontal ( ) , stack )
if minetest.get_item_group ( stack : get_name ( ) , " compass " ) - 1 ~= compass_image and minetest.get_item_group ( stack : get_name ( ) , " compass " ) - 1 .. " _lodestone " ~= compass_image then --Explaination: First check for normal compasses, secound check for lodestone ones
local itemname = " mcl_compass: " .. compass_image
--minetest.log(os.time(os.date("!*t")))
stack : set_name ( itemname )
player : get_inventory ( ) : set_stack ( " main " , j , stack )
end
2015-06-29 20:55:56 +03:00
end
2022-04-30 11:57:03 +03:00
2015-06-29 20:55:56 +03:00
end
end
end
end )
2017-01-09 03:03:09 +02:00
local images = { }
2017-08-17 22:26:09 +03:00
for frame = 0 , compass_frames - 1 do
2017-07-20 23:04:15 +03:00
local s = string.format ( " %02d " , frame )
table.insert ( images , " mcl_compass_compass_ " .. s .. " .png " )
2017-01-09 03:03:09 +02:00
end
2015-06-29 20:55:56 +03:00
2021-05-29 17:12:33 +03:00
local doc_mod = minetest.get_modpath ( " doc " )
2017-03-20 19:12:05 +02:00
2015-06-29 20:55:56 +03:00
for i , img in ipairs ( images ) do
local inv = 1
2017-01-09 04:26:00 +02:00
if i == stereotype_frame then
2015-06-29 20:55:56 +03:00
inv = 0
end
2021-05-23 01:17:12 +03:00
local use_doc , longdesc , tt
2022-04-30 11:57:03 +03:00
--Why is there no usage help? This should be fixed.
--local usagehelp
2017-03-20 19:12:05 +02:00
use_doc = i == stereotype_frame
if use_doc then
2020-02-19 05:54:17 +02:00
tt = S ( " Points to the world origin " )
2019-03-08 00:40:43 +02:00
longdesc = S ( " Compasses are tools which point to the world origin (X=0, Z=0) or the spawn point in the Overworld. " )
2017-03-02 22:55:25 +02:00
end
2017-03-20 19:12:05 +02:00
local itemstring = " mcl_compass: " .. ( i - 1 )
minetest.register_craftitem ( itemstring , {
2019-03-08 00:40:43 +02:00
description = S ( " Compass " ) ,
2020-02-19 05:54:17 +02:00
_tt_help = tt ,
2017-03-20 19:12:05 +02:00
_doc_items_create_entry = use_doc ,
2017-03-02 22:55:25 +02:00
_doc_items_longdesc = longdesc ,
2021-05-23 01:17:12 +03:00
--_doc_items_usagehelp = usagehelp,
2015-06-29 20:55:56 +03:00
inventory_image = img ,
wield_image = img ,
2017-02-08 17:59:34 +02:00
stack_max = 64 ,
2020-12-19 16:32:32 +02:00
groups = { not_in_creative_inventory = inv , compass = i , tool = 1 , disable_repair = 1 }
2015-06-29 20:55:56 +03:00
} )
2022-04-30 11:57:03 +03:00
minetest.register_craftitem ( itemstring .. " _lodestone " , {
description = S ( " Lodestone Compass " ) ,
_tt_help = tt ,
_doc_items_create_entry = use_doc ,
_doc_items_longdesc = longdesc ,
--_doc_items_usagehelp = usagehelp,
inventory_image = img .. " ^[colorize:purple:50 " ,
wield_image = img .. " ^[colorize:purple:50 " ,
stack_max = 64 ,
groups = { not_in_creative_inventory = 1 , compass = i , tool = 1 , disable_repair = 1 }
} )
2017-03-20 19:12:05 +02:00
-- Help aliases. Makes sure the lookup tool works correctly
if not use_doc and doc_mod then
doc.add_entry_alias ( " craftitems " , " mcl_compass: " .. ( stereotype_frame - 1 ) , " craftitems " , itemstring )
end
2015-06-29 20:55:56 +03:00
end
minetest.register_craft ( {
2021-05-29 17:12:33 +03:00
output = " mcl_compass: " .. stereotype_frame ,
2015-06-29 20:55:56 +03:00
recipe = {
2021-05-29 17:12:33 +03:00
{ " " , " mcl_core:iron_ingot " , " " } ,
{ " mcl_core:iron_ingot " , " mesecons:redstone " , " mcl_core:iron_ingot " } ,
{ " " , " mcl_core:iron_ingot " , " " }
2015-06-29 20:55:56 +03:00
}
2017-01-04 06:04:13 +02:00
} )
2017-01-09 04:26:00 +02:00
2022-04-30 11:57:03 +03:00
minetest.register_craft ( {
output = " mcl_compass:lodestone " ,
recipe = {
{ " mcl_core:stonebrickcarved " , " mcl_core:stonebrickcarved " , " mcl_core:stonebrickcarved " } ,
{ " mcl_core:stonebrickcarved " , " mcl_core:diamondblock " , " mcl_core:stonebrickcarved " } ,
{ " mcl_core:stonebrickcarved " , " mcl_core:stonebrickcarved " , " mcl_core:stonebrickcarved " }
}
} )
2017-01-09 04:26:00 +02:00
minetest.register_alias ( " mcl_compass:compass " , " mcl_compass: " .. stereotype_frame )
2017-02-20 22:14:10 +02:00
-- Export stereotype item for other mods to use
mcl_compass.stereotype = " mcl_compass: " .. tostring ( stereotype_frame )
2022-04-30 11:57:03 +03:00
minetest.register_node ( " mcl_compass:lodestone " , {
description = S ( " Lodestone " ) ,
on_rightclick = function ( pos , node , player , itemstack )
if itemstack.get_name ( itemstack ) . match ( itemstack.get_name ( itemstack ) , " mcl_compass: " ) then
if itemstack.get_name ( itemstack ) ~= " mcl_compass:lodestone " then
itemstack : get_meta ( ) : set_string ( " pointsto " , minetest.pos_to_string ( pos ) )
end
end
end ,
tiles = {
" lodestone_top.png " ,
" lodestone_bottom.png " ,
" lodestone_side1.png " ,
" lodestone_side2.png " ,
" lodestone_side3.png " ,
" lodestone_side4.png "
} ,
groups = { pickaxey = 1 , material_stone = 1 } ,
_mcl_hardness = 1.5 ,
_mcl_blast_resistance = 6 ,
sounds = mcl_sounds.node_sound_stone_defaults ( )
} )