diff --git a/aerial_faith_plate.lua b/aerial_faith_plate.lua index 9a28f14..487e8df 100644 --- a/aerial_faith_plate.lua +++ b/aerial_faith_plate.lua @@ -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 }) diff --git a/config.lua b/config.lua index 4037adb..843c519 100644 --- a/config.lua +++ b/config.lua @@ -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} diff --git a/gun.lua b/gun.lua index ff1cf74..40a442e 100644 --- a/gun.lua +++ b/gun.lua @@ -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, diff --git a/init.lua b/init.lua index 10f76d3..51c5d4c 100644 --- a/init.lua +++ b/init.lua @@ -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) diff --git a/models/portaltest_aerial_faith_plate_active.b3d b/models/portaltest_aerial_faith_plate_active.b3d index 5292d4f..d00f2dc 100644 Binary files a/models/portaltest_aerial_faith_plate_active.b3d and b/models/portaltest_aerial_faith_plate_active.b3d differ diff --git a/models/portaltest_aerial_faith_plate_active.blend b/models/portaltest_aerial_faith_plate_active.blend index 7f2748a..29f44d9 100644 Binary files a/models/portaltest_aerial_faith_plate_active.blend and b/models/portaltest_aerial_faith_plate_active.blend differ diff --git a/models/portaltest_aerial_faith_plate_active.blend1 b/models/portaltest_aerial_faith_plate_active.blend1 index e06f21d..1d10e08 100644 Binary files a/models/portaltest_aerial_faith_plate_active.blend1 and b/models/portaltest_aerial_faith_plate_active.blend1 differ diff --git a/settingtypes.txt b/settingtypes.txt new file mode 100644 index 0000000..f441522 --- /dev/null +++ b/settingtypes.txt @@ -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)