2017-07-30 16:04:31 -04:00
local player_to_id_text = { } -- Storage of players so the mod knows what huds to update
2017-08-01 11:09:25 -04:00
local player_to_id_mtext = { }
2017-07-30 17:20:44 -04:00
local player_to_id_image = { }
2017-08-01 10:09:44 -04:00
local player_to_cnode = { } -- Get the current looked at node
2017-08-01 10:36:59 -04:00
local player_to_animtime = { } -- For animation
local player_to_animon = { } -- For disabling animation
2017-08-01 11:30:44 -04:00
local player_to_enabled = { } -- For disabling WiTT
2017-08-01 10:36:59 -04:00
local ypos = 0.1
2017-07-30 11:15:43 -04:00
2017-07-30 16:04:31 -04:00
minetest.register_globalstep ( function ( dtime ) -- This will run every tick, so around 20 times/second
for _ , player in ipairs ( minetest : get_connected_players ( ) ) do -- Do everything below for each player in-game
2017-08-01 11:30:44 -04:00
if player_to_enabled [ player ] == nil then player_to_enabled [ player ] = true end -- Enable by default
if not player_to_enabled [ player ] then return end -- Don't do anything if they have it disabled
2017-07-30 16:04:31 -04:00
local lookat = get_looking_node ( player ) -- Get the node they're looking at
2017-07-30 11:15:43 -04:00
2017-08-01 11:30:44 -04:00
player_to_animtime [ player ] = math.min ( ( player_to_animtime [ player ] or 0.4 ) + dtime , 0.5 ) -- Animation calculation
2017-08-01 10:36:59 -04:00
2017-08-01 11:30:44 -04:00
if player_to_animon [ player ] then -- If they have animation on, display it
2017-08-01 11:15:40 -04:00
update_player_hud_pos ( player , player_to_animtime [ player ] )
2017-08-01 10:36:59 -04:00
end
2017-08-01 11:30:44 -04:00
if lookat then
if player_to_cnode [ player ] ~= lookat.name then -- Only do anything if they are looking at a different type of block than before
player_to_animtime [ player ] = nil -- Reset the animation
local nodename , mod = describe_node ( lookat ) -- Get the details of the block in a nice looking way
2017-08-01 11:09:25 -04:00
player : hud_change ( player_to_id_text [ player ] , " text " , nodename ) -- If they are looking at something, display that
player : hud_change ( player_to_id_mtext [ player ] , " text " , mod )
2017-08-01 11:30:44 -04:00
local node_object = minetest.registered_nodes [ lookat.name ] -- Get information about the block
player : hud_change ( player_to_id_image [ player ] , " text " , handle_tiles ( node_object ) ) -- Pass it to handle_tiles which will return a texture of that block (or nothing if it can't create it)
2017-08-01 10:09:44 -04:00
end
2017-08-01 11:30:44 -04:00
player_to_cnode [ player ] = lookat.name -- Update the current node
2017-07-30 11:15:43 -04:00
else
2017-08-01 11:19:47 -04:00
blank_player_hud ( player ) -- If they are not looking at anything, do not display the text
2017-08-01 11:30:44 -04:00
player_to_cnode [ player ] = nil -- Update the current node
2017-07-30 11:15:43 -04:00
end
2017-08-01 10:09:44 -04:00
2017-07-30 11:15:43 -04:00
end
end )
2017-07-30 16:04:31 -04:00
minetest.register_on_joinplayer ( function ( player ) -- Add the hud to all players
2017-08-01 11:30:44 -04:00
player_to_id_text [ player ] = player : hud_add ( { -- Add the block name text
2017-07-30 11:15:43 -04:00
hud_elem_type = " text " ,
text = " test " ,
number = 0xffffff ,
2017-08-01 10:59:21 -04:00
alignment = { x = 1 , y = 0 } ,
2017-08-01 10:36:59 -04:00
position = { x = 0.5 , y = ypos } ,
2017-07-30 17:20:44 -04:00
} )
2017-08-01 11:30:44 -04:00
player_to_id_mtext [ player ] = player : hud_add ( { -- Add the mod name text
2017-08-01 11:09:25 -04:00
hud_elem_type = " text " ,
text = " test " ,
number = 0x2d62b7 ,
alignment = { x = 1 , y = 0 } ,
position = { x = 0.5 , y = ypos + 0.015 } ,
} )
2017-08-01 11:30:44 -04:00
player_to_id_image [ player ] = player : hud_add ( { -- Add the block image
2017-07-30 17:20:44 -04:00
hud_elem_type = " image " ,
text = " " ,
scale = { x = 1 , y = 1 } ,
alignment = 0 ,
2017-08-01 10:59:21 -04:00
position = { x = 0.5 , y = ypos } ,
offset = { x = - 40 , y = 0 }
2017-07-30 11:15:43 -04:00
} )
end )
2017-08-02 12:05:11 -04:00
minetest.register_chatcommand ( " wanim " , { -- Command to turn witt animations on/off
params = " <on/off> " ,
description = " Turn WiTT animations on/off " ,
func = function ( name , param )
2017-08-01 10:36:59 -04:00
local player = minetest.get_player_by_name ( name )
if not player then return false end
2017-08-02 12:05:11 -04:00
player_to_animon [ player ] = param == " on "
2017-08-01 10:36:59 -04:00
return true
end
} )
2017-08-02 12:05:11 -04:00
minetest.register_chatcommand ( " witt " , { -- Command to turn witt on/off
params = " <on/off> " ,
description = " Turn WiTT on/off " ,
func = function ( name , param )
2017-08-01 10:36:59 -04:00
local player = minetest.get_player_by_name ( name )
if not player then return false end
2017-08-02 12:05:11 -04:00
player_to_enabled [ player ] = param == " on "
2017-08-01 11:15:40 -04:00
blank_player_hud ( player )
2017-08-01 10:42:10 -04:00
player_to_cnode [ player ] = nil
return true
end
} )
2017-07-30 16:04:31 -04:00
function get_looking_node ( player ) -- Return the node the given player is looking at or nil
2017-07-30 11:15:43 -04:00
local lookat
for i = 0 , 10 do -- 10 is the maximum distance you can point to things in creative mode by default
local lookvector = -- This variable will store what node we might be looking at
vector.add ( -- This add function corrects for the players approximate height
vector.add ( -- This add function applies the camera's position to the look vector
vector.multiply ( -- This multiply function adjusts the distance from the camera by the iteration of the loop we're in
player : get_look_dir ( ) ,
i -- Goes from 0 to 10
) ,
player : get_pos ( )
) ,
vector.new ( 0 , 1.5 , 0 )
)
lookat = minetest.get_node_or_nil ( -- This actually gets the node we might be looking at
lookvector
) or lookat
2017-07-30 13:39:04 -04:00
if lookat ~= nil and lookat.name ~= " air " and lookat.name ~= " walking_light:light " then break else lookat = nil end -- If we *are* looking at something, stop the loop and continue
2017-07-30 11:15:43 -04:00
end
return lookat
end
2017-07-30 16:04:31 -04:00
function describe_node ( node ) -- Return a string that describes the node and mod
2017-08-01 11:30:44 -04:00
local mod , nodename = minetest.registered_nodes [ node.name ] . mod_origin , minetest.registered_nodes [ node.name ] . description -- Get basic (not pretty) info
if nodename == " " then -- If it doesn't have a proper name, just use the technical one
2017-07-30 17:27:06 -04:00
nodename = node.name
end
2017-08-01 11:30:44 -04:00
mod = remove_unneeded ( capitalize ( mod ) ) -- Make it look good
2017-07-30 11:15:43 -04:00
nodename = remove_unneeded ( capitalize ( nodename ) )
2017-08-01 11:09:25 -04:00
return nodename , mod
2017-07-30 11:15:43 -04:00
end
2017-07-30 16:04:31 -04:00
function remove_unneeded ( str ) -- Remove characters like '-' and '_' to make the string look better
2017-07-30 11:15:43 -04:00
return str : gsub ( " [_-] " , " " )
end
2017-07-30 16:04:31 -04:00
function capitalize ( str ) -- Capitalize every word in a string, looks good for node names
2017-07-30 15:55:38 -04:00
return string.gsub ( " " .. str , " %W%l " , string.upper ) : sub ( 2 )
2017-07-30 17:20:44 -04:00
end
2017-08-01 11:30:44 -04:00
function handle_tiles ( node ) -- Return an image of the tile
2017-07-31 14:56:48 -04:00
local tiles = node.tiles
2017-08-01 11:30:44 -04:00
if tiles then -- Make sure every tile is a string
2017-07-31 17:20:09 -04:00
for i , v in pairs ( tiles ) do
if type ( v ) == " table " then
if tiles [ i ] . name then
tiles [ i ] = tiles [ i ] . name
else
return " "
end
2017-07-31 14:56:48 -04:00
end
2017-07-30 17:20:44 -04:00
end
2017-07-31 14:56:48 -04:00
2017-08-01 11:30:44 -04:00
-- These are the types it can draw correctly
2017-07-31 17:20:09 -04:00
if node.drawtype == " normal " or node.drawtype == " allfaces " or node.drawtype == " allfaces_optional " or node.drawtype == " glasslike " or node.drawtype == " glasslike_framed " or node.drawtype == " glasslike_framed_optional " then
2017-08-01 11:30:44 -04:00
if # tiles == 1 then -- This type of block has only 1 image, so it must be on all faces
2017-07-31 17:20:09 -04:00
return minetest.inventorycube ( tiles [ 1 ] , tiles [ 1 ] , tiles [ 1 ] )
2017-08-01 11:30:44 -04:00
elseif # tiles == 3 then -- This type of block has 3 images, so it's probably 1 on top, 1 on bottom, the rest on the side
2017-07-31 17:20:09 -04:00
return minetest.inventorycube ( tiles [ 1 ] , tiles [ 3 ] , tiles [ 3 ] )
2017-08-01 11:30:44 -04:00
elseif # tiles == 6 then -- This one has 6 images, so display the ones we can
return minetest.inventorycube ( tiles [ 1 ] , tiles [ 6 ] , tiles [ 5 ] ) -- Not actually sure if 5 is the correct number but it's basically the same thing most of the time
2017-07-31 17:20:09 -04:00
end
2017-07-31 14:56:48 -04:00
end
2017-07-30 17:20:44 -04:00
end
2017-07-31 14:56:48 -04:00
2017-08-01 11:30:44 -04:00
return " " -- If it can't do anything, return with a blank image
2017-08-01 11:15:40 -04:00
end
2017-08-01 11:30:44 -04:00
function update_player_hud_pos ( player , to_x , to_y ) -- Change position of hud elements
2017-08-01 11:15:40 -04:00
to_y = to_y or ypos
player : hud_change ( player_to_id_text [ player ] , " position " , { x = to_x , y = to_y } )
player : hud_change ( player_to_id_image [ player ] , " position " , { x = to_x , y = to_y } )
player : hud_change ( player_to_id_mtext [ player ] , " position " , { x = to_x , y = to_y + 0.015 } )
end
2017-08-01 11:30:44 -04:00
function blank_player_hud ( player ) -- Make hud appear blank
2017-08-01 11:15:40 -04:00
player : hud_change ( player_to_id_text [ player ] , " text " , " " )
player : hud_change ( player_to_id_mtext [ player ] , " text " , " " )
player : hud_change ( player_to_id_image [ player ] , " text " , " " )
2017-07-30 11:15:43 -04:00
end