Written a bounce code for the aerial faith plate, improved shooting out from the gun

master
Andrey2470T 2021-10-15 01:15:40 +03:00
parent 4751f16483
commit fa808f8613
8 changed files with 217 additions and 40 deletions

View File

@ -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", {
description = "Aerial Faith Plate (Click to set up parameters of bouncing)",
drawtype = "mesh",
@ -24,23 +35,53 @@ minetest.register_node("portaltest:aerial_faith_plate_idle", {
},
groups = {choppy=2.5},
sounds = default.node_sound_wood_defaults(),
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", [[
formspec_version[4]
size[9,7]
style_type[label;font=normal,bold;font_size=*1.5]
]] ..
"label[1.5,1;Set up bouncing direction and\n maximum height and distance:]" ..
[[
style_type[label;font=normal,bold;font_size=]
label[1.5,2.5;Max Height:]
label[5.5,2.5;Max Distance:]
label[3.5,4;Direction:]
field[1.5,3;2,0.5;max_height;;]
field[5.5,3;2,0.5;max_distance;;]
field[3.5,4.5;2,0.5;direction;;]
button[3,5.5;3,1;save;Save]
]])
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local owner = minetest.get_meta(pos):get_string("owner")
local clickername = clicker:get_player_name()
if owner ~= clickername then
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
end
clicker:get_meta():set_string("cur_edited_afp_node_pos", minetest.serialize(pos))
minetest.show_formspec(clickername, "portaltest:afp_params_form", aerial_faith_plate_f)
end,
after_place_node = function(pos, placer, itemstack, pointed_thing)
minetest.get_meta(pos):set_string("owner", placer:get_player_name())
end
})
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
})

View File

@ -1,17 +1,26 @@
-- GUN CONFIGURATION --
gsettings = {}
-- gravity acceleration (metres/second^2)
gsettings.SPLASH_STREAM_GRAVITY = 9.8
-- splash drop gravity acceleration (metres/second^2)
gsettings.SPLASH_DROP_GRAVITY = tonumber(minetest.settings:get("portaltest_splash_drop_gravity")) or 9.8
-- speed of stream splash (metres/second)
gsettings.SPLASH_STREAM_SPEED = 50
-- speed of gun ball (metres/second)
gsettings.GUN_BALL_SPEED = tonumber(minetest.settings:get("portaltest_gun_ball_speed")) or 50.0
-- 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
gsettings.SPLASH_STREAM_COLLISION_BOX = {-0.01, -0.01, -0.01, 0.01, 0.01, 0.01}
-- gun ball collision box
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
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
View File

@ -5,8 +5,6 @@ gun = {}
-- Table for referencing to a gun entity of each player that is wielding that currently
gun.spawned_guns = {}
local gun_shift = {x=0.3, y=1.2, z=0.5}
gun.generate_splash_particles = function(pos, normal, splash_color)
local rand_amount = math.random(20, 25)
@ -20,8 +18,8 @@ gun.generate_splash_particles = function(pos, normal, splash_color)
maxpos = pos,
minvel = vector.multiply(min_vel_dir, 5),
maxvel = vector.multiply(max_vel_dir, 5),
minacc = {x=0, y=-gsettings.SPLASH_STREAM_GRAVITY, z=0},
maxacc = {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_DROP_GRAVITY, z=0},
minexptime = 1.5,
maxexptime = 2.5,
minsize = 3,
@ -38,19 +36,19 @@ end
gun.calculate_gun_pos_and_rot = function(player)
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
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.
gun.knockback_gun = function(player, gun)
local shift_back = -0.05
local rot_right = -math.rad(1)
local cam_rot_d = -math.rad(5)
local shift_back = -0.1
local rot_right = -math.rad(2)
local cam_rot_d = -math.rad(2)
local elapsed = 0.0
local dtime = 0.05
local dtime = 0.1
local orig_cam_dir = player:get_look_dir()
minetest.debug("gun.knockback_gun()")
@ -61,7 +59,8 @@ gun.knockback_gun = function(player, gun)
return
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")
rot_right = -rot_right
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})
if elapsed < 1.0 then
if elapsed < 0.6 then
minetest.after(dtime, knockback, gun)
else
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 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_velocity(vector.multiply(dir, gsettings.SPLASH_STREAM_SPEED))
gun_ball:set_velocity(vector.multiply(dir, gsettings.GUN_BALL_SPEED))
return true
end
@ -167,6 +166,7 @@ gun.global_step_through_players_with_guns = function()
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")
@ -411,7 +411,7 @@ minetest.register_entity("portaltest:gun_ball", {
visual_size = {x=1, y=1, z=1},
physical = true,
collide_with_objects = false,
collisionbox = gsettings.SPLASH_STREAM_COLLISION_BOX,
collisionbox = gsettings.GUN_BALL_COLLISION_BOX,
selectionbox = {0, 0, 0, 0, 0, 0},
textures = {"portaltest_gun_ball.png"},
backface_culling = false,

112
init.lua
View File

@ -1,7 +1,119 @@
local modpath = minetest.get_modpath("portaltest")
local DEFAULT_GRAVITY = -9.8
-- Load separate files
dofile(modpath .. "/aerial_faith_plate.lua")
dofile(modpath .. "/config.lua")
dofile(modpath .. "/gun.lua")
dofile(modpath .. "/panels.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)

15
settingtypes.txt Normal file
View File

@ -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)