Rocket Launcher modeled, animated, new things re: particles

fps_game
Jordan Snelling 2021-05-24 03:32:48 +01:00
parent 8f4beb6327
commit 1644eeee02
20 changed files with 46507 additions and 260 deletions

View File

@ -7,7 +7,8 @@
"core",
"VoxelArea",
"ItemStack",
"dump"
"dump",
"particulate"
],
"Lua.diagnostics.disable": [
"undefined-field",

20
mods/LICENSE Normal file
View File

@ -0,0 +1,20 @@
Files and Media Under Non Open Media Compatible Licenses:
Files and Media Under Xbox Game Content Usage Rules:
3D Models:
/weapons/models/arms_spnkrx.x
/weapons/models/preview_spnkrx.obj
Textures:
/weapons/textures/materials/SPNKR.png
Sounds:
TBA
See for more information:
https://www.xbox.com/en-US/developers/rules

358
mods/particulate/init.lua Normal file
View File

@ -0,0 +1,358 @@
-- Particulate
-- A mod to create cubic or other worldly shaped particles in the same vein as the Irrlicht ones.
-- License: MIT
-- Author: Jordach
particulate = {}
particulate.known_particles = {}
function particulate.register_cubic_particle(name, definition, physics, factor, sound_name, sound_def)
local def = table.copy(definition)
def.visual = "mesh"
def.mesh = "particulate_cubic.obj"
local onstep = particulate["prefab_"..physics.."_particle"](factor)
def.on_step = onstep
def._physics = physics
def._factor = factor
def._sound_name = sound_name
def._sound_def = table.copy(sound_def)
def._timer = 0
def.collisionbox = {-0.05, -0.05, -0.05, 0.05, 0.05, 0.05}
def.visual_size = {x=1, y=1}
def.use_texture_alpha = true
def.physical = true
def.collide_with_objects = false
def.pointable = false
particulate.known_particles = table.copy(def)
minetest.register_entity(":"..name, table.copy(def))
end
function particulate.calc_collisionbox_size(scale)
local size = 0.05 * scale
return {-size, -size, -size, size, size, size}, size
end
--[[
pos, size_min, size_max, vel_min, vel_max, del_min, del_max
Pointed Velocity Logic:
North Facing: intersection_normal.z == -1; vdepth <= 0; x + y
South Facing: intersection_normal.z == 1; vdepth >= 0; x + y
East Facing: intersection_normal.x == -1; vdepth <= 0; z + y
West Facing: intersection_normal.x == 1; vdepth >= 0; z + y
Bot Facing: intersection_normal.y == -1; vdepth <= 0; x + z
Top Facing: intersection_normal.y == 1; vdepth >= 0; x + z
]]--
function particulate.spawn_particles(name, number, spawn_props, pointed, textures, destroyed)
for i=1, number do
local px, py, pz = 0, 0, 0
local vx, vy, vz = 0, 0, 0
local vel = vector.new(0, 0, 0)
local vdepth, vsides, vhight = 0, 0, 0
local scale = math.random(spawn_props.size_min*100, spawn_props.size_max*100) / 100
local coll_box, doffset = particulate.calc_collisionbox_size(scale)
local rot = vector.new(math.random(-180, 180), math.random(-180, 180), math.random(-180, 180))
doffset = doffset + 0.01
if pointed == nil then
vdepth = math.random(spawn_props.vel_min*100, spawn_props.vel_max*100) / 100
vhight = math.random(spawn_props.vel_min*100, spawn_props.vel_max*100) / 100
vsides = math.random(spawn_props.vel_min*100, spawn_props.vel_max*100) / 100
if destroyed then
px = spawn_props.pos.x + 0.5
py = spawn_props.pos.y + 0.5
pz = spawn_props.pos.z + 0.5
vhight = math.random(spawn_props.del_min*100, spawn_props.del_max*100) / 100
rot = vector.new(90 * math.random(0, 3), 0, 0)
else
px = spawn_props.pos.x + (math.random(-105, 105) / 100)
py = spawn_props.pos.y + (math.random(-105, 105) / 100)
pz = spawn_props.pos.z + (math.random(-105, 105) / 100)
end
vel = vector.new(vsides, vhight, vdepth)
else
local pos_floor = table.copy(pointed.under)
px = spawn_props.pos.x + (math.random(-5, 5) / 100)
py = spawn_props.pos.y + (math.random(-5, 5) / 100)
pz = spawn_props.pos.z + (math.random(-5, 5) / 100)
vdepth = math.random(spawn_props.del_min*100, spawn_props.del_max*100) / 100
vsides = math.random(spawn_props.vel_min*100, spawn_props.vel_max*100) / 100
vhight = math.random(spawn_props.vel_min*100, spawn_props.vel_max*100) / 100
if pointed.intersection_normal.x == -1 then
vel = vector.new(-vdepth, vsides, vhight)
px = spawn_props.pos.x - doffset
elseif pointed.intersection_normal.x == 1 then
vel = vector.new(vdepth, vsides, vhight)
px = spawn_props.pos.x + doffset
elseif pointed.intersection_normal.y == -1 then
vel = vector.new(vsides, -vdepth, vhight)
py = spawn_props.pos.y - doffset
elseif pointed.intersection_normal.y == 1 then
vel = vector.new(vsides, vdepth, vhight)
py = spawn_props.pos.y + doffset
elseif pointed.intersection_normal.z == -1 then
vel = vector.new(vsides, vhight, -vdepth)
pz = spawn_props.pos.z - doffset
elseif pointed.intersection_normal.z == 1 then
vel = vector.new(vsides, vhight, vdepth)
pz = spawn_props.pos.z + doffset
end
end
local pos = vector.new(px, py, pz)
local ent = minetest.add_entity(pos, name)
ent:set_acceleration({x=0, y=-9.80, z=0})
ent:set_rotation(rot)
ent:set_velocity(vel)
ent:set_properties(
{
visual_size = {x=scale, y=scale},
collisionbox = coll_box,
textures = textures
}
)
end
end
function particulate.prefab_bouncing_particle(factor)
local function onstep(self, dtime, moveresult)
local rot = self.object:get_rotation()
local velocity = {x=0, y=0, z=0}
if moveresult.collides then
local old_vel
-- Check for velocities:
if moveresult.collisions[1] == nil then
old_vel = self.object:get_velocity()
else
old_vel = table.copy(moveresult.collisions[1].old_velocity)
end
-- Handle air resistance, friction:
if moveresult.touching_ground then
old_vel.x = old_vel.x * 0.75
old_vel.z = old_vel.z * 0.75
else
old_vel.x = old_vel.x * 0.975
old_vel.z = old_vel.z * 0.975
end
if moveresult.collisions[1] == nil then
if not moveresult.touching_ground then
velocity.x = old_vel.x
velocity.z = old_vel.z
end
velocity.y = old_vel.y
elseif moveresult.collisions[1].axis == "x" then
velocity.x = -(old_vel.x * factor)
velocity.y = old_vel.y
velocity.z = old_vel.z
minetest.sound_play({name = self._sound_name},
{object=self.object, max_hear_distance=self._sound_def.dist, gain=self._sound_def.gain}, true)
elseif moveresult.collisions[1].axis == "y" then
velocity.x = old_vel.x
velocity.y = -(old_vel.y * factor)
velocity.z = old_vel.z
if math.abs(old_vel.y) > 0.38 then
minetest.sound_play({name = self._sound_name},
{object=self.object, max_hear_distance=self._sound_def.dist, gain=self._sound_def.gain}, true)
end
elseif moveresult.collisions[1].axis == "z" then
velocity.x = old_vel.x
velocity.y = old_vel.y
velocity.z = -(old_vel.z * factor)
minetest.sound_play({name = self._sound_name},
{object=self.object, max_hear_distance=self._sound_def.dist, gain=self._sound_def.gain}, true)
end
self.object:set_velocity(velocity)
end
local norm = self.object:get_velocity()
norm.x = norm.x * 0.66
norm.y = norm.y * 0.66
norm.z = norm.z * 0.66
rot.z = rot.z + ((norm.x + norm.z) / 3)
self.object:set_rotation(rot)
if self._timer > self._ttl then
if math.random(1, 10) == 1 then
self.object:remove()
end
end
if self._timer > self._ttl_max then
self.object:remove()
end
self._timer = self._timer + dtime
end
return onstep
end
function particulate.prefab_bouncing_alt_particle(factor)
local function onstep(self, dtime, moveresult)
local rot = self.object:get_rotation()
local velocity = {x=0, y=0, z=0}
if moveresult.collides then
local old_vel
-- Check for velocities:
if moveresult.collisions[1] == nil then
old_vel = self.object:get_velocity()
else
old_vel = table.copy(moveresult.collisions[1].old_velocity)
end
-- Handle air resistance, friction:
if moveresult.touching_ground then
old_vel.x = old_vel.x * 0.75
old_vel.z = old_vel.z * 0.75
else
old_vel.x = old_vel.x * 0.975
old_vel.z = old_vel.z * 0.975
end
if moveresult.collisions[1] == nil then
if not moveresult.touching_ground then
velocity.x = old_vel.x
velocity.z = old_vel.z
end
velocity.y = old_vel.y
elseif moveresult.collisions[1].axis == "x" then
velocity.x = -(old_vel.x * factor)
velocity.y = old_vel.y
velocity.z = old_vel.z
minetest.sound_play({name = self._sound_name},
{object=self.object, max_hear_distance=self._sound_def.dist, gain=self._sound_def.gain}, true)
elseif moveresult.collisions[1].axis == "y" then
velocity.x = old_vel.x
velocity.y = -(old_vel.y * factor)
velocity.z = old_vel.z
if math.abs(old_vel.y) > 0.38 then
minetest.sound_play({name = self._sound_name},
{object=self.object, max_hear_distance=self._sound_def.dist, gain=self._sound_def.gain}, true)
end
elseif moveresult.collisions[1].axis == "z" then
velocity.x = old_vel.x
velocity.y = old_vel.y
velocity.z = -(old_vel.z * factor)
minetest.sound_play({name = self._sound_name},
{object=self.object, max_hear_distance=self._sound_def.dist, gain=self._sound_def.gain}, true)
end
self.object:set_velocity(velocity)
end
local norm = self.object:get_velocity()
norm.x = norm.x * 0.66
norm.y = norm.y * 0.66
norm.z = norm.z * 0.66
rot.z = rot.z + ((norm.x + norm.z) / 3)
self.object:set_rotation(rot)
if self._timer > self._effect_timer then
local props = self.object:get_properties()
if props == nil then
return
elseif props.visual_size == nil then
return
end
props.visual_size.x = props.visual_size.x * 0.985
props.visual_size.y = props.visual_size.y * 0.985
props.visual_size.z = props.visual_size.z * 0.985
props.collisionbox = particulate.calc_collisionbox_size(props.visual_size.x)
self.object:set_properties(props)
end
if self._timer > self._ttl then
if math.random(1, 10) == 1 then
self.object:remove()
end
end
if self._timer > self._ttl_max then
self.object:remove()
end
self._timer = self._timer + dtime
end
return onstep
end
function particulate.prefab_smoke_particle(factor)
local function onstep(self, dtime, moveresult)
local rot = self.object:get_rotation()
local norm = self.object:get_velocity()
norm.x = norm.x * 0.66
norm.y = norm.y * 0.66
norm.z = norm.z * 0.66
rot.z = rot.z + ((norm.x + norm.z + norm.y) / 15)
self.object:set_rotation(rot)
local props = self.object:get_properties()
if props == nil then
return
elseif props.visual_size == nil then
return
end
props.visual_size.x = props.visual_size.x * 1.007
props.visual_size.y = props.visual_size.y * 1.007
props.visual_size.z = props.visual_size.z * 1.007
self.object:set_properties(props)
if self._timer > self._ttl then
if math.random(1, 10) == 1 then
self.object:remove()
end
end
if self._timer > self._ttl_max then
self.object:remove()
end
self._timer = self._timer + dtime
end
return onstep
end
--[[
Spawn Props:
vel.x/y/z initial and only velocity
pos.x/y/z position to be created at
offset_min, offset_max the random value that affects the spawn position by
vel_min, vel_max the random value that affects the given initial velocity
size_min, size_max the random values that affects the given size and collision box
]]--
function particulate.spawn_gas_particles(name, number, spawn_props, textures)
for i=1, number do
local npos = table.copy(spawn_props.pos)
npos.x = npos.x + math.random(spawn_props.offset_min*100, spawn_props.offset_max*100) / 100
npos.y = npos.y + math.random(spawn_props.offset_min*100, spawn_props.offset_max*100) / 100
npos.z = npos.z + math.random(spawn_props.offset_min*100, spawn_props.offset_max*100) / 100
local nvel = table.copy(spawn_props.vel)
nvel.x = nvel.x + math.random(spawn_props.vel_min*100, spawn_props.vel_max*100) / 100
nvel.y = nvel.y + math.random(spawn_props.vel_min*100, spawn_props.vel_max*100) / 100
nvel.z = nvel.z + math.random(spawn_props.vel_min*100, spawn_props.vel_max*100) / 100
local nrot = vector.new(math.random(-180, 180), math.random(-180, 180), math.random(-180, 180))
local scale = math.random(spawn_props.size_min*100, spawn_props.size_max*100) / 100
local coll_box, doffset = particulate.calc_collisionbox_size(scale)
local ent = minetest.add_entity(npos, name)
ent:set_velocity(nvel)
ent:set_rotation(nrot)
ent:set_properties({
visual_size = {x=scale, y=scale},
collisionbox = coll_box,
textures = textures
})
end
end

View File

@ -0,0 +1,63 @@
# Blender v2.79 (sub 0) OBJ File: 'particulate model.blend'
# www.blender.org
mtllib particulate_cubic.mtl
o Cube
v 0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 0.500000
v -0.500000 -0.500000 0.500000
v -0.500000 -0.500000 -0.500000
v 0.500000 0.500000 -0.500000
v 0.500000 0.500000 0.500000
v -0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.500000
vt 0.000100 0.999900
vt 0.999899 0.000100
vt 0.999900 0.999900
vt 0.000100 0.000100
vt 0.999900 0.999900
vt 0.000100 0.000100
vt 0.999900 0.000100
vt 0.000100 0.999900
vt 0.000100 0.000100
vt 0.000100 0.999900
vt 0.999900 0.000100
vt 0.999900 0.999900
vt 0.000100 0.000100
vt 0.999900 0.999900
vt 0.000100 0.999900
vt 0.999900 0.000100
vt 0.999900 0.999900
vt 0.000100 0.000100
vt 0.999900 0.000100
vt 0.000100 0.999900
vn 0.0000 1.0000 -0.0000
vn 0.0000 -1.0000 0.0000
vn 1.0000 -0.0000 0.0000
vn -1.0000 -0.0000 -0.0000
vn 0.0000 0.0000 -1.0000
vn -0.0000 -0.0000 1.0000
g Cube_Cube_Top
usemtl Top
s off
f 8/1/1 6/2/1 5/3/1
f 8/1/1 7/4/1 6/2/1
g Cube_Cube_Bottom
usemtl Bottom
f 2/5/2 4/6/2 1/7/2
f 2/5/2 3/8/2 4/6/2
g Cube_Cube_Right
usemtl Right
f 5/3/3 2/9/3 1/7/3
f 5/3/3 6/10/3 2/9/3
g Cube_Cube_Left
usemtl Left
f 3/11/4 8/1/4 4/6/4
f 3/11/4 7/12/4 8/1/4
g Cube_Cube_Front
usemtl Front
f 1/13/5 8/14/5 5/15/5
f 1/13/5 4/16/5 8/14/5
g Cube_Cube_Back
usemtl Back
f 6/17/6 3/18/6 2/19/6
f 6/17/6 7/20/6 3/18/6

View File

@ -77,6 +77,7 @@ minetest.register_node(":core:water_source", {
liquid_viscosity = 1,
post_effect_color = {a = 153, r = 18, g = 78, b = 137},
groups = {water = 3, source = 1, puts_out_fire = 1, can_grow = 1},
_no_particles = true,
})
minetest.register_node(":core:water_flowing", {
@ -122,6 +123,7 @@ minetest.register_node(":core:water_flowing", {
liquid_viscosity = 1,
post_effect_color = {a = 153, r = 18, g = 78, b = 137},
groups = {water = 3, flowing = 1, puts_out_fire = 1, can_grow = 1, not_in_creative_inventory = 1},
_no_particles = true,
})
-- Grasses:
@ -142,6 +144,7 @@ for i=1, 3 do
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
},
_no_particles = true,
--sounds = mcore.sound_plants,
})
end

View File

@ -1,3 +1,4 @@
solarsail
persistence
particulate
discord?

View File

@ -184,12 +184,13 @@ end
function weapons.calc_block_damage(nodedef, weapon, target_pos, pointed)
if nodedef == nil then
return 0, "air", nil
elseif nodedef.name == "air" then
return 0, "air", nil
elseif nodedef.name == "ignore" then
return 0, "air", nil
elseif nodedef._health == nil then
weapons.spray_particles(pointed, nodedef, target_pos)
weapons.spray_particles(pointed, nodedef, target_pos, true)
return 0, "air", nil
elseif nodedef._takes_damage == nil then
local nodedamage
@ -202,52 +203,31 @@ function weapons.calc_block_damage(nodedef, weapon, target_pos, pointed)
end
if nodedamage < 1 then
weapons.spray_particles(pointed, nodedef, target_pos)
weapons.spray_particles(pointed, nodedef, target_pos, true)
return 0, "air", nil
else
weapons.spray_particles(pointed, nodedef, target_pos)
weapons.spray_particles(pointed, nodedef, target_pos, false)
return nodedamage, nodedef._name.."_"..nodedamage, nil
end
else
weapons.spray_particles(pointed, nodedef, target_pos)
weapons.spray_particles(pointed, nodedef, target_pos, false)
return 0, nodedef.name, false
end
end
function weapons.spray_particles(pointed, nodedef, target_pos)
local npos, npos_floor
if pointed == nil then
npos = table.copy(target_pos)
npos_floor = table.copy(target_pos)
npos_floor.x = math.floor(npos_floor.x)
npos_floor.y = math.floor(npos_floor.y)
npos_floor.z = math.floor(npos_floor.z)
else
npos = table.copy(pointed.intersection_point)
npos_floor = table.copy(pointed.under)
function weapons.create_2x2_node_texture(texture_string)
local xmod = math.random(-14, 0)
local ymod = math.random(-14, 0)
local splits = string.split(texture_string, "^")
local modifier = "[combine:2x2:"
for k, v in pairs(splits) do
if k ~= #splits then
modifier = modifier ..xmod..","..ymod.."="..v..":"
else
modifier = modifier ..xmod..","..ymod.."="..v
end
end
if nodedef.tiles == nil then return end
minetest.add_particlespawner({
amount = math.random(8, 12),
time = 0.03,
texture = nodedef.tiles[1],
node = {name=minetest.get_node(npos_floor).name},
collisiondetection = true,
collision_removal = false,
object_collision = false,
vertical = false,
minpos = vector.new(npos.x-0.05,npos.y-0.05,npos.z-0.05),
maxpos = vector.new(npos.x+0.05,npos.y+0.05,npos.z+0.05),
minvel = vector.new(-1, -1, -1),
maxvel = vector.new(1, 1, 1),
minacc = vector.new(0,-5,0),
maxacc = vector.new(0,-5,0),
minsize = 0.95,
maxsize = 1.15,
minexptime = 1,
maxexptime = 3
})
return modifier
end
function weapons.reset_health(player)
@ -259,7 +239,7 @@ end
function weapons.respawn_player(player, respawn)
local pname = player:get_player_name()
local x, y, z = 0
local x, y, z = 0, 0, 0
local blu = 192-42
if weapons.player_list[pname].team == "red" then
x = math.random(168, 176)

View File

@ -348,6 +348,7 @@ dofile(minetest.get_modpath("weapons").."/skybox.lua")
dofile(minetest.get_modpath("weapons").."/chat.lua")
dofile(minetest.get_modpath("weapons").."/hud.lua")
dofile(minetest.get_modpath("weapons").."/builtin_blocks.lua")
dofile(minetest.get_modpath("weapons").."/particles.lua")
dofile(minetest.get_modpath("weapons").."/weapons.lua")
-- Player viewmodel settings:
@ -379,6 +380,7 @@ dofile(minetest.get_modpath("weapons").."/weapons/plasma_autorifle.lua")
dofile(minetest.get_modpath("weapons").."/weapons/light_machine_gun.lua")
-- Exotic (Treated as Primary Slot)
dofile(minetest.get_modpath("weapons").."/weapons/rocketry.lua")
dofile(minetest.get_modpath("weapons").."/weapons/minigun.lua")
-- Secondary
@ -386,7 +388,6 @@ dofile(minetest.get_modpath("weapons").."/weapons/boringpistol.lua")
--dofile(minetest.get_modpath("weapons").."/weapons/smg.lua")
--dofile(minetest.get_modpath("weapons").."/weapons/rocketry.lua")
--dofile(minetest.get_modpath("weapons").."/weapons/grenades.lua")
minetest.register_on_player_receive_fields(

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

117
mods/weapons/particles.lua Normal file
View File

@ -0,0 +1,117 @@
-- Particles for BfA:
-- Author: Jordach
-- License: Reserved
particulate.register_cubic_particle(
"weapons:block_debris",
{
_effect_timer = 1.5,
_ttl = 3,
_ttl_max = 10,
},
"bouncing",
0.35,
"debris_falling",
{dist=16, gain=1}
)
particulate.register_cubic_particle(
"weapons:block_debris_destroyed",
{
_effect_timer = 1.5,
_ttl = 3,
_ttl_max = 10,
},
"bouncing_alt",
0.35,
"debris_falling",
{dist=16, gain=1}
)
particulate.register_cubic_particle(
"weapons:smoke_particle",
{
_ttl = 6,
_ttl_max = 12,
},
"smoke",
1,
"smoke",
{dist=16, gain=1}
)
function weapons.spray_particles(pointed, nodedef, target_pos, node_destroyed)
local destroyed = false
if node_destroyed == nil then
else
destroyed = node_destroyed
end
local npos, npos_floor
if pointed == nil then
npos = table.copy(target_pos)
npos_floor = table.copy(target_pos)
npos_floor.x = math.floor(npos_floor.x)
npos_floor.y = math.floor(npos_floor.y)
npos_floor.z = math.floor(npos_floor.z)
else
npos = table.copy(pointed.intersection_point)
npos_floor = table.copy(pointed.under)
end
if nodedef.tiles == nil then return end
if nodedef._no_particles ~= nil then return end
local tex = {}
for ind, png in pairs(nodedef.tiles) do
local txtr
if destroyed then
txtr = nodedef.tiles[ind]
else
txtr = weapons.create_2x2_node_texture(nodedef.tiles[ind])
end
tex[ind] = txtr
if ind == #nodedef.tiles then
local fill_val = ind
repeat
fill_val = fill_val + 1
tex[fill_val] = txtr
until #tex == 6
end
end
local name = "weapons:block_debris"
local size_min, size_max = 0.95, 1.55
local vel_min, vel_max = -1.5, 1.5
local del_min, del_max = 2.5, 3.75
local nparticles = math.random(3, 6)
local pnt = nil
if destroyed then
size_min = 9
size_max = 9.5
vel_min = -0.5
vel_max = 0.5
del_min = 1.75
del_max = 2.5
nparticles = 1
name = name .. "_destroyed"
else
pnt = pointed
end
particulate.spawn_particles(name, nparticles,
{
pos = table.copy(npos),
size_min = size_min,
size_max = size_max,
vel_min = vel_min,
vel_max = vel_max,
del_min = del_min,
del_max = del_max,
},
pnt,
tex,
destroyed
)
end

View File

@ -318,9 +318,9 @@ function weapons.creator.player_stats(player, pname)
local helmet_dropdown = "dropdown[20.5,6.5;3;armour_chooser;Default Helmet,Unlockable Helmet,Placeholder Hemlet;"..helmet_index..";true]"
local armour_dropdown = "dropdown[20.5,7.5;3;armour_chooser;Default Armour,Unlockable Armour,Placeholder Armour;"..armour_index..";true]"
local undersuit_dropdown = "dropdown[20.5,8.5;3;undersuit_chooser;Default Undersuit,Unlockable Undersuit,Placeholder Undersuit;"..undersuit_index..";true]"
local enable_custom_skin = "checkbox[21,10;custom_skin;Hide User Head;]"
return
return
points_label..
lbl_hp..
cost_hp..
@ -345,8 +345,8 @@ function weapons.creator.player_stats(player, pname)
player_preview..
undersuit_dropdown..
armour_dropdown..
helmet_dropdown
helmet_dropdown..
enable_custom_skin
end
function weapons.creator.display_formspec(pname, player, fields)
@ -709,15 +709,18 @@ local function unlock_anim(pname)
anim_frame[pname] = -1
end
local function unlock_arms(pname)
local function unlock_arms(pname, weapon)
-- if solarsail.controls.player[pname].LMB then
-- local curr_anim, spd, bl, loop = weapons.player_arms[pname]:get_animation()
-- curr_anim.x = curr_anim.y
-- weapons.player_arms[pname]:set_animation(curr_anim, 60, 0.15, false)
-- else
-- local curr_anim, spd, bl, loop = weapons.player_arms[pname]:get_animation()
-- weapons.player_arms[pname]:set_animation({x=curr_anim.x, y=curr_anim.x+1}, 60, 0, false)
-- end
arm_frame[pname] = -1
arm_type[pname] = "idle"
--if solarsail.controls.player[pname].LMB then
local curr_anim, spd, bl, loop = weapons.player_arms[pname]:get_animation()
curr_anim.x = curr_anim.y
weapons.player_arms[pname]:set_animation(curr_anim, 60, 0.15, false)
--end
end
local function reset_arm_pos(pname, weapon)
@ -746,7 +749,7 @@ minetest.register_globalstep(function(dtime)
local pname = player:get_player_name()
local wield = player:get_wielded_item():get_name()
local weapon = minetest.registered_nodes[wield]
if true then -- Legs/Body, Head anim foldable for your viewing pleasure
if true then -- Legs/Body, Head anim; foldable for your viewing pleasure
local ppitch = -math.deg(player:get_look_vertical())
local frame_offset = 0
local anim_group
@ -758,13 +761,12 @@ minetest.register_globalstep(function(dtime)
if weapon == nil then
elseif weapon._min_arm_angle == nil then
elseif weapon._max_arm_angle == nil then
else
elseif weapons.is_reloading[pname][wield] then
-- Prevent arm rotations when the entity doesn't
-- exist
if weapons.player_arms[pname] ~= nil then
if ppitch > weapon._max_arm_angle then
ppitch = weapon._max_arm_angle
elseif ppitch < weapon._min_arm_angle then
ppitch = weapon._min_arm_angle
end
local ret_pitch = look_pitch[pname] * 0.5
--Manually control arms bone here
local bpos = arms_pos
if weapon._arms.pos ~= nil then
@ -773,8 +775,33 @@ minetest.register_globalstep(function(dtime)
weapons.player_arms[pname]:set_bone_position(
"Armature_Root",
bpos,
{x=ppitch+arms_rot.x, y=arms_rot.y, z=arms_rot.z}
{x=ret_pitch+arms_rot.x, y=arms_rot.y, z=arms_rot.z}
)
-- again, avoid Lua aliasing
look_pitch[pname] = ret_pitch+0
end
else
if weapons.player_arms[pname] ~= nil then
-- Prevent arm rotations when the entity doesn't
-- exist
if weapons.is_reloading[pname][wield] then
else
if ppitch > weapon._max_arm_angle then
ppitch = weapon._max_arm_angle
elseif ppitch < weapon._min_arm_angle then
ppitch = weapon._min_arm_angle
end
--Manually control arms bone here
local bpos = arms_pos
if weapon._arms.pos ~= nil then
bpos = weapon._arms.pos
end
weapons.player_arms[pname]:set_bone_position(
"Armature_Root",
bpos,
{x=ppitch+arms_rot.x, y=arms_rot.y, z=arms_rot.z}
)
end
end
end
end
@ -869,14 +896,14 @@ minetest.register_globalstep(function(dtime)
if not weapons.player_list[pname].anim_mode then
arm_frame[pname] = 0
arm_type[pname] = "reload"
arm_after[pname] = minetest.after(weapon._reload, unlock_arms, pname)
arm_after[pname] = minetest.after(weapon._reload, unlock_arms, pname, weapon)
if weapons.player_arms[pname] ~= nil then
weapons.player_arms[pname]:set_animation(weapon._anim.reload, 60, 0.15, true)
end
else
arm_frame[pname] = 0
arm_type[pname] = "reload_alt"
arm_after[pname] = minetest.after((weapon._reload*0.9), unlock_arms, pname)
arm_after[pname] = minetest.after((weapon._reload*0.9), unlock_arms, pname, weapon)
if weapons.player_arms[pname] ~= nil then
weapons.player_arms[pname]:set_animation(weapon._anim.reload_alt, 60, 0.15, true)
end
@ -886,14 +913,12 @@ minetest.register_globalstep(function(dtime)
if weapons.player_list[pname][ammo] > 0 or ammo == "blocks" then
arm_frame[pname] = 0
arm_type[pname] = "aim_fire"
arm_after[pname] = minetest.after((60 / weapon._rpm), unlock_arms, pname)
arm_after[pname] = minetest.after((60 / weapon._rpm), unlock_arms, pname, weapon)
if weapons.player_arms[pname] ~= nil then
weapons.player_arms[pname]:set_animation(weapon._anim.aim_fire, 60, 0.15, true)
end
end
else
--arm_frame[pname] = -1
arm_type[pname] = "aim"
if weapons.player_arms[pname] ~= nil then
weapons.player_arms[pname]:set_animation(weapon._anim.aim, 60, 0.15, true)
end
@ -903,13 +928,12 @@ minetest.register_globalstep(function(dtime)
if weapons.player_list[pname][ammo] > 0 or ammo == "blocks" then
arm_frame[pname] = 0
arm_type[pname] = "idle_fire"
arm_after[pname] = minetest.after((60 / weapon._rpm), unlock_arms, pname)
arm_after[pname] = minetest.after((60 / weapon._rpm), unlock_arms, pname, weapon)
if weapons.player_arms[pname] ~= nil then
weapons.player_arms[pname]:set_animation(weapon._anim.idle_fire, 60, 0.15, true)
end
end
else
--arm_frame[pname] = -1
arm_type[pname] = "idle"
if weapons.player_arms[pname] ~= nil then
weapons.player_arms[pname]:set_animation(weapon._anim.idle, 60, 0.15, true)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 492 B

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 B

View File

@ -92,10 +92,12 @@ function weapons.magazine_reload(player, weapon, wield, keypressed)
local chambered = false
local chamber_bonus = 1 -- Normal reload speed
weapons.player_list[pname].anim_mode = false
if weapons.player_list[pname][ammo] > 0 then -- Ensure there's a round in the chamber
chambered = true
chamber_bonus = 0.9
weapons.player_list[pname].anim_mode = true
if keypressed then
if weapons.player_list[pname][ammo] > 0 then -- Ensure there's a round in the chamber
chambered = true
chamber_bonus = 0.9
weapons.player_list[pname].anim_mode = true
end
end
weapons.player_list[pname][ammo] = 0
if not weapons.is_reloading[pname][wield] then

View File

@ -22,10 +22,10 @@ local function explosion_tracers(pos)
math.random(-100, 100)/100,
math.random(-100, 100)/100
)
if moveresult == nil then
elseif moveresult.touching_ground then
vector_mod.y = math.random(1, 100)/100
end
--if moveresult == nil then
--elseif moveresult.touching_ground then
--vector_mod.y = math.random(1, 100)/100
--end
local rayend = vector.add(pos, vector_mod)
-- Tracers; performance heavy?
@ -274,10 +274,8 @@ local function register_grenade(name, class, killfeed_name, stats)
range = 1,
node_placement_prediction = "",
_ammo_bg = "grenade",
_fov_mult = 0,
_crosshair = "railgun_crosshair.png",
_ammo_bg = "grenade_bg",
_type = "grenade",
_ammo_type = "grenade",
_phys_alt = 1,

View File

@ -1,18 +1,40 @@
-- Rocket Science for Super CTF:
-- Rocket Science for BfA:
-- Author: Jordach
-- License: Reserved
local r_block_chance = 100
local inside_chance = 100
local outside_chance = 90
local function rocket_explode_damage_blocks(pos)
local bpos = table.copy(pos)
local weapon = table.copy(minetest.registered_nodes["weapons:rocket_launcher_red"])
for x=-1, 1 do
for y=-1, 1 do
for z=-1, 1 do
local weapon = table.copy(minetest.registered_nodes["weapons:rocket_launcher"])
for x=-2, 2 do
for y=-2, 2 do
for z=-2, 2 do
local npos = {x=bpos.x+x, y=bpos.y+y, z=bpos.z+z}
local nodedef = table.copy(minetest.registered_nodes[minetest.get_node(npos).name])
weapon._break_hits = math.random(1, 4)
local damage, node, result = weapons.calc_block_damage(nodedef, weapon, npos)
minetest.set_node(npos, {name=node})
weapon._block_chance = r_block_chance
if x == -2 or x == 2 then
weapon._block_chance = outside_chance
if y == -2 or y == 2 then
if z == -2 or z == 2 then
-- Remove corners
weapon._block_chance = 0
end
end
elseif z == -2 or z == 2 then
weapon._block_chance = outside_chance
elseif x == -1 or x == 1 then
weapon._block_chance = inside_chance
elseif z == -1 or z == 1 then
weapon._block_chance = inside_chance
end
local damage, node, result = weapons.calc_block_damage(nodedef, weapon, npos, nil)
local p2 = minetest.get_node(npos).param2
minetest.set_node(npos, {name=node, param2=p2})
minetest.check_for_falling(npos)
end
end
end
@ -20,73 +42,38 @@ end
local function launch_rocket(player, weapon)
-- Handle recoil of the equipped weapon
solarsail.util.functions.apply_recoil(player, weapon)
--solarsail.util.functions.apply_recoil(player, weapon)
local rocket_pos = vector.add(
vector.add(player:get_pos(), vector.new(0, weapons.default_eye_height, 0)),
vector.multiply(player:get_look_dir(), 1)
)
local pname = player:get_player_name()
local ammo = weapon._ammo_type
local rocket_vel = vector.add(
vector.multiply(player:get_look_dir(), 45), vector.new(0, 0, 0)
if weapons.player_list[pname][ammo] > 0 then
weapons.player_list[pname][ammo] = weapons.player_list[pname][ammo] - 1
local rocket_pos = vector.add(
vector.add(player:get_pos(), vector.new(0, weapons.default_eye_height, 0)),
vector.multiply(player:get_look_dir(), 1)
)
local ent = minetest.add_entity(rocket_pos, "weapons:rocket_ent")
local luaent = ent:get_luaentity()
luaent._player_ref = player
local rocket_vel = vector.multiply(player:get_look_dir(), 20)
luaent._loop_sound_ref =
minetest.sound_play({name="rocket_fly"},
{object=ent, max_hear_distance=32, gain=1.2, loop=true})
local ent = minetest.add_entity(rocket_pos, "weapons:rocket_ent")
local luaent = ent:get_luaentity()
luaent._player_ref = player
luaent._loop_sound_ref =
minetest.sound_play({name="rocket_fly"},
{object=ent, max_hear_distance=32, gain=1.2, loop=true})
-- Commit audio suicide when attached audio stops working:tm:
minetest.after(15, minetest.sound_stop, luaent._loop_sound_ref)
local look_vertical = player:get_look_vertical()
local look_horizontal = player:get_look_horizontal()
for i=1, 3 do
minetest.add_particlespawner({
attached = ent,
amount = 30,
time = 0,
texture = "rocket_smoke_" .. i .. ".png",
collisiondetection = true,
collision_removal = false,
object_collision = false,
vertical = false,
minpos = vector.new(-0.15,-0.15,-0.15),
maxpos = vector.new(0.15,0.15,0.15),
minvel = vector.new(-1, 0.1, -1),
maxvel = vector.new(1, 0.75, 1),
minacc = vector.new(0,0,0),
maxacc = vector.new(0,0,0),
minsize = 7,
maxsize = 12,
minexptime = 2,
maxexptime = 6
})
-- Commit audio suicide when attached audio stops working:tm:
minetest.after(15, minetest.sound_stop, luaent._loop_sound_ref)
local look_vertical = player:get_look_vertical()
local look_horizontal = player:get_look_horizontal()
ent:set_velocity(rocket_vel)
ent:set_rotation(vector.new(-look_vertical, look_horizontal, 0))
weapons.veteran_reload(player, weapon, player:get_wielded_item():get_name()
, false)
end
minetest.add_particlespawner({
attached = ent,
amount = 15,
time = 0,
texture = "rocket_fire.png",
collisiondetection = true,
collision_removal = false,
vertical = false,
minpos = vector.new(0,0,0),
maxpos = vector.new(0,0,0),
minvel = vector.new(0,0,0),
maxvel = vector.new(0,0,0),
minacc = vector.new(0,0,0),
maxacc = vector.new(0,0,0),
minsize = 4.5,
maxsize = 9,
minexptime = 0.1,
maxexptime = 0.3,
glow = 14
})
ent:set_velocity(rocket_vel)
ent:set_rotation(vector.new(-look_vertical, look_horizontal, 0))
end
local rocket_ent = {
@ -102,76 +89,82 @@ local rocket_ent = {
visual_size = {x=5, y=5},
_player_ref = nil,
_loop_sound_ref = nil,
_timer = 0
_timer = 0,
_stimer = 2
}
function rocket_ent:explode(self, moveresult)
if self._player_ref == nil then
self.object:remove()
return
end
local pos = self.object:get_pos()
local pos_block
local pos_block, collided = {}, false
if moveresult.collisions[1] == nil then
pos_block = table.copy(self.object:get_pos())
pos_block.x = math.floor(pos_block.x)
pos_block.y = math.floor(pos_block.y)
pos_block.z = math.floor(pos_block.z)
elseif moveresult.collisions[1].type == "object" then
if moveresult.collisions[1].object:get_pos() ~= nil then
pos_block = table.copy(moveresult.collisions[1].object:get_pos())
pos_block.x = math.floor(pos_block.x)
pos_block.y = math.floor(pos_block.y)
pos_block.z = math.floor(pos_block.z)
else
pos_block = table.copy(pos)
pos_block.x = math.floor(pos_block.x)
pos_block.y = math.floor(pos_block.y)
pos_block.z = math.floor(pos_block.z)
end
elseif moveresult.collisions[1].type == "node" then
pos_block = table.copy(moveresult.collisions[1].node_pos)
else
pos_block = table.copy(pos)
pos_block.x = math.floor(pos_block.x)
pos_block.y = math.floor(pos_block.y)
pos_block.z = math.floor(pos_block.z)
for index, coll_table in pairs(moveresult.collisions) do
if moveresult.collisions[index].type == "object" then
if moveresult.collisions[index].object:is_player() then
collided = true
local col_pos = moveresult.collisions[index].object:get_pos()
pos_block = vector.new(
math.floor(col_pos.x),
math.floor(col_pos.y),
math.floor(col_pos.z)
)
-- If we find a player that we did collide with, deal extra damage and finish this loop
-- otherwise we continue searching the list of possible players, else we just explode
-- at our current position.
break
else
pos_block = vector.new(
math.floor(pos.x),
math.floor(pos.y),
math.floor(pos.z)
)
end
elseif moveresult.collisions[index].type == "node" then
pos_block = table.copy(moveresult.collisions[1].node_pos)
end
end
end
local node = minetest.registered_nodes[minetest.get_node(pos).name]
local rocket = minetest.registered_nodes["weapons:rocket_launcher_red"]
local rocket_damage = table.copy(rocket)
if self._player_ref == nil then
self.object:remove()
return
end
local rocket = table.copy(minetest.registered_nodes["weapons:rocket_launcher"])
for _, player in ipairs(minetest.get_connected_players()) do
local ppos = player:get_pos()
local pname = player:get_player_name()
local dist = solarsail.util.functions.pos_to_dist(pos, ppos)
if dist < 4.01 then
if player == self._player_ref then
rocket_damage._damage = rocket._damage/2.5
weapons.handle_damage(rocket_damage, self._player_ref, player, dist, nil)
rocket._damage = math.floor(rocket._damage / 2.75)
weapons.handle_damage(rocket, self._player_ref, player, dist, nil)
else
dist = solarsail.util.functions.pos_to_dist(self._player_ref:get_pos(), ppos)
weapons.handle_damage(rocket_damage, self._player_ref, player, dist, nil)
if collided then
rocket._damage = rocket._damage_direct
weapons.handle_damage(rocket, self._player_ref, player, dist, nil)
else
weapons.handle_damage(rocket, self._player_ref, player, dist, nil)
end
end
-- Add player knockback:
solarsail.util.functions.apply_explosion_recoil(player, 25, pos)
end
end
rocket_explode_damage_blocks(pos_block)
for i=1, 25 do
minetest.add_particle({
pos = pos,
velocity = {x=math.random()*2.5, y=math.random()*2.5, z=math.random()*2.5},
expirationtime = 4,
collisiondetection = true,
collision_removal = false,
texture = "rocket_smoke_"..math.random(1,3)..".png",
size = math.random(5, 12)
})
end
minetest.sound_play({name="rocket_explode"},
{pos=pos_block, max_hear_distance=64, gain=7}, true)
{pos=pos_block, max_hear_distance=96, gain=7}, true)
if self._loop_sound_ref ~= nil then
minetest.sound_stop(self._loop_sound_ref)
end
@ -181,92 +174,125 @@ end
function rocket_ent:on_step(dtime, moveresult)
if moveresult.collides then
rocket_ent:explode(self, moveresult)
return
elseif self._timer > 15 then
rocket_ent:explode(self, moveresult)
return
end
local vel = self.object:get_velocity()
if vel == nil then
else
vel.x = vel.x * 1.01
vel.y = vel.y * 1.01
vel.z = vel.z * 1.01
self.object:set_velocity(vel)
end
self._timer = self._timer + dtime
self._stimer = self._stimer + dtime
if self._stimer > 0.15 then
local tex = {}
for i=1, 6 do
tex[i] = weapons.create_2x2_node_texture("rocket_smoke_cubic.png")
end
local nvel = vector.new(0, 0.25, 0)
local props = {
pos = self.object:get_pos(),
vel = nvel,
offset_min = -0.15,
offset_max = 0.15,
vel_min = -0.5,
vel_max = 0.5,
size_min = 2.5,
size_max = 3.25,
}
particulate.spawn_gas_particles("weapons:smoke_particle", 2, props, tex)
self._stimer = 0
end
end
minetest.register_entity("weapons:rocket_ent", rocket_ent)
local launcher_def_red = {
tiles = {
{name="rocket_launcher.png", backface_culling=false},
{name="assault_class_red.png", backface_culling=false}
local rl_name = "SPNKr Model X"
local chance = math.random(1, 20)
if chance == 1 then
rl_name = "Locket Rauncher"
elseif chance == 2 then
rl_name = "Rocket LawnChair"
end
weapons.register_weapon("weapons:rocket_launcher", true, {
-- Config
_type = "gun",
_ammo_type = "single_rocket",
_slot = "primary",
_localisation = {
itemstring = "weapons:rocket_launcher",
name = rl_name,
tooltip = rl_name ..
[[
Stats:
65 Splash Damage.
185 Direct Hit Damage.
3.4 second reload.
Explodes after 6 seconds of flight.
Accelerates as it moves faster.
TIP: These rockets hurt you less, and can be used to propel you to greater heights.]],
preview = "preview_spnkrx.obj"
},
drawtype = "mesh",
mesh = "rocket_launcher_fp.b3d",
use_texture_alpha = true,
range = 1,
node_placement_prediction = "",
_no_reload_hud = true,
_reload_node = "weapons:rocket_launcher_reload_red",
_kf_name = "Rocket Launcher",
_fov_mult = 0.95,
_crosshair = "railgun_crosshair.png",
_type = "rocket",
_ammo_type = "rocket",
_firing_sound = "rocket_launch",
-- HUD stuff.
_name = "rocket_launcher",
_mag = 1,
_rpm = 80,
_reload = 15,
_damage = 45,
_recoil = 3,
_phys_alt = 1,
_break_hits = 2,
_crosshair = "railgun_crosshair.png",
_crosshair_aim = "railgun_crosshair.png",
_fov_mult = 0,
_fov_mult_aim = 0.5,
_min_arm_angle = -65,
_max_arm_angle = 70,
_arm_angle_offset = 0,
-- Sound:
_firing_sound = "rocket_launch",
_reload_sound = "rocket_reload",
_reload_sound_alt = "rocket_swap",
on_place = function(itemstack, placer, pointed_thing)
return itemstack
end,
on_drop = function(itemstack, dropper, pointed_thing)
return itemstack
end,
-- Base Stats:
_pellets = 1,
_mag = 2,
_rpm = 95,
_reload = 3.43,
_damage = 65,
_damage_direct = 185,
_movespeed = 0.75,
_movespeed_aim = 0.45,
_fatigue = 0,
_fatigue_timer = 0.1,
_fatigue_recovery = 0.99,
_break_hits = 4,
_block_chance = 98,
-- Arm Animations + Arm visual settings;
_anim = {
idle = {x=0, y=179},
idle_fire = {x=190, y=225},
aim = {x=0, y=179},
aim_fire = {x=190, y=225},
reload = {x=270, y=476},
reload_alt = {x=270, y=476},
},
_arms = {
mesh = "arms_spnkrx.x",
skin_pos = 1,
textures = {"transarent.png", "rubber.png", "steel_dark.png", "steel_grey.png^SPNKR.png", "steel_light.png", "warning_mark.png"},
},
on_fire = launch_rocket,
}
minetest.register_node("weapons:rocket_launcher_red", launcher_def_red)
local launcher_def_blue = table.copy(launcher_def_red)
launcher_def_blue.tiles = {"rocket_launcher.png", {name="assault_class_blue.png",
backface_culling=false}}
launcher_def_blue._reload_node = "weapons:rocket_launcher_reload_blue"
minetest.register_node("weapons:rocket_launcher_blue", launcher_def_blue)
local launcher_reload_red = {
drawtype = "mesh",
mesh = "rocket_launcher_reload_fp.b3d",
use_texture_alpha = true,
range = 1,
node_placement_prediction = "",
tiles = {"rocket_launcher.png", "rocket_ent.png",
{name="assault_class_red.png", backface_culling=true}},
_no_reload_hud = true,
_reset_node = "weapons:rocket_launcher_red",
_kf_name = "Rocket Launcher",
_damage = 0,
_mag = 1,
_fov_mult = 0.95,
_type = "rocket",
_ammo_type = "rocket",
_phys_alt = 0.75,
on_place = function(itemstack, placer, pointed_thing)
return itemstack
on_reload = function(player, weapon, wield, keypressed)
weapons.magazine_reload(player, weapon, wield, false)
end,
on_drop = function(itemstack, dropper, pointed_thing)
return itemstack
end
}
minetest.register_node("weapons:rocket_launcher_reload_red", launcher_reload_red)
local launcher_reload_blue = table.copy(launcher_reload_red)
launcher_reload_blue.tiles = {"rocket_launcher.png", "rocket_ent.png",
{name="assault_class_blue.png", backface_culling=true}}
launcher_reload_blue._reset_node = "weapons:rocket_launcher_blue"
minetest.register_node("weapons:rocket_launcher_reload_blue", launcher_reload_blue)
})