123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- -- Author: MustTest/BluebirdGreycoat51/GoldFireUn
- -- License: MIT
- if not minetest.global_exists("bone_mark") then bone_mark = {} end
- bone_mark.modpath = minetest.get_modpath("bone_mark")
- bone_mark.players = bone_mark.players or {}
- local STEP_TIME = 3.5
- local BONE_NEAR_DIST = 3
- local BONE_FAR_DIST = 100
- local CORPSE_MISSING_TIME = 120
- function bone_mark.add_corpse(pos, pname)
- bone_mark.players[pname] = bone_mark.players[pname] or {}
- local t = bone_mark.players[pname]
- t[#t + 1] = {
- pos = vector.round(pos),
- shown = false,
- hud = nil,
- remove = false,
- timer = 0,
- }
- end
- local function keep_mark(t)
- if not t.remove then
- return true
- end
- end
- function bone_mark.notify_hud_update_needed(pname)
- step_timer = STEP_TIME
- local pdata = bone_mark.players[pname]
- if pdata then
- -- pref should *usually* never be nil, but check for it anyway for edge cases.
- local pref = minetest.get_player_by_name(pname)
- if pref then
- for index, mdata in ipairs(pdata) do
- if mdata.hud then pref:hud_remove(mdata.hud) end
- mdata.hud = nil
- mdata.shown = false
- end
- end
- end
- end
- local step_timer = 0
- function bone_mark.on_globalstep(dtime)
- step_timer = step_timer + dtime
- if step_timer < STEP_TIME then return end
- step_timer = 0
- for pname, pdata in pairs(bone_mark.players) do
- -- pdata is an array.
- for index, mdata in ipairs(pdata) do
- -- pref should never be nil, because we remove player's data from the main
- -- player-table when they leave the game. Check anyway for edge cases.
- local pref = minetest.get_player_by_name(pname)
- if not pref then
- goto continue
- end
- local ppos = pref:get_pos()
- local node = minetest.get_node_or_nil(mdata.pos)
- local message = "Corpse"
- if node and node.name ~= "bones:bones" then
- message = "Corpse Missing"
- mdata.timer = (mdata.timer or 0) + STEP_TIME
- -- Missing bones HUD element timeout.
- if mdata.timer > CORPSE_MISSING_TIME then
- if mdata.hud then pref:hud_remove(mdata.hud) end
- mdata.hud = nil
- mdata.remove = true
- end
- -- Update HUD element right away.
- if not mdata.corpse_gone then
- if mdata.hud then pref:hud_remove(mdata.hud) end
- mdata.hud = nil
- mdata.shown = false
- mdata.corpse_gone = true
- end
- end
- local far_dist = BONE_FAR_DIST
- if passport.player_has_key(pname, pref) then
- far_dist = BONE_FAR_DIST * 10
- end
- local same_realm = rc.same_realm(mdata.pos, ppos)
- if not mdata.remove then
- local dist = vector.distance(ppos, mdata.pos)
- if not mdata.shown then
- if dist > BONE_NEAR_DIST and dist <= far_dist and same_realm then
- -- Show waypoint if player in range.
- -- Just in case, but this probably shouldn't happen.
- if mdata.hud then pref:hud_remove(mdata.hud) end
- -- http://www.shodor.org/~efarrow/trunk/html/rgbint.html
- local number = "6368886"
- local precision = 0
- if passport.player_has_key(pname, pref) then
- precision = 10
- end
- mdata.hud = pref:hud_add({
- hud_elem_type = "waypoint",
- name = message,
- number = number,
- world_pos = mdata.pos,
- precision = precision,
- })
- mdata.shown = true
- end
- elseif mdata.shown then
- -- Hide waypoint when player too far or too near.
- if dist > far_dist or not same_realm then
- if mdata.hud then pref:hud_remove(mdata.hud) end
- mdata.hud = nil
- mdata.shown = false
- elseif dist < BONE_NEAR_DIST and pref:get_hp() > 0 then
- -- Remove waypoint when player near enough and NOT dead.
- -- Need the HP check because otherwise waypoint would be removed
- -- right away if player doesn't press respawn quickly enough.
- if mdata.hud then pref:hud_remove(mdata.hud) end
- mdata.hud = nil
- mdata.remove = true
- end
- end
- end -- If not to be removed.
- ::continue::
- end
- -- Get rid of dead ones.
- utility.array_remove(pdata, keep_mark)
- end
- end
- function bone_mark.on_leaveplayer(pref)
- local pname = pref:get_player_name()
- bone_mark.players[pname] = nil
- end
- if not bone_mark.registered then
- minetest.register_globalstep(function(...)
- return bone_mark.on_globalstep(...)
- end)
- minetest.register_on_leaveplayer(function(...)
- return bone_mark.on_leaveplayer(...)
- end)
- local c = "bone_mark:core"
- local f = bone_mark.modpath .. "/init.lua"
- reload.register_file(c, f, false)
- bone_mark.registered = true
- end
|