Improve bow/arrow physics
This commit is contained in:
parent
a4fe82b0e0
commit
3088b10e53
257
api.lua
257
api.lua
|
@ -236,6 +236,7 @@ function XBows.register_bow(self, name, def, override)
|
|||
wield_image = def.custom.wield_image_charged or def.custom.inventory_image_charged,
|
||||
groups = def.custom.groups_charged,
|
||||
wield_scale = {x = 2, y = 2, z = 1.5},
|
||||
range = 0,
|
||||
---@param itemstack ItemStack
|
||||
---@param user ObjectRef|nil
|
||||
---@param pointed_thing PointedThingDef
|
||||
|
@ -605,6 +606,7 @@ function XBows.shoot(self, itemstack, user, pointed_thing)
|
|||
user:get_player_name()
|
||||
)
|
||||
|
||||
---Handle HUD and 3d Quiver
|
||||
if is_arrow_from_quiver == 1 then
|
||||
XBowsQuiver:udate_or_create_hud(user, detached_inv:get_list('main'), found_arrow_stack_idx)
|
||||
|
||||
|
@ -618,7 +620,7 @@ function XBows.shoot(self, itemstack, user, pointed_thing)
|
|||
if not inv:is_empty('x_bows:arrow_inv') then
|
||||
XBowsQuiver:udate_or_create_hud(user, inv:get_list('x_bows:arrow_inv'))
|
||||
else
|
||||
---no ammo (fake stack)
|
||||
---no ammo (fake stack just for the HUD)
|
||||
XBowsQuiver:udate_or_create_hud(user, {ItemStack({
|
||||
name = 'x_bows:no_ammo'
|
||||
})})
|
||||
|
@ -637,16 +639,6 @@ function XBows.shoot(self, itemstack, user, pointed_thing)
|
|||
local bow_name = x_bows_registered_bow_charged_def.custom.name
|
||||
local uses = x_bows_registered_bow_charged_def.custom.uses
|
||||
local crit_chance = x_bows_registered_bow_charged_def.custom.crit_chance
|
||||
local bow_strength = x_bows_registered_bow_charged_def.custom.strength
|
||||
local bow_strength_min = x_bows_registered_bow_charged_def.custom.strength_min
|
||||
local bow_strength_max = x_bows_registered_bow_charged_def.custom.strength_max
|
||||
local acc_x_min = x_bows_registered_bow_charged_def.custom.acc_x_min
|
||||
local acc_y_min = x_bows_registered_bow_charged_def.custom.acc_y_min
|
||||
local acc_z_min = x_bows_registered_bow_charged_def.custom.acc_z_min
|
||||
local acc_x_max = x_bows_registered_bow_charged_def.custom.acc_x_max
|
||||
local acc_y_max = x_bows_registered_bow_charged_def.custom.acc_y_max
|
||||
local acc_z_max = x_bows_registered_bow_charged_def.custom.acc_z_max
|
||||
local gravity = x_bows_registered_bow_charged_def.custom.gravity
|
||||
---Arrow
|
||||
local projectile_entity = x_bows_registered_arrow_def.custom.projectile_entity
|
||||
---Quiver
|
||||
|
@ -655,11 +647,12 @@ function XBows.shoot(self, itemstack, user, pointed_thing)
|
|||
local _tool_capabilities = x_bows_registered_arrow_def.custom.tool_capabilities
|
||||
local quiver_xbows_def = x_bows_registered_quiver_def
|
||||
|
||||
---@type EnityStaticDataAttrDef
|
||||
local staticdata = {
|
||||
_arrow_name = arrow_name,
|
||||
_bow_name = bow_name,
|
||||
user_name = user:get_player_name(),
|
||||
is_critical_hit = false,
|
||||
_user_name = user:get_player_name(),
|
||||
_is_critical_hit = false,
|
||||
_tool_capabilities = _tool_capabilities,
|
||||
_tflp = tflp,
|
||||
_add_damage = 0
|
||||
|
@ -668,13 +661,13 @@ function XBows.shoot(self, itemstack, user, pointed_thing)
|
|||
---crits, only on full punch interval
|
||||
if crit_chance and crit_chance > 1 and tflp >= _tool_capabilities.full_punch_interval then
|
||||
if math.random(1, crit_chance) == 1 then
|
||||
staticdata.is_critical_hit = true
|
||||
staticdata._is_critical_hit = true
|
||||
end
|
||||
end
|
||||
|
||||
---speed multiply
|
||||
if quiver_xbows_def and quiver_xbows_def.custom.faster_arrows and quiver_xbows_def.custom.faster_arrows > 1 then
|
||||
staticdata.faster_arrows_multiplier = quiver_xbows_def.custom.faster_arrows
|
||||
staticdata._faster_arrows_multiplier = quiver_xbows_def.custom.faster_arrows
|
||||
end
|
||||
|
||||
---add quiver damage
|
||||
|
@ -684,20 +677,23 @@ function XBows.shoot(self, itemstack, user, pointed_thing)
|
|||
|
||||
---sound
|
||||
local sound_name = x_bows_registered_bow_charged_def.custom.sound_shoot
|
||||
if staticdata.is_critical_hit then
|
||||
if staticdata._is_critical_hit then
|
||||
sound_name = x_bows_registered_bow_charged_def.custom.sound_shoot_crit
|
||||
end
|
||||
|
||||
meta:set_string('arrow_itemstack_string', '')
|
||||
itemstack:set_name(bow_name)
|
||||
---stop punching close objects/nodes when shooting
|
||||
minetest.after(0.2, function()
|
||||
if user:get_wielded_item():get_name() == itemstack:get_name() then
|
||||
user:set_wielded_item(ItemStack({name = bow_name, wear = itemstack:get_wear()}))
|
||||
end
|
||||
end)
|
||||
|
||||
local pos = user:get_pos()
|
||||
local dir = user:get_look_dir()
|
||||
local player_pos = user:get_pos()
|
||||
local obj = minetest.add_entity(
|
||||
{
|
||||
x = pos.x,
|
||||
y = pos.y + 1.5,
|
||||
z = pos.z
|
||||
x = player_pos.x,
|
||||
y = player_pos.y + 1.5,
|
||||
z = player_pos.z
|
||||
},
|
||||
projectile_entity,
|
||||
minetest.serialize(staticdata)
|
||||
|
@ -707,44 +703,6 @@ function XBows.shoot(self, itemstack, user, pointed_thing)
|
|||
return itemstack
|
||||
end
|
||||
|
||||
local strength_multiplier = tflp
|
||||
|
||||
if strength_multiplier > _tool_capabilities.full_punch_interval then
|
||||
strength_multiplier = 1
|
||||
|
||||
---faster arrow, only on full punch interval
|
||||
if staticdata.faster_arrows_multiplier then
|
||||
strength_multiplier = strength_multiplier + (strength_multiplier / staticdata.faster_arrows_multiplier)
|
||||
end
|
||||
end
|
||||
|
||||
if bow_strength_max and bow_strength_min then
|
||||
bow_strength = math.random(bow_strength_min, bow_strength_max)
|
||||
end
|
||||
|
||||
---acceleration
|
||||
local acc_x = dir.x
|
||||
local acc_y = gravity
|
||||
local acc_z = dir.z
|
||||
|
||||
if acc_x_min and acc_x_max then
|
||||
acc_x = math.random(acc_x_min, acc_x_max)
|
||||
end
|
||||
|
||||
if acc_y_min and acc_y_max then
|
||||
acc_y = math.random(acc_y_min, acc_y_max)
|
||||
end
|
||||
|
||||
if acc_z_min and acc_z_max then
|
||||
acc_z = math.random(acc_z_min, acc_z_max)
|
||||
end
|
||||
|
||||
local strength = bow_strength * strength_multiplier
|
||||
|
||||
obj:set_velocity(vector.multiply(dir, strength))
|
||||
obj:set_acceleration({x = acc_x, y = acc_y, z = acc_z})
|
||||
obj:set_yaw(minetest.dir_to_yaw(dir))
|
||||
|
||||
if not self:is_creative(user:get_player_name()) then
|
||||
itemstack:add_wear(65535 / uses)
|
||||
end
|
||||
|
@ -843,24 +801,9 @@ local function limit(x, min, max)
|
|||
return math.min(math.max(x, min), max)
|
||||
end
|
||||
|
||||
---Gets collision box
|
||||
---@param obj ObjectRef
|
||||
---@return number[]
|
||||
local function get_obj_box(obj)
|
||||
local box
|
||||
|
||||
if obj:is_player() then
|
||||
box = obj:get_properties().collisionbox or {-0.5, 0.0, -0.5, 0.5, 1.0, 0.5}
|
||||
else
|
||||
box = obj:get_luaentity().collisionbox or {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}
|
||||
end
|
||||
|
||||
return box
|
||||
end
|
||||
|
||||
---Function receive a "luaentity" table as `self`. Called when the object is instantiated.
|
||||
---@param self EntityDef|EntityDefCustom|XBows
|
||||
---@param selfObj table
|
||||
---@param selfObj EnityCustomAttrDef
|
||||
---@param staticdata string
|
||||
---@param dtime_s? integer|number
|
||||
---@return nil
|
||||
|
@ -870,7 +813,7 @@ function XBowsEntityDef.on_activate(self, selfObj, staticdata, dtime_s)
|
|||
return
|
||||
end
|
||||
|
||||
local _staticdata = minetest.deserialize(staticdata)
|
||||
local _staticdata = minetest.deserialize(staticdata)--[[@as EnityStaticDataAttrDef]]
|
||||
|
||||
-- set/reset - do not inherit from previous entity table
|
||||
selfObj._velocity = {x = 0, y = 0, z = 0}
|
||||
|
@ -888,12 +831,12 @@ function XBowsEntityDef.on_activate(self, selfObj, staticdata, dtime_s)
|
|||
selfObj._shot_from_pos = selfObj.object:get_pos()
|
||||
selfObj._arrow_name = _staticdata._arrow_name
|
||||
selfObj._bow_name = _staticdata._bow_name
|
||||
selfObj._user_name = _staticdata.user_name
|
||||
selfObj.user = minetest.get_player_by_name(_staticdata.user_name)
|
||||
selfObj._user_name = _staticdata._user_name
|
||||
selfObj._user = minetest.get_player_by_name(_staticdata._user_name)
|
||||
selfObj._tflp = _staticdata._tflp
|
||||
selfObj._tool_capabilities = _staticdata._tool_capabilities
|
||||
selfObj._is_critical_hit = _staticdata.is_critical_hit
|
||||
selfObj._faster_arrows_multiplier = _staticdata.faster_arrows_multiplier
|
||||
selfObj._is_critical_hit = _staticdata._is_critical_hit
|
||||
selfObj._faster_arrows_multiplier = _staticdata._faster_arrows_multiplier
|
||||
selfObj._add_damage = _staticdata._add_damage
|
||||
selfObj._caused_damage = 0
|
||||
selfObj._caused_knockback = 0
|
||||
|
@ -903,9 +846,58 @@ function XBowsEntityDef.on_activate(self, selfObj, staticdata, dtime_s)
|
|||
selfObj._arrow_particle_effect_crit = x_bows_registered_arrow_def.custom.particle_effect_crit
|
||||
selfObj._arrow_particle_effect_fast = x_bows_registered_arrow_def.custom.particle_effect_fast
|
||||
|
||||
---Bow Def
|
||||
local x_bows_registered_bow_def = self.registered_bows[selfObj._bow_name]
|
||||
selfObj._sound_hit = x_bows_registered_bow_def.custom.sound_hit
|
||||
local bow_strength = x_bows_registered_bow_def.custom.strength
|
||||
local acc_x_min = x_bows_registered_bow_def.custom.acc_x_min
|
||||
local acc_y_min = x_bows_registered_bow_def.custom.acc_y_min
|
||||
local acc_z_min = x_bows_registered_bow_def.custom.acc_z_min
|
||||
local acc_x_max = x_bows_registered_bow_def.custom.acc_x_max
|
||||
local acc_y_max = x_bows_registered_bow_def.custom.acc_y_max
|
||||
local acc_z_max = x_bows_registered_bow_def.custom.acc_z_max
|
||||
local gravity = x_bows_registered_bow_def.custom.gravity
|
||||
local bow_strength_min = x_bows_registered_bow_def.custom.strength_min
|
||||
local bow_strength_max = x_bows_registered_bow_def.custom.strength_max
|
||||
|
||||
---acceleration
|
||||
selfObj._player_look_dir = selfObj._user:get_look_dir()
|
||||
|
||||
selfObj._acc_x = selfObj._player_look_dir.x
|
||||
selfObj._acc_y = gravity
|
||||
selfObj._acc_z = selfObj._player_look_dir.z
|
||||
|
||||
if acc_x_min and acc_x_max then
|
||||
selfObj._acc_x = math.random(acc_x_min, acc_x_max)
|
||||
end
|
||||
|
||||
if acc_y_min and acc_y_max then
|
||||
selfObj._acc_y = math.random(acc_y_min, acc_y_max)
|
||||
end
|
||||
|
||||
if acc_z_min and acc_z_max then
|
||||
selfObj._acc_z = math.random(acc_z_min, acc_z_max)
|
||||
end
|
||||
|
||||
---strength
|
||||
local strength_multiplier = selfObj._tflp
|
||||
|
||||
if strength_multiplier > selfObj._tool_capabilities.full_punch_interval then
|
||||
strength_multiplier = 1
|
||||
|
||||
---faster arrow, only on full punch interval
|
||||
if selfObj._faster_arrows_multiplier then
|
||||
strength_multiplier = strength_multiplier + (strength_multiplier / selfObj._faster_arrows_multiplier)
|
||||
end
|
||||
end
|
||||
|
||||
if bow_strength_max and bow_strength_min then
|
||||
bow_strength = math.random(bow_strength_min, bow_strength_max)
|
||||
end
|
||||
|
||||
selfObj._strength = bow_strength * strength_multiplier
|
||||
|
||||
---rotation factor
|
||||
local x_bows_registered_entity_def = self.registered_entities[selfObj.name]
|
||||
selfObj._rotation_factor = x_bows_registered_entity_def._custom.rotation_factor
|
||||
|
||||
|
@ -913,15 +905,19 @@ function XBowsEntityDef.on_activate(self, selfObj, staticdata, dtime_s)
|
|||
selfObj._rotation_factor = selfObj._rotation_factor()
|
||||
end
|
||||
|
||||
---add infotext
|
||||
selfObj.object:set_properties({
|
||||
infotext = selfObj._arrow_name,
|
||||
})
|
||||
|
||||
|
||||
---idle animation
|
||||
if x_bows_registered_entity_def and x_bows_registered_entity_def._custom.animations.idle then
|
||||
selfObj.object:set_animation(unpack(x_bows_registered_entity_def._custom.animations.idle))
|
||||
end
|
||||
|
||||
---counter, e.g. for initial values set `on_step`
|
||||
selfObj._step_count = 0
|
||||
|
||||
---Callbacks
|
||||
local on_after_activate_callback = x_bows_registered_arrow_def.custom.on_after_activate
|
||||
|
||||
|
@ -932,7 +928,7 @@ end
|
|||
|
||||
---Function receive a "luaentity" table as `self`. Called when the object dies.
|
||||
---@param self XBows
|
||||
---@param selfObj table
|
||||
---@param selfObj EnityCustomAttrDef
|
||||
---@param killer ObjectRef|nil
|
||||
---@return nil
|
||||
function XBowsEntityDef.on_death(self, selfObj, killer)
|
||||
|
@ -946,10 +942,20 @@ end
|
|||
|
||||
--- Function receive a "luaentity" table as `self`. Called on every server tick, after movement and collision processing. `dtime`: elapsed time since last call. `moveresult`: table with collision info (only available if physical=true).
|
||||
---@param self XBows
|
||||
---@param selfObj table
|
||||
---@param selfObj EnityCustomAttrDef
|
||||
---@param dtime number
|
||||
---@return nil
|
||||
function XBowsEntityDef.on_step(self, selfObj, dtime)
|
||||
selfObj._step_count = selfObj._step_count + 1
|
||||
|
||||
if selfObj._step_count == 1 then
|
||||
---initialize
|
||||
---this has to be done here for raycast to kick-in asap
|
||||
selfObj.object:set_velocity(vector.multiply(selfObj._player_look_dir, selfObj._strength))
|
||||
selfObj.object:set_acceleration({x = selfObj._acc_x, y = selfObj._acc_y, z = selfObj._acc_z})
|
||||
selfObj.object:set_yaw(minetest.dir_to_yaw(selfObj._player_look_dir))
|
||||
end
|
||||
|
||||
local pos = selfObj.object:get_pos()
|
||||
selfObj._old_pos = selfObj._old_pos or pos
|
||||
local ray = minetest.raycast(selfObj._old_pos, pos, true, true)
|
||||
|
@ -1029,7 +1035,7 @@ function XBowsEntityDef.on_step(self, selfObj, dtime)
|
|||
and pointed_thing.ref ~= selfObj.object
|
||||
and pointed_thing.ref:get_hp() > 0
|
||||
and (
|
||||
(pointed_thing.ref:is_player() and pointed_thing.ref:get_player_name() ~= selfObj.user:get_player_name())
|
||||
(pointed_thing.ref:is_player() and pointed_thing.ref:get_player_name() ~= selfObj._user:get_player_name())
|
||||
or (
|
||||
pointed_thing.ref:get_luaentity()
|
||||
and pointed_thing.ref:get_luaentity().physical
|
||||
|
@ -1041,25 +1047,16 @@ function XBowsEntityDef.on_step(self, selfObj, dtime)
|
|||
then
|
||||
if pointed_thing.ref:is_player() then
|
||||
minetest.sound_play('x_bows_arrow_successful_hit', {
|
||||
to_player = selfObj.user:get_player_name(),
|
||||
to_player = selfObj._user:get_player_name(),
|
||||
gain = 0.3
|
||||
})
|
||||
else
|
||||
minetest.sound_play(selfObj._sound_hit, {
|
||||
to_player = selfObj.user:get_player_name(),
|
||||
to_player = selfObj._user:get_player_name(),
|
||||
gain = 0.6
|
||||
})
|
||||
end
|
||||
|
||||
-- store these here before punching in case pointed_thing.ref dies
|
||||
local collisionbox = get_obj_box(pointed_thing.ref)
|
||||
local xmin = collisionbox[1] * 100
|
||||
local ymin = collisionbox[2] * 100
|
||||
local zmin = collisionbox[3] * 100
|
||||
local xmax = collisionbox[4] * 100
|
||||
local ymax = collisionbox[5] * 100
|
||||
local zmax = collisionbox[6] * 100
|
||||
|
||||
selfObj.object:set_velocity({x = 0, y = 0, z = 0})
|
||||
selfObj.object:set_acceleration({x = 0, y = 0, z = 0})
|
||||
|
||||
|
@ -1136,7 +1133,6 @@ function XBowsEntityDef.on_step(self, selfObj, dtime)
|
|||
|
||||
-- attach arrow prepare
|
||||
local rotation = {x = 0, y = 0, z = 0}
|
||||
local position = {x = 0, y = 0, z = 0}
|
||||
|
||||
if in_pos.x == 1 then
|
||||
-- x = 0
|
||||
|
@ -1145,10 +1141,6 @@ function XBowsEntityDef.on_step(self, selfObj, dtime)
|
|||
rotation.x = math.random(-10, 10)
|
||||
rotation.y = math.random(-100, -80)
|
||||
rotation.z = math.random(-10, 10)
|
||||
|
||||
position.x = xmax / 10
|
||||
position.y = math.random(ymin, ymax) / 10
|
||||
position.z = math.random(zmin, zmax) / 10
|
||||
elseif in_pos.x == -1 then
|
||||
-- x = 0
|
||||
-- y = 90
|
||||
|
@ -1156,10 +1148,6 @@ function XBowsEntityDef.on_step(self, selfObj, dtime)
|
|||
rotation.x = math.random(-10, 10)
|
||||
rotation.y = math.random(80, 100)
|
||||
rotation.z = math.random(-10, 10)
|
||||
|
||||
position.x = xmin / 10
|
||||
position.y = math.random(ymin, ymax) / 10
|
||||
position.z = math.random(zmin, zmax) / 10
|
||||
elseif in_pos.y == 1 then
|
||||
-- x = -90
|
||||
-- y = 0
|
||||
|
@ -1167,10 +1155,6 @@ function XBowsEntityDef.on_step(self, selfObj, dtime)
|
|||
rotation.x = math.random(-100, -80)
|
||||
rotation.y = math.random(-10, 10)
|
||||
rotation.z = math.random(-190, -170)
|
||||
|
||||
position.x = math.random(xmin, xmax) / 10
|
||||
position.y = ymax / 10
|
||||
position.z = math.random(zmin, zmax) / 10
|
||||
elseif in_pos.y == -1 then
|
||||
-- x = 90
|
||||
-- y = 0
|
||||
|
@ -1178,10 +1162,6 @@ function XBowsEntityDef.on_step(self, selfObj, dtime)
|
|||
rotation.x = math.random(80, 100)
|
||||
rotation.y = math.random(-10, 10)
|
||||
rotation.z = math.random(170, 190)
|
||||
|
||||
position.x = math.random(xmin, xmax) / 10
|
||||
position.y = ymin / 10
|
||||
position.z = math.random(zmin, zmax) / 10
|
||||
elseif in_pos.z == 1 then
|
||||
-- x = 180
|
||||
-- y = 0
|
||||
|
@ -1189,10 +1169,6 @@ function XBowsEntityDef.on_step(self, selfObj, dtime)
|
|||
rotation.x = math.random(170, 190)
|
||||
rotation.y = math.random(-10, 10)
|
||||
rotation.z = math.random(170, 190)
|
||||
|
||||
position.x = math.random(xmin, xmax) / 10
|
||||
position.y = math.random(ymin, ymax) / 10
|
||||
position.z = zmax / 10
|
||||
elseif in_pos.z == -1 then
|
||||
-- x = -180
|
||||
-- y = 180
|
||||
|
@ -1200,10 +1176,6 @@ function XBowsEntityDef.on_step(self, selfObj, dtime)
|
|||
rotation.x = math.random(-190, -170)
|
||||
rotation.y = math.random(170, 190)
|
||||
rotation.z = math.random(-190, -170)
|
||||
|
||||
position.x = math.random(xmin, xmax) / 10
|
||||
position.y = math.random(ymin, ymax) / 10
|
||||
position.z = zmin / 10
|
||||
end
|
||||
|
||||
if not XBows.settings.x_bows_attach_arrows_to_entities and not pointed_thing.ref:is_player() then
|
||||
|
@ -1211,7 +1183,26 @@ function XBowsEntityDef.on_step(self, selfObj, dtime)
|
|||
return
|
||||
end
|
||||
|
||||
---normalize arrow scale when attached to scaled entity (prevents huge arrows when attached to scaled up entity models)
|
||||
local obj_props = selfObj.object:get_properties()
|
||||
local obj_to_props = pointed_thing.ref:get_properties()
|
||||
local vs = vector.divide(obj_props.visual_size, obj_to_props.visual_size)
|
||||
|
||||
selfObj.object:set_properties({visual_size = vs})
|
||||
|
||||
-- attach arrow
|
||||
local position = vector.subtract(
|
||||
ip_pos,
|
||||
pointed_thing.ref:get_pos()
|
||||
)
|
||||
|
||||
if pointed_thing.ref:is_player() then
|
||||
position = vector.multiply(position, 10)
|
||||
end
|
||||
|
||||
---`after` here prevents visual glitch when the arrow still shows as huge for a split second
|
||||
---before the new calculated scale is applied
|
||||
minetest.after(0, function()
|
||||
selfObj.object:set_attach(
|
||||
pointed_thing.ref,
|
||||
'',
|
||||
|
@ -1219,6 +1210,8 @@ function XBowsEntityDef.on_step(self, selfObj, dtime)
|
|||
rotation,
|
||||
true
|
||||
)
|
||||
end)
|
||||
|
||||
selfObj._attached = true
|
||||
selfObj._attached_to.type = pointed_thing.type
|
||||
selfObj._attached_to.pos = position
|
||||
|
@ -1329,6 +1322,24 @@ function XBowsEntityDef.on_step(self, selfObj, dtime)
|
|||
on_hit_node_callback(selfObj, pointed_thing)
|
||||
end
|
||||
|
||||
local new_pos = selfObj.object:get_pos()
|
||||
|
||||
minetest.add_particlespawner({
|
||||
amount = 5,
|
||||
time = 0.25,
|
||||
minpos = {x = new_pos.x - 0.4, y = new_pos.y + 0.2, z = new_pos.z - 0.4},
|
||||
maxpos = {x = new_pos.x + 0.4, y = new_pos.y + 0.3, z = new_pos.z + 0.4},
|
||||
minvel = {x = 0, y = 3, z = 0},
|
||||
maxvel = {x = 0, y = 4, z = 0},
|
||||
minacc = {x = 0, y = -28, z = 0},
|
||||
maxacc = {x = 0, y = -32, z = 0},
|
||||
minexptime = 1,
|
||||
maxexptime = 1.5,
|
||||
node = {name = node_def.name},
|
||||
collisiondetection = true,
|
||||
object_collision = true,
|
||||
})
|
||||
|
||||
minetest.sound_play(selfObj._sound_hit, {
|
||||
pos = pointed_thing.under,
|
||||
gain = 0.6,
|
||||
|
@ -1346,7 +1357,7 @@ end
|
|||
|
||||
---Function receive a "luaentity" table as `self`. Called when somebody punches the object. Note that you probably want to handle most punches using the automatic armor group system. Can return `true` to prevent the default damage mechanism.
|
||||
---@param self XBows
|
||||
---@param selfObj table
|
||||
---@param selfObj EnityCustomAttrDef
|
||||
---@param puncher ObjectRef|nil
|
||||
---@param time_from_last_punch number|integer|nil
|
||||
---@param tool_capabilities ToolCapabilitiesDef
|
||||
|
|
|
@ -31,12 +31,19 @@
|
|||
---@field move_to fun(self: ObjectRef, pos: Vector, continuous?: boolean): nil Does an interpolated move for Lua entities for visually smooth transitions. If `continuous` is true, the Lua entity will not be moved to the current position before starting the interpolated move. For players this does the same as `set_pos`,`continuous` is ignored.
|
||||
---@field set_hp fun(self: ObjectRef, hp: number, reason: table): nil set number of health points See reason in register_on_player_hpchange Is limited to the range of 0 ... 65535 (2^16 - 1) For players: HP are also limited by `hp_max` specified in object properties
|
||||
---@field set_animation fun(self: ObjectRef, frame_range?: {["x"]: number, ["y"]: number}, frame_speed?: number, frame_blend?: number, frame_loop?: boolean): nil `frame_range`: table {x=num, y=num}, default: `{x=1, y=1}`, `frame_speed`: number, default: `15.0`, `frame_blend`: number, default: `0.0`, `frame_loop`: boolean, default: `true`
|
||||
---@field get_velocity fun(self: ObjectRef): Vector returns the velocity, a vector.
|
||||
---@field set_rotation fun(self: ObjectRef, rot: Vector): nil `rot` is a vector (radians). X is pitch (elevation), Y is yaw (heading) and Z is roll (bank).
|
||||
---@field set_pos fun(self: ObjectRef, pos: Vector): nil
|
||||
|
||||
|
||||
---Moving things in the game are generally these.
|
||||
---This is basically a reference to a C++ `ServerActiveObject`.
|
||||
---@class ObjectRefLuaEntityRef
|
||||
---@field set_velocity fun(self: ObjectRef, vel: Vector): nil `vel` is a vector, e.g. `{x=0.0, y=2.3, z=1.0}`
|
||||
---@field remove fun(): nil remove object, The object is removed after returning from Lua. However the `ObjectRef` itself instantly becomes unusable with all further method calls having no effect and returning `nil`.
|
||||
---@field get_rotation fun(self: ObjectRef): Vector returns the rotation, a vector (radians)
|
||||
---@field get_attach fun(self: ObjectRef): any Returns parent, bone, position, rotation, forced_visible, or nil if it isn't attached.
|
||||
---@field set_attach fun(self: ObjectRef, parent: ObjectRef, bone?: string, position?: Vector, rotation?: Vector, forced_visible?: boolean): any Returns parent, bone, position, rotation, forced_visible, or nil if it isn't attached.
|
||||
|
||||
---`ObjectRef` armor groups
|
||||
---@class ObjectRefArmorGroups
|
||||
|
|
|
@ -13,3 +13,4 @@
|
|||
---@field round fun(v: Vector): Vector Returns a vector, each dimension rounded to nearest integer. At a multiple of 0.5, rounds away from zero.
|
||||
---@field new fun(a, b?, c?): Vector Returns a new vector `(a, b, c)`.
|
||||
---@field direction fun(p1: Vector, p2: Vector): Vector Returns a vector of length 1 with direction `p1` to `p2`. If `p1` and `p2` are identical, returns `(0, 0, 0)`.
|
||||
---@field divide fun(v: Vector, s: Vector | number): Vector Returns a scaled vector. Deprecated: If `s` is a vector: Returns the Schur quotient.
|
||||
|
|
|
@ -154,3 +154,51 @@
|
|||
---@class EntityAnimationDef
|
||||
---@field idle {frame_range?: {["x"]: number, ["y"]: number}, frame_speed?: number, frame_blend?: number, frame_loop?: boolean}
|
||||
---@field on_hit_node {frame_range?: {["x"]: number, ["y"]: number}, frame_speed?: number, frame_blend?: number, frame_loop?: boolean}
|
||||
|
||||
---Arrow object and custom attributes
|
||||
---@class EnityCustomAttrDef
|
||||
---@field object ObjectRef
|
||||
---@field _velocity Vector
|
||||
---@field _old_pos Vector
|
||||
---@field _attached boolean
|
||||
---@field _attached_to {["type"]: string, ["pos"]: Vector | nil}
|
||||
---@field _has_particles boolean
|
||||
---@field _lifetimer number
|
||||
---@field _nodechecktimer number
|
||||
---@field _is_drowning boolean
|
||||
---@field _in_liquid boolean
|
||||
---@field _shot_from_pos Vector
|
||||
---@field _arrow_name string
|
||||
---@field _bow_name string
|
||||
---@field _user_name string
|
||||
---@field _user ObjectRef
|
||||
---@field _tflp number
|
||||
---@field _tool_capabilities ToolCapabilitiesDef
|
||||
---@field _is_critical_hit boolean
|
||||
---@field _faster_arrows_multiplier number
|
||||
---@field _add_damage number
|
||||
---@field _caused_damage number
|
||||
---@field _caused_knockback number
|
||||
---@field _arrow_particle_effect string
|
||||
---@field _arrow_particle_effect_crit string
|
||||
---@field _arrow_particle_effect_fast string
|
||||
---@field _sound_hit string
|
||||
---@field _player_look_dir Vector
|
||||
---@field _acc_x number
|
||||
---@field _acc_y number
|
||||
---@field _acc_z number
|
||||
---@field _strength number
|
||||
---@field name string
|
||||
---@field _rotation_factor number | fun(): number
|
||||
---@field _step_count number
|
||||
|
||||
---Staticdata attributes
|
||||
---@class EnityStaticDataAttrDef
|
||||
---@field _arrow_name string
|
||||
---@field _bow_name string
|
||||
---@field _user_name string
|
||||
---@field _is_critical_hit boolean
|
||||
---@field _tool_capabilities ToolCapabilitiesDef
|
||||
---@field _tflp number
|
||||
---@field _add_damage number
|
||||
---@field _faster_arrows_multiplier number | nil
|
||||
|
|
Ŝarĝante…
Reference in New Issue