2024-05-15 10:51:46 +02:00
|
|
|
|
|
|
|
local fake_player = {is_fake_player = true}
|
|
|
|
local identifier = "fakelib:player"
|
|
|
|
local check, secure_table = ...
|
|
|
|
|
|
|
|
local player_controls = {
|
|
|
|
up = 1, down = 2, left = 4, right = 8, jump = 16,
|
|
|
|
aux1 = 32, sneak = 64, dig = 128, place = 256, zoom = 512,
|
|
|
|
}
|
|
|
|
|
|
|
|
-- API functions
|
|
|
|
----------------------------------------
|
|
|
|
|
|
|
|
function fakelib.is_player(x)
|
|
|
|
if type(x) == "userdata" and x.get_player_name then
|
|
|
|
return true
|
|
|
|
elseif type(x) == "table" and getmetatable(x) == identifier then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
function fakelib.create_player(player)
|
|
|
|
local data = {}
|
|
|
|
if type(player) == "string" then
|
|
|
|
data.name = player
|
|
|
|
elseif fakelib.is_player(player) then
|
|
|
|
data.name = player:get_player_name()
|
|
|
|
elseif type(player) == "table" then
|
|
|
|
if type(player.name) == "string" then
|
|
|
|
data.name = player.name
|
|
|
|
end
|
|
|
|
if type(player.position) == "table" then
|
|
|
|
data.position = vector.copy(player.position)
|
|
|
|
end
|
|
|
|
if type(player.direction) == "table" then
|
|
|
|
local dir = vector.normalize(player.direction)
|
|
|
|
data.pitch = -math.asin(dir.y)
|
|
|
|
data.yaw = math.atan2(-dir.x, dir.z) % (math.pi * 2)
|
|
|
|
end
|
|
|
|
if type(player.controls) == "table" then
|
|
|
|
data.controls = {}
|
|
|
|
player.controls.dig = player.controls.dig or player.controls.LMB
|
|
|
|
player.controls.place = player.controls.place or player.controls.RMB
|
|
|
|
for name in pairs(player_controls) do
|
|
|
|
data.controls[name] = player.controls[name] == true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if fakelib.is_metadata(player.metadata) then
|
|
|
|
data.metadata = fakelib.create_metadata(player.metadata)
|
|
|
|
end
|
|
|
|
if fakelib.is_inventory(player.inventory) then
|
2024-05-15 14:15:33 +02:00
|
|
|
data.inventory = player.inventory
|
2024-05-15 10:51:46 +02:00
|
|
|
end
|
|
|
|
local size = 32
|
|
|
|
if data.inventory and type(player.wield_list) == "string" then
|
|
|
|
size = data.inventory:get_size(player.wield_list)
|
|
|
|
if size > 0 then
|
|
|
|
data.wield_list = player.wield_list
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if type(player.wield_index) == "number" then
|
|
|
|
if player.wield_index > 0 and player.wield_index <= size then
|
|
|
|
data.wield_index = player.wield_index
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return secure_table({data = data}, fake_player, identifier)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Helper functions
|
|
|
|
----------------------------------------
|
|
|
|
|
|
|
|
local function check_vector(v)
|
|
|
|
local t = type(v)
|
|
|
|
if t ~= "table" then
|
|
|
|
error(string.format("\"Invalid vector (expected table got %s).\"", t), 3)
|
|
|
|
end
|
|
|
|
for _,c in ipairs({"x", "y", "z"}) do
|
|
|
|
t = type(v[c])
|
|
|
|
if t ~= "number" then
|
|
|
|
error(string.format("\"Invalid vector coordinate %s (expected number got %s).\"", c, t), 3)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Dynamic get/set functions
|
|
|
|
----------------------------------------
|
|
|
|
|
|
|
|
function fake_player:get_player_name()
|
|
|
|
return self.data.name or ""
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player:get_inventory()
|
|
|
|
if not self.data.inventory then
|
|
|
|
self.data.inventory = fakelib.create_inventory({
|
|
|
|
main = 32, craft = 9, craftpreview = 1, craftresult = 1
|
|
|
|
})
|
|
|
|
end
|
|
|
|
return self.data.inventory
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player:get_meta()
|
|
|
|
if not self.data.metadata then
|
|
|
|
self.data.metadata = fakelib:create_metadata()
|
|
|
|
end
|
|
|
|
return self.data.metadata
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player:get_look_dir()
|
|
|
|
local p, y = self.data.pitch or 0, self.data.yaw or 0
|
|
|
|
return vector.new(math.sin(-y) * math.cos(p), math.sin(-p), math.cos(y) * math.cos(p))
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player:get_look_horizontal()
|
|
|
|
return self.data.yaw or 0
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player:set_look_horizontal(value)
|
|
|
|
check(1, value, "number")
|
|
|
|
self.data.yaw = value % (math.pi * 2)
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player:get_look_vertical()
|
|
|
|
return self.data.pitch or 0
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player:set_look_vertical(value)
|
|
|
|
check(1, value, "number")
|
|
|
|
self.data.pitch = math.max(-math.pi / 2, math.min(value, math.pi / 2))
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player:get_player_control()
|
|
|
|
local controls = {}
|
|
|
|
if self.data.controls then
|
|
|
|
for name in pairs(player_controls) do
|
|
|
|
controls[name] = self.data.controls[name]
|
|
|
|
end
|
|
|
|
else
|
|
|
|
for name in pairs(player_controls) do
|
|
|
|
controls[name] = false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
controls.LMB = controls.dig
|
|
|
|
controls.RMB = controls.place
|
|
|
|
return controls
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player:get_player_control_bits()
|
|
|
|
if not self.data.controls then
|
|
|
|
return 0
|
|
|
|
end
|
|
|
|
local total = 0
|
|
|
|
for name, value in pairs(player_controls) do
|
|
|
|
total = total + self.data.controls[name] and value or 0
|
|
|
|
end
|
|
|
|
return total
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player:get_pos()
|
|
|
|
if self.data.position then
|
|
|
|
return vector.copy(self.data.position)
|
|
|
|
end
|
|
|
|
return vector.zero()
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player:set_pos(pos)
|
|
|
|
check_vector(pos)
|
|
|
|
self.data.position = vector.copy(pos)
|
|
|
|
end
|
|
|
|
fake_player.move_to = fake_player.set_pos
|
|
|
|
|
|
|
|
function fake_player:add_pos(pos)
|
|
|
|
check_vector(pos)
|
|
|
|
if self.data.position then
|
|
|
|
self.data.position = vector.add(self.data.position, pos)
|
|
|
|
else
|
|
|
|
self.data.position = vector.copy(pos)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player:get_wield_index()
|
|
|
|
return self.data.wield_index or 1
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player:get_wield_list()
|
|
|
|
return self.data.wield_list or "main"
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player:get_wielded_item()
|
|
|
|
if self.data.inventory then
|
|
|
|
return self.data.inventory:get_stack(self:get_wield_list(), self:get_wield_index())
|
|
|
|
end
|
|
|
|
return ItemStack()
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player:set_wielded_item(stack)
|
|
|
|
stack = ItemStack(stack)
|
|
|
|
if not self.data.inventory and stack:is_empty() then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
self:get_inventory():set_stack(self:get_wield_list(), self:get_wield_index(), stack)
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Static get functions
|
|
|
|
----------------------------------------
|
|
|
|
|
|
|
|
function fake_player.is_player()
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_animation()
|
|
|
|
return {x = 1, y = 1}, 15, 0, true
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_armor_groups()
|
|
|
|
return {immortal = 1}
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_bone_override()
|
|
|
|
return {
|
|
|
|
position = {absolute = false, vec = vector.zero(), interpolation = 0},
|
|
|
|
rotation = {absolute = false, vec = vector.zero(), interpolation = 0},
|
|
|
|
scale = {absolute = false, vec = vector.new(1, 1, 1), interpolation = 0},
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_bone_overrides()
|
|
|
|
return {}
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_bone_position()
|
|
|
|
return vector.zero(), vector.zero()
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_breath()
|
|
|
|
return 10
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_children()
|
|
|
|
return {}
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_clouds()
|
|
|
|
return {
|
|
|
|
ambient = {r = 0, g = 0, b = 0, a = 255},
|
|
|
|
color = {r = 240, g = 240, b = 255, a = 229},
|
|
|
|
density = 0.4,
|
|
|
|
height = 120,
|
|
|
|
speed = {x = 0, y = -2},
|
|
|
|
thickness = 16,
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_eye_offset()
|
|
|
|
return vector.zero(), vector.zero(), vector.zero()
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_formspec_prepend()
|
|
|
|
return ""
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_fov()
|
|
|
|
return 0, false, 0
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_hp()
|
|
|
|
return 20
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_inventory_formspec()
|
|
|
|
return ""
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_lighting()
|
|
|
|
return {
|
|
|
|
exposure = {
|
|
|
|
speed_bright_dark = 1000,
|
|
|
|
center_weight_power = 1,
|
|
|
|
luminance_min = -3,
|
|
|
|
luminance_max = -3,
|
|
|
|
exposure_correction = 0,
|
|
|
|
speed_dark_bright = 1000
|
|
|
|
},
|
|
|
|
saturation = 1,
|
|
|
|
shadows = {intensity = 0},
|
|
|
|
volumetric_light = {strength = 0},
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_local_animation()
|
|
|
|
return {x = 0, y = 0}, {x = 0, y = 0}, {x = 0, y = 0}, {x = 0, y = 0}, 0
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_moon()
|
|
|
|
return {
|
|
|
|
scale = 1,
|
|
|
|
texture = "moon.png",
|
|
|
|
tonemap = "moon_tonemap.png",
|
|
|
|
visible = true,
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_nametag_attributes()
|
|
|
|
return {
|
|
|
|
bgcolor = false,
|
|
|
|
color = {r = 255, g = 255, b = 255, a = 255},
|
|
|
|
text = "",
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_physics_override()
|
|
|
|
return {
|
|
|
|
acceleration_air = 1, acceleration_default = 1, acceleration_fast = 1,
|
|
|
|
gravity = 1, jump = 1, speed = 1,
|
|
|
|
liquid_fluidity = 1, liquid_fluidity_smooth = 1, liquid_sink = 1,
|
|
|
|
speed_climb = 1, speed_crouch = 1, speed_fast = 1, speed_walk = 1,
|
|
|
|
new_move = true, sneak = true, sneak_glitch = false,
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_properties()
|
|
|
|
return {
|
|
|
|
automatic_face_movement_dir = false,
|
|
|
|
automatic_face_movement_max_rotation_per_sec = -1,
|
|
|
|
automatic_rotate = 0,
|
|
|
|
backface_culling = false,
|
|
|
|
breath_max = 10,
|
|
|
|
collide_with_objects = true,
|
|
|
|
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
|
|
|
|
colors = {{r = 255, g = 255, b = 255, a = 255}},
|
|
|
|
damage_texture_modifier = "^[brighten",
|
|
|
|
eye_height = 0,
|
|
|
|
glow = 0,
|
|
|
|
hp_max = 20,
|
|
|
|
infotext = "",
|
|
|
|
initial_sprite_basepos = {x = 0, y = 0},
|
|
|
|
is_visible = true,
|
|
|
|
makes_footstep_sound = true,
|
|
|
|
mesh = "",
|
|
|
|
nametag = "",
|
|
|
|
nametag_bgcolor = false,
|
|
|
|
nametag_color = {r = 255, g = 255, b = 255, a = 255},
|
|
|
|
physical = false,
|
|
|
|
pointable = true,
|
|
|
|
selectionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5, rotate = false},
|
|
|
|
shaded = true,
|
|
|
|
show_on_minimap = true,
|
|
|
|
spritediv = {x = 1, y = 1},
|
|
|
|
static_save = true,
|
|
|
|
stepheight = 0.6,
|
|
|
|
textures = {"blank.png"},
|
|
|
|
use_texture_alpha = false,
|
|
|
|
visual = "cube",
|
|
|
|
visual_size = vector.new(1, 1, 1),
|
|
|
|
wield_item = "",
|
|
|
|
zoom_fov = 15,
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_sky_color()
|
|
|
|
return fake_player.get_sky(true).sky_color
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_sky(as_table)
|
|
|
|
if as_table then
|
|
|
|
return {
|
|
|
|
base_color = {r = 255, g = 255, b = 255, a = 255},
|
|
|
|
clouds = true,
|
|
|
|
fog = {fog_distance = -1, fog_start = -1},
|
|
|
|
sky_color = {
|
|
|
|
day_sky = {r = 97, g = 181, b = 245, a = 255},
|
|
|
|
day_horizon = {r = 144, g = 211, b = 246, a = 255},
|
|
|
|
dawn_sky = {r = 180, g = 186, b = 250, a = 255},
|
|
|
|
dawn_horizon = {r = 186, g = 193, b = 240, a = 255},
|
|
|
|
night_sky = {r = 0, g = 107, b = 255, a = 255},
|
|
|
|
night_horizon = {r = 64, g = 144, b = 255, a = 255},
|
|
|
|
indoors = {r = 100, g = 100, b = 100, a = 255},
|
|
|
|
fog_sun_tint = {r = 244, g = 125, b = 29, a = 255},
|
|
|
|
fog_moon_tint = {r = 128, g = 153, b = 204, a = 255},
|
|
|
|
fog_tint_type = "default",
|
|
|
|
},
|
|
|
|
textures = {},
|
|
|
|
type = "regular",
|
|
|
|
}
|
|
|
|
end
|
|
|
|
return {r = 255, g = 255, b = 255, a = 255}, "regular", {}, true
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_stars()
|
|
|
|
return {
|
|
|
|
count = 1000,
|
|
|
|
day_opacity = 0,
|
|
|
|
scale = 1,
|
|
|
|
star_color = {r = 235, g = 235, b = 255, a = 105},
|
|
|
|
visible = true,
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_sun()
|
|
|
|
return {
|
|
|
|
scale = 1,
|
|
|
|
sunrise = "sunrisebg.png",
|
|
|
|
sunrise_visible = true,
|
|
|
|
texture = "sun.png",
|
|
|
|
tonemap = "sun_tonemap.png",
|
|
|
|
visible = true,
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.get_velocity()
|
|
|
|
return vector.zero()
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.hud_get_all()
|
|
|
|
return {}
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.hud_get_flags()
|
|
|
|
return {
|
|
|
|
basic_debug = false,
|
|
|
|
breathbar = false,
|
|
|
|
chat = false,
|
|
|
|
crosshair = false,
|
|
|
|
healthbar = false,
|
|
|
|
hotbar = false,
|
|
|
|
minimap = false,
|
|
|
|
minimap_radar = false,
|
|
|
|
wielditem = false,
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.hud_get_hotbar_image()
|
|
|
|
return ""
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.hud_get_hotbar_itemcount()
|
|
|
|
return 8
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player.hud_get_hotbar_selected_image()
|
|
|
|
return ""
|
|
|
|
end
|
|
|
|
|
|
|
|
-- No-op functions
|
|
|
|
----------------------------------------
|
|
|
|
do
|
|
|
|
local functions = {
|
|
|
|
-- Lua entity only (no-op for players)
|
|
|
|
"get_acceleration", "get_entity_name", "get_luaentity", "get_rotation",
|
|
|
|
"get_texture_mod", "get_yaw", "getacceleration", "getyaw", "remove",
|
|
|
|
"set_acceleration", "set_rotation", "set_sprite", "set_texture_mod",
|
|
|
|
"set_velocity", "set_yaw", "setacceleration", "setsprite",
|
|
|
|
"settexturemod", "setvelocity", "setyaw",
|
|
|
|
-- Non-functional get/set functions
|
|
|
|
"add_velocity", "get_attach", "get_attribute", "get_day_night_ratio",
|
|
|
|
"hud_add", "hud_change", "hud_get", "hud_remove", "hud_set_flags",
|
|
|
|
"hud_set_hotbar_image", "hud_set_hotbar_itemcount",
|
|
|
|
"hud_set_hotbar_selected_image", "override_day_night_ratio",
|
|
|
|
"set_animation", "set_animation_frame_speed", "set_armor_groups",
|
|
|
|
"set_attach", "set_attribute", "set_bone_override", "set_bone_position",
|
|
|
|
"set_breath", "set_clouds", "set_detach", "set_eye_offset",
|
|
|
|
"set_formspec_prepend", "set_fov", "set_hp", "set_inventory_formspec",
|
|
|
|
"set_lighting", "set_local_animation", "set_minimap_modes", "set_moon",
|
|
|
|
"set_nametag_attributes", "set_physics_override",
|
|
|
|
"set_properties", "set_sky", "set_stars", "set_sun",
|
|
|
|
-- Other functions that do nothing
|
|
|
|
"punch", "respawn", "right_click", "send_mapblock",
|
|
|
|
}
|
|
|
|
for _,func in ipairs(functions) do
|
|
|
|
fake_player[func] = function() end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Deprecated functions
|
|
|
|
----------------------------------------
|
|
|
|
|
|
|
|
function fake_player:get_look_pitch()
|
|
|
|
return self:get_look_vertical() * -1
|
|
|
|
end
|
|
|
|
|
|
|
|
function fake_player:get_look_yaw()
|
|
|
|
return self:get_look_horizontal() + math.pi / 2
|
|
|
|
end
|
|
|
|
|
|
|
|
fake_player.set_look_pitch = fake_player.set_look_vertical
|
|
|
|
fake_player.set_look_yaw = fake_player.set_look_horizontal
|
|
|
|
fake_player.getpos = fake_player.get_pos
|
|
|
|
fake_player.setpos = fake_player.set_pos
|
|
|
|
fake_player.moveto = fake_player.set_pos
|
|
|
|
fake_player.getvelocity = fake_player.get_velocity
|
|
|
|
fake_player.add_player_velocity = fake_player.add_velocity
|
|
|
|
fake_player.get_player_velocity = fake_player.get_velocity
|