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", "core",
"VoxelArea", "VoxelArea",
"ItemStack", "ItemStack",
"dump" "dump",
"particulate"
], ],
"Lua.diagnostics.disable": [ "Lua.diagnostics.disable": [
"undefined-field", "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, liquid_viscosity = 1,
post_effect_color = {a = 153, r = 18, g = 78, b = 137}, post_effect_color = {a = 153, r = 18, g = 78, b = 137},
groups = {water = 3, source = 1, puts_out_fire = 1, can_grow = 1}, groups = {water = 3, source = 1, puts_out_fire = 1, can_grow = 1},
_no_particles = true,
}) })
minetest.register_node(":core:water_flowing", { minetest.register_node(":core:water_flowing", {
@ -122,6 +123,7 @@ minetest.register_node(":core:water_flowing", {
liquid_viscosity = 1, liquid_viscosity = 1,
post_effect_color = {a = 153, r = 18, g = 78, b = 137}, 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}, groups = {water = 3, flowing = 1, puts_out_fire = 1, can_grow = 1, not_in_creative_inventory = 1},
_no_particles = true,
}) })
-- Grasses: -- Grasses:
@ -142,6 +144,7 @@ for i=1, 3 do
type = "fixed", type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}, fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
}, },
_no_particles = true,
--sounds = mcore.sound_plants, --sounds = mcore.sound_plants,
}) })
end end

View File

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

View File

@ -184,12 +184,13 @@ end
function weapons.calc_block_damage(nodedef, weapon, target_pos, pointed) function weapons.calc_block_damage(nodedef, weapon, target_pos, pointed)
if nodedef == nil then if nodedef == nil then
return 0, "air", nil
elseif nodedef.name == "air" then elseif nodedef.name == "air" then
return 0, "air", nil return 0, "air", nil
elseif nodedef.name == "ignore" then elseif nodedef.name == "ignore" then
return 0, "air", nil return 0, "air", nil
elseif nodedef._health == nil then elseif nodedef._health == nil then
weapons.spray_particles(pointed, nodedef, target_pos) weapons.spray_particles(pointed, nodedef, target_pos, true)
return 0, "air", nil return 0, "air", nil
elseif nodedef._takes_damage == nil then elseif nodedef._takes_damage == nil then
local nodedamage local nodedamage
@ -202,52 +203,31 @@ function weapons.calc_block_damage(nodedef, weapon, target_pos, pointed)
end end
if nodedamage < 1 then if nodedamage < 1 then
weapons.spray_particles(pointed, nodedef, target_pos) weapons.spray_particles(pointed, nodedef, target_pos, true)
return 0, "air", nil return 0, "air", nil
else else
weapons.spray_particles(pointed, nodedef, target_pos) weapons.spray_particles(pointed, nodedef, target_pos, false)
return nodedamage, nodedef._name.."_"..nodedamage, nil return nodedamage, nodedef._name.."_"..nodedamage, nil
end end
else else
weapons.spray_particles(pointed, nodedef, target_pos) weapons.spray_particles(pointed, nodedef, target_pos, false)
return 0, nodedef.name, false return 0, nodedef.name, false
end end
end end
function weapons.spray_particles(pointed, nodedef, target_pos) function weapons.create_2x2_node_texture(texture_string)
local npos, npos_floor local xmod = math.random(-14, 0)
if pointed == nil then local ymod = math.random(-14, 0)
npos = table.copy(target_pos) local splits = string.split(texture_string, "^")
npos_floor = table.copy(target_pos) local modifier = "[combine:2x2:"
npos_floor.x = math.floor(npos_floor.x) for k, v in pairs(splits) do
npos_floor.y = math.floor(npos_floor.y) if k ~= #splits then
npos_floor.z = math.floor(npos_floor.z) modifier = modifier ..xmod..","..ymod.."="..v..":"
else else
npos = table.copy(pointed.intersection_point) modifier = modifier ..xmod..","..ymod.."="..v
npos_floor = table.copy(pointed.under) end
end end
return modifier
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
})
end end
function weapons.reset_health(player) function weapons.reset_health(player)
@ -259,7 +239,7 @@ end
function weapons.respawn_player(player, respawn) function weapons.respawn_player(player, respawn)
local pname = player:get_player_name() local pname = player:get_player_name()
local x, y, z = 0 local x, y, z = 0, 0, 0
local blu = 192-42 local blu = 192-42
if weapons.player_list[pname].team == "red" then if weapons.player_list[pname].team == "red" then
x = math.random(168, 176) 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").."/chat.lua")
dofile(minetest.get_modpath("weapons").."/hud.lua") dofile(minetest.get_modpath("weapons").."/hud.lua")
dofile(minetest.get_modpath("weapons").."/builtin_blocks.lua") dofile(minetest.get_modpath("weapons").."/builtin_blocks.lua")
dofile(minetest.get_modpath("weapons").."/particles.lua")
dofile(minetest.get_modpath("weapons").."/weapons.lua") dofile(minetest.get_modpath("weapons").."/weapons.lua")
-- Player viewmodel settings: -- 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") dofile(minetest.get_modpath("weapons").."/weapons/light_machine_gun.lua")
-- Exotic (Treated as Primary Slot) -- Exotic (Treated as Primary Slot)
dofile(minetest.get_modpath("weapons").."/weapons/rocketry.lua")
dofile(minetest.get_modpath("weapons").."/weapons/minigun.lua") dofile(minetest.get_modpath("weapons").."/weapons/minigun.lua")
-- Secondary -- 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/smg.lua")
--dofile(minetest.get_modpath("weapons").."/weapons/rocketry.lua")
--dofile(minetest.get_modpath("weapons").."/weapons/grenades.lua") --dofile(minetest.get_modpath("weapons").."/weapons/grenades.lua")
minetest.register_on_player_receive_fields( 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 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 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 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.. points_label..
lbl_hp.. lbl_hp..
cost_hp.. cost_hp..
@ -345,8 +345,8 @@ function weapons.creator.player_stats(player, pname)
player_preview.. player_preview..
undersuit_dropdown.. undersuit_dropdown..
armour_dropdown.. armour_dropdown..
helmet_dropdown helmet_dropdown..
enable_custom_skin
end end
function weapons.creator.display_formspec(pname, player, fields) function weapons.creator.display_formspec(pname, player, fields)
@ -709,15 +709,18 @@ local function unlock_anim(pname)
anim_frame[pname] = -1 anim_frame[pname] = -1
end 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_frame[pname] = -1
arm_type[pname] = "idle" 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 end
local function reset_arm_pos(pname, weapon) local function reset_arm_pos(pname, weapon)
@ -746,7 +749,7 @@ minetest.register_globalstep(function(dtime)
local pname = player:get_player_name() local pname = player:get_player_name()
local wield = player:get_wielded_item():get_name() local wield = player:get_wielded_item():get_name()
local weapon = minetest.registered_nodes[wield] 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 ppitch = -math.deg(player:get_look_vertical())
local frame_offset = 0 local frame_offset = 0
local anim_group local anim_group
@ -758,13 +761,12 @@ minetest.register_globalstep(function(dtime)
if weapon == nil then if weapon == nil then
elseif weapon._min_arm_angle == nil then elseif weapon._min_arm_angle == nil then
elseif weapon._max_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 weapons.player_arms[pname] ~= nil then
if ppitch > weapon._max_arm_angle then local ret_pitch = look_pitch[pname] * 0.5
ppitch = weapon._max_arm_angle
elseif ppitch < weapon._min_arm_angle then
ppitch = weapon._min_arm_angle
end
--Manually control arms bone here --Manually control arms bone here
local bpos = arms_pos local bpos = arms_pos
if weapon._arms.pos ~= nil then if weapon._arms.pos ~= nil then
@ -773,8 +775,33 @@ minetest.register_globalstep(function(dtime)
weapons.player_arms[pname]:set_bone_position( weapons.player_arms[pname]:set_bone_position(
"Armature_Root", "Armature_Root",
bpos, 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 end
end end
@ -869,14 +896,14 @@ minetest.register_globalstep(function(dtime)
if not weapons.player_list[pname].anim_mode then if not weapons.player_list[pname].anim_mode then
arm_frame[pname] = 0 arm_frame[pname] = 0
arm_type[pname] = "reload" 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 if weapons.player_arms[pname] ~= nil then
weapons.player_arms[pname]:set_animation(weapon._anim.reload, 60, 0.15, true) weapons.player_arms[pname]:set_animation(weapon._anim.reload, 60, 0.15, true)
end end
else else
arm_frame[pname] = 0 arm_frame[pname] = 0
arm_type[pname] = "reload_alt" 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 if weapons.player_arms[pname] ~= nil then
weapons.player_arms[pname]:set_animation(weapon._anim.reload_alt, 60, 0.15, true) weapons.player_arms[pname]:set_animation(weapon._anim.reload_alt, 60, 0.15, true)
end end
@ -886,14 +913,12 @@ minetest.register_globalstep(function(dtime)
if weapons.player_list[pname][ammo] > 0 or ammo == "blocks" then if weapons.player_list[pname][ammo] > 0 or ammo == "blocks" then
arm_frame[pname] = 0 arm_frame[pname] = 0
arm_type[pname] = "aim_fire" 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 if weapons.player_arms[pname] ~= nil then
weapons.player_arms[pname]:set_animation(weapon._anim.aim_fire, 60, 0.15, true) weapons.player_arms[pname]:set_animation(weapon._anim.aim_fire, 60, 0.15, true)
end end
end end
else else
--arm_frame[pname] = -1
arm_type[pname] = "aim"
if weapons.player_arms[pname] ~= nil then if weapons.player_arms[pname] ~= nil then
weapons.player_arms[pname]:set_animation(weapon._anim.aim, 60, 0.15, true) weapons.player_arms[pname]:set_animation(weapon._anim.aim, 60, 0.15, true)
end end
@ -903,13 +928,12 @@ minetest.register_globalstep(function(dtime)
if weapons.player_list[pname][ammo] > 0 or ammo == "blocks" then if weapons.player_list[pname][ammo] > 0 or ammo == "blocks" then
arm_frame[pname] = 0 arm_frame[pname] = 0
arm_type[pname] = "idle_fire" 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 if weapons.player_arms[pname] ~= nil then
weapons.player_arms[pname]:set_animation(weapon._anim.idle_fire, 60, 0.15, true) weapons.player_arms[pname]:set_animation(weapon._anim.idle_fire, 60, 0.15, true)
end end
end end
else else
--arm_frame[pname] = -1
arm_type[pname] = "idle" arm_type[pname] = "idle"
if weapons.player_arms[pname] ~= nil then if weapons.player_arms[pname] ~= nil then
weapons.player_arms[pname]:set_animation(weapon._anim.idle, 60, 0.15, true) 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 chambered = false
local chamber_bonus = 1 -- Normal reload speed local chamber_bonus = 1 -- Normal reload speed
weapons.player_list[pname].anim_mode = false weapons.player_list[pname].anim_mode = false
if weapons.player_list[pname][ammo] > 0 then -- Ensure there's a round in the chamber if keypressed then
chambered = true if weapons.player_list[pname][ammo] > 0 then -- Ensure there's a round in the chamber
chamber_bonus = 0.9 chambered = true
weapons.player_list[pname].anim_mode = true chamber_bonus = 0.9
weapons.player_list[pname].anim_mode = true
end
end end
weapons.player_list[pname][ammo] = 0 weapons.player_list[pname][ammo] = 0
if not weapons.is_reloading[pname][wield] then 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,
math.random(-100, 100)/100 math.random(-100, 100)/100
) )
if moveresult == nil then --if moveresult == nil then
elseif moveresult.touching_ground then --elseif moveresult.touching_ground then
vector_mod.y = math.random(1, 100)/100 --vector_mod.y = math.random(1, 100)/100
end --end
local rayend = vector.add(pos, vector_mod) local rayend = vector.add(pos, vector_mod)
-- Tracers; performance heavy? -- Tracers; performance heavy?
@ -274,10 +274,8 @@ local function register_grenade(name, class, killfeed_name, stats)
range = 1, range = 1,
node_placement_prediction = "", node_placement_prediction = "",
_ammo_bg = "grenade",
_fov_mult = 0, _fov_mult = 0,
_crosshair = "railgun_crosshair.png", _crosshair = "railgun_crosshair.png",
_ammo_bg = "grenade_bg",
_type = "grenade", _type = "grenade",
_ammo_type = "grenade", _ammo_type = "grenade",
_phys_alt = 1, _phys_alt = 1,

View File

@ -1,18 +1,40 @@
-- Rocket Science for Super CTF: -- Rocket Science for BfA:
-- Author: Jordach -- Author: Jordach
-- License: Reserved -- License: Reserved
local r_block_chance = 100
local inside_chance = 100
local outside_chance = 90
local function rocket_explode_damage_blocks(pos) local function rocket_explode_damage_blocks(pos)
local bpos = table.copy(pos) local bpos = table.copy(pos)
local weapon = table.copy(minetest.registered_nodes["weapons:rocket_launcher_red"]) local weapon = table.copy(minetest.registered_nodes["weapons:rocket_launcher"])
for x=-1, 1 do for x=-2, 2 do
for y=-1, 1 do for y=-2, 2 do
for z=-1, 1 do for z=-2, 2 do
local npos = {x=bpos.x+x, y=bpos.y+y, z=bpos.z+z} 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]) local nodedef = table.copy(minetest.registered_nodes[minetest.get_node(npos).name])
weapon._break_hits = math.random(1, 4) weapon._block_chance = r_block_chance
local damage, node, result = weapons.calc_block_damage(nodedef, weapon, npos) if x == -2 or x == 2 then
minetest.set_node(npos, {name=node}) 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 end
end end
@ -20,73 +42,38 @@ end
local function launch_rocket(player, weapon) local function launch_rocket(player, weapon)
-- Handle recoil of the equipped 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( local pname = player:get_player_name()
vector.add(player:get_pos(), vector.new(0, weapons.default_eye_height, 0)), local ammo = weapon._ammo_type
vector.multiply(player:get_look_dir(), 1)
)
local rocket_vel = vector.add( if weapons.player_list[pname][ammo] > 0 then
vector.multiply(player:get_look_dir(), 45), vector.new(0, 0, 0) 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() local rocket_vel = vector.multiply(player:get_look_dir(), 20)
luaent._player_ref = player
luaent._loop_sound_ref = local ent = minetest.add_entity(rocket_pos, "weapons:rocket_ent")
minetest.sound_play({name="rocket_fly"}, local luaent = ent:get_luaentity()
{object=ent, max_hear_distance=32, gain=1.2, loop=true}) 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: -- Commit audio suicide when attached audio stops working:tm:
minetest.after(15, minetest.sound_stop, luaent._loop_sound_ref) minetest.after(15, minetest.sound_stop, luaent._loop_sound_ref)
local look_vertical = player:get_look_vertical() local look_vertical = player:get_look_vertical()
local look_horizontal = player:get_look_horizontal() local look_horizontal = player:get_look_horizontal()
for i=1, 3 do
minetest.add_particlespawner({ ent:set_velocity(rocket_vel)
attached = ent, ent:set_rotation(vector.new(-look_vertical, look_horizontal, 0))
amount = 30, weapons.veteran_reload(player, weapon, player:get_wielded_item():get_name()
time = 0, , false)
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
})
end 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 end
local rocket_ent = { local rocket_ent = {
@ -102,76 +89,82 @@ local rocket_ent = {
visual_size = {x=5, y=5}, visual_size = {x=5, y=5},
_player_ref = nil, _player_ref = nil,
_loop_sound_ref = nil, _loop_sound_ref = nil,
_timer = 0 _timer = 0,
_stimer = 2
} }
function rocket_ent:explode(self, moveresult) 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 = self.object:get_pos()
local pos_block local pos_block, collided = {}, false
if moveresult.collisions[1] == nil then if moveresult.collisions[1] == nil then
pos_block = table.copy(self.object:get_pos()) pos_block = table.copy(self.object:get_pos())
pos_block.x = math.floor(pos_block.x) pos_block.x = math.floor(pos_block.x)
pos_block.y = math.floor(pos_block.y) pos_block.y = math.floor(pos_block.y)
pos_block.z = math.floor(pos_block.z) 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 else
pos_block = table.copy(pos) for index, coll_table in pairs(moveresult.collisions) do
pos_block.x = math.floor(pos_block.x) if moveresult.collisions[index].type == "object" then
pos_block.y = math.floor(pos_block.y) if moveresult.collisions[index].object:is_player() then
pos_block.z = math.floor(pos_block.z) 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 end
local node = minetest.registered_nodes[minetest.get_node(pos).name] local node = minetest.registered_nodes[minetest.get_node(pos).name]
local rocket = minetest.registered_nodes["weapons:rocket_launcher_red"] local rocket = table.copy(minetest.registered_nodes["weapons:rocket_launcher"])
local rocket_damage = table.copy(rocket)
if self._player_ref == nil then
self.object:remove()
return
end
for _, player in ipairs(minetest.get_connected_players()) do for _, player in ipairs(minetest.get_connected_players()) do
local ppos = player:get_pos() local ppos = player:get_pos()
local pname = player:get_player_name()
local dist = solarsail.util.functions.pos_to_dist(pos, ppos) local dist = solarsail.util.functions.pos_to_dist(pos, ppos)
if dist < 4.01 then if dist < 4.01 then
if player == self._player_ref then if player == self._player_ref then
rocket_damage._damage = rocket._damage/2.5 rocket._damage = math.floor(rocket._damage / 2.75)
weapons.handle_damage(rocket_damage, self._player_ref, player, dist, nil) weapons.handle_damage(rocket, self._player_ref, player, dist, nil)
else else
dist = solarsail.util.functions.pos_to_dist(self._player_ref:get_pos(), ppos) 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 end
-- Add player knockback: -- Add player knockback:
solarsail.util.functions.apply_explosion_recoil(player, 25, pos) solarsail.util.functions.apply_explosion_recoil(player, 25, pos)
end end
end end
rocket_explode_damage_blocks(pos_block) 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"}, 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 if self._loop_sound_ref ~= nil then
minetest.sound_stop(self._loop_sound_ref) minetest.sound_stop(self._loop_sound_ref)
end end
@ -181,92 +174,125 @@ end
function rocket_ent:on_step(dtime, moveresult) function rocket_ent:on_step(dtime, moveresult)
if moveresult.collides then if moveresult.collides then
rocket_ent:explode(self, moveresult) rocket_ent:explode(self, moveresult)
return
elseif self._timer > 15 then elseif self._timer > 15 then
rocket_ent:explode(self, moveresult) rocket_ent:explode(self, moveresult)
return
end 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._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 end
minetest.register_entity("weapons:rocket_ent", rocket_ent) minetest.register_entity("weapons:rocket_ent", rocket_ent)
local launcher_def_red = { local rl_name = "SPNKr Model X"
tiles = { local chance = math.random(1, 20)
{name="rocket_launcher.png", backface_culling=false}, if chance == 1 then
{name="assault_class_red.png", backface_culling=false} 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, -- HUD stuff.
_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",
_name = "rocket_launcher", _name = "rocket_launcher",
_mag = 1, _crosshair = "railgun_crosshair.png",
_rpm = 80, _crosshair_aim = "railgun_crosshair.png",
_reload = 15, _fov_mult = 0,
_damage = 45, _fov_mult_aim = 0.5,
_recoil = 3, _min_arm_angle = -65,
_phys_alt = 1, _max_arm_angle = 70,
_break_hits = 2, _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) -- Base Stats:
return itemstack _pellets = 1,
end, _mag = 2,
on_drop = function(itemstack, dropper, pointed_thing) _rpm = 95,
return itemstack _reload = 3.43,
end, _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, on_fire = launch_rocket,
} on_reload = function(player, weapon, wield, keypressed)
minetest.register_node("weapons:rocket_launcher_red", launcher_def_red) weapons.magazine_reload(player, weapon, wield, false)
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
end, 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)