Written a bounce code for the aerial faith plate, improved shooting out from the gun
parent
4751f16483
commit
fa808f8613
|
@ -1,3 +1,14 @@
|
||||||
|
local aerial_faith_plate_f = [[
|
||||||
|
formspec_version[4]
|
||||||
|
size[10,5.5]
|
||||||
|
style_type[label;font=normal,bold;font_size=*1.5]
|
||||||
|
label[0.5,1;Set up bouncing maximum height and distance:]
|
||||||
|
field[1.5,2.5;3,1;max_height;Max Height:;]
|
||||||
|
field[5.5,2.5;3,1;max_distance;Max Distance:;]
|
||||||
|
button[3.5,4;3,1;save;Save]
|
||||||
|
style_type[label;font=normal,bold;font_size=]
|
||||||
|
]]
|
||||||
|
|
||||||
minetest.register_node("portaltest:aerial_faith_plate_idle", {
|
minetest.register_node("portaltest:aerial_faith_plate_idle", {
|
||||||
description = "Aerial Faith Plate (Click to set up parameters of bouncing)",
|
description = "Aerial Faith Plate (Click to set up parameters of bouncing)",
|
||||||
drawtype = "mesh",
|
drawtype = "mesh",
|
||||||
|
@ -24,23 +35,53 @@ minetest.register_node("portaltest:aerial_faith_plate_idle", {
|
||||||
},
|
},
|
||||||
groups = {choppy=2.5},
|
groups = {choppy=2.5},
|
||||||
sounds = default.node_sound_wood_defaults(),
|
sounds = default.node_sound_wood_defaults(),
|
||||||
on_construct = function(pos)
|
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
||||||
local meta = minetest.get_meta(pos)
|
local owner = minetest.get_meta(pos):get_string("owner")
|
||||||
meta:set_string("formspec", [[
|
local clickername = clicker:get_player_name()
|
||||||
formspec_version[4]
|
|
||||||
size[9,7]
|
if owner ~= clickername then
|
||||||
style_type[label;font=normal,bold;font_size=*1.5]
|
minetest.chat_send_player(clickername, "You can not edit the parameters of the aerial faith plate as you are not an owner of it!")
|
||||||
]] ..
|
return
|
||||||
"label[1.5,1;Set up bouncing direction and\n maximum height and distance:]" ..
|
end
|
||||||
[[
|
|
||||||
style_type[label;font=normal,bold;font_size=]
|
clicker:get_meta():set_string("cur_edited_afp_node_pos", minetest.serialize(pos))
|
||||||
label[1.5,2.5;Max Height:]
|
minetest.show_formspec(clickername, "portaltest:afp_params_form", aerial_faith_plate_f)
|
||||||
label[5.5,2.5;Max Distance:]
|
end,
|
||||||
label[3.5,4;Direction:]
|
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||||
field[1.5,3;2,0.5;max_height;;]
|
minetest.get_meta(pos):set_string("owner", placer:get_player_name())
|
||||||
field[5.5,3;2,0.5;max_distance;;]
|
end
|
||||||
field[3.5,4.5;2,0.5;direction;;]
|
})
|
||||||
button[3,5.5;3,1;save;Save]
|
|
||||||
]])
|
minetest.register_node("portaltest:aerial_faith_plate_active", {
|
||||||
|
description = "Aerial Faith Plate (Click to set up parameters of bouncing)",
|
||||||
|
drawtype = "mesh",
|
||||||
|
mesh = "portaltest_aerial_faith_plate_active.b3d",
|
||||||
|
tiles = {"portaltest_aerial_faith_plate.png"},
|
||||||
|
use_texture_alpha = "blend",
|
||||||
|
paramtype = "light",
|
||||||
|
paramtype2 = "facedir",
|
||||||
|
drop = "portaltest:aerial_faith_plate_idle",
|
||||||
|
collision_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {
|
||||||
|
--{-0.85, -1.5, -0.85, 0.85, -0.5, 0.85},
|
||||||
|
{-1.5, -0.5, -1.5, 1.5, -0.3, 1.5},
|
||||||
|
{-0.1, -0.3, -0.1, 0.1, 0.2, 0.1},
|
||||||
|
{-0.85, 0.2, -0.85, 0.85, 0.3, 0.85}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selection_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {
|
||||||
|
--{-0.85, -1.5, -0.85, 0.85, -0.5, 0.85},
|
||||||
|
{-1.5, -0.5, -1.5, 1.5, -0.3, 1.5},
|
||||||
|
{-0.1, -0.3, -0.1, 0.1, 0.2, 0.1},
|
||||||
|
{-0.85, 0.2, -0.85, 0.85, 0.3, 0.85}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
groups = {choppy=2.5, not_in_creative_inventory=1},
|
||||||
|
sounds = default.node_sound_wood_defaults(),
|
||||||
|
on_timer = function(pos, elapsed)
|
||||||
|
minetest.swap_node(pos, {name = "portaltest:aerial_faith_plate_idle", param2 = minetest.get_node(pos).param2})
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
25
config.lua
25
config.lua
|
@ -1,17 +1,26 @@
|
||||||
-- GUN CONFIGURATION --
|
-- GUN CONFIGURATION --
|
||||||
|
|
||||||
gsettings = {}
|
gsettings = {}
|
||||||
-- gravity acceleration (metres/second^2)
|
-- splash drop gravity acceleration (metres/second^2)
|
||||||
gsettings.SPLASH_STREAM_GRAVITY = 9.8
|
gsettings.SPLASH_DROP_GRAVITY = tonumber(minetest.settings:get("portaltest_splash_drop_gravity")) or 9.8
|
||||||
|
|
||||||
-- speed of stream splash (metres/second)
|
-- speed of gun ball (metres/second)
|
||||||
gsettings.SPLASH_STREAM_SPEED = 50
|
gsettings.GUN_BALL_SPEED = tonumber(minetest.settings:get("portaltest_gun_ball_speed")) or 50.0
|
||||||
|
|
||||||
-- lifetime of splash drop (seconds)
|
-- lifetime of splash drop (seconds)
|
||||||
gsettings.SPLASH_DROP_LIFETIME = 2
|
gsettings.SPLASH_DROP_LIFETIME = tonumber(minetest.settings:get("portaltest_splash_drop_lifetime")) or 2.0
|
||||||
|
|
||||||
-- splash stream collision box
|
-- gun ball collision box
|
||||||
gsettings.SPLASH_STREAM_COLLISION_BOX = {-0.01, -0.01, -0.01, 0.01, 0.01, 0.01}
|
gsettings.GUN_BALL_COLLISION_BOX = {
|
||||||
|
table.unpack(minetest.setting_get_pos("portaltest_gun_ball_collision_box_min_edge") or {-0.01, -0.01, -0.01}),
|
||||||
|
table.unpack(minetest.setting_get_pos("portaltest_gun_ball_collision_box_max_edge") or {0.01, 0.01, 0.01})
|
||||||
|
}
|
||||||
|
|
||||||
-- splash drop collision box
|
-- splash drop collision box
|
||||||
gsettings.SPLASH_DROP_COLLISION_BOX = {-0.005, -0.005, -0.005, 0.005, 0.005, 0.005}
|
gsettings.SPLASH_DROP_COLLISION_BOX = {
|
||||||
|
table.unpack(minetest.setting_get_pos("portaltest_splash_drop_collision_box_min_edge") or {-0.005, -0.005, -0.005}),
|
||||||
|
table.unpack(minetest.setting_get_pos("portaltest_splash_drop_collision_box_max_edge") or {0.005, 0.005, 0.005})
|
||||||
|
}
|
||||||
|
|
||||||
|
-- gun shift position
|
||||||
|
gsettings.GUN_POSITION_SHIFT = minetest.setting_get_pos("portaltest_gun_position_shift") or {0.3, 1.2, 0.5}
|
||||||
|
|
28
gun.lua
28
gun.lua
|
@ -5,8 +5,6 @@ gun = {}
|
||||||
-- Table for referencing to a gun entity of each player that is wielding that currently
|
-- Table for referencing to a gun entity of each player that is wielding that currently
|
||||||
gun.spawned_guns = {}
|
gun.spawned_guns = {}
|
||||||
|
|
||||||
local gun_shift = {x=0.3, y=1.2, z=0.5}
|
|
||||||
|
|
||||||
gun.generate_splash_particles = function(pos, normal, splash_color)
|
gun.generate_splash_particles = function(pos, normal, splash_color)
|
||||||
local rand_amount = math.random(20, 25)
|
local rand_amount = math.random(20, 25)
|
||||||
|
|
||||||
|
@ -20,8 +18,8 @@ gun.generate_splash_particles = function(pos, normal, splash_color)
|
||||||
maxpos = pos,
|
maxpos = pos,
|
||||||
minvel = vector.multiply(min_vel_dir, 5),
|
minvel = vector.multiply(min_vel_dir, 5),
|
||||||
maxvel = vector.multiply(max_vel_dir, 5),
|
maxvel = vector.multiply(max_vel_dir, 5),
|
||||||
minacc = {x=0, y=-gsettings.SPLASH_STREAM_GRAVITY, z=0},
|
minacc = {x=0, y=-gsettings.SPLASH_DROP_GRAVITY, z=0},
|
||||||
maxacc = {x=0, y=-gsettings.SPLASH_STREAM_GRAVITY, z=0},
|
maxacc = {x=0, y=-gsettings.SPLASH_DROP_GRAVITY, z=0},
|
||||||
minexptime = 1.5,
|
minexptime = 1.5,
|
||||||
maxexptime = 2.5,
|
maxexptime = 2.5,
|
||||||
minsize = 3,
|
minsize = 3,
|
||||||
|
@ -38,19 +36,19 @@ end
|
||||||
gun.calculate_gun_pos_and_rot = function(player)
|
gun.calculate_gun_pos_and_rot = function(player)
|
||||||
local rot = {x=-player:get_look_vertical(), y=player:get_look_horizontal(), z=0}
|
local rot = {x=-player:get_look_vertical(), y=player:get_look_horizontal(), z=0}
|
||||||
|
|
||||||
local pos = vector.add(player:get_pos(), vector.rotate(gun_shift, {x=0, y=player:get_look_horizontal(), z=0}))
|
local pos = vector.add(player:get_pos(), vector.rotate(gsettings.GUN_POSITION_SHIFT, {x=0, y=player:get_look_horizontal(), z=0}))
|
||||||
|
|
||||||
return pos, rot
|
return pos, rot
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Shifts the gun entity backward and turns right a bit for a visual effect while shooting. Also knockback a bit the player`s camera.
|
-- Shifts the gun entity backward and turns right a bit for a visual effect while shooting. Also knockback a bit the player`s camera.
|
||||||
gun.knockback_gun = function(player, gun)
|
gun.knockback_gun = function(player, gun)
|
||||||
local shift_back = -0.05
|
local shift_back = -0.1
|
||||||
local rot_right = -math.rad(1)
|
local rot_right = -math.rad(2)
|
||||||
local cam_rot_d = -math.rad(5)
|
local cam_rot_d = -math.rad(2)
|
||||||
|
|
||||||
local elapsed = 0.0
|
local elapsed = 0.0
|
||||||
local dtime = 0.05
|
local dtime = 0.1
|
||||||
|
|
||||||
local orig_cam_dir = player:get_look_dir()
|
local orig_cam_dir = player:get_look_dir()
|
||||||
minetest.debug("gun.knockback_gun()")
|
minetest.debug("gun.knockback_gun()")
|
||||||
|
@ -61,7 +59,8 @@ gun.knockback_gun = function(player, gun)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if elapsed >= 0.5 and elapsed < 0.55 or elapsed > 0.45 and elapsed <= 0.5 then
|
if (math.floor(elapsed * 10) / 10) == 0.3 then
|
||||||
|
--if elapsed >= 0.5 and elapsed < 0.55 or elapsed > 0.45 and elapsed <= 0.5 then
|
||||||
minetest.debug("elapsed = 0.5")
|
minetest.debug("elapsed = 0.5")
|
||||||
rot_right = -rot_right
|
rot_right = -rot_right
|
||||||
shift_back = -shift_back
|
shift_back = -shift_back
|
||||||
|
@ -75,7 +74,7 @@ gun.knockback_gun = function(player, gun)
|
||||||
gun:set_rotation({x=cur_rot.x, y=cur_rot.y+rot_right, z=cur_rot.z})
|
gun:set_rotation({x=cur_rot.x, y=cur_rot.y+rot_right, z=cur_rot.z})
|
||||||
|
|
||||||
|
|
||||||
if elapsed < 1.0 then
|
if elapsed < 0.6 then
|
||||||
minetest.after(dtime, knockback, gun)
|
minetest.after(dtime, knockback, gun)
|
||||||
else
|
else
|
||||||
player:get_meta():set_string("is_shooting", "")
|
player:get_meta():set_string("is_shooting", "")
|
||||||
|
@ -109,9 +108,9 @@ gun.shoot = function(player, gun, ball_color)
|
||||||
local dir = player:get_look_dir()
|
local dir = player:get_look_dir()
|
||||||
local gun_pos = gun:get_pos()
|
local gun_pos = gun:get_pos()
|
||||||
|
|
||||||
local gun_ball = minetest.add_entity(gun_pos, "portaltest:gun_ball")
|
local gun_ball = minetest.add_entity(vector.add(gun_pos, vector.multiply(dir, -0.3)), "portaltest:gun_ball")
|
||||||
gun_ball:set_properties({textures={"portaltest_gun_ball.png^[multiply:" .. ball_color}})
|
gun_ball:set_properties({textures={"portaltest_gun_ball.png^[multiply:" .. ball_color}})
|
||||||
gun_ball:set_velocity(vector.multiply(dir, gsettings.SPLASH_STREAM_SPEED))
|
gun_ball:set_velocity(vector.multiply(dir, gsettings.GUN_BALL_SPEED))
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
@ -167,6 +166,7 @@ gun.global_step_through_players_with_guns = function()
|
||||||
player_api.set_animation(player, anim, speed)
|
player_api.set_animation(player, anim, speed)
|
||||||
else
|
else
|
||||||
if gun.spawned_guns[name] then
|
if gun.spawned_guns[name] then
|
||||||
|
minetest.debug("remove gun entity")
|
||||||
gun.spawned_guns[name]:remove()
|
gun.spawned_guns[name]:remove()
|
||||||
gun.spawned_guns[name] = nil
|
gun.spawned_guns[name] = nil
|
||||||
player_api.set_model(player, "character.b3d")
|
player_api.set_model(player, "character.b3d")
|
||||||
|
@ -411,7 +411,7 @@ minetest.register_entity("portaltest:gun_ball", {
|
||||||
visual_size = {x=1, y=1, z=1},
|
visual_size = {x=1, y=1, z=1},
|
||||||
physical = true,
|
physical = true,
|
||||||
collide_with_objects = false,
|
collide_with_objects = false,
|
||||||
collisionbox = gsettings.SPLASH_STREAM_COLLISION_BOX,
|
collisionbox = gsettings.GUN_BALL_COLLISION_BOX,
|
||||||
selectionbox = {0, 0, 0, 0, 0, 0},
|
selectionbox = {0, 0, 0, 0, 0, 0},
|
||||||
textures = {"portaltest_gun_ball.png"},
|
textures = {"portaltest_gun_ball.png"},
|
||||||
backface_culling = false,
|
backface_culling = false,
|
||||||
|
|
112
init.lua
112
init.lua
|
@ -1,7 +1,119 @@
|
||||||
local modpath = minetest.get_modpath("portaltest")
|
local modpath = minetest.get_modpath("portaltest")
|
||||||
|
|
||||||
|
local DEFAULT_GRAVITY = -9.8
|
||||||
|
|
||||||
|
-- Load separate files
|
||||||
dofile(modpath .. "/aerial_faith_plate.lua")
|
dofile(modpath .. "/aerial_faith_plate.lua")
|
||||||
dofile(modpath .. "/config.lua")
|
dofile(modpath .. "/config.lua")
|
||||||
dofile(modpath .. "/gun.lua")
|
dofile(modpath .. "/gun.lua")
|
||||||
dofile(modpath .. "/panels.lua")
|
dofile(modpath .. "/panels.lua")
|
||||||
dofile(modpath .. "/portal.lua")
|
dofile(modpath .. "/portal.lua")
|
||||||
|
|
||||||
|
-- Global callbacks
|
||||||
|
|
||||||
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
|
if formname == "portaltest:afp_params_form" then
|
||||||
|
local cur_edited_afp_node_pos = minetest.deserialize(player:get_meta():get_string("cur_edited_afp_node_pos"))
|
||||||
|
|
||||||
|
if not cur_edited_afp_node_pos then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.quit then
|
||||||
|
player:get_meta():set_string("cur_edited_afp_node_pos", "")
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
if fields.save then
|
||||||
|
local params = {height = tonumber(fields.max_height), distance = tonumber(fields.max_distance)}
|
||||||
|
|
||||||
|
minetest.get_meta(cur_edited_afp_node_pos):set_string("params", minetest.serialize(params))
|
||||||
|
player:get_meta():set_string("cur_edited_afp_node_pos", "")
|
||||||
|
minetest.show_formspec(player:get_player_name(), formname, "")
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
minetest.register_globalstep(function(dtime)
|
||||||
|
for _, player in ipairs(minetest.get_connected_players()) do
|
||||||
|
local pos = player:get_pos()
|
||||||
|
local under_node = minetest.get_node(pos)
|
||||||
|
--minetest.debug("under_node: " .. under_node.name)
|
||||||
|
|
||||||
|
if under_node.name == "portaltest:aerial_faith_plate_idle" then
|
||||||
|
local node_dir = minetest.facedir_to_dir(under_node.param2)
|
||||||
|
local params = minetest.deserialize(minetest.get_meta(pos):get_string("params"))
|
||||||
|
|
||||||
|
if params and params.height and params.distance then
|
||||||
|
local gravity = DEFAULT_GRAVITY * player:get_physics_override().gravity
|
||||||
|
|
||||||
|
local v_y = math.sqrt(19.6 * params.height)
|
||||||
|
local v_z = 2 * -DEFAULT_GRAVITY * params.distance / v_y
|
||||||
|
|
||||||
|
local v = {x=0, y=v_y, z=v_z}
|
||||||
|
|
||||||
|
v = vector.rotate_around_axis(v, {x=0, y=1, z=0}, vector.dir_to_rotation(node_dir).y)
|
||||||
|
|
||||||
|
player:add_velocity(v)
|
||||||
|
|
||||||
|
minetest.swap_node(pos, {name = "portaltest:aerial_faith_plate_active", param2 = under_node.param2})
|
||||||
|
local timer = minetest.get_node_timer(pos)
|
||||||
|
timer:start(2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local name = player:get_player_name()
|
||||||
|
if player:get_wielded_item():get_name() == "portaltest:gun_item" then
|
||||||
|
local gun_pos, gun_rot = gun.calculate_gun_pos_and_rot(player)
|
||||||
|
if not gun.spawned_guns[name] then
|
||||||
|
minetest.debug("add gun entity")
|
||||||
|
gun.spawned_guns[name] = minetest.add_entity(gun_pos, "portaltest:gun")
|
||||||
|
player_api.set_model(player, "portaltest_player_with_gun.b3d")
|
||||||
|
else
|
||||||
|
gun.spawned_guns[name]:set_pos(gun_pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
gun.spawned_guns[name]:set_rotation(gun_rot)
|
||||||
|
|
||||||
|
|
||||||
|
local ctrls = player:get_player_control()
|
||||||
|
|
||||||
|
local anim
|
||||||
|
local speed = 30
|
||||||
|
local meta = player:get_meta()
|
||||||
|
if ctrls.up or ctrls.right then
|
||||||
|
anim = "walk_forward"
|
||||||
|
elseif ctrls.down or ctrls.left then
|
||||||
|
anim = "walk_backward"
|
||||||
|
elseif ctrls.LMB or ctrls.RMB then
|
||||||
|
if meta:get_string("is_shooting") == "" then
|
||||||
|
minetest.debug("\'is_shooting\' is empty!")
|
||||||
|
anim = "shoot"
|
||||||
|
speed = 10
|
||||||
|
|
||||||
|
local gun_color = ctrls.LMB and "blue" or "orange"
|
||||||
|
meta:set_string("is_shooting", "1")
|
||||||
|
minetest.debug("\'is_shooting\' is 1!")
|
||||||
|
|
||||||
|
gun.spawned_guns[name]:set_properties({textures={"portaltest_gun.png", "portaltest_gun_" .. gun_color .. "_tube.png"}})
|
||||||
|
|
||||||
|
gun.shoot(player, gun.spawned_guns[name], gun_color)
|
||||||
|
gun.knockback_gun(player, gun.spawned_guns[name])
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
elseif meta:get_string("is_shooting") == "" then
|
||||||
|
anim = "stand"
|
||||||
|
end
|
||||||
|
|
||||||
|
player_api.set_animation(player, anim, speed)
|
||||||
|
else
|
||||||
|
if gun.spawned_guns[name] then
|
||||||
|
minetest.debug("remove gun entity")
|
||||||
|
gun.spawned_guns[name]:remove()
|
||||||
|
gun.spawned_guns[name] = nil
|
||||||
|
player_api.set_model(player, "character.b3d")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,15 @@
|
||||||
|
portaltest_gun_ball_speed (Gun ball speed) float 50.0
|
||||||
|
|
||||||
|
portaltest_splash_drop_gravity (Splash drop gravity) float 9.8
|
||||||
|
|
||||||
|
portaltest_splash_drop_lifetime (Splash drop lifetime) float 2.0
|
||||||
|
|
||||||
|
portaltest_gun_ball_collision_box_min_edge (Minimal edge position of the gun ball collision box) v3f (-0.01, -0.01, -0.01)
|
||||||
|
|
||||||
|
portaltest_gun_ball_collision_box_max_edge (Maximal edge position of the gun ball collision box) v3f (0.01, 0.01, 0.01)
|
||||||
|
|
||||||
|
portaltest_splash_drop_collision_box_min_edge (Minimal edge position of the splash drop collision box) v3f (-0.005, -0.005, -0.005)
|
||||||
|
|
||||||
|
portaltest_splash_drop_collision_box_max_edge (Maximal edge position of the splash drop collision box) v3f (0.005, 0.005, 0.005)
|
||||||
|
|
||||||
|
portaltest_gun_position_shift (Shift of the gun entity position) v3f (0.3, 1.2, 0.5)
|
Loading…
Reference in New Issue