432 lines
14 KiB
Lua
432 lines
14 KiB
Lua
local ns = firefly
|
|
|
|
ns.players = {}
|
|
|
|
|
|
minetest.register_entity(":firefly:player", {
|
|
initial_properties = {
|
|
visual = "mesh",
|
|
mesh = "firefly_character.gltf",
|
|
textures = {"firefly_character.png"},
|
|
backface_culling = false,
|
|
pointable = false,
|
|
visual_size = vector.new(1,1,1),
|
|
collisionbox = {2/3, 1.625, 2/3, -2/3, 0, -2/3},
|
|
selectionbox = {2/3, 1.625, 2/3, -2/3, 0, -2/3},
|
|
static_save = false,
|
|
},
|
|
on_deactivate = function(e)
|
|
-- Ensure that the player's display will never get lost until the player leaves.
|
|
if e.owner and e.owner.player:get_pos() then
|
|
e.owner.object = minetest.add_entity(e.owner.pos, "firefly:player")
|
|
e.owner.object:set_attach(e.owner.player)
|
|
end
|
|
end,
|
|
on_step = function(e, dtime, movement)
|
|
if e.owner then
|
|
e.owner.movement = movement
|
|
end
|
|
end
|
|
})
|
|
|
|
function ns.add_jetpack_particles(m)
|
|
local def = {
|
|
attached = m.jetpack_a,
|
|
pos = {
|
|
min = vector.new(-0.1,-0.1,-0.1),
|
|
max = vector.new(0.1,0.1,0.1)
|
|
},
|
|
vel = {
|
|
min = vector.new(0, -5, 0),
|
|
max = vector.new(0, -1, 0)
|
|
},
|
|
animation = {
|
|
type = "vertical_frames",
|
|
aspect_w = 1,
|
|
aspect_h = 1,
|
|
length = -1
|
|
},
|
|
texture = ns.solid_color_frames {"#f7d19b", "#f0a951", "#e1820c", "#cd5819", "#5d342c", "#444"},
|
|
time = 0,
|
|
amount = 50,
|
|
exptime = 0.5,
|
|
size_tween = {
|
|
{min = 1, max = 2},
|
|
0.05
|
|
}
|
|
|
|
}
|
|
m.jetpack_particles_a = minetest.add_particlespawner(table.copy(def))
|
|
def.attached = m.jetpack_b
|
|
m.jetpack_particles_b = minetest.add_particlespawner(def)
|
|
end
|
|
|
|
function ns.remove_jetpack_particles(m)
|
|
minetest.delete_particlespawner(m.jetpack_particles_a)
|
|
minetest.delete_particlespawner(m.jetpack_particles_b)
|
|
end
|
|
|
|
function ns.enter_jetpack_mode(m)
|
|
m.jetpack_mode = true
|
|
m:set_physics_override("jetpack", {
|
|
speed = 3,
|
|
})
|
|
ns.add_jetpack_particles(m)
|
|
end
|
|
|
|
function ns.exit_jetpack_mode(m)
|
|
m.jetpack_mode = nil
|
|
m:set_physics_override("jetpack")
|
|
ns.remove_jetpack_particles(m)
|
|
end
|
|
|
|
local blank_physics_override = {
|
|
speed = 1,
|
|
speed_walk = 1,
|
|
speed_crouch = 1,
|
|
speed_fast = 1,
|
|
speed_climb = 1,
|
|
speed_jump = 1,
|
|
jump = 1,
|
|
gravity = 1,
|
|
liquid_fluidity = 1,
|
|
liquid_fluidity_smooth = 1,
|
|
liquid_sink = 1,
|
|
acceleration_default = 1,
|
|
acceleration_air = 1,
|
|
acceleration_fast = 1,
|
|
}
|
|
|
|
Player = {
|
|
listeners = {},
|
|
init = function(p)
|
|
local m = {
|
|
active = true,
|
|
player = p,
|
|
name = p:get_player_name(),
|
|
object = minetest.add_entity(p:get_pos(), "firefly:player"),
|
|
hud = {},
|
|
physics_overrides = {},
|
|
pos = p:get_pos()
|
|
}
|
|
setmetatable(m, {__index = Player})
|
|
m.object:get_luaentity().owner = m
|
|
|
|
p:set_properties {
|
|
visual = "sprite",
|
|
textures = {"blank.png"},
|
|
pointable = false
|
|
}
|
|
|
|
p:hud_set_flags {
|
|
healthbar = false,
|
|
breathbar = false,
|
|
|
|
}
|
|
|
|
m.eye_height = p:get_properties().eye_height
|
|
|
|
m.object:set_attach(p)
|
|
|
|
m.jetpack = minetest.add_entity(m.pos, "display")
|
|
m.jetpack:set_properties {
|
|
visual = "mesh",
|
|
mesh = "firefly_jetpack.gltf",
|
|
textures = {"firefly_jetpack.png", "blank.png"}
|
|
}
|
|
m.jetpack:set_attach(m.object, "Torso")
|
|
m.jetpack_a = minetest.add_entity(m.pos, "display")
|
|
m.jetpack_a:set_attach(m.jetpack, "exhaust1")
|
|
m.jetpack_b = minetest.add_entity(m.pos, "display")
|
|
m.jetpack_b:set_attach(m.jetpack, "exhaust2")
|
|
|
|
|
|
m.stats_bg = m.player:hud_add {
|
|
type = "image",
|
|
text = "firefly_stats_bg.png",
|
|
position = {x = 0, y = 1},
|
|
offset = {x = 50, y = -50},
|
|
alignment = {x = 1, y = -1},
|
|
scale = {x = 6, y = 6},
|
|
}
|
|
|
|
m.healthbar = m.player:hud_add {
|
|
type = "image",
|
|
text = "[fill:4x32:0,0:#0000^[lowpart:100:firefly_health_bar.png^[transformR270^[multiply:#d33",
|
|
position = {x = 0, y = 1},
|
|
offset = {x = 50 +(29 *6), y = -50 -(19 *6)},
|
|
alignment = {x = 1, y = -1},
|
|
scale = {x = 6, y = 6},
|
|
}
|
|
|
|
m.ammobar = m.player:hud_add {
|
|
type = "image",
|
|
text = "[fill:4x32:0,0:#0000^[lowpart:100:firefly_health_bar.png^[transformR270^[multiply:#dc4",
|
|
position = {x = 0, y = 1},
|
|
offset = {x = 50 +(29 *6), y = -50 -(13 *6)},
|
|
alignment = {x = 1, y = -1},
|
|
scale = {x = 6, y = 6},
|
|
}
|
|
|
|
m.ammobar2 = m.player:hud_add {
|
|
type = "image",
|
|
text = "[fill:4x32:0,0:#0000^[lowpart:100:firefly_health_bar.png^[transformR270^[multiply:#4dc",
|
|
position = {x = 0, y = 1},
|
|
offset = {x = 50 +(29 *6), y = -50 -(7 *6)},
|
|
alignment = {x = 1, y = -1},
|
|
scale = {x = 6, y = 6},
|
|
}
|
|
|
|
m:set_hotbar_size(8)
|
|
|
|
|
|
m.ctl = {}
|
|
m.pitch = 0
|
|
m.yaw = 0
|
|
m.last_jump = 0
|
|
Player:dispatch('init', m)
|
|
return m
|
|
end,
|
|
deinit = function(m)
|
|
m.active = false
|
|
end,
|
|
tick = function(m, dtime)
|
|
local p = m.player
|
|
local pos = p:get_pos()
|
|
m.eye_pos = pos:offset(0, m.eye_height, 0)
|
|
local vel = p:get_velocity()
|
|
local pitch = p:get_look_vertical()
|
|
local yaw = p:get_look_horizontal()
|
|
local look_dir = p:get_look_dir()
|
|
local ctl = p:get_player_control()
|
|
local time = minetest.get_us_time()
|
|
|
|
local standing_on = minetest.get_node(pos:offset(0, -0.5, 0))
|
|
|
|
local moving = ctl.up or ctl.left or ctl.down or ctl.right
|
|
|
|
-- MARK: Wield callbacks
|
|
|
|
local wielded_item = p:get_wielded_item()
|
|
local wi_def = wielded_item:get_definition()
|
|
if not m.wielded_item or m.wielded_item:get_name() ~= wielded_item:get_name() then
|
|
if m.wielded_item then
|
|
local old_def = m.wielded_item:get_definition()
|
|
if old_def.on_unwield then
|
|
old_def.on_unwield(m.wielded_item, old_def, m)
|
|
end
|
|
end
|
|
m.wielded_item = wielded_item
|
|
if wi_def.on_wield then
|
|
wi_def.on_wield(wielded_item, wi_def, m)
|
|
end
|
|
end
|
|
if wi_def.while_wielded then
|
|
wi_def.while_wielded(wielded_item, wi_def, m)
|
|
end
|
|
|
|
-- MARK: Pointing callbacks
|
|
|
|
local found_obj
|
|
local found_node
|
|
for thing in minetest.raycast(m.eye_pos, m.eye_pos +(look_dir *5)) do
|
|
if thing.type == "object" then
|
|
found_obj = true
|
|
local e = thing.ref:get_luaentity()
|
|
if not m.pointed_obj or (m.pointed_obj.name or m.pointed_obj._name) ~= (e.name or e._name) then
|
|
if m.pointed_obj and m.pointed_obj.on_unhover then
|
|
m.pointed_obj:on_unhover(m)
|
|
end
|
|
m.pointed_obj = e
|
|
if e.on_hover then
|
|
e:on_hover(m)
|
|
end
|
|
end
|
|
break
|
|
elseif thing.type == "node" then
|
|
found_node = true
|
|
if not m.pointed_node or thing.under ~= m.pointed_node.under then
|
|
if m.pointed_node then
|
|
local on_unhover = minetest.registered_nodes[m.pointed_node.node_under.name].on_unhover
|
|
if on_unhover then
|
|
on_unhover(m.pointed_node.under, m)
|
|
end
|
|
end
|
|
thing.node_under = minetest.get_node(thing.under)
|
|
m.pointed_node = thing
|
|
local on_hover = minetest.registered_nodes[thing.node_under.name].on_hover
|
|
if on_hover then
|
|
on_hover(thing.under, m)
|
|
end
|
|
end
|
|
break
|
|
end
|
|
end
|
|
if not found_obj and m.pointed_obj then
|
|
if m.pointed_obj and m.pointed_obj.on_unhover then
|
|
m.pointed_obj:on_unhover(m)
|
|
end
|
|
m.pointed_obj = nil
|
|
end
|
|
if not found_node and m.pointed_node then
|
|
local on_unhover = minetest.registered_nodes[m.pointed_node.node_under.name].on_unhover
|
|
if m.pointed_node and on_unhover then
|
|
on_unhover(m.pointed_node.under, m)
|
|
end
|
|
m.pointed_node = nil
|
|
end
|
|
|
|
-- MARK: Animation
|
|
|
|
m.object:set_bone_override("root", {
|
|
rotation = {
|
|
vec = vector.new(0, -yaw, 0), absolute = true, interpolation = 0.1
|
|
}
|
|
})
|
|
|
|
m.object:set_bone_override("Head", {
|
|
rotation = {
|
|
vec = vector.new(pitch, 0, 0), absolute = true, interpolation = 0.1
|
|
}
|
|
})
|
|
|
|
m.moving = moving
|
|
|
|
if m.jetpack_mode then
|
|
if ctl.jump and vel.y < 10 then
|
|
p:add_velocity(vector.new(0, 32 *dtime, 0))
|
|
if not m.ctl.jump then
|
|
m:set_physics_override("jetpack", {
|
|
speed = 3,
|
|
})
|
|
ns.add_jetpack_particles(m)
|
|
end
|
|
end
|
|
|
|
if m.ctl.jump and not ctl.jump then
|
|
m:set_physics_override("jetpack")
|
|
ns.remove_jetpack_particles(m)
|
|
end
|
|
|
|
if standing_on.name ~= "air" then
|
|
ns.exit_jetpack_mode(m)
|
|
end
|
|
else
|
|
if ctl.jump and not m.ctl.jump then
|
|
if standing_on.name == "air" then
|
|
ns.enter_jetpack_mode(m)
|
|
end
|
|
end
|
|
end
|
|
|
|
m.standing_on = standing_on
|
|
m.yaw = yaw
|
|
m.pitch = pitch
|
|
m.look_dir = look_dir
|
|
m.pos = pos
|
|
m.ctl = ctl
|
|
|
|
Player:dispatch('tick', m)
|
|
end,
|
|
set_properties = function(m, ...)
|
|
return m.object:set_properties(...)
|
|
end,
|
|
set_physics_override = function(m, name, override)
|
|
m.physics_overrides[name] = override
|
|
m.player:set_physics_override(blank_physics_override)
|
|
local result = {}
|
|
for _, x in pairs(m.physics_overrides) do
|
|
for k, v in pairs(x) do
|
|
result[k] = (result[k] or 1) *v
|
|
end
|
|
end
|
|
m.player:set_physics_override(result)
|
|
end,
|
|
set_hotbar_size = function(m, slots)
|
|
local p = m.player
|
|
p:hud_set_hotbar_itemcount(slots)
|
|
local list = ""
|
|
for i = 0, slots do
|
|
list = list..":"..(21*i)..",0=firefly_hotbar_bg.png"
|
|
end
|
|
p:hud_set_hotbar_image("[combine:"..(21 *slots +1).."x22"..list)
|
|
p:hud_set_hotbar_selected_image("firefly_hotbar_selected_bg.png")
|
|
end,
|
|
}
|
|
setmetatable(Player, {
|
|
__call = function(_, ...) return Player.init(...) end,
|
|
__index = EventTarget
|
|
})
|
|
|
|
minetest.register_globalstep(function(...)
|
|
for _, m in pairs(ns.players) do
|
|
m:tick(...)
|
|
end
|
|
end)
|
|
|
|
minetest.register_on_newplayer(function(p)
|
|
local name = p:get_player_name()
|
|
if ns.is_admin(name) then
|
|
minetest.registered_chatcommands.grantme.func(name, "all")
|
|
end
|
|
end)
|
|
|
|
minetest.register_on_joinplayer(function(p)
|
|
ns.players[p:get_player_name()] = Player(p)
|
|
end)
|
|
|
|
minetest.register_on_leaveplayer(function(p)
|
|
ns.players[p:get_player_name()]:deinit()
|
|
ns.players[p:get_player_name()] = nil
|
|
end)
|
|
|
|
minetest.register_on_player_hpchange(function(p, delta)
|
|
local m = ns.players[p:get_player_name()]
|
|
local hp = p:get_hp() +delta
|
|
m.player:hud_change(m.healthbar, "text", "[fill:4x32:0,0:#0000^[lowpart:"..(hp /20 *100)..":firefly_health_bar.png^[transformR270^[multiply:#d33")
|
|
end)
|
|
|
|
minetest.register_chatcommand("test", {
|
|
func = function(name)
|
|
minetest.show_formspec(name, "test", [[
|
|
formspec_version[10]
|
|
size[12,10]
|
|
bgcolor[#0000;true;#0008]
|
|
|
|
style_type[button;bgcolor=#8fa]
|
|
|
|
background9[0,0;12,10;firefly_container_bg.png;true;16,16]
|
|
|
|
style[test.up;fgimg=firefly_grass.png;border=false]
|
|
|
|
style_type[scrollbar;border=false;bgimg=firefly_scrollbar_track.png;bgimg_middle=8;fgimg=firefly_scrollbar_thumb.png;padding=0,8;size=32]
|
|
|
|
blahscrollbaroptions[arrows=hide]
|
|
|
|
scrollbar[1,0.5;0.5,9;vertical;test;]
|
|
scrollbar[2,0.5;0.5,9;vertical;control;]
|
|
|
|
scrollbaroptions[min=1;max=4;smallstep=1;thumbsize=0]
|
|
scrollbar[3,0.5;5,0.5;horizontal;test2;]
|
|
box[3,1.25;7,9;#000f]
|
|
hypertext[3,1.5;3,8;ht;]]..minetest.formspec_escape(string.rep("a\n", 100))..[[]
|
|
textarea[6,1.5;3,8;_;;]]..minetest.formspec_escape(string.rep("a\n", 100))..[[]
|
|
|
|
textlist[2,2;3,2;blah;a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p;;]
|
|
]])
|
|
end
|
|
})
|
|
|
|
-- MARK: CSM compatibility
|
|
|
|
local comm = minetest.mod_channel_join("firefly")
|
|
|
|
minetest.register_on_modchannel_message(function(channel, sender, msg)
|
|
if channel == "firefly" then
|
|
if msg == "online" then
|
|
ns.players[sender].has_csm = true
|
|
elseif msg == "inv_opened" then
|
|
say(sender.." opened inventory")
|
|
end
|
|
end
|
|
end)
|