Add spread option and update shotgun definition
This commit is contained in:
parent
88750a0353
commit
8e18c0b117
4 changed files with 104 additions and 21 deletions
|
@ -2,7 +2,6 @@ allow_defined_top = true
|
||||||
|
|
||||||
read_globals = {
|
read_globals = {
|
||||||
"ItemStack",
|
"ItemStack",
|
||||||
"vector",
|
|
||||||
"VoxelArea",
|
"VoxelArea",
|
||||||
"VoxelManip",
|
"VoxelManip",
|
||||||
"PseudoRandom",
|
"PseudoRandom",
|
||||||
|
@ -11,6 +10,7 @@ read_globals = {
|
||||||
}
|
}
|
||||||
|
|
||||||
globals = {
|
globals = {
|
||||||
|
"vector",
|
||||||
"minetest",
|
"minetest",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -188,6 +188,11 @@ Used by `shooter.register_weapon`
|
||||||
-- Range (in nodes) of each shot
|
-- Range (in nodes) of each shot
|
||||||
step = 30,
|
step = 30,
|
||||||
-- Distance per `shooter_rounds_update_time`
|
-- Distance per `shooter_rounds_update_time`
|
||||||
|
shots = 1,
|
||||||
|
-- Number of shots fired per `round`
|
||||||
|
spread = 10,
|
||||||
|
-- Spread of shots in degrees if `shots` > 1
|
||||||
|
-- Uses a sunflower seed arrangement for even distributuion
|
||||||
tool_caps = {
|
tool_caps = {
|
||||||
-- Tool capabilities, used for object/player damage
|
-- Tool capabilities, used for object/player damage
|
||||||
full_punch_interval = 1.0,
|
full_punch_interval = 1.0,
|
||||||
|
|
104
shooter/api.lua
104
shooter/api.lua
|
@ -59,6 +59,11 @@ local shooting = {}
|
||||||
local config = shooter.config
|
local config = shooter.config
|
||||||
local server_step = minetest.settings:get("dedicated_server_step")
|
local server_step = minetest.settings:get("dedicated_server_step")
|
||||||
local v3d = vector
|
local v3d = vector
|
||||||
|
local PI = math.pi
|
||||||
|
local sin = math.sin
|
||||||
|
local cos = math.cos
|
||||||
|
local sqrt = math.sqrt
|
||||||
|
local phi = (math.sqrt(5) + 1) / 2 -- Golden ratio
|
||||||
|
|
||||||
shooter.register_weapon = function(name, def)
|
shooter.register_weapon = function(name, def)
|
||||||
-- Fix definition table
|
-- Fix definition table
|
||||||
|
@ -240,6 +245,74 @@ shooter.punch_object = function(object, tool_caps, dir, on_blast)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function matrix_from_quat(q)
|
||||||
|
local m = {{}, {}, {}}
|
||||||
|
m[1][1] = 1 - 2 * q.y * q.y - 2 * q.z * q.z
|
||||||
|
m[1][2] = 2 * q.x * q.y + 2 * q.z * q.w
|
||||||
|
m[1][3] = 2 * q.x * q.z - 2 * q.y * q.w
|
||||||
|
m[2][1] = 2 * q.x * q.y - 2 * q.z * q.w
|
||||||
|
m[2][2] = 1 - 2 * q.x * q.x - 2 * q.z * q.z
|
||||||
|
m[2][3] = 2 * q.z * q.y + 2 * q.x * q.w
|
||||||
|
m[3][1] = 2 * q.x * q.z + 2 * q.y * q.w
|
||||||
|
m[3][2] = 2 * q.z * q.y - 2 * q.x * q.w
|
||||||
|
m[3][3] = 1 - 2 * q.x * q.x - 2 * q.y * q.y
|
||||||
|
return m
|
||||||
|
end
|
||||||
|
|
||||||
|
local function quat_from_angle_axis(angle, axis)
|
||||||
|
local t = angle / 2
|
||||||
|
local s = sin(t)
|
||||||
|
return {
|
||||||
|
x = s * axis.x,
|
||||||
|
y = s * axis.y,
|
||||||
|
z = s * axis.z,
|
||||||
|
w = cos(t),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
v3d.cross = function(v1, v2)
|
||||||
|
return {
|
||||||
|
x = v1.y * v2.z - v2.y * v1.z,
|
||||||
|
y = v1.z * v2.x - v2.z * v1.x,
|
||||||
|
z = v1.x * v2.y - v2.x * v1.y,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
v3d.mult_matrix = function(v, m)
|
||||||
|
return {
|
||||||
|
x = m[1][1] * v.x + m[1][2] * v.y + m[1][3] * v.z,
|
||||||
|
y = m[2][1] * v.x + m[2][2] * v.y + m[2][3] * v.z,
|
||||||
|
z = m[3][1] * v.x + m[3][2] * v.y + m[3][3] * v.z,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
v3d.rotate = function(v, angle, axis)
|
||||||
|
local q = quat_from_angle_axis(angle, axis)
|
||||||
|
local m = matrix_from_quat(q)
|
||||||
|
return v3d.mult_matrix(v, m)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_directions(dir, spec)
|
||||||
|
local directions = {dir}
|
||||||
|
local n = spec.shots or 1
|
||||||
|
if n > 1 then
|
||||||
|
local right = v3d.normalize(v3d.cross(dir, {x=0, y=1, z=0}))
|
||||||
|
local up = v3d.normalize(v3d.cross(dir, right))
|
||||||
|
local s = spec.spread or 10
|
||||||
|
s = s * 0.017453 -- Convert to radians
|
||||||
|
for k = 1, n - 1 do
|
||||||
|
-- Sunflower seed arrangement
|
||||||
|
local r = sqrt(k - 0.5) / sqrt(n - 0.5)
|
||||||
|
local theta = 2 * PI * k / (phi * phi)
|
||||||
|
local x = r * cos(theta) * s
|
||||||
|
local y = r * sin(theta) * s
|
||||||
|
local d = v3d.rotate(dir, y, up)
|
||||||
|
directions[k + 1] = v3d.rotate(d, x, right)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return directions
|
||||||
|
end
|
||||||
|
|
||||||
local function process_hit(pointed_thing, spec, dir)
|
local function process_hit(pointed_thing, spec, dir)
|
||||||
local def = minetest.registered_items[spec.name] or {}
|
local def = minetest.registered_items[spec.name] or {}
|
||||||
if type(def.on_hit) == "function" then
|
if type(def.on_hit) == "function" then
|
||||||
|
@ -295,22 +368,25 @@ local function fire_weapon(player, itemstack, spec, extended)
|
||||||
local interval = spec.tool_caps.full_punch_interval
|
local interval = spec.tool_caps.full_punch_interval
|
||||||
shots[spec.user] = minetest.get_us_time() / 1000000 + interval
|
shots[spec.user] = minetest.get_us_time() / 1000000 + interval
|
||||||
minetest.sound_play(spec.sound, {object=player})
|
minetest.sound_play(spec.sound, {object=player})
|
||||||
if spec.bullet_image then
|
local directions = get_directions(dir, spec)
|
||||||
minetest.add_particle({
|
for _, d in pairs(directions) do
|
||||||
pos = pos,
|
if spec.bullet_image then
|
||||||
velocity = v3d.multiply(dir, 30),
|
minetest.add_particle({
|
||||||
acceleration = {x=0, y=0, z=0},
|
pos = pos,
|
||||||
expirationtime = 0.5,
|
velocity = v3d.multiply(d, 30),
|
||||||
size = 0.25,
|
acceleration = {x=0, y=0, z=0},
|
||||||
texture = spec.bullet_image,
|
expirationtime = 0.5,
|
||||||
|
size = 0.25,
|
||||||
|
texture = spec.bullet_image,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
process_round({
|
||||||
|
spec = spec,
|
||||||
|
pos = v3d.new(spec.origin),
|
||||||
|
dir = d,
|
||||||
|
dist = 0,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
process_round({
|
|
||||||
spec = spec,
|
|
||||||
pos = v3d.new(spec.origin),
|
|
||||||
dir = dir,
|
|
||||||
dist = 0,
|
|
||||||
})
|
|
||||||
if extended then
|
if extended then
|
||||||
itemstack:add_wear(spec.wear)
|
itemstack:add_wear(spec.wear)
|
||||||
if itemstack:get_count() == 0 then
|
if itemstack:get_count() == 0 then
|
||||||
|
|
|
@ -62,14 +62,16 @@ shooter.register_weapon("shooter_guns:shotgun", {
|
||||||
rounds = 50,
|
rounds = 50,
|
||||||
range = 30,
|
range = 30,
|
||||||
step = 15,
|
step = 15,
|
||||||
tool_caps = {full_punch_interval=1.5, damage_groups={fleshy=4}},
|
shots = 15,
|
||||||
groups = {cracky=3, snappy=2, crumbly=2, choppy=2, fleshy=1, oddly_breakable_by_hand=1},
|
spread = 10,
|
||||||
|
tool_caps = {full_punch_interval=0.5, damage_groups={fleshy=2}},
|
||||||
|
groups = {snappy=3, fleshy=3, oddly_breakable_by_hand=3},
|
||||||
sound = "shooter_shotgun",
|
sound = "shooter_shotgun",
|
||||||
bullet_image = "smoke_puff.png",
|
bullet_image = "shooter_cap.png",
|
||||||
particles = {
|
particles = {
|
||||||
amount = 16,
|
amount = 8,
|
||||||
minsize = 1,
|
minsize = 0.25,
|
||||||
maxsize = 2,
|
maxsize = 0.75,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue