local S if minetest.get_translator then S = minetest.get_translator("calendar") else S = function(s) return s end end local F = minetest.formspec_escape local COLOR_HOLIDAY = "#00FF00" local COLOR_DAYBOX = "#00000080" local COLOR_DAYBOX_TODAY = "#FFFFFF80" local player_current_calendars = {} local ORDINAL = false local function show_calendar(player_name, ordinal, wanted_months, wanted_years) local days, months, years = calendar.get_date() local total_days = minetest.get_day_count() local ddays, dmonths, dyears = calendar.get_date(nil, ordinal) local wanted_dmonths, wanted_dyears if not wanted_months then wanted_months = months end if not wanted_years then wanted_years = years end wanted_dmonths = wanted_months wanted_dyears = wanted_years if ordinal then wanted_dmonths = wanted_dmonths + 1 wanted_dyears = wanted_dyears + 1 end local formspec = "formspec_version[3]size["..(calendar.WEEK_DAYS+2)..",10]" if ordinal then formspec = formspec .. "label[0.5,0.5;"..F(S("@1, year @2", calendar.month_names[wanted_months+1], wanted_dyears)).."]" else formspec = formspec .. "label[0.5,0.5;"..F(S("@1, @2 years", calendar.month_names[wanted_months+1], wanted_dyears)).."]" end local start_day, end_day local tdays = 0 tdays = tdays + wanted_years * (calendar.MONTHS * calendar.MONTH_DAYS) tdays = tdays + wanted_months * calendar.MONTH_DAYS local tdays_start = tdays local weekday = calendar.get_weekday(tdays) local x, y = 0.75, 1.2 for w=1, #calendar.weekday_names_short do formspec = formspec .. "label["..x..","..y..";"..calendar.weekday_names_short[w].."]" x = x + 1.1 end x, y = 0.5, 1.7 for iday=0, calendar.MONTH_DAYS - 1 do weekday = weekday + 1 if weekday > calendar.WEEK_DAYS then weekday = 1 y = y + 1.1 end x = (weekday*1.1)- 0.5 local pday = iday if ordinal then pday = iday + 1 end local day_str = tostring(pday) local box_color = COLOR_DAYBOX local holidays = calendar.get_holidays(tdays) local tooltip_lines = {} if #holidays > 0 then table.insert(tooltip_lines, minetest.colorize(COLOR_HOLIDAY, holidays[1].name)) day_str = minetest.colorize(COLOR_HOLIDAY, day_str) end if tdays == total_days then box_color = COLOR_DAYBOX_TODAY table.insert(tooltip_lines, S("Today")) end if #tooltip_lines > 0 then formspec = formspec .. "tooltip["..x..","..y..";1,1;"..F(table.concat(tooltip_lines, "\n")).."]" end day_str = F(day_str) formspec = formspec .. "box["..x..","..y..";1,1;"..box_color.."]" .. "label["..(x+0.15)..","..(y+0.3)..";"..day_str.."]" tdays = tdays + 1 end y = y + 1.1 if calendar.get_weekday(tdays_start) <= calendar.get_weekday(tdays - 1) then y = y + 1.1 end y = y + 0.1 if wanted_months > 0 or wanted_years > 0 then formspec = formspec .. "button[0.5,"..y..";1,1;prev_year;<<]" .. "button[1.5,"..y..";1,1;prev_month;<]" end formspec = formspec .. "button[2.5,"..y..";1,1;next_month;>]" .. "button[3.5,"..y..";1,1;next_year;>>]" minetest.show_formspec(player_name, "calendar:calendar", formspec) player_current_calendars[player_name] = { years = wanted_years, months = wanted_months } end minetest.register_on_player_receive_fields(function(player, formname, fields) if formname ~= "calendar:calendar" then return end if not player:is_player() then return end local name = player:get_player_name() local cur_years, cur_months if not player_current_calendars then return end cur_years = player_current_calendars[name].years cur_months = player_current_calendars[name].months if fields.next_year then cur_years = cur_years + 1 show_calendar(name, ORDINAL, cur_months, cur_years) elseif fields.prev_year then if cur_years == 0 then cur_months = 0 else cur_years = cur_years - 1 end show_calendar(name, ORDINAL, cur_months, cur_years) elseif fields.next_month then cur_months = cur_months + 1 if cur_months > calendar.MONTHS - 1 then cur_months = 0 cur_years = cur_years + 1 end show_calendar(name, ORDINAL, cur_months, cur_years) elseif fields.prev_month then cur_months = cur_months - 1 if cur_months < 0 then if cur_years > 0 then cur_months = calendar.MONTHS - 1 cur_years = cur_years - 1 end end show_calendar(name, ORDINAL, cur_months, cur_years) end end) minetest.register_on_leaveplayer(function(player) local name = player:get_player_name() player_current_calendars[name] = nil end) minetest.register_chatcommand("calendar", { param = "", description = S("Display calendar"), func = function( name, param ) show_calendar(name, ORDINAL) end, })