aboutsummaryrefslogtreecommitdiff
path: root/ch_core/init.lua
diff options
context:
space:
mode:
Diffstat (limited to 'ch_core/init.lua')
-rw-r--r--ch_core/init.lua518
1 files changed, 518 insertions, 0 deletions
diff --git a/ch_core/init.lua b/ch_core/init.lua
new file mode 100644
index 0000000..50e94d6
--- /dev/null
+++ b/ch_core/init.lua
@@ -0,0 +1,518 @@
+ch_base.open_mod(core.get_current_modname())
+
+local modpath = core.get_modpath("ch_core")
+ch_core = {
+ storage = minetest.get_mod_storage(),
+ submods_loaded = {}, -- submod => true
+
+ ap_interval = 15, -- interval pro podmód „ap“
+ cas = 0,
+ gs_tasks = {},
+ inventory_size = {
+ normal = 32,
+ extended = 64,
+ },
+ supported_lang_codes = {cs = true, sk = true},
+ verze_ap = 1, -- aktuální verze podmódu „ap“
+ vezeni_data = {
+ min = vector.new(-1000, -1000, -1000),
+ max = vector.new(1000, 1000, 1000),
+ -- dvere = nil,
+ stred = vector.new(0, 0, 0),
+ },
+ colors = {
+ black = minetest.get_color_escape_sequence("#000000"),
+ blue = minetest.get_color_escape_sequence("#0000AA"),
+ green = minetest.get_color_escape_sequence("#00AA00"),
+ cyan = minetest.get_color_escape_sequence("#00AAAA"),
+ red = minetest.get_color_escape_sequence("#AA0000"),
+ magenta = minetest.get_color_escape_sequence("#AA00AA"),
+ brown = minetest.get_color_escape_sequence("#AA5500"),
+ yellow = minetest.get_color_escape_sequence("#AAAA00"),
+ light_gray = minetest.get_color_escape_sequence("#CCCCCC"),
+ dark_gray = minetest.get_color_escape_sequence("#555555"),
+ light_blue = minetest.get_color_escape_sequence("#5555FF"),
+ light_green = minetest.get_color_escape_sequence("#55FF55"),
+ light_cyan = minetest.get_color_escape_sequence("#55FFFF"),
+ light_red = minetest.get_color_escape_sequence("#FF5555"),
+ light_magenta = minetest.get_color_escape_sequence("#FF55FF"),
+ light_yellow = minetest.get_color_escape_sequence("#FFFF55"),
+ white = minetest.get_color_escape_sequence("#FFFFFF"),
+ },
+ overridable = {
+ -- funkce a proměnné, které mohou být přepsány z ostatních módů
+ reset_bank_account = function(player_name) return end,
+ trash_all_sound = "", -- zvuk k přehrání při mazání více předmětů
+ trash_one_sound = "", -- zvuk k přehrání při mazání jednoho předmětu
+ chyba_handler = function(player, text) return end,
+ },
+}
+
+ch_time.set_time_speed_during_day(26) -- was 24
+ch_time.set_time_speed_during_night(132) -- was 48
+
+local current_submod
+
+function ch_core.open_submod(submod, required_submods)
+ if current_submod ~= nil then
+ error("[ch_core/"..current_submod.."] modul nebyl uzavřen!")
+ end
+ for s, c in pairs(required_submods or {}) do
+ if c and not ch_core.submods_loaded[s] then
+ error("ch_core submodule '"..s.."' is required to be loaded before '"..submod.."'!")
+ end
+ end
+ current_submod = submod
+ return true
+end
+function ch_core.close_submod(submod)
+ if current_submod == nil then
+ error("Vícenásobné volání ch_core.close_submod()!")
+ elseif current_submod ~= submod then
+ error("[ch_core/"..current_submod.."] modul chybně uzavřen jako "..submod.."!")
+ end
+ current_submod = nil
+ ch_core.submods_loaded[submod] = true
+ return true
+end
+
+dofile(modpath .. "/active_objects.lua")
+dofile(modpath .. "/markers.lua")
+dofile(modpath .. "/barvy_linek.lua")
+dofile(modpath .. "/nodes.lua")
+dofile(modpath .. "/plaster.lua")
+dofile(modpath .. "/hotbar.lua")
+dofile(modpath .. "/vgroups.lua")
+dofile(modpath .. "/data.lua")
+dofile(modpath .. "/lib.lua") -- : data
+dofile(modpath .. "/entity_register.lua") -- : lib
+dofile(modpath .. "/interiors.lua") -- : lib
+dofile(modpath .. "/shapes_db.lua") -- : lib
+dofile(modpath .. "/penize.lua") -- : lib
+dofile(modpath .. "/nodedir.lua") -- : lib
+dofile(modpath .. "/formspecs.lua") -- : data, lib
+dofile(modpath .. "/areas.lua") -- : data, lib
+dofile(modpath .. "/nametag.lua") -- : data, lib
+dofile(modpath .. "/privs.lua")
+dofile(modpath .. "/clean_players.lua") -- : data, lib, privs
+dofile(modpath .. "/localize_chatcommands.lua") -- : data, lib, privs
+dofile(modpath .. "/udm.lua") -- : areas, data, lib
+dofile(modpath .. "/chat.lua") -- : areas, data, lib, privs, nametag, udm
+dofile(modpath .. "/shape_selector.lua") -- : chat, formspecs, lib
+dofile(modpath .. "/events.lua") -- : chat, data, lib, privs
+dofile(modpath .. "/stavby.lua") -- : chat, events, lib
+-- dofile(modpath .. "/inv_inspector.lua") -- : data, formspecs, lib, chat
+dofile(modpath .. "/podnebi.lua") -- : privs, chat
+dofile(modpath .. "/dennoc.lua") -- : privs, chat
+dofile(modpath .. "/hud.lua") -- : data, lib, chat
+dofile(modpath .. "/ap.lua") -- : chat, data, events, hud, lib
+dofile(modpath .. "/registrace.lua") -- : chat, data, events, lib, nametag
+dofile(modpath .. "/pryc.lua") -- : data, lib, events, privs
+dofile(modpath .. "/joinplayer.lua") -- : chat, data, formspecs, lib, nametag, pryc, events
+dofile(modpath .. "/padlock.lua") -- : data, lib
+dofile(modpath .. "/vezeni.lua") -- : privs, data, lib, chat, hud
+dofile(modpath .. "/timers.lua") -- : data, chat, hud
+dofile(modpath .. "/wielded_light.lua") -- : data, lib, nodes
+dofile(modpath .. "/teleportace.lua") -- : data, lib, chat, privs, stavby, timers
+dofile(modpath .. "/creative_inventory.lua") -- : lib
+dofile(modpath .. "/kos.lua") -- : lib
+
+
+local ifthenelse = assert(ch_core.ifthenelse)
+local last_timeofday = 0 -- pravděpodobně se pokusí něco přehrát v prvním globalstepu,
+-- ale to nevadí, protöže v tu chvíli stejně nemůže být ještě nikdo online.
+local abs = math.abs
+local get_timeofday = core.get_timeofday
+local gain_1 = {gain = 1.0}
+local head_bone_name = "Head"
+local head_bone_override = {
+ position = {vec = vector.new(0, 6.35, 0), absolute = true},
+ rotation = {vec = vector.zero(), absolute = true},
+}
+local emoting = (core.get_modpath("emote") and emote.emoting) or {}
+local globstep_dtime_accumulated = 0.0
+local hud_dtime_accumulated = 0.0
+local get_us_time = assert(core.get_us_time)
+local has_wielded_light = core.get_modpath("wielded_light")
+local custom_globalsteps = {}
+local last_ap_timestamp = 0
+local use_forbidden_height = ifthenelse(core.settings:get_bool("ch_forbidden_height", false), true, false)
+local gs_task
+local gs_task_next_step
+local gs_handler = {
+ cancel = "on_cancelled",
+ finished = "on_finished",
+ failed = "on_failed",
+}
+
+local stepheight_low = {stepheight = 0.3}
+local stepheight_high = {stepheight = 1.1}
+
+local function get_root(o)
+ local r = o:get_attach()
+ while r do
+ o = r
+ r = o:get_attach()
+ end
+ return o
+end
+
+function ch_core.register_player_globalstep(func, index)
+ if not index then
+ index = #custom_globalsteps + 1
+ end
+ if not func then
+ error("Invalid call to ch_core.register_player_globalstep()!")
+ end
+ custom_globalsteps[index] = func
+ return index
+end
+
+local function globalstep(dtime)
+ if globstep_dtime_accumulated == 0 then
+ -- první globalstep:
+ ch_core.update_creative_inventory(true)
+ globstep_dtime_accumulated = globstep_dtime_accumulated + dtime
+ return
+ end
+
+ globstep_dtime_accumulated = globstep_dtime_accumulated + dtime
+ ch_core.cas = globstep_dtime_accumulated
+ local ch_core_cas = globstep_dtime_accumulated
+ local us_time = get_us_time()
+
+ -- DEN: 5:30 .. 19:00
+ local tod = get_timeofday()
+ local byla_noc = last_timeofday < 0.2292 or last_timeofday > 0.791666
+ local je_noc = tod < 0.2292 or tod > 0.791666
+ if byla_noc and not je_noc then
+ -- Ráno
+ minetest.sound_play("birds", gain_1)
+ local new_speed = ch_time.get_time_speed_during_day()
+ if new_speed ~= nil then
+ core.settings:set("time_speed", tostring(new_speed))
+ end
+ elseif not byla_noc and je_noc then
+ -- Noc
+ core.sound_play("owl", gain_1)
+ local new_speed = ch_time.get_time_speed_during_night()
+ if new_speed ~= nil then
+ core.settings:set("time_speed", tostring(new_speed))
+ end
+ end
+ last_timeofday = tod
+
+ local process_ap = us_time - last_ap_timestamp >= ch_core.ap_interval * 1000000
+ if process_ap then
+ last_ap_timestamp = us_time
+ end
+
+ hud_dtime_accumulated = hud_dtime_accumulated + dtime
+ if hud_dtime_accumulated > 1 then
+ hud_dtime_accumulated = 0
+ ch_core.update_gametime_hudbar(nil, tod)
+ end
+
+ -- PRO KAŽDÉHO HRÁČE/KU:
+ local connected_players = core.get_connected_players()
+ for _, player in pairs(connected_players) do
+ local player_name = player:get_player_name()
+ local player_pos = player:get_pos()
+ local online_charinfo = ch_data.online_charinfo[player_name]
+ local offline_charinfo = ch_data.get_or_add_offline_charinfo(player_name)
+ local disrupt_teleport_flag = false
+ local disrupt_pryc_flag = false
+ local player_wielded_item_name = player:get_wielded_item():get_name() or ""
+ local player_root = get_root(player)
+
+ if online_charinfo then
+ local previous_wield_item_name = online_charinfo.wielded_item_name or ""
+ online_charinfo.wielded_item_name = player_wielded_item_name
+
+ -- ÚHEL HLAVY:
+ local emote = emoting[player]
+ if not emote or emote ~= "lehni" then
+ local puvodni_uhel_hlavy = online_charinfo.uhel_hlavy or 0
+ local novy_uhel_hlavy = player:get_look_vertical() - 0.01745329251994329577 * (online_charinfo.head_offset or 0)
+ local rozdil = novy_uhel_hlavy - puvodni_uhel_hlavy
+ if rozdil > 0.001 or rozdil < -0.001 then
+ if rozdil > 0.3 then
+ -- omezit pohyb hlavy
+ novy_uhel_hlavy = puvodni_uhel_hlavy + 0.3
+ elseif rozdil < -0.3 then
+ novy_uhel_hlavy = puvodni_uhel_hlavy - 0.3
+ end
+ head_bone_override.rotation.vec.x = -0.5 * (puvodni_uhel_hlavy + novy_uhel_hlavy)
+ player:set_bone_override(head_bone_name, head_bone_override)
+ online_charinfo.uhel_hlavy = novy_uhel_hlavy
+ end
+ else
+ head_bone_override.rotation.vec.x = 0
+ player:set_bone_override(head_bone_name, head_bone_override)
+ end
+
+ -- REAGOVAT NA KLÁVESY:
+ local old_control_bits = online_charinfo.klavesy_b or 0
+ local new_control_bits = player:get_player_control_bits()
+ if new_control_bits ~= old_control_bits then
+ local new_controls = player:get_player_control()
+ local old_controls = online_charinfo.klavesy or new_controls
+ online_charinfo.klavesy = new_controls
+ online_charinfo.klavesy_b = new_control_bits
+ if new_controls.aux1 and not old_controls.aux1 then
+ ch_core.show_player_list(player, online_charinfo)
+ player:set_properties(stepheight_high)
+ elseif not new_controls.aux1 and old_controls.aux1 then
+ ch_core.hide_player_list(player, online_charinfo)
+ player:set_properties(stepheight_low)
+ end
+
+ disrupt_pryc_flag = true
+ if not disrupt_teleport_flag and (new_controls.up or new_controls.down or new_controls.left or new_controls.right or new_controls.jump or new_controls.dig or new_controls.place) then
+ disrupt_teleport_flag = true
+ end
+ end
+
+ -- VĚZENÍ, zakázaná výška:
+ if --[[ ch_core.submods_loaded["vezeni"] and ]] offline_charinfo.player.trest > 0 then
+ ch_core.vykon_trestu(player, player_pos, us_time, online_charinfo)
+ elseif use_forbidden_height and player_pos.y >= 1024 and player_pos.y <= 1256 then
+ -- zakázaná výška
+ minetest.log("warning", "Player "..player_name.." reached forbidden area at "..minetest.pos_to_string(player_pos).."!")
+ minetest.after(0.1, function()
+ ch_core.teleport_player({
+ type = "admin",
+ player = player,
+ target_pos = ch_core.positions["zacatek_1"] or vector.zero(),
+ sound_after = "chat3_bell",
+ })
+ ch_core.systemovy_kanal(player_name, "Dostali jste se do zakázaného výškového pásma! Pozice y >= 1024 jsou nepřístupné.")
+ end)
+ end
+
+ -- pokud se změnil držený předmět, možná bude potřeba zobrazit jeho nápovědu
+ if player_wielded_item_name ~= previous_wield_item_name then
+ disrupt_pryc_flag = true
+ local help_def = ch_data.should_show_help(player, online_charinfo, player_wielded_item_name)
+ if help_def then
+ local zluta = minetest.get_color_escape_sequence("#ffff00")
+ local zelena = minetest.get_color_escape_sequence("#00ff00")
+ local s = zluta.."Nápověda k předmětu „"..zelena..(help_def.description or ""):gsub("\n", "\n "..zelena)..zluta.."“:\n "..zluta..(help_def._ch_help or ""):gsub("\n", "\n "..zluta)
+ ch_core.systemovy_kanal(player_name, s)
+ end
+
+ -- periskop:
+ if online_charinfo.periskop ~= nil and player_wielded_item_name ~= "ch_extras:periskop" then
+ online_charinfo.periskop.cancel()
+ end
+ end
+
+ -- ZRUŠIT /pryč:
+ if disrupt_pryc_flag and online_charinfo.pryc then
+ online_charinfo.pryc(player, online_charinfo)
+ end
+
+ -- ČASOVAČE
+ local timers = online_charinfo.ch_timers
+ if timers then
+ for timer_id, timer_def in pairs(table.copy(timers)) do
+ local remains = timer_def.run_at - ch_core_cas
+ if remains <= 0.1 then
+ local func_to_run = timer_def.func
+ ch_core.cancel_ch_timer(online_charinfo, timer_id)
+ if func_to_run then
+ minetest.after(0.1, function()
+ return func_to_run()
+ end)
+ end
+ elseif timer_def.hudbar then
+ remains = math.ceil(remains)
+ if remains ~= timer_def.last_hud_value then
+ hb.change_hudbar(player, timer_def.hudbar, remains)
+ timer_def.last_hud_value = remains
+ end
+ end
+ end
+ end
+
+ -- ZRUŠIT teleport
+ local teleport_def = ch_core.get_ch_timer_info(online_charinfo, "teleportace")
+ if teleport_def then
+ if not disrupt_teleport_flag then
+ local ts_pos = teleport_def.start_pos
+ if ts_pos then
+ disrupt_teleport_flag = abs(ts_pos.x - player_pos.x) > 0.5 or abs(ts_pos.z - player_pos.z) > 0.5
+ end
+ end
+ if disrupt_teleport_flag then
+ ch_core.cancel_teleport(player_name, true)
+ end
+ end
+
+ -- ZRUŠIT horkou zprávu
+ local horka_zprava = online_charinfo.horka_zprava
+ if horka_zprava and ch_core_cas >= horka_zprava.timeout then
+ online_charinfo.horka_zprava = nil
+ player:set_nametag_attributes(ch_core.compute_player_nametag(online_charinfo, offline_charinfo))
+ end
+
+ -- nesmrtelnost (stačilo by spouštět občas)
+ if minetest.is_creative_enabled(player_name) then
+ if not online_charinfo.is_creative then
+ online_charinfo.is_creative = true
+ ch_core.set_immortal(player, online_charinfo.is_creative)
+ end
+ else
+ if online_charinfo.is_creative then
+ online_charinfo.is_creative = false
+ ch_core.set_immortal(player, online_charinfo.is_creative)
+ end
+ end
+
+ -- SPUSTIT registrované obslužné funkce
+ local i = 1
+ while custom_globalsteps[i] do
+ custom_globalsteps[i](player, player_name, online_charinfo, offline_charinfo, us_time)
+ i = i + 1
+ end
+
+ -- SLEDOVÁNÍ AKTIVITY
+ local ap = online_charinfo.ap
+ if ap then
+ if player_pos.x ~= ap.pos.x then
+ ap.pos_x_gen = ap.pos_x_gen + 1
+ end
+ if player_pos.y ~= ap.pos.y then
+ ap.pos_y_gen = ap.pos_y_gen + 1
+ end
+ if player_pos.z ~= ap.pos.z then
+ ap.pos_z_gen = ap.pos_z_gen + 1
+ end
+ ap.pos = player_pos
+
+ local player_velocity = player_root:get_velocity()
+ if player_velocity.x ~= ap.velocity.x then
+ ap.velocity_x_gen = ap.velocity_x_gen + 1
+ end
+ if player_velocity.y ~= ap.velocity.y then
+ ap.velocity_y_gen = ap.velocity_y_gen + 1
+ end
+ if player_velocity.z ~= ap.velocity.z then
+ ap.velocity_z_gen = ap.velocity_z_gen + 1
+ end
+ ap.velocity = player_velocity
+
+ local player_control_bits = player:get_player_control_bits()
+ if player_control_bits ~= ap.control then
+ ap.control = player_control_bits
+ ap.control_gen = ap.control_gen + 1
+ end
+
+ local look_horizontal = player:get_look_horizontal()
+ if look_horizontal ~= ap.look_h then
+ ap.look_h = look_horizontal
+ ap.look_h_gen = ap.look_h_gen + 1
+ end
+ local look_vertical = player:get_look_vertical()
+ if look_vertical ~= ap.look_v then
+ ap.look_v = look_vertical
+ ap.look_v_gen = ap.look_v_gen + 1
+ end
+
+ local last
+ last = ch_core.last_mistni
+ if last.char == player_name then
+ ap.chat_mistni_gen = last.char_gen
+ end
+ last = ch_core.last_celoserverovy
+ if last.char == player_name then
+ ap.chat_celoserverovy_gen = last.char_gen
+ end
+ last = ch_core.last_sepot
+ if last.char == player_name then
+ ap.chat_sepot_gen = last.char_gen
+ end
+ last = ch_core.last_soukromy
+ if last.char == player_name then
+ ap.chat_soukromy_gen = last.char_gen
+ end
+
+ if process_ap then
+ ch_core.ap_update(player, online_charinfo, offline_charinfo)
+ end
+ elseif process_ap then
+ ch_core.ap_init(player, online_charinfo, offline_charinfo)
+ end
+
+ -- NASTAVIT OSVĚTLENÍ [data, nodes, wielded_light]
+ -- - provést po proběhnutí registrovaných obslužných funkcí,
+ -- protože ty mohly osvětlení změnit
+ local light_slots = has_wielded_light and online_charinfo.wielded_lights
+ if light_slots then
+ local new_light_level = 0
+ for _, light_level in pairs(light_slots) do
+ if light_level > new_light_level then
+ new_light_level = light_level
+ end
+ end
+ if new_light_level ~= online_charinfo.light_level then
+ minetest.log("info", "Light level of player "..player_name.." changed: "..online_charinfo.light_level.." to "..new_light_level)
+ if new_light_level > 0 then
+ wielded_light.track_user_entity(player, "ch_core", string.format("ch_core:light_%02d", new_light_level))
+ else
+ wielded_light.track_user_entity(player, "ch_core", "default:cobble")
+ end
+ online_charinfo.light_level = new_light_level
+ online_charinfo.light_level_timestamp = us_time
+ elseif new_light_level > 0 and us_time - online_charinfo.light_level_timestamp > 5000000 then
+ -- refresh non-zero light level each 5 seconds
+ wielded_light.track_user_entity(player, "ch_core", string.format("ch_core:light_%02d", new_light_level))
+ online_charinfo.light_level_timestamp = us_time
+ end
+ end
+ end
+ end
+
+ -- globalstep tasks:
+ if gs_task ~= nil then
+ -- run the step
+ local context = gs_task.context
+ local step = gs_task.steps[gs_task_next_step]
+ local n_steps = #gs_task.steps
+ local result = gs_task.on_step(context, step, gs_task_next_step, n_steps)
+ local handler = gs_handler[result] -- if this crashes on nil, add 'or ""'
+ if handler == nil then
+ if gs_task_next_step < n_steps then
+ -- příště pokračovat dalším krokem stejného úkolu
+ gs_task_next_step = gs_task_next_step + 1
+ else
+ -- úkol dokončen
+ handler = "on_finished"
+ end
+ end
+ if handler ~= nil then
+ -- zavolat obsluhu a skončit
+ handler = gs_task[handler]
+ if handler ~= nil then
+ handler(context, gs_task_next_step, n_steps)
+ end
+ gs_task = nil
+ end
+
+ elseif ch_core.gs_tasks[1] ~= nil then
+ -- vyzvednout další úkol a zavolat jeho on_start()
+ gs_task = ch_core.gs_tasks[1]
+ gs_task_next_step = 1
+ table.remove(ch_core.gs_tasks, 1)
+ if gs_task.on_start ~= nil then
+ local result = gs_task.on_start(gs_task.context)
+ local handler = gs_handler[result] -- if this crashes on nil, add 'or ""'
+ if handler ~= nil then
+ gs_task = nil
+ end
+ end
+ end
+end
+core.register_globalstep(globalstep)
+
+ch_base.close_mod(minetest.get_current_modname())