Crossbow improvements
Update turret mod Fix undeclared global in blast function Update rockets and grenades Update grapple hook and flares Unlink model textures
This commit is contained in:
parent
49d6fe5741
commit
cff296d70b
10 changed files with 252 additions and 220 deletions
|
@ -80,12 +80,22 @@ function shooter:spawn_particles(pos, texture)
|
|||
texture = config.explosion_texture
|
||||
end
|
||||
local spread = {x=0.1, y=0.1, z=0.1}
|
||||
minetest.add_particlespawner(15, 0.3,
|
||||
vector.subtract(pos, spread), vector.add(pos, spread),
|
||||
{x=-1, y=1, z=-1}, {x=1, y=2, z=1},
|
||||
{x=-2, y=-2, z=-2}, {x=2, y=-2, z=2},
|
||||
0.1, 0.75, 1, 2, false, texture
|
||||
)
|
||||
minetest.add_particlespawner({
|
||||
amount = 15,
|
||||
time = 0.3,
|
||||
minpos = vector.subtract(pos, spread),
|
||||
maxpos = vector.add(pos, spread),
|
||||
minvel = {x=-1, y=1, z=-1},
|
||||
maxvel = {x=1, y=2, z=1},
|
||||
minacc = {x=-2, y=-2, z=-2},
|
||||
maxacc = {x=2, y=-2, z=2},
|
||||
minexptime = 0.1,
|
||||
maxexptime = 0.75,
|
||||
minsize = 1,
|
||||
maxsize = 2,
|
||||
collisiondetection = false,
|
||||
texture = texture,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -261,21 +271,32 @@ function shooter:blast(pos, radius, fleshy, distance, user)
|
|||
end
|
||||
end
|
||||
if config.enable_particle_fx == true then
|
||||
minetest.add_particlespawner(50, 0.1,
|
||||
p1, p2, {x=-0, y=-0, z=-0}, {x=0, y=0, z=0},
|
||||
{x=-0.5, y=5, z=-0.5}, {x=0.5, y=5, z=0.5},
|
||||
0.1, 1, 8, 15, false, "tnt_smoke.png"
|
||||
)
|
||||
minetest.add_particlespawner({
|
||||
amount = 50,
|
||||
time = 0.1,
|
||||
minpos = p1,
|
||||
maxpos = p2,
|
||||
minvel = {x=0, y=0, z=0},
|
||||
maxvel = {x=0, y=0, z=0},
|
||||
minacc = {x=-0.5, y=5, z=-0.5},
|
||||
maxacc = {x=0.5, y=5, z=0.5},
|
||||
minexptime = 0.1,
|
||||
maxexptime = 1,
|
||||
minsize = 8,
|
||||
maxsize = 15,
|
||||
collisiondetection = false,
|
||||
texture = "tnt_smoke.png",
|
||||
})
|
||||
end
|
||||
local objects = minetest.get_objects_inside_radius(pos, distance)
|
||||
for _,obj in ipairs(objects) do
|
||||
if shooter:is_valid_object(obj) then
|
||||
local obj_pos = obj:getpos()
|
||||
local obj_pos = obj:get_pos()
|
||||
local dist = vector.distance(obj_pos, pos)
|
||||
local damage = (fleshy * 0.5 ^ dist) * 2
|
||||
if dist ~= 0 then
|
||||
obj_pos.y = obj_pos.y + 1
|
||||
blast_pos = {x=pos.x, y=pos.y + 4, z=pos.z}
|
||||
local blast_pos = {x=pos.x, y=pos.y + 4, z=pos.z}
|
||||
if minetest.line_of_sight(obj_pos, blast_pos, 1) then
|
||||
obj:punch(user, 1.0, {
|
||||
full_punch_interval = 1.0,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
local config = {
|
||||
crossbow_uses = 50,
|
||||
arrow_lifetime = 180,
|
||||
arrow_object_attach = false,
|
||||
}
|
||||
|
||||
-- Legacy Config Support
|
||||
|
@ -21,12 +22,14 @@ if minetest.global_exists("SHOOTER_ARROW_TOOL_CAPS") then
|
|||
arrow_tool_caps = table.copy(SHOOTER_ARROW_TOOL_CAPS)
|
||||
end
|
||||
|
||||
minetest.register_alias("shooter_crossbow:arrow", "shooter_crossbow:arrow_white")
|
||||
minetest.register_alias("shooter:crossbow_loaded", "shooter:crossbow_loaded_white")
|
||||
|
||||
local dye_basecolors = (dye and dye.basecolors) or
|
||||
{"white", "grey", "black", "red", "yellow", "green", "cyan", "blue", "magenta"}
|
||||
|
||||
-- name is the overlay texture name, colour is used to select the wool texture
|
||||
local function get_texture(name, colour)
|
||||
return "wool_"..colour..".png^shooter_"..name..".png^[makealpha:255,126,126"
|
||||
end
|
||||
|
||||
local function get_animation_frame(dir)
|
||||
local angle = math.atan(dir.y)
|
||||
local frame = 90 - math.floor(angle * 360 / math.pi)
|
||||
|
@ -38,15 +41,55 @@ local function get_animation_frame(dir)
|
|||
return frame
|
||||
end
|
||||
|
||||
local function get_target_pos(p1, p2, dir, offset)
|
||||
local d = vector.distance(p1, p2) - offset
|
||||
local td = vector.multiply(dir, {x=d, y=d, z=d})
|
||||
return vector.add(p1, td)
|
||||
local function get_pointed_thing(pos, dir, dist)
|
||||
local p1 = vector.add(pos, dir)
|
||||
local p2 = vector.add(pos, vector.multiply(dir, dist))
|
||||
local ray = minetest.raycast(p1, p2, true, true)
|
||||
return ray:next()
|
||||
end
|
||||
|
||||
-- name is the overlay texture name, colour is used to select the wool texture
|
||||
local function get_texture(name, colour)
|
||||
return "wool_"..colour..".png^shooter_"..name..".png^[makealpha:255,126,126"
|
||||
local function strike(arrow, pointed_thing, name)
|
||||
local puncher = minetest.get_player_by_name(name)
|
||||
if not puncher then
|
||||
return
|
||||
end
|
||||
local object = arrow.object
|
||||
local hit_pos = pointed_thing.intersection_point or object:get_pos()
|
||||
local dir = vector.normalize(object:get_velocity())
|
||||
if pointed_thing.type == "object" then
|
||||
local target = pointed_thing.ref
|
||||
if shooter:is_valid_object(target) then
|
||||
local puncher = minetest.get_player_by_name(name)
|
||||
if puncher and puncher ~= target then
|
||||
local groups = target:get_armor_groups() or {}
|
||||
if groups.fleshy then
|
||||
shooter:spawn_particles(hit_pos,
|
||||
shooter.config.explosion_texture)
|
||||
end
|
||||
target:punch(object, nil, arrow_tool_caps, dir)
|
||||
if config.arrow_object_attach then
|
||||
local pos = vector.multiply(vector.subtract(target:get_pos(),
|
||||
hit_pos), -10)
|
||||
local rot = vector.new()
|
||||
rot.y = (target:get_yaw() - object:get_yaw()) * 57.2958
|
||||
object:set_attach(target, "", pos, rot)
|
||||
arrow.state = "stuck"
|
||||
else
|
||||
arrow.state = "dropped"
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif pointed_thing.type == "node" then
|
||||
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
|
||||
local node = minetest.get_node(pos)
|
||||
hit_pos = vector.subtract(hit_pos, vector.multiply(dir, 0.25))
|
||||
arrow.node_pos = pos
|
||||
arrow.state = "stuck"
|
||||
shooter:play_node_sound(node, pos)
|
||||
else
|
||||
return
|
||||
end
|
||||
arrow:stop(hit_pos)
|
||||
end
|
||||
|
||||
minetest.register_entity("shooter_crossbow:arrow_entity", {
|
||||
|
@ -60,14 +103,14 @@ minetest.register_entity("shooter_crossbow:arrow_entity", {
|
|||
color = "white",
|
||||
timer = 0,
|
||||
lifetime = config.arrow_lifetime,
|
||||
player = nil,
|
||||
user = nil,
|
||||
state = "init",
|
||||
node_pos = nil,
|
||||
collisionbox = {0,0,0, 0,0,0},
|
||||
stop = function(self, pos)
|
||||
local acceleration = {x=0, y=-10, z=0}
|
||||
if self.state == "stuck" then
|
||||
pos = pos or self.object:getpos()
|
||||
pos = pos or self.object:get_pos()
|
||||
acceleration = {x=0, y=0, z=0}
|
||||
end
|
||||
if pos then
|
||||
|
@ -77,22 +120,8 @@ minetest.register_entity("shooter_crossbow:arrow_entity", {
|
|||
physical = true,
|
||||
collisionbox = {-1/8,-1/8,-1/8, 1/8,1/8,1/8},
|
||||
})
|
||||
self.object:setvelocity({x=0, y=0, z=0})
|
||||
self.object:setacceleration(acceleration)
|
||||
end,
|
||||
strike = function(self, object)
|
||||
local puncher = self.player
|
||||
if puncher and shooter:is_valid_object(object) then
|
||||
if puncher ~= object then
|
||||
local dir = puncher:get_look_dir()
|
||||
local p1 = puncher:getpos()
|
||||
local p2 = object:getpos()
|
||||
local tpos = get_target_pos(p1, p2, dir, 0)
|
||||
shooter:spawn_particles(tpos, shooter.config.explosion_texture)
|
||||
object:punch(puncher, nil, arrow_tool_caps, dir)
|
||||
end
|
||||
end
|
||||
self:stop(object:getpos())
|
||||
self.object:set_velocity({x=0, y=0, z=0})
|
||||
self.object:set_acceleration(acceleration)
|
||||
end,
|
||||
on_activate = function(self, staticdata)
|
||||
self.object:set_armor_groups({immortal=1})
|
||||
|
@ -143,25 +172,12 @@ minetest.register_entity("shooter_crossbow:arrow_entity", {
|
|||
return
|
||||
end
|
||||
if self.timer > 0.2 then
|
||||
local dir = vector.normalize(self.object:getvelocity())
|
||||
local dir = vector.normalize(self.object:get_velocity())
|
||||
local frame = get_animation_frame(dir)
|
||||
local p1 = vector.add(self.object:getpos(), dir)
|
||||
local p2 = vector.add(p1, vector.multiply(dir, 4))
|
||||
local ray = minetest.raycast(p1, p2, true, true)
|
||||
local pointed_thing = ray:next() or {}
|
||||
if pointed_thing.type == "object" then
|
||||
local obj = pointed_thing.ref
|
||||
if shooter:is_valid_object(obj) then
|
||||
self:strike(obj)
|
||||
end
|
||||
elseif pointed_thing.type == "node" then
|
||||
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
|
||||
local node = minetest.get_node(pos)
|
||||
local target_pos = get_target_pos(p1, pos, dir, 0.66)
|
||||
self.node_pos = pos
|
||||
self.state = "stuck"
|
||||
self:stop(target_pos)
|
||||
shooter:play_node_sound(node, pos)
|
||||
local pos = self.object:get_pos()
|
||||
local pointed_thing = get_pointed_thing(pos, dir, 5)
|
||||
if pointed_thing then
|
||||
strike(self, pointed_thing, self.user)
|
||||
end
|
||||
self.object:set_animation({x=frame, y=frame}, 0)
|
||||
self.timer = 0
|
||||
|
@ -184,22 +200,22 @@ for _, color in pairs(dye_basecolors) do
|
|||
on_use = function(itemstack, user, pointed_thing)
|
||||
minetest.sound_play("shooter_click", {object=user})
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
itemstack:add_wear(65535/config.crossbow_uses)
|
||||
itemstack:add_wear(65535 / config.crossbow_uses)
|
||||
end
|
||||
itemstack = "shooter_crossbow:crossbow 1 "..itemstack:get_wear()
|
||||
local pos = user:getpos()
|
||||
local pos = user:get_pos()
|
||||
local dir = user:get_look_dir()
|
||||
local yaw = user:get_look_yaw()
|
||||
local yaw = user:get_look_horizontal()
|
||||
if pos and dir and yaw then
|
||||
pos.y = pos.y + shooter.config.camera_height
|
||||
pos = vector.add(pos, dir)
|
||||
local obj = minetest.add_entity(pos, "shooter_crossbow:arrow_entity")
|
||||
local obj = minetest.add_entity(pos,
|
||||
"shooter_crossbow:arrow_entity")
|
||||
local ent = nil
|
||||
if obj then
|
||||
ent = obj:get_luaentity()
|
||||
end
|
||||
if ent then
|
||||
ent.player = ent.player or user
|
||||
ent.user = user:get_player_name()
|
||||
ent.state = "flight"
|
||||
ent.color = color
|
||||
obj:set_properties({
|
||||
|
@ -207,32 +223,14 @@ for _, color in pairs(dye_basecolors) do
|
|||
})
|
||||
minetest.sound_play("shooter_throw", {object=obj})
|
||||
local frame = get_animation_frame(dir)
|
||||
obj:setyaw(yaw + math.pi)
|
||||
obj:set_yaw(yaw - math.pi / 2)
|
||||
obj:set_animation({x=frame, y=frame}, 0)
|
||||
obj:setvelocity({x=dir.x * 14, y=dir.y * 14, z=dir.z * 14})
|
||||
if pointed_thing.type ~= "nothing" then
|
||||
local ppos = minetest.get_pointed_thing_position(pointed_thing, false)
|
||||
local _, npos = minetest.line_of_sight(pos, ppos, 1)
|
||||
if npos then
|
||||
ppos = npos
|
||||
pointed_thing.type = "node"
|
||||
obj:set_velocity({x=dir.x * 14, y=dir.y * 14, z=dir.z * 14})
|
||||
obj:set_acceleration({x=dir.x * -3, y=-5, z=dir.z * -3})
|
||||
pointed_thing = get_pointed_thing(pos, dir, 5)
|
||||
if pointed_thing then
|
||||
strike(ent, pointed_thing, ent.user)
|
||||
end
|
||||
if pointed_thing.type == "object" then
|
||||
ent:strike(pointed_thing.ref)
|
||||
return itemstack
|
||||
elseif pointed_thing.type == "node" then
|
||||
local node = minetest.get_node(ppos)
|
||||
local tpos = get_target_pos(pos, ppos, dir, 0.66)
|
||||
minetest.after(0.2, function(object, pos, npos)
|
||||
ent.node_pos = npos
|
||||
ent.state = "stuck"
|
||||
ent:stop(pos)
|
||||
shooter:play_node_sound(node, npos)
|
||||
end, obj, tpos, ppos)
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
obj:setacceleration({x=dir.x * -3, y=-5, z=dir.z * -3})
|
||||
end
|
||||
end
|
||||
return itemstack
|
||||
|
|
Binary file not shown.
|
@ -12,7 +12,7 @@ minetest.register_node("shooter_flaregun:flare_light", {
|
|||
walkable = false,
|
||||
buildable_to = true,
|
||||
sunlight_propagates = true,
|
||||
light_source = LIGHT_MAX,
|
||||
light_source = 14,
|
||||
pointable = false,
|
||||
})
|
||||
|
||||
|
@ -47,7 +47,7 @@ minetest.register_entity("shooter_flaregun:flare_entity", {
|
|||
"shooter_flare.png",
|
||||
"shooter_flare.png",
|
||||
},
|
||||
player = nil,
|
||||
glow = 14,
|
||||
collisionbox = {-1/16,-1/16,-1/16, 1/16,1/16,1/16},
|
||||
on_activate = function(self, staticdata)
|
||||
if staticdata == "expired" then
|
||||
|
@ -57,29 +57,41 @@ minetest.register_entity("shooter_flaregun:flare_entity", {
|
|||
on_step = function(self, dtime)
|
||||
self.timer = self.timer + dtime
|
||||
if self.timer > 0.2 then
|
||||
local pos = self.object:getpos()
|
||||
local pos = self.object:get_pos()
|
||||
local below = {x=pos.x, y=pos.y - 1, z=pos.z}
|
||||
local node = minetest.get_node(below)
|
||||
if node.name ~= "air" then
|
||||
self.object:setvelocity({x=0, y=-10, z=0})
|
||||
self.object:setacceleration({x=0, y=0, z=0})
|
||||
self.object:set_velocity({x=0, y=-10, z=0})
|
||||
self.object:set_acceleration({x=0, y=0, z=0})
|
||||
if minetest.get_node(pos).name == "air" and
|
||||
node.name ~= "default:water_source" and
|
||||
node.name ~= "default:water_flowing" then
|
||||
minetest.place_node(pos, {name="shooter_flaregun:flare_light"})
|
||||
local meta = minetest.get_meta(pos)
|
||||
pos.y = pos.y - 0.1
|
||||
local id = minetest.add_particlespawner(
|
||||
1000, 30, pos, pos,
|
||||
{x=-1, y=1, z=-1}, {x=1, y=1, z=1},
|
||||
{x=2, y=-2, z=-2}, {x=2, y=-2, z=2},
|
||||
0.1, 0.75, 1, 8, false, "shooter_flare_particle.png"
|
||||
)
|
||||
local id = minetest.add_particlespawner({
|
||||
amount = 1000,
|
||||
time = 30,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = {x=-1, y=1, z=-1},
|
||||
maxvel = {x=1, y=1, z=1},
|
||||
minacc = {x=2, y=-2, z=-2},
|
||||
maxacc = {x=2, y=-2, z=2},
|
||||
minexptime = 0.1,
|
||||
maxexptime = 0.75,
|
||||
minsize = 1,
|
||||
maxsize = 8,
|
||||
collisiondetection = false,
|
||||
texture = "shooter_flare_particle.png",
|
||||
glow = 14,
|
||||
})
|
||||
meta:set_int("particle_id", id)
|
||||
meta:set_int("init_time", os.time())
|
||||
local sound = minetest.sound_play("shooter_flare_burn", {
|
||||
object = self.player,
|
||||
pos = pos,
|
||||
loop = true,
|
||||
max_hear_distance = 8,
|
||||
})
|
||||
minetest.after(30, function(sound)
|
||||
minetest.sound_stop(sound)
|
||||
|
@ -106,23 +118,19 @@ minetest.register_tool("shooter_flaregun:flaregun", {
|
|||
end
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
inv:remove_item("main", "shooter:flare 1")
|
||||
itemstack:add_wear(65535/100)
|
||||
itemstack:add_wear(65535 / 100)
|
||||
end
|
||||
local pos = user:getpos()
|
||||
local pos = user:get_pos()
|
||||
local dir = user:get_look_dir()
|
||||
local yaw = user:get_look_yaw()
|
||||
local yaw = user:get_look_horizontal()
|
||||
if pos and dir and yaw then
|
||||
pos.y = pos.y + 1.5
|
||||
local obj = minetest.add_entity(pos, "shooter_flaregun:flare_entity")
|
||||
if obj then
|
||||
minetest.sound_play("shooter_flare_fire", {object=obj})
|
||||
obj:setvelocity({x=dir.x * 16, y=dir.y * 16, z=dir.z * 16})
|
||||
obj:setacceleration({x=dir.x * -3, y=-10, z=dir.z * -3})
|
||||
obj:setyaw(yaw + math.pi)
|
||||
local ent = obj:get_luaentity()
|
||||
if ent then
|
||||
ent.player = ent.player or user
|
||||
end
|
||||
obj:set_velocity(vector.multiply(dir, 16))
|
||||
obj:set_acceleration({x=dir.x * -3, y=-10, z=dir.z * -3})
|
||||
obj:set_yaw(yaw + math.pi / 2)
|
||||
end
|
||||
end
|
||||
return itemstack
|
||||
|
|
|
@ -11,7 +11,7 @@ minetest.register_entity("shooter_grenade:grenade_entity", {
|
|||
"shooter_grenade.png",
|
||||
"shooter_grenade.png",
|
||||
},
|
||||
player = nil,
|
||||
user = nil,
|
||||
collisionbox = {0,0,0, 0,0,0},
|
||||
on_activate = function(self, staticdata)
|
||||
if staticdata == "expired" then
|
||||
|
@ -21,11 +21,16 @@ minetest.register_entity("shooter_grenade:grenade_entity", {
|
|||
on_step = function(self, dtime)
|
||||
self.timer = self.timer + dtime
|
||||
if self.timer > 0.2 then
|
||||
local pos = self.object:getpos()
|
||||
local pos = self.object:get_pos()
|
||||
local above = {x=pos.x, y=pos.y + 1, z=pos.z}
|
||||
if minetest.get_node(pos).name ~= "air" then
|
||||
if self.user then
|
||||
local player = minetest.get_player_by_name(self.user)
|
||||
if player then
|
||||
shooter:blast(above, 2, 25, 5, player)
|
||||
end
|
||||
end
|
||||
self.object:remove()
|
||||
shooter:blast(above, 2, 25, 5, self.player)
|
||||
end
|
||||
self.timer = 0
|
||||
end
|
||||
|
@ -40,28 +45,29 @@ minetest.register_tool("shooter_grenade:grenade", {
|
|||
inventory_image = "shooter_hand_grenade.png",
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
itemstack = ""
|
||||
itemstack:clear()
|
||||
end
|
||||
if pointed_thing.type ~= "nothing" then
|
||||
local pointed = minetest.get_pointed_thing_position(pointed_thing)
|
||||
if vector.distance(user:getpos(), pointed) < 8 then
|
||||
if vector.distance(user:get_pos(), pointed) < 8 then
|
||||
shooter:blast(pointed, 1, 25, 5)
|
||||
return
|
||||
end
|
||||
end
|
||||
local pos = user:getpos()
|
||||
local pos = user:get_pos()
|
||||
local dir = user:get_look_dir()
|
||||
local yaw = user:get_look_yaw()
|
||||
local yaw = user:get_look_horizontal()
|
||||
if pos and dir then
|
||||
pos.y = pos.y + 1.5
|
||||
pos.y = pos.y + shooter.config.camera_height
|
||||
local obj = minetest.add_entity(pos, "shooter_grenade:grenade_entity")
|
||||
if obj then
|
||||
obj:setvelocity({x=dir.x * 15, y=dir.y * 15, z=dir.z * 15})
|
||||
obj:setacceleration({x=dir.x * -3, y=-10, z=dir.z * -3})
|
||||
obj:setyaw(yaw + math.pi)
|
||||
minetest.sound_play("shooter_throw", {object=obj})
|
||||
obj:set_velocity(vector.multiply(dir, 15))
|
||||
obj:set_acceleration({x=dir.x * -3, y=-10, z=dir.z * -3})
|
||||
obj:set_yaw(yaw + math.pi / 2)
|
||||
local ent = obj:get_luaentity()
|
||||
if ent then
|
||||
ent.player = ent.player or user
|
||||
ent.user = user:get_player_name()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
local function throw_hook(itemstack, user, vel)
|
||||
local inv = user:get_inventory()
|
||||
local pos = user:getpos()
|
||||
local pos = user:get_pos()
|
||||
local dir = user:get_look_dir()
|
||||
local yaw = user:get_look_yaw()
|
||||
local yaw = user:get_look_horizontal()
|
||||
if pos and dir and yaw then
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
itemstack:add_wear(65535/100)
|
||||
itemstack:add_wear(65535 / 100)
|
||||
end
|
||||
pos.y = pos.y + 1.5
|
||||
local obj = minetest.add_entity(pos, "shooter_hook:hook")
|
||||
if obj then
|
||||
minetest.sound_play("shooter_throw", {object=obj})
|
||||
obj:setvelocity({x=dir.x * vel, y=dir.y * vel, z=dir.z * vel})
|
||||
obj:setacceleration({x=dir.x * -3, y=-10, z=dir.z * -3})
|
||||
obj:setyaw(yaw + math.pi)
|
||||
obj:set_velocity(vector.multiply(dir, vel))
|
||||
obj:set_acceleration({x=dir.x * -3, y=-10, z=dir.z * -3})
|
||||
obj:set_yaw(yaw + math.pi / 2)
|
||||
local ent = obj:get_luaentity()
|
||||
if ent then
|
||||
ent.player = ent.player or user
|
||||
ent.user = user:get_player_name()
|
||||
ent.itemstack = itemstack
|
||||
end
|
||||
end
|
||||
|
@ -29,7 +29,7 @@ minetest.register_entity("shooter_hook:hook", {
|
|||
visual = "wielditem",
|
||||
visual_size = {x=1/2, y=1/2},
|
||||
textures = {"shooter_hook:grapple_hook"},
|
||||
player = nil,
|
||||
user = nil,
|
||||
itemstack = "",
|
||||
collisionbox = {-1/4,-1/4,-1/4, 1/4,1/4,1/4},
|
||||
on_activate = function(self, staticdata)
|
||||
|
@ -39,20 +39,23 @@ minetest.register_entity("shooter_hook:hook", {
|
|||
end
|
||||
end,
|
||||
on_step = function(self, dtime)
|
||||
if not self.player then
|
||||
if not self.user then
|
||||
return
|
||||
end
|
||||
self.timer = self.timer + dtime
|
||||
if self.timer > 0.25 then
|
||||
local pos = self.object:getpos()
|
||||
local pos = self.object:get_pos()
|
||||
local below = {x=pos.x, y=pos.y - 1, z=pos.z}
|
||||
local node = minetest.get_node(below)
|
||||
if node.name ~= "air" then
|
||||
self.object:setvelocity({x=0, y=-10, z=0})
|
||||
self.object:setacceleration({x=0, y=0, z=0})
|
||||
self.object:set_velocity({x=0, y=-10, z=0})
|
||||
self.object:set_acceleration({x=0, y=0, z=0})
|
||||
if minetest.get_item_group(node.name, "liquid") == 0 and
|
||||
minetest.get_node(pos).name == "air" then
|
||||
self.player:moveto(pos)
|
||||
local player = minetest.get_player_by_name(self.user)
|
||||
if player then
|
||||
player:moveto(pos)
|
||||
end
|
||||
end
|
||||
if minetest.get_item_group(node.name, "lava") == 0 then
|
||||
minetest.add_item(pos, self.itemstack)
|
||||
|
|
|
@ -17,7 +17,7 @@ minetest.register_entity("shooter_rocket:rocket_entity", {
|
|||
"shooter_bullet.png",
|
||||
"shooter_bullet.png",
|
||||
},
|
||||
player = nil,
|
||||
user = nil,
|
||||
collisionbox = {0,0,0, 0,0,0},
|
||||
on_activate = function(self, staticdata)
|
||||
if staticdata == "expired" then
|
||||
|
@ -27,11 +27,16 @@ minetest.register_entity("shooter_rocket:rocket_entity", {
|
|||
on_step = function(self, dtime)
|
||||
self.timer = self.timer + dtime
|
||||
if self.timer > 0.2 then
|
||||
local pos = self.object:getpos()
|
||||
local pos = self.object:get_pos()
|
||||
local above = {x=pos.x, y=pos.y + 1, z=pos.z}
|
||||
if minetest.get_node(pos).name ~= "air" then
|
||||
if self.user then
|
||||
local player = minetest.get_player_by_name(self.user)
|
||||
if player then
|
||||
shooter:blast(above, 4, 50, 8, player)
|
||||
end
|
||||
end
|
||||
self.object:remove()
|
||||
shooter:blast(above, 4, 50, 8, self.player)
|
||||
end
|
||||
self.timer = 0
|
||||
end
|
||||
|
@ -47,30 +52,30 @@ minetest.register_tool("shooter_rocket:rocket_gun_loaded", {
|
|||
groups = {not_in_creative_inventory=1},
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
itemstack:add_wear(65535/50)
|
||||
itemstack:add_wear(65535 / 50)
|
||||
end
|
||||
itemstack = "shooter_rocket:rocket_gun 1 "..itemstack:get_wear()
|
||||
if pointed_thing.type ~= "nothing" then
|
||||
local pointed = minetest.get_pointed_thing_position(pointed_thing)
|
||||
if vector.distance(user:getpos(), pointed) < 8 then
|
||||
if vector.distance(user:get_pos(), pointed) < 8 then
|
||||
shooter:blast(pointed, 2, 50, 7)
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
local pos = user:getpos()
|
||||
local pos = user:get_pos()
|
||||
local dir = user:get_look_dir()
|
||||
local yaw = user:get_look_yaw()
|
||||
local yaw = user:get_look_horizontal()
|
||||
if pos and dir and yaw then
|
||||
pos.y = pos.y + 1.5
|
||||
pos.y = pos.y + shooter.config.camera_height
|
||||
local obj = minetest.add_entity(pos, "shooter_rocket:rocket_entity")
|
||||
if obj then
|
||||
minetest.sound_play("shooter_rocket_fire", {object=obj})
|
||||
obj:setvelocity({x=dir.x * 20, y=dir.y * 20, z=dir.z * 20})
|
||||
obj:setacceleration({x=dir.x * -3, y=-10, z=dir.z * -3})
|
||||
obj:setyaw(yaw + math.pi)
|
||||
obj:set_velocity(vector.multiply(dir, 20))
|
||||
obj:set_acceleration({x=dir.x * -3, y=-10, z=dir.z * -3})
|
||||
obj:set_yaw(yaw + math.pi / 2)
|
||||
local ent = obj:get_luaentity()
|
||||
if ent then
|
||||
ent.player = ent.player or user
|
||||
ent.user = user:get_player_name()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
shooter
|
||||
shooter_rocket
|
||||
player_api?
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
local use_player_api = minetest.get_modpath("player_api")
|
||||
|
||||
local function get_turret_entity(pos)
|
||||
local entity = nil
|
||||
local objects = minetest.get_objects_inside_radius(pos, 1)
|
||||
|
@ -17,42 +19,6 @@ local function get_turret_entity(pos)
|
|||
return entity
|
||||
end
|
||||
|
||||
minetest.register_entity("shooter_turret:tnt_entity", {
|
||||
physical = false,
|
||||
timer = 0,
|
||||
visual = "cube",
|
||||
visual_size = {x=1/4, y=1/4},
|
||||
textures = {
|
||||
"tnt_top.png",
|
||||
"tnt_bottom.png",
|
||||
"tnt_side.png",
|
||||
"tnt_side.png",
|
||||
"tnt_side.png",
|
||||
"tnt_side.png",
|
||||
},
|
||||
player = nil,
|
||||
collisionbox = {0,0,0, 0,0,0},
|
||||
on_activate = function(self, staticdata)
|
||||
if staticdata == "expired" then
|
||||
self.object:remove()
|
||||
end
|
||||
end,
|
||||
on_step = function(self, dtime)
|
||||
self.timer = self.timer + dtime
|
||||
if self.timer > 0.2 then
|
||||
local pos = self.object:getpos()
|
||||
if minetest.get_node(pos).name ~= "air" then
|
||||
self.object:remove()
|
||||
shooter:blast(pos, 4, 80, 10, self.player)
|
||||
end
|
||||
self.timer = 0
|
||||
end
|
||||
end,
|
||||
get_staticdata = function(self)
|
||||
return "expired"
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_entity("shooter_turret:turret_entity", {
|
||||
physical = true,
|
||||
visual = "mesh",
|
||||
|
@ -63,13 +29,13 @@ minetest.register_entity("shooter_turret:turret_entity", {
|
|||
"shooter_turret_uv.png",
|
||||
},
|
||||
timer = 0,
|
||||
player = nil,
|
||||
user = nil,
|
||||
pitch = 40,
|
||||
yaw = 0,
|
||||
firing = false,
|
||||
on_activate = function(self, staticdata)
|
||||
self.pos = self.object:getpos()
|
||||
self.yaw = self.object:getyaw()
|
||||
self.pos = self.object:get_pos()
|
||||
self.yaw = self.object:get_yaw()
|
||||
if minetest.get_node(self.pos).name ~= "shooter_turret:turret" then
|
||||
self.object:remove()
|
||||
return
|
||||
|
@ -80,23 +46,36 @@ minetest.register_entity("shooter_turret:turret_entity", {
|
|||
get_turret_entity(self.pos)
|
||||
end,
|
||||
on_rightclick = function(self, clicker)
|
||||
if self.player then
|
||||
self.player:set_detach()
|
||||
self.player = nil
|
||||
if self.user then
|
||||
local player = minetest.get_player_by_name(self.user)
|
||||
if player then
|
||||
player:set_detach()
|
||||
if use_player_api then
|
||||
player_api.player_attached[self.user] = false
|
||||
end
|
||||
end
|
||||
self.user = nil
|
||||
else
|
||||
clicker:set_attach(self.object, "", {x=0,y=5,z=-8}, {x=0,y=0,z=0})
|
||||
self.player = clicker
|
||||
clicker:set_attach(self.object, "", {x=0,y=-5,z=-8}, {x=0,y=0,z=0})
|
||||
self.user = clicker:get_player_name()
|
||||
if use_player_api then
|
||||
player_api.player_attached[self.user] = true
|
||||
end
|
||||
end
|
||||
end,
|
||||
on_step = function(self, dtime)
|
||||
self.timer = self.timer + dtime
|
||||
if self.timer < 0.1 then
|
||||
if not self.user then
|
||||
return
|
||||
end
|
||||
if self.player then
|
||||
self.timer = self.timer + dtime
|
||||
if self.timer < 0.2 then
|
||||
return
|
||||
end
|
||||
local player = minetest.get_player_by_name(self.user)
|
||||
if player then
|
||||
local pitch = self.pitch
|
||||
local yaw = self.object:getyaw()
|
||||
local ctrl = self.player:get_player_control()
|
||||
local yaw = self.object:get_yaw()
|
||||
local ctrl = player:get_player_control()
|
||||
local step = 2
|
||||
if ctrl then
|
||||
if ctrl.sneak then
|
||||
|
@ -130,7 +109,7 @@ minetest.register_entity("shooter_turret:turret_entity", {
|
|||
self.pitch = pitch
|
||||
end
|
||||
if self.yaw ~= yaw then
|
||||
self.object:setyaw(yaw)
|
||||
self.object:set_yaw(yaw)
|
||||
self.yaw = yaw
|
||||
end
|
||||
end
|
||||
|
@ -138,19 +117,20 @@ minetest.register_entity("shooter_turret:turret_entity", {
|
|||
self.timer = 0
|
||||
end,
|
||||
fire = function(self)
|
||||
if not self.user then
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(self.pos)
|
||||
local inv = meta:get_inventory()
|
||||
if not inv then
|
||||
return
|
||||
end
|
||||
if not inv:contains_item("main", "tnt:tnt") then
|
||||
if not inv:contains_item("main", "shooter_rocket:rocket") then
|
||||
minetest.sound_play("shooter_click", {object=self.object})
|
||||
return
|
||||
end
|
||||
inv:remove_item("main", "shooter_rocket:rocket")
|
||||
minetest.sound_play("shooter_shotgun", {object=self.object})
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
inv:remove_item("main", "tnt:tnt")
|
||||
end
|
||||
local pitch = math.rad(self.pitch - 40)
|
||||
local len = math.cos(pitch)
|
||||
local dir = vector.normalize({
|
||||
|
@ -159,26 +139,35 @@ minetest.register_entity("shooter_turret:turret_entity", {
|
|||
z = len * math.cos(self.yaw),
|
||||
})
|
||||
local pos = {x=self.pos.x, y=self.pos.y + 0.87, z=self.pos.z}
|
||||
pos = vector.add(pos, {x=dir.x * 1.5, y=dir.y * 1.5, z=dir.z * 1.5})
|
||||
local obj = minetest.add_entity(pos, "shooter_turret:tnt_entity")
|
||||
pos = vector.add(pos, vector.multiply(dir, 1.5))
|
||||
local obj = minetest.add_entity(pos, "shooter_rocket:rocket_entity")
|
||||
if obj then
|
||||
local ent = obj:get_luaentity()
|
||||
if ent then
|
||||
minetest.sound_play("shooter_rocket_fire", {object=obj})
|
||||
ent.player = self.player
|
||||
obj:setyaw(self.yaw)
|
||||
obj:setvelocity({x=dir.x * 20, y=dir.y * 20, z=dir.z * 20})
|
||||
obj:setacceleration({x=dir.x * -3, y=-10, z=dir.z * -3})
|
||||
ent.user = self.user
|
||||
obj:set_yaw(self.yaw)
|
||||
obj:set_velocity(vector.multiply(dir, 30))
|
||||
obj:set_acceleration({x=dir.x * -3, y=-10, z=dir.z * -3})
|
||||
end
|
||||
end
|
||||
if shooter.config.enable_particle_fx == true then
|
||||
minetest.add_particlespawner(10, 0.1,
|
||||
{x=pos.x - 1, y=pos.y - 1, z=pos.z - 1},
|
||||
{x=pos.x + 1, y=pos.y + 1, z=pos.z + 1},
|
||||
{x=0, y=0, z=0}, {x=0, y=0, z=0},
|
||||
{x=-0.5, y=-0.5, z=-0.5}, {x=0.5, y=0.5, z=0.5},
|
||||
0.1, 1, 8, 15, false, "tnt_smoke.png"
|
||||
)
|
||||
minetest.add_particlespawner({
|
||||
amount = 10,
|
||||
time = 0.1,
|
||||
minpos = {x=pos.x - 1, y=pos.y - 1, z=pos.z - 1},
|
||||
maxpos = {x=pos.x + 1, y=pos.y + 1, z=pos.z + 1},
|
||||
minvel = {x=0, y=0, z=0},
|
||||
maxvel = {x=0, y=0, z=0},
|
||||
minacc = {x=-0.5, y=-0.5, z=-0.5},
|
||||
maxacc = {x=0.5, y=0.5, z=0.5},
|
||||
minexptime = 0.1,
|
||||
maxexptime = 1,
|
||||
minsize = 8,
|
||||
maxsize = 15,
|
||||
collisiondetection = false,
|
||||
texture = "tnt_smoke.png",
|
||||
})
|
||||
end
|
||||
end
|
||||
})
|
||||
|
@ -191,7 +180,7 @@ minetest.register_node("shooter_turret:turret", {
|
|||
drawtype = "nodebox",
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=3},
|
||||
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=3},
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
|
@ -207,7 +196,8 @@ minetest.register_node("shooter_turret:turret", {
|
|||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("formspec", "size[8,9]"..
|
||||
"list[current_name;main;2,0;4,4;]"..
|
||||
"list[current_player;main;0,5;8,4;]"
|
||||
"list[current_player;main;0,5;8,4;]"..
|
||||
"listring[]"
|
||||
)
|
||||
meta:set_string("infotext", "Turret Gun")
|
||||
local inv = meta:get_inventory()
|
||||
|
|
Binary file not shown.
Loading…
Reference in a new issue