2016-07-29 11:37:16 +02:00
local S
2016-07-29 11:02:10 +02:00
if ( minetest.get_modpath ( " intllib " ) ) then
2016-11-09 02:14:10 +01:00
S = intllib.Getter ( )
2016-07-29 11:02:10 +02:00
else
S = function ( s ) return s end
end
2015-08-28 22:29:35 +02:00
local orienteering = { }
orienteering.playerhuds = { }
2016-07-28 02:58:20 +02:00
orienteering.settings = { }
2016-07-29 11:02:10 +02:00
orienteering.settings . speed_unit = S ( " m/s " )
orienteering.settings . length_unit = S ( " m " )
2016-10-28 15:03:54 +02:00
orienteering.settings . hud_pos = { x = 0.5 , y = 0 }
orienteering.settings . hud_offset = { x = 0 , y = 15 }
orienteering.settings . hud_alignment = { x = 0 , y = 0 }
local set = tonumber ( minetest.setting_get ( " orienteering_hud_pos_x " ) )
if set then orienteering.settings . hud_pos.x = set end
set = tonumber ( minetest.setting_get ( " orienteering_hud_pos_y " ) )
if set then orienteering.settings . hud_pos.y = set end
set = tonumber ( minetest.setting_get ( " orienteering_hud_offset_x " ) )
if set then orienteering.settings . hud_offset.x = set end
set = tonumber ( minetest.setting_get ( " orienteering_hud_offset_y " ) )
if set then orienteering.settings . hud_offset.y = set end
set = minetest.setting_get ( " orienteering_hud_alignment " )
if set == " left " then
orienteering.settings . hud_alignment.x = 1
elseif set == " center " then
orienteering.settings . hud_alignment.x = 0
elseif set == " right " then
orienteering.settings . hud_alignment.x = - 1
end
2015-08-28 22:29:35 +02:00
2016-10-28 01:12:26 +02:00
local o_lines = 4 -- Number of lines in HUD
2016-07-29 11:50:12 +02:00
-- Helper function to switch between 12h and 24 mode for the time
2016-10-28 16:09:45 +02:00
function orienteering . toggle_time_mode ( itemstack , user , pointed_thing )
2016-07-29 11:50:12 +02:00
local name = user : get_player_name ( )
if orienteering.playerhuds [ name ] . twelve then
orienteering.playerhuds [ name ] . twelve = false
else
orienteering.playerhuds [ name ] . twelve = true
end
2016-10-28 16:09:45 +02:00
orienteering.update_hud_displays ( user )
2016-07-29 11:50:12 +02:00
end
2016-10-30 04:15:20 +01:00
local use = S ( " Put this tool in your hotbar to see the data it provides. " )
local use_time = S ( " Put this tool in your hotbar to make use of its functionality. Leftclick to toggle between 24-hour and 12-hour display for the time feature. " )
2015-08-28 20:39:05 +02:00
-- Displays height (Y)
minetest.register_tool ( " orienteering:altimeter " , {
2016-07-29 11:02:10 +02:00
description = S ( " Altimeter " ) ,
2016-11-16 06:49:20 +01:00
_doc_items_longdesc = S ( " It shows you your current elevation (Y). " ) ,
_doc_items_usagehelp = use ,
2015-08-28 20:39:05 +02:00
wield_image = " orienteering_altimeter.png " ,
inventory_image = " orienteering_altimeter.png " ,
} )
-- Displays X and Z coordinates
minetest.register_tool ( " orienteering:triangulator " , {
2016-07-29 11:02:10 +02:00
description = S ( " Triangulator " ) ,
2016-11-16 06:49:20 +01:00
_doc_items_longdesc = S ( " It shows you the coordinates of your current position in the horizontal plane (X and Z). " ) ,
_doc_items_usagehelp = use ,
2015-08-28 20:39:05 +02:00
wield_image = " orienteering_triangulator.png " ,
inventory_image = " orienteering_triangulator.png " ,
} )
2016-07-28 23:46:52 +02:00
-- Displays player yaw
-- TODO: calculate yaw difference between 2 points
2015-08-28 20:39:05 +02:00
minetest.register_tool ( " orienteering:compass " , {
2016-07-29 11:02:10 +02:00
description = S ( " Compass " ) ,
2016-11-16 06:49:20 +01:00
_doc_items_longdesc = S ( " It shows you your yaw (horizontal viewing angle) in degrees. " ) ,
_doc_items_usagehelp = use ,
2015-08-28 20:39:05 +02:00
wield_image = " orienteering_compass_wield.png " ,
inventory_image = " orienteering_compass_inv.png " ,
} )
2016-07-28 23:46:52 +02:00
-- Displays player pitch
-- TODO: calculate pitch difference between 2 points
2015-08-28 20:39:05 +02:00
minetest.register_tool ( " orienteering:sextant " , {
2016-07-29 11:02:10 +02:00
description = S ( " Sextant " ) ,
2016-11-16 06:49:20 +01:00
_doc_items_longdesc = S ( " It shows you your pitch (vertical viewing angle) in degrees. " ) ,
_doc_items_usagehelp = use ,
2015-08-28 20:39:05 +02:00
wield_image = " orienteering_sextant_wield.png " ,
inventory_image = " orienteering_sextant_inv.png " ,
} )
2016-07-28 23:46:12 +02:00
-- Ultimate orienteering tool: Displays X,Y,Z, yaw, pitch, time, speed and enables the minimap
minetest.register_tool ( " orienteering:quadcorder " , {
2016-07-29 11:02:10 +02:00
description = S ( " Quadcorder " ) ,
2016-11-16 06:49:20 +01:00
_doc_items_longdesc = S ( " This is the ultimate orientieering tool. It shows you your coordinates (X, Y and Z), shows your yaw and pitch (horizontal and vertical viewing angles), the current time, your current speed and it enables you to access the minimap. " ) ,
2016-07-28 23:46:12 +02:00
wield_image = " orienteering_quadcorder.png " ,
2016-11-16 06:49:20 +01:00
_doc_items_usagehelp = use_time ,
2016-07-28 23:46:12 +02:00
wield_scale = { x = 1 , y = 1 , z = 3.5 } ,
inventory_image = " orienteering_quadcorder.png " ,
2016-10-28 16:09:45 +02:00
on_use = orienteering.toggle_time_mode ,
2016-07-28 23:46:12 +02:00
} )
2015-08-28 20:39:05 +02:00
-- Displays game time
minetest.register_tool ( " orienteering:watch " , {
2016-07-29 11:02:10 +02:00
description = S ( " Watch " ) ,
2016-11-16 06:49:20 +01:00
_doc_items_longdesc = S ( " It shows you the current time. " ) ,
_doc_items_usagehelp = S ( " Put the watch in your hotbar to see the time. Leftclick to toggle between the 24-hour and 12-hour display. " ) ,
2015-08-28 20:39:05 +02:00
wield_image = " orienteering_watch.png " ,
inventory_image = " orienteering_watch.png " ,
2016-10-28 16:09:45 +02:00
on_use = orienteering.toggle_time_mode ,
2015-08-28 20:39:05 +02:00
} )
-- Displays speed
minetest.register_tool ( " orienteering:speedometer " , {
2016-07-29 11:02:10 +02:00
description = S ( " Speedometer " ) ,
2016-11-16 06:49:20 +01:00
_doc_items_longdesc = S ( " It shows you your current horizontal (“hor.”) and vertical (“ver.”) speed in meters per second, where one meter is the side length of a single cube. " ) ,
_doc_items_usagehelp = use ,
2015-08-28 20:39:05 +02:00
wield_image = " orienteering_speedometer_wield.png " ,
inventory_image = " orienteering_speedometer_inv.png " ,
} )
-- Enables minimap
minetest.register_tool ( " orienteering:automapper " , {
2016-07-29 11:02:10 +02:00
description = S ( " Automapper " ) ,
2016-11-16 06:49:20 +01:00
_doc_items_longdesc = S ( " The automapper automatically creates a map of the area around you and enables you to view a minimap of your surroundings. It also has a built-in radar. " ) ,
_doc_items_usagehelp = S ( " If you put an automapper in your hotbar, you will be able to access the minimap. By default the minimap can be opened with [F7]. " ) ,
2015-08-28 20:39:05 +02:00
wield_image = " orienteering_automapper_wield.png " ,
2016-07-28 23:46:12 +02:00
wield_scale = { x = 1 , y = 1 , z = 2 } ,
2015-08-28 20:39:05 +02:00
inventory_image = " orienteering_automapper_inv.png " ,
} )
2016-07-28 03:39:33 +02:00
-- Displays X,Y,Z coordinates, yaw and game time
2015-08-28 20:39:05 +02:00
minetest.register_tool ( " orienteering:gps " , {
2016-07-29 11:02:10 +02:00
description = S ( " GPS device " ) ,
2016-11-16 06:49:20 +01:00
_doc_items_longdesc = S ( " The GPS device shows you your coordinates (X, Y and Z), your yaw (horizontal viewing angle) and the time. " ) ,
_doc_items_usagehelp = use_time ,
2015-08-28 20:39:05 +02:00
wield_image = " orienteering_gps_wield.png " ,
2016-07-28 23:46:12 +02:00
wield_scale = { x = 1 , y = 1 , z = 2 } ,
2015-08-28 20:39:05 +02:00
inventory_image = " orienteering_gps_inv.png " ,
2016-10-28 16:09:45 +02:00
on_use = orienteering.toggle_time_mode ,
2015-08-28 20:39:05 +02:00
} )
2016-07-28 03:39:33 +02:00
if minetest.get_modpath ( " default " ) ~= nil then
-- Register crafts
minetest.register_craft ( {
output = " orienteering:altimeter " ,
recipe = {
2016-10-27 22:56:25 +02:00
{ " default:glass " } ,
2016-08-08 06:36:50 +02:00
{ " default:steel_ingot " } ,
{ " default:steel_ingot " } ,
2016-07-28 03:39:33 +02:00
}
} )
minetest.register_craft ( {
output = " orienteering:triangulator " ,
recipe = {
{ " " , " default:bronze_ingot " , " " } ,
{ " default:bronze_ingot " , " " , " default:bronze_ingot " } ,
}
} )
minetest.register_craft ( {
output = " orienteering:sextant " ,
recipe = {
{ " " , " default:gold_ingot " , " " } ,
{ " default:gold_ingot " , " default:gold_ingot " , " default:gold_ingot " } ,
}
} )
minetest.register_craft ( {
output = " orienteering:compass " ,
recipe = {
{ " " , " default:copper_ingot " , " " } ,
{ " default:copper_ingot " , " group:stick " , " default:copper_ingot " } ,
{ " " , " default:copper_ingot " , " " } ,
}
} )
minetest.register_craft ( {
output = " orienteering:speedometer " ,
recipe = {
2016-08-08 06:36:50 +02:00
{ " " , " default:gold_ingot " , " " } ,
{ " default:steel_ingot " , " group:stick " , " default:steel_ingot " } ,
{ " " , " default:steel_ingot " , " " } ,
2016-07-28 03:39:33 +02:00
}
} )
minetest.register_craft ( {
output = " orienteering:automapper " ,
recipe = {
{ " default:gold_ingot " , " default:gold_ingot " , " default:gold_ingot " } ,
{ " default:mese_crystal " , " default:obsidian_shard " , " default:mese_crystal " } ,
{ " default:gold_ingot " , " default:gold_ingot " , " default:gold_ingot " }
}
} )
minetest.register_craft ( {
output = " orienteering:gps " ,
recipe = {
{ " default:gold_ingot " , " orienteering:triangulator " , " default:gold_ingot " } ,
{ " orienteering:compass " , " default:bronze_ingot " , " orienteering:watch " } ,
{ " default:steel_ingot " , " orienteering:altimeter " , " default:steel_ingot " }
}
} )
2016-07-29 00:25:28 +02:00
minetest.register_craft ( {
output = " orienteering:quadcorder " ,
recipe = {
{ " default:gold_ingot " , " default:gold_ingot " , " default:gold_ingot " } ,
{ " orienteering:speedometer " , " default:diamond " , " orienteering:automapper " , } ,
{ " orienteering:sextant " , " default:diamond " , " orienteering:gps " }
}
} )
2016-07-28 03:39:33 +02:00
minetest.register_craft ( {
output = " orienteering:watch " ,
recipe = {
{ " default:copper_ingot " } ,
{ " default:glass " } ,
{ " default:copper_ingot " }
}
} )
end
2015-08-28 20:39:05 +02:00
2015-08-28 21:02:08 +02:00
2016-10-28 16:09:45 +02:00
function orienteering . update_automapper ( player )
2016-10-28 16:47:27 +02:00
if orienteering.tool_active ( player , " orienteering:automapper " ) or orienteering.tool_active ( player , " orienteering:quadcorder " ) then
2015-08-28 21:02:08 +02:00
player : hud_set_flags ( { minimap = true } )
else
player : hud_set_flags ( { minimap = false } )
end
end
2016-10-28 16:47:27 +02:00
-- Checks whether a certain orienteering tool is “active” and ready for use
function orienteering . tool_active ( player , item )
-- Requirement: player carries the tool in the hotbar
local inv = player : get_inventory ( )
local hotbar = player : hud_get_hotbar_itemcount ( )
for i = 1 , hotbar do
if inv : get_stack ( " main " , i ) : get_name ( ) == item then
return true
end
end
return false
end
2016-10-28 15:03:54 +02:00
2016-10-28 16:09:45 +02:00
function orienteering . init_hud ( player )
orienteering.update_automapper ( player )
2015-08-28 22:29:35 +02:00
local name = player : get_player_name ( )
orienteering.playerhuds [ name ] = { }
2016-10-28 01:12:26 +02:00
for i = 1 , o_lines do
orienteering.playerhuds [ name ] [ " o_line " .. i ] = player : hud_add ( {
2015-08-28 22:29:35 +02:00
hud_elem_type = " text " ,
text = " " ,
2016-10-28 15:03:54 +02:00
position = orienteering.settings . hud_pos ,
offset = { x = orienteering.settings . hud_offset.x , y = orienteering.settings . hud_offset.y + 20 * ( i - 1 ) } ,
alignment = orienteering.settings . hud_alignment ,
2015-08-28 22:29:35 +02:00
number = 0xFFFFFF ,
scale = { x = 100 , y = 20 } ,
} )
end
2015-08-28 23:18:49 +02:00
orienteering.playerhuds [ name ] . twelve = false
2015-08-28 22:29:35 +02:00
end
2015-08-28 21:02:08 +02:00
2016-10-28 16:09:45 +02:00
function orienteering . update_hud_displays ( player )
2015-08-28 23:18:49 +02:00
local name = player : get_player_name ( )
2016-07-28 23:46:12 +02:00
local gps , altimeter , triangulator , compass , sextant , watch , speedometer , quadcorder
2015-08-28 23:18:49 +02:00
2016-10-28 16:47:27 +02:00
if orienteering.tool_active ( player , " orienteering:gps " ) then
2015-08-28 22:29:35 +02:00
gps = true
end
2016-10-28 16:47:27 +02:00
if orienteering.tool_active ( player , " orienteering:altimeter " ) then
2015-08-28 22:29:35 +02:00
altimeter = true
end
2016-10-28 16:47:27 +02:00
if orienteering.tool_active ( player , " orienteering:triangulator " ) then
2015-08-28 22:29:35 +02:00
triangulator = true
end
2016-10-28 16:47:27 +02:00
if orienteering.tool_active ( player , " orienteering:compass " ) then
2015-08-28 22:29:35 +02:00
compass = true
end
2016-10-28 16:47:27 +02:00
if orienteering.tool_active ( player , " orienteering:sextant " ) then
2015-08-28 22:29:35 +02:00
sextant = true
end
2016-10-28 16:47:27 +02:00
if orienteering.tool_active ( player , " orienteering:watch " ) then
2015-08-28 22:29:35 +02:00
watch = true
end
2016-10-28 16:47:27 +02:00
if orienteering.tool_active ( player , " orienteering:speedometer " ) then
2015-08-28 22:29:35 +02:00
speedometer = true
end
2016-10-28 16:47:27 +02:00
if orienteering.tool_active ( player , " orienteering:quadcorder " ) then
2016-07-28 23:46:12 +02:00
quadcorder = true
end
2015-08-28 22:29:35 +02:00
local str_pos , str_angles , str_time , str_speed
local pos = vector.apply ( player : getpos ( ) , math.floor )
2016-07-28 23:46:12 +02:00
if ( altimeter and triangulator ) or gps or quadcorder then
2016-07-29 11:02:10 +02:00
str_pos = string.format ( S ( " Coordinates: X=%d, Y=%d, Z=%d " ) , pos.x , pos.y , pos.z )
2015-08-28 22:29:35 +02:00
elseif altimeter then
2016-07-29 11:02:10 +02:00
str_pos = string.format ( S ( " Height: Y=%d " ) , pos.y )
2015-08-28 22:29:35 +02:00
elseif triangulator then
2016-07-29 11:02:10 +02:00
str_pos = string.format ( S ( " Coordinates: X=%d, Z=%d " ) , pos.x , pos.z )
2015-08-28 22:29:35 +02:00
else
str_pos = " "
end
2016-07-29 11:02:10 +02:00
local yaw = ( player : get_look_yaw ( ) - math.pi * 0.5 ) / ( 2 * math.pi ) * 360
2016-08-12 22:03:47 +02:00
local pitch = player : get_look_pitch ( ) / math.pi * 180
2016-07-28 23:46:12 +02:00
if ( ( compass or gps ) and sextant ) or quadcorder then
2016-07-29 11:02:10 +02:00
str_angles = string.format ( S ( " Yaw: %.1f°, pitch: %.1f° " ) , yaw , pitch )
2015-08-28 22:29:35 +02:00
elseif compass or gps then
2016-07-29 11:02:10 +02:00
str_angles = string.format ( S ( " Yaw: %.1f° " ) , yaw )
2015-08-28 22:29:35 +02:00
elseif sextant then
2016-07-29 11:02:10 +02:00
str_angles = string.format ( S ( " Pitch: %.1f° " ) , pitch )
2015-08-28 22:29:35 +02:00
else
str_angles = " "
end
local time = minetest.get_timeofday ( )
2016-07-28 23:46:12 +02:00
if watch or gps or quadcorder then
2015-08-28 22:29:35 +02:00
local totalminutes = time * 1440
2016-11-19 01:14:43 +01:00
local minutes = totalminutes % 60
local hours = math.floor ( ( totalminutes - minutes ) / 60 )
2015-08-28 23:18:49 +02:00
local twelve = orienteering.playerhuds [ name ] . twelve
if twelve then
local ampm
if hours == 12 and minutes == 0 then
2016-07-29 11:02:10 +02:00
str_time = S ( " Time: noon " )
2015-08-28 23:18:49 +02:00
elseif hours == 0 and minutes == 0 then
2016-07-29 11:02:10 +02:00
str_time = S ( " Time: midnight " )
2015-08-28 23:18:49 +02:00
else
2016-07-29 11:02:10 +02:00
if hours >= 12 then ampm = S ( " p.m. " ) else ampm = S ( " a.m. " ) end
2015-08-28 23:18:49 +02:00
hours = math.fmod ( hours , 12 )
if hours == 0 then hours = 12 end
2016-07-29 11:02:10 +02:00
str_time = string.format ( S ( " Time: %i:%02i %s " ) , hours , minutes , ampm )
2015-08-28 23:18:49 +02:00
end
else
2016-07-29 11:02:10 +02:00
str_time = string.format ( S ( " Time: %02i:%02i " ) , hours , minutes )
2015-08-28 23:18:49 +02:00
end
2015-08-28 22:29:35 +02:00
else
str_time = " "
end
2016-10-27 23:49:59 +02:00
local speed_hor , speed_ver
local v
2016-10-24 17:50:07 +02:00
local attach = player : get_attach ( )
if attach == nil then
2016-10-27 23:49:59 +02:00
v = player : get_player_velocity ( )
2016-10-24 17:50:07 +02:00
else
2016-10-27 23:49:59 +02:00
v = attach : getvelocity ( )
2016-10-24 17:50:07 +02:00
end
2016-10-27 23:49:59 +02:00
speed_ver = v.y
v.y = 0
speed_hor = vector.length ( v )
2016-07-28 23:46:12 +02:00
if speedometer or quadcorder then
2016-10-27 23:49:59 +02:00
local u = orienteering.settings . speed_unit
str_speed = string.format ( S ( " Speed: hor.: %.1f %s, vert.: %.1f %s " ) , speed_hor , u , speed_ver , u )
2015-08-28 22:29:35 +02:00
else
str_speed = " "
end
2016-10-28 01:12:26 +02:00
local strs = { str_pos , str_angles , str_time , str_speed }
local line = 1
for i = 1 , o_lines do
if strs [ i ] ~= " " then
player : hud_change ( orienteering.playerhuds [ name ] [ " o_line " .. line ] , " text " , strs [ i ] )
line = line + 1
end
end
for l = line , o_lines do
player : hud_change ( orienteering.playerhuds [ name ] [ " o_line " .. l ] , " text " , " " )
end
2015-08-28 22:29:35 +02:00
end
2016-10-28 16:09:45 +02:00
minetest.register_on_newplayer ( orienteering.init_hud )
minetest.register_on_joinplayer ( orienteering.init_hud )
2015-08-28 22:29:35 +02:00
minetest.register_on_leaveplayer ( function ( player )
orienteering.playerhuds [ player : get_player_name ( ) ] = nil
2015-08-28 21:02:08 +02:00
end )
local updatetimer = 0
minetest.register_globalstep ( function ( dtime )
updatetimer = updatetimer + dtime
if updatetimer > 0.1 then
local players = minetest.get_connected_players ( )
for i = 1 , # players do
2016-10-28 16:09:45 +02:00
orienteering.update_automapper ( players [ i ] )
orienteering.update_hud_displays ( players [ i ] )
2015-08-28 21:02:08 +02:00
end
updatetimer = updatetimer - dtime
end
end )
2016-08-01 15:26:33 +02:00
2016-08-01 15:26:56 +02:00
if minetest.get_modpath ( " awards " ) ~= nil and minetest.get_modpath ( " default " ) ~= nil then
2016-08-01 15:26:33 +02:00
awards.register_achievement ( " orienteering_quadcorder " , {
title = S ( " Master of Orienteering " ) ,
description = S ( " Craft a quadcorder. " ) ,
icon = " orienteering_quadcorder.png " ,
trigger = {
type = " craft " ,
item = " orienteering:quadcorder " ,
target = 1
}
} )
end