Added aerial faith plates model/texture, the portal gun is entity now, added animation and visual effects of shooting

master
Andrey2470T 2021-10-03 02:00:18 +03:00
parent 7f82e2adf1
commit b45891677c
19 changed files with 294 additions and 94 deletions

41
aerial_faith_plate.lua Normal file
View File

@ -0,0 +1,41 @@
minetest.register_node("portaltest:aerial_faith_plate", {
description = "Aerial Faith Plate (Click to set up parameters of bouncing)",
drawtype = "nodebox",
tiles = {
"portaltest_aerial_faith_plate_top.png",
"portaltest_aerial_faith_plate_bottom.png",
"portaltest_aerial_faith_plate_side.png"
},
use_texture_alpha = true,
paramtype = "light",
paramtype2 = "facedir",
node_box = {
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, -0.41, 0.5}
},
selection_box = {
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, -0.41, 0.5}
},
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]
]])
end
})

View File

@ -11,7 +11,7 @@ gsettings.SPLASH_STREAM_SPEED = 50
gsettings.SPLASH_DROP_LIFETIME = 2
-- splash stream collision box
gsettings.SPLASH_STREAM_COLLISION_BOX = {-0.1, -0.1, -0.1, 0.1, 0.1, 0.1}
gsettings.SPLASH_STREAM_COLLISION_BOX = {-0.01, -0.01, -0.01, 0.01, 0.01, 0.01}
-- splash drop collision box
gsettings.SPLASH_DROP_COLLISION_BOX = {-0.05, -0.05, -0.05, 0.05, 0.05, 0.05}
gsettings.SPLASH_DROP_COLLISION_BOX = {-0.005, -0.005, -0.005, 0.005, 0.005, 0.005}

220
gun.lua
View File

@ -2,11 +2,16 @@
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)
local min_vel_dir = vector.rotate(normal, {x=0, y=-math.pi/4, z=0})
local max_vel_dir = vector.rotate(normal, {x=-math.pi/4, y=math.pi/4, z=0})
local min_vel_dir = vector.rotate(normal, {x=-math.pi/4, y=-math.pi/4, z=0})
local max_vel_dir = vector.rotate(normal, {x=math.pi/4, y=math.pi/4, z=0})
minetest.add_particlespawner({
amount = rand_amount,
@ -27,19 +32,61 @@ gun.generate_splash_particles = function(pos, normal, splash_color)
texture = "portaltest_splash_drop.png^[multiply:" .. splash_color,
glow = 7
})
--[[for i = 1, rand_amount do
local rand_pitch = -math.rad(math.random(10, 45))
local rand_yaw = math.rad(math.random(10, 45)) * signs[math.random(1, 2)]
end
normal = vector.rotate_around_axis(normal, side, rand_pitch)
local up = vector.cross(side, normal)
-- Recalculates a new position and rotation for gun relatively to the player`s rotation.
gun.calculate_gun_pos_and_rot = function(player)
local rot = {x=-player:get_look_vertical(), y=player:get_look_horizontal(), z=0}
local res_dir = vector.rotate_around_axis(normal, up, rand_yaw)
local pos = vector.add(player:get_pos(), vector.rotate(gun_shift, {x=0, y=player:get_look_horizontal(), z=0}))
local splash_drop = minetest.add_entity(pos, "portaltest:splash_drop")
splash_drop:set_properties({textures={"portaltest_splash_drop.png^[multiply:" .. splash_color}})
splash_drop:set_velocity(vector.multiply(res_dir, 4))
end]]
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 elapsed = 0.0
local dtime = 0.05
local orig_cam_dir = player:get_look_dir()
minetest.debug("gun.knockback_gun()")
local function knockback(gun)
elapsed = elapsed + dtime
minetest.debug("elapsed: " .. tostring(elapsed))
if not gun:get_luaentity() then
return
end
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
cam_rot_d = -cam_rot_d
end
player:set_look_vertical(player:get_look_vertical()+cam_rot_d)
gun:set_pos(vector.add(gun:get_pos(), vector.multiply(orig_cam_dir, shift_back)))
local cur_rot = gun:get_rotation()
gun:set_rotation({x=cur_rot.x, y=cur_rot.y+rot_right, z=cur_rot.z})
if elapsed < 1.0 then
minetest.after(dtime, knockback, gun)
else
player:get_meta():set_string("is_shooting", "")
end
return true
end
minetest.after(dtime, knockback, gun)
return true
end
gun.bounce_splash_drop = function(drop, surface_normal)
@ -54,11 +101,80 @@ gun.bounce_splash_drop = function(drop, surface_normal)
drop:set_velocity(new_vel)
end
gun.shoot = function(player, gun, ball_color)
if not gun:get_luaentity() then
return
end
local dir = player:get_look_dir()
local gun_pos = gun:get_pos()
local gun_ball = minetest.add_entity(gun_pos, "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))
return true
end
gun.global_step_through_players_with_guns = function()
local players = minetest.get_connected_players()
for _, player in ipairs(players) do
if player:get_wielded_item():get_name() == "portaltest:gun_empty" then
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
gun.spawned_guns[name]:remove()
gun.spawned_guns[name] = nil
player_api.set_model(player, "character.b3d")
end
end
--[[
local ctrls = player:get_player_control()
local color = ""
@ -89,7 +205,7 @@ gun.global_step_through_players_with_guns = function()
minetest.after(0.5, function()
player:set_wielded_item(ItemStack("portaltest:gun_empty"))
end)
end
end]]
end
end
@ -99,7 +215,7 @@ gun.get_pointedthing_info = function(pos, dir, ray_length)
local target_pt
for pt in raycast do
if pt.type == "object" then
--[[if pt.type == "object" then
local self = pt.ref:get_luaentity()
if self then
minetest.debug("ray has intersected an object with name: " .. self.name)
@ -110,14 +226,16 @@ gun.get_pointedthing_info = function(pos, dir, ray_length)
--minetest.debug("raycast: " .. self.name)
end
end
elseif pt.type == "node" then
minetest.debug("raycast has intersected a node with name: " .. minetest.get_node(pt.under).name)
target_pt = pt
break
else]]
if pt.type == "node" then
--minetest.debug("raycast has intersected a node with name: " .. minetest.get_node(pt.under).name)
return pt
--target_pt = pt
--break
end
end
return target_pt
return
end
gun.update_player_portals_datas = function(player_meta)
@ -187,7 +305,42 @@ gun.place_portal = function(placer, pt, color, param2, dir_to_top)
setp_meta:set_string("dir_to_top", minetest.serialize(dir_to_top))
end
minetest.register_node("portaltest:gun_empty", {
-- Player model with gun
player_api.register_model("portaltest_player_with_gun.b3d", {
animations = {
stand = {x = 1, y = 80},
sit = {x = 81, y = 161},
lay = {x = 162, y = 167},
walk_forward = {x = 168, y = 188},
walk_backward = {x = 188, y = 168},
shoot = {x = 189, y = 199}
}
})
-- Portal gun
minetest.register_entity("portaltest:gun", {
visual_size = {x=3, y=3, z=3},
physical = false,
collision_box = {0, 0, 0, 0, 0, 0},
pointable = false,
visual = "mesh",
mesh = "portaltest_gun.b3d",
textures = {"portaltest_gun.png"},
glow = 4,
static_save = false
})
minetest.register_craftitem("portaltest:gun_item", {
description = "Portal Gun",
inventory_image = "portaltest_gun_inv.png",
wield_image = "portaltest_gun_inv.png^[opacity:0",
range = 0.0
})
-- Legacy code
--[[minetest.register_node("portaltest:gun_empty", {
drawtype = "mesh",
visual_scale = 0.5,
tiles = {"portaltest_gun.png^portaltest_gun_empty_tube.png"},
@ -248,19 +401,19 @@ minetest.register_node("portaltest:gun_blue", {
on_place = function(itemstack, placer, pointed_thing)
return nil
end
})
})]]
minetest.register_entity("portaltest:splash_stream", {
minetest.register_entity("portaltest:gun_ball", {
visual = "sprite",
visual_size = {x=1, y=1, z=1},
physical = true,
collide_with_objects = true,
collide_with_objects = false,
collisionbox = gsettings.SPLASH_STREAM_COLLISION_BOX,
selectionbox = {0, 0, 0, 0, 0, 0},
textures = {"portaltest_splash_stream.png"},
textures = {"portaltest_gun_ball.png"},
backface_culling = false,
glow = 7,
on_activate = function(self, staticdata, dtime_s)
@ -279,12 +432,12 @@ minetest.register_entity("portaltest:splash_stream", {
--minetest.debug("self.last_velocity: " .. minetest.pos_to_string(self.last_velocity))
--minetest.debug("current velocity: " .. minetest.pos_to_string(vel))
local pt
if vector.length(self.move_dir) == 0 then
local pt = gun.get_pointedthing_info(pos, self.move_dir, 1)
--[[if vector.length(self.move_dir) == 0 then
pt = gun.get_pointedthing_info(pos, vector.normalize(vel), 1)
else
pt = gun.get_pointedthing_info(pos, self.move_dir, 1)
end
end]]
if pt then
minetest.debug("\'pt\' is not nil!")
@ -293,8 +446,8 @@ minetest.register_entity("portaltest:splash_stream", {
--minetest.debug("pt.type: " .. pt.type)
local s, e = texture:find("%^%[multiply:", 1)
local color = texture:sub(e+1, texture:len())
local player = minetest.get_player_by_name(self.stream_emitter)
if pt.type == "node" then
--local player = minetest.get_player_by_name(self.stream_emitter)
--[[if pt.type == "node" then
if pt.intersection_normal.y == 0 then
-- Portal is placed on the wall
local node = minetest.get_node_or_nil(pt.under)
@ -354,7 +507,7 @@ minetest.register_entity("portaltest:splash_stream", {
gun.place_portal(player, pt, color, target_param2, dir_to_top)
end
end
end
end]]
gun.generate_splash_particles(pt.intersection_point, pt.intersection_normal, color)
@ -424,6 +577,11 @@ minetest.register_entity("portaltest:splash_stream", {
end
})]]
minetest.register_on_shutdown(function()
for i, player in ipairs(minetest.get_connected_players()) do
player:get_meta():set_string("is_shooting", "")
end
end)
minetest.register_globalstep(function(dtime)
gun.global_step_through_players_with_guns()

View File

@ -1,5 +1,6 @@
local modpath = minetest.get_modpath("portaltest")
dofile(modpath .. "/aerial_faith_plate.lua")
dofile(modpath .. "/config.lua")
dofile(modpath .. "/gun.lua")
dofile(modpath .. "/panels.lua")

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 791 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

Before

Width:  |  Height:  |  Size: 467 B

After

Width:  |  Height:  |  Size: 467 B

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB