Update shooter to 0.6.1

master
rubenwardy 3 years ago committed by GitHub
parent 85bf7b96d1
commit 63726848ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      .gitmodules
  2. 4
      .luacheckrc
  3. 16
      mods/ctf/ctf_classes/api.lua
  4. 45
      mods/ctf/ctf_classes/classes.lua
  5. 30
      mods/ctf/ctf_classes/items.lua
  6. 2
      mods/ctf/ctf_classes/mod.conf
  7. 38
      mods/ctf/ctf_classes/ranged.lua
  8. 8
      mods/ctf/ctf_match/init.lua
  9. 2
      mods/ctf/ctf_match/mod.conf
  10. 1
      mods/pvp/shooter
  11. 8
      mods/pvp/shooter/.gitignore
  12. 33
      mods/pvp/shooter/LICENSE.txt
  13. 169
      mods/pvp/shooter/README.txt
  14. 293
      mods/pvp/shooter/crossbow.lua
  15. 146
      mods/pvp/shooter/flaregun.lua
  16. 136
      mods/pvp/shooter/grapple.lua
  17. 81
      mods/pvp/shooter/grenade.lua
  18. 126
      mods/pvp/shooter/guns.lua
  19. 26
      mods/pvp/shooter/init.lua
  20. 3
      mods/pvp/shooter/mod.conf
  21. BIN
      mods/pvp/shooter/models/shooter_arrow.b3d
  22. BIN
      mods/pvp/shooter/models/shooter_arrow.blend
  23. BIN
      mods/pvp/shooter/models/shooter_turret.b3d
  24. BIN
      mods/pvp/shooter/models/shooter_turret.blend
  25. 113
      mods/pvp/shooter/rocket.lua
  26. BIN
      mods/pvp/shooter/screenshot.png
  27. 81
      mods/pvp/shooter/shooter.conf.example
  28. 492
      mods/pvp/shooter/shooter.lua
  29. BIN
      mods/pvp/shooter/sounds/shooter_click.ogg
  30. BIN
      mods/pvp/shooter/sounds/shooter_explode.ogg
  31. BIN
      mods/pvp/shooter/sounds/shooter_flare_burn.ogg
  32. BIN
      mods/pvp/shooter/sounds/shooter_flare_fire.ogg
  33. BIN
      mods/pvp/shooter/sounds/shooter_pistol.ogg
  34. BIN
      mods/pvp/shooter/sounds/shooter_reload.ogg
  35. BIN
      mods/pvp/shooter/sounds/shooter_rifle.ogg
  36. BIN
      mods/pvp/shooter/sounds/shooter_rocket_fire.ogg
  37. BIN
      mods/pvp/shooter/sounds/shooter_shotgun.ogg
  38. BIN
      mods/pvp/shooter/sounds/shooter_throw.ogg
  39. BIN
      mods/pvp/shooter/textures/shooter_ammo.png
  40. BIN
      mods/pvp/shooter/textures/shooter_arrow_inv.png
  41. BIN
      mods/pvp/shooter/textures/shooter_arrow_uv.png
  42. BIN
      mods/pvp/shooter/textures/shooter_bullet.png
  43. BIN
      mods/pvp/shooter/textures/shooter_cap.png
  44. BIN
      mods/pvp/shooter/textures/shooter_crossbow.png
  45. BIN
      mods/pvp/shooter/textures/shooter_crossbow_loaded.png
  46. BIN
      mods/pvp/shooter/textures/shooter_flare.png
  47. BIN
      mods/pvp/shooter/textures/shooter_flare_inv.png
  48. BIN
      mods/pvp/shooter/textures/shooter_flare_light.png
  49. BIN
      mods/pvp/shooter/textures/shooter_flare_particle.png
  50. BIN
      mods/pvp/shooter/textures/shooter_flaregun.png
  51. BIN
      mods/pvp/shooter/textures/shooter_grenade.png
  52. BIN
      mods/pvp/shooter/textures/shooter_hand_grenade.png
  53. BIN
      mods/pvp/shooter/textures/shooter_hit.png
  54. BIN
      mods/pvp/shooter/textures/shooter_hook.png
  55. BIN
      mods/pvp/shooter/textures/shooter_hook_gun.png
  56. BIN
      mods/pvp/shooter/textures/shooter_hook_gun_loaded.png
  57. BIN
      mods/pvp/shooter/textures/shooter_pistol.png
  58. BIN
      mods/pvp/shooter/textures/shooter_rifle.png
  59. BIN
      mods/pvp/shooter/textures/shooter_rocket_gun.png
  60. BIN
      mods/pvp/shooter/textures/shooter_rocket_gun_loaded.png
  61. BIN
      mods/pvp/shooter/textures/shooter_rocket_inv.png
  62. BIN
      mods/pvp/shooter/textures/shooter_shotgun.png
  63. BIN
      mods/pvp/shooter/textures/shooter_smgun.png
  64. BIN
      mods/pvp/shooter/textures/shooter_turret_base.png
  65. BIN
      mods/pvp/shooter/textures/shooter_turret_gun.png
  66. BIN
      mods/pvp/shooter/textures/shooter_turret_uv.png
  67. BIN
      mods/pvp/shooter/textures/tnt_smoke.png
  68. BIN
      mods/pvp/shooter/textures/wool_black.png
  69. BIN
      mods/pvp/shooter/textures/wool_blue.png
  70. BIN
      mods/pvp/shooter/textures/wool_brown.png
  71. BIN
      mods/pvp/shooter/textures/wool_cyan.png
  72. BIN
      mods/pvp/shooter/textures/wool_dark_green.png
  73. BIN
      mods/pvp/shooter/textures/wool_dark_grey.png
  74. BIN
      mods/pvp/shooter/textures/wool_green.png
  75. BIN
      mods/pvp/shooter/textures/wool_grey.png
  76. BIN
      mods/pvp/shooter/textures/wool_magenta.png
  77. BIN
      mods/pvp/shooter/textures/wool_orange.png
  78. BIN
      mods/pvp/shooter/textures/wool_pink.png
  79. BIN
      mods/pvp/shooter/textures/wool_red.png
  80. BIN
      mods/pvp/shooter/textures/wool_violet.png
  81. BIN
      mods/pvp/shooter/textures/wool_white.png
  82. BIN
      mods/pvp/shooter/textures/wool_yellow.png
  83. 265
      mods/pvp/shooter/turret.lua
  84. 135
      mods/pvp/shooter_tweaks/init.lua
  85. 2
      mods/pvp/shooter_tweaks/mod.conf

3
.gitmodules vendored

@ -4,3 +4,6 @@
[submodule "mods/ctf/ctf_map/ctf_map_core/maps"]
path = mods/ctf/ctf_map/ctf_map_core/maps
url = https://github.com/MT-CTF/maps
[submodule "mods/pvp/shooter"]
path = mods/pvp/shooter
url = https://github.com/MT-CTF/shooter

@ -30,6 +30,10 @@ read_globals = {
"prometheus", "hb",
"awards",
"VoxelArea",
"VoxelManip",
"PseudoRandom",
-- Testing
"describe",

@ -17,16 +17,28 @@ function ctf_classes.register(cname, def)
if not def.properties.item_blacklist then
def.properties.item_blacklist = {}
for i=1, #def.properties.initial_stuff do
table.insert(def.properties.item_blacklist, def.properties.initial_stuff[i])
def.properties.item_blacklist[i] =
ItemStack(def.properties.initial_stuff[i]):get_name()
end
end
if def.properties.additional_item_blacklist then
for i=1, #def.properties.additional_item_blacklist do
table.insert(def.properties.item_blacklist, def.properties.additional_item_blacklist[i])
table.insert(def.properties.item_blacklist,
def.properties.additional_item_blacklist[i])
end
end
-- Validate items
for i=1, #def.properties.initial_stuff do
local item_name = ItemStack(def.properties.initial_stuff[i]):get_name()
assert(minetest.registered_items[item_name], "Item " .. item_name .. " not found")
end
for i=1, #def.properties.item_blacklist do
local item_name = def.properties.item_blacklist[i]
assert(minetest.registered_items[item_name], "Item " .. item_name .. " not found")
end
def.properties.speed = def.properties.speed or 1
def.properties.max_hp = def.properties.max_hp or 20
end

@ -14,9 +14,9 @@ ctf_classes.register("knight", {
},
allowed_guns = {
"shooter:pistol",
"shooter:smg",
"shooter:shotgun",
"shooter_guns:pistol",
"shooter_guns:smg",
"shooter_guns:shotgun",
},
},
})
@ -30,25 +30,28 @@ ctf_classes.register("shooter", {
allow_grapples = true,
initial_stuff = {
"shooter:rifle",
"shooter:grapple_gun_loaded",
"shooter_guns:rifle_loaded",
"shooter_hook:grapple_gun_loaded",
},
additional_item_blacklist = {
"shooter:grapple_gun",
"shooter:grapple_hook",
"shooter_hook:grapple_gun",
"shooter_hook:grapple_hook",
"shooter_guns:rifle",
},
allowed_guns = {
"shooter:pistol",
"shooter:rifle",
"shooter:smg",
"shooter:shotgun",
"shooter_guns:pistol",
"shooter_guns:rifle",
"shooter_guns:smg",
"shooter_guns:shotgun",
},
shooter_multipliers = {
range = 1.5,
full_punch_interval = 0.8,
tool_caps = {
full_punch_interval = 0.8,
},
},
},
})
@ -66,9 +69,9 @@ ctf_classes.register("medic", {
},
allowed_guns = {
"shooter:pistol",
"shooter:smg",
"shooter:shotgun",
"shooter_guns:pistol",
"shooter_guns:smg",
"shooter_guns:shotgun",
},
},
})
@ -80,18 +83,18 @@ ctf_classes.register("rocketeer", {
color = "#fa0",
properties = {
initial_stuff = {
"shooter:rocket_gun_loaded",
"shooter:rocket 4",
"shooter_rocket:rocket_gun_loaded",
"shooter_rocket:rocket 4",
},
additional_item_blacklist = {
"shooter:rocket_gun",
"shooter_rocket:rocket_gun",
},
allowed_guns = {
"shooter:pistol",
"shooter:smg",
"shooter:shotgun",
"shooter_guns:pistol",
"shooter_guns:smg",
"shooter_guns:shotgun",
},
},
})

@ -9,30 +9,46 @@ end
-- Returns true if the item shouldn't be allowed to be dropped etc
local function is_class_blacklisted(player, itemname)
local class = ctf_classes.get(player)
local items = stack_list_to_map(class.properties.item_blacklist or {})
local items = stack_list_to_map(class.properties.item_blacklist)
return items[itemname]
end
give_initial_stuff.register_stuff_provider(function(player)
local class = ctf_classes.get(player)
return class.properties.initial_stuff or {}
return class.properties.initial_stuff
end, 1)
local function remove_blacklist_in_list(list, blacklist_map)
local removed = false
for i=1, #list do
if blacklist_map[ItemStack(list[i]):get_name()] then
list[i] = ""
removed = true
end
end
return removed
end
ctf_classes.register_on_changed(function(player, old, new)
local inv = player:get_inventory()
if old then
local items = old.properties.item_blacklist or {}
for i = 1, #items do
inv:remove_item("main", ItemStack(items[i]))
local blacklist = old.properties.item_blacklist
if old and #blacklist > 0 then
local blacklist_map = stack_list_to_map(blacklist)
for listname, list in pairs(inv:get_lists()) do
if remove_blacklist_in_list(list, blacklist_map) then
inv:set_list(listname, list)
end
end
end
do
assert(new)
local items = new.properties.initial_stuff or {}
local items = new.properties.initial_stuff
for i = 1, #items do
inv:add_item("main", ItemStack(items[i]))
end

@ -1,3 +1,3 @@
name = ctf_classes
depends = ctf, ctf_flag, ctf_colors, ctf_map_core, physics, shooter, hpregen, give_initial_stuff, dropondie
depends = ctf, ctf_flag, ctf_colors, ctf_map_core, ctf_bandages, physics, shooter, hpregen, give_initial_stuff, dropondie
description = Adds classes, including knight, shooter, and medic

@ -1,30 +1,30 @@
local specs_cache = {}
local function recursive_multiply(source, multiplier)
for key, value in pairs(multiplier) do
assert(type(source[key]) == type(value))
if type(value) == "table" then
recursive_multiply(source[key], value)
else
source[key] = source[key] * value
end
end
end
local function get_shooter_specs(weapon_name, multiplier)
local spec = shooter.registered_weapons[weapon_name]
if not spec then
return nil
end
spec = spec.spec
-- this will convert the multipler to a table pointer
local idx = ("%s:%s"):format(multiplier or "nil", weapon_name)
if specs_cache[idx] then
return specs_cache[idx]
end
spec = table.copy(spec)
specs_cache[idx] = spec
spec = table.copy(spec.spec)
for key, value in pairs(multiplier) do
spec[key] = spec[key] * value
if multiplier then
recursive_multiply(spec, multiplier)
end
return spec
end
shooter.get_weapon_spec = function(_, user, weapon_name)
shooter.get_weapon_spec = function(user, weapon_name)
local class = ctf_classes.get(user)
if table.indexof(class.properties.allowed_guns or {}, weapon_name) == -1 then
@ -34,7 +34,9 @@ shooter.get_weapon_spec = function(_, user, weapon_name)
end
local spec = get_shooter_specs(weapon_name, class.properties.shooter_multipliers)
spec.name = user and user:get_player_name()
if not spec then
return nil
end
return spec
end
@ -64,6 +66,6 @@ local function check_grapple(itemname)
})
end
check_grapple("shooter:grapple_gun_loaded")
check_grapple("shooter:grapple_gun")
check_grapple("shooter:grapple_hook")
check_grapple("shooter_hook:grapple_gun_loaded")
check_grapple("shooter_hook:grapple_gun")
check_grapple("shooter_hook:grapple_hook")

@ -40,3 +40,11 @@ end
minetest.after(5, function()
ctf_match.next()
end)
ctf_match.register_on_build_time_start(function()
shooter.config.allow_players = false
end)
ctf_match.register_on_build_time_end(function()
shooter.config.allow_players = true
end)

@ -1,3 +1,3 @@
name = ctf_match
depends = ctf, ctf_flag, ctf_inventory, ctf_alloc, vote, hudkit
depends = ctf, ctf_flag, ctf_inventory, ctf_alloc, vote, hudkit, shooter
optional_depends = irc

@ -0,0 +1 @@
Subproject commit 5593df448fbb8a74478c54ad2e4e3755ffa51ce9

@ -1,8 +0,0 @@
## Generic ignorable patterns and files
*~
.*.swp
*bak*
tags
*.vim
shooter.conf
crosshair.png

@ -1,33 +0,0 @@
Minetest Mod - Simple Shooter [shooter]
=======================================
License Source Code: 2013 Stuart Jones - LGPL v2.1
Additional credit for code ideas taken from other mods.
PilzAdam [throwing] for the throwing physics
ShadowNinja [nuke] for the vm explosion routine
License Textures: Stuart Jones - WTFPL
Licence Models: Stuart Jones - CC-BY-SA 3.0
License Sounds: freesound.org
flobert1_20070728.wav by Nonoo - Attribution 3.0 Unported (CC BY 3.0)
shot.wav by Sergenious - Attribution 3.0 Unported (CC BY 3.0)
GUNSHOT.WAV by erkanozan - CC0 1.0 Universal (CC0 1.0)
winchester-rifle-cock-reload.wav by MentalSanityOff - CC0 1.0 Universal (CC0 1.0)
trigger-with-hammer-fall.wav by Nanashi - CC0 1.0 Universal (CC0 1.0)
woosh.wav by ReadeOnly - CC0 1.0 Universal (CC0 1.0)
AGM-114 Hellfire Rocket Missile Launch.flac by qubodup - CC0 1.0 Universal (CC0 1.0)
Sparkler.aif by Ned Bouhalassa - CC0 1.0 Universal (CC0 1.0)
tnt_explode.ogg by steveygos93, TumeniNodes - CC0 1.0 Universal (CC0 1.0)

@ -1,169 +0,0 @@
Minetest Mod - Simple Shooter [shooter]
=======================================
Mod Version: 0.5.3
Minetest Version: 0.4.9, 0.4.10, 0.4.11
Depends: default, dye, tnt, wool
An experimental first person shooter mod that uses simple vector mathematics
to produce an accurate and server-firendly method of hit detection.
By default this mod is configured to work only against other players in
multiplayer mode and against Simple Mobs [mobs] in singleplayer mode.
Default configuration can be customised by adding a shooter.conf file to
the mod's main directory, see shooter.conf.example for more details.
This is still very much a work in progress which I eventually plan to use
as the base for a 'Spades' style FPS game using the minetest engine.
Crafting
========
<color> = grey, black, red, yellow, green, cyan, blue, magenta
A = Arrow [shooter:arrow_white]
C = Color Dye [dye:<color>]
W = Wooden Stick [default:stick]
P = Paper [default:paper]
S = Steel Ingot [default:steel_ingot]
B = Bronze Ingot [default:bronze_ingot]
M = Mese Crystal [default:mese_crysytal]
D = Diamond [default:diamond]
R = Red Wool [wool:red]
G = Gun Powder [tnt:gunpowder]
Crossbow: [shooter:crossbow]
+---+---+---+
| W | W | W |
+---+---+---+
| W | W | |
+---+---+---+
| W | | B |
+---+---+---+
White Arrow: [shooter:arrow_white]
+---+---+---+
| S | | |
+---+---+---+
| | W | P |
+---+---+---+
| | P | W |
+---+---+---+
Coloured Arrow: [shooter:arrow_<color>]
+---+---+
| C | A |
+---+---+
Pistol: [shooter:pistol]
+---+---+
| S | S |
+---+---+
| | M |
+---+---+
Rifle: [shooter:rifle]
+---+---+---+
| S | | |
+---+---+---+
| | B | |
+---+---+---+
| | M | B |
+---+---+---+
Shotgun: [shooter:shotgun]
+---+---+---+
| S | | |
+---+---+---+
| | S | |
+---+---+---+
| | M | B |
+---+---+---+
Sub Machine Gun: [shooter:machine_gun]
+---+---+---+
| S | S | S |
+---+---+---+
| | B | M |
+---+---+---+
| | B | |
+---+---+---+
Ammo Pack: [shooter:ammo]
+---+---+
| G | B |
+---+---+
Grappling Hook: [shooter:grapple_hook]
+---+---+---+
| S | S | D |
+---+---+---+
| S | S | |
+---+---+---+
| D | | S |
+---+---+---+
Grappling Hook Gun: [shooter:grapple_gun]
+---+---+
| S | S |
+---+---+
| | D |
+---+---+
Flare: [shooter:flare]
+---+---+
| G | R |
+---+---+
Flare Gun: [shooter:flaregun]
+---+---+---+
| R | R | R |
+---+---+---+
| | | S |
+---+---+---+
Grenade: [shooter:grenade]
+---+---+
| G | S |
+---+---+
Flare Gun: [shooter:rocket_gun]
+---+---+---+
| B | S | S |
+---+---+---+
| | | D |
+---+---+---+
Rocket: [shooter:rocket]
+---+---+---+
| B | G | B |
+---+---+---+
Turret: [shooter:turret]
+---+---+---+
| B | B | S |
+---+---+---+
| | B | S |
+---+---+---+
| | D | |
+---+---+---+

@ -1,293 +0,0 @@
SHOOTER_CROSSBOW_USES = 50
SHOOTER_ARROW_TOOL_CAPS = {damage_groups={fleshy=2}}
SHOOTER_ARROW_LIFETIME = 180 -- 3 minutes
minetest.register_alias("shooter:arrow", "shooter:arrow_white")
minetest.register_alias("shooter:crossbow_loaded", "shooter:crossbow_loaded_white")
local dye_basecolors = (dye and dye.basecolors) or
{"white", "grey", "black", "red", "yellow", "green", "cyan", "blue", "magenta"}
local function get_animation_frame(dir)
local angle = math.atan(dir.y)
local frame = 90 - math.floor(angle * 360 / math.pi)
if frame < 1 then
frame = 1
elseif frame > 180 then
frame = 180
end
return frame
end
local function get_target_pos(p1, p2, dir, offset)
local d = vector.distance(p1, p2) - offset
local td = vector.multiply(dir, {x=d, y=d, z=d})
return vector.add(p1, td)
end
-- name is the overlay texture name, colour is used to select the wool texture
local function get_texture(name, colour)
return "shooter_"..name..".png^wool_"..colour..".png^shooter_"..name..".png^[makealpha:255,126,126"
end
minetest.register_entity("shooter:arrow_entity", {
physical = false,
collide_with_objects = false,
visual = "mesh",
mesh = "shooter_arrow.b3d",
visual_size = {x=1, y=1},
textures = {
get_texture("arrow_uv", "white"),
},
color = "white",
timer = 0,
lifetime = SHOOTER_ARROW_LIFETIME,
player = nil,
state = "init",
node_pos = nil,
collisionbox = {0,0,0, 0,0,0},
stop = function(self, pos)
local acceleration = {x=0, y=-10, z=0}
if self.state == "stuck" then
pos = pos or self.object:get_pos()
acceleration = {x=0, y=0, z=0}
end
if pos then
self.object:move_to(pos)
end
self.object:set_properties({
physical = true,
collisionbox = {-1/8, -1/8, -1/8, 1/8, 1/8, 1/8},
})
self.object:set_velocity({x=0, y=0, z=0})
self.object:set_acceleration(acceleration)
end,
strike = function(self, object)
local puncher = self.player
if puncher and shooter:is_valid_object(object) then
if puncher ~= object then
local dir = puncher:get_look_dir()
local p1 = puncher:get_pos()
local p2 = object:get_pos()
local tpos = get_target_pos(p1, p2, dir, 0)
shooter:spawn_particles(tpos, SHOOTER_EXPLOSION_TEXTURE)
object:punch(puncher, nil, SHOOTER_ARROW_TOOL_CAPS, dir)
end
end
self:stop(object:get_pos())
end,
on_activate = function(self, staticdata)
self.object:set_armor_groups({immortal=1})
if staticdata == "expired" then
self.object:remove()
end
end,
on_punch = function(self, puncher)
if puncher then
if puncher:is_player() then
local stack = "shooter:arrow_"..self.color
local inv = puncher:get_inventory()
if inv:room_for_item("main", stack) then
inv:add_item("main", stack)
self.object:remove()
end
end
end
end,
on_step = function(self, dtime)
if self.state == "init" then
return
end
self.timer = self.timer + dtime
self.lifetime = self.lifetime - dtime
if self.lifetime < 0 then
self.object:remove()
return
elseif self.state == "dropped" then
return
elseif self.state == "stuck" then
if self.timer > 1 then
if self.node_pos then
local node = minetest.get_node(self.node_pos)
if node.name then
local item = minetest.registered_items[node.name]
if item then
if not item.walkable then
self.state = "dropped"
self:stop()
return
end
end
end
end
self.timer = 0
end
return
end
if self.timer > 0.2 then
local pos = self.object:getpos()
local dir = vector.normalize(self.object:getvelocity())
local frame = get_animation_frame(dir)
self.object:set_animation({x=frame, y=frame}, 0)
local objects = minetest.get_objects_inside_radius(pos, 5)
for _, obj in ipairs(objects) do
if shooter:is_valid_object(obj) and obj ~= self.player then
local collisionbox = {-0.25,-1.0,-0.25, 0.25,0.8,0.25}
local offset = SHOOTER_PLAYER_OFFSET
if not obj:is_player() then
offset = SHOOTER_ENTITY_OFFSET
local ent = obj:get_luaentity()
if ent then
local def = minetest.registered_entities[ent.name]
collisionbox = def.collisionbox or collisionbox
end
end
local opos = vector.add(obj:get_pos(), offset)
local ray = {pos=pos, dir=dir}
local plane = {pos=opos, normal={x=-1, y=0, z=-1}}
local ipos = shooter:get_intersect_pos(ray, plane, collisionbox)
if ipos then
self:strike(obj)
end
end
end
local p = vector.add(pos, vector.multiply(dir, {x=5, y=5, z=5}))
local _, npos = minetest.line_of_sight(pos, p, 1)
if npos then
local node = minetest.get_node(npos)
local tpos = get_target_pos(pos, npos, dir, 0.66)
self.node_pos = npos
self.state = "stuck"
self:stop(tpos)
shooter:play_node_sound(node, npos)
end
self.timer = 0
end
end,
get_staticdata = function(self)
return "expired"
end,
})
for _, color in pairs(dye_basecolors) do
minetest.register_craftitem("shooter:arrow_"..color, {
description = color:gsub("%a", string.upper, 1).." Arrow",
inventory_image = get_texture("arrow_inv", color),
})
minetest.register_tool("shooter:crossbow_loaded_"..color, {
description = "Crossbow",
inventory_image = get_texture("crossbow_loaded", color),
groups = {not_in_creative_inventory=1},
on_use = function(itemstack, user, pointed_thing)
minetest.sound_play("shooter_click", {object=user})
if not minetest.settings:get_bool("creative_mode") then
itemstack:add_wear(65535/SHOOTER_CROSSBOW_USES)
end
itemstack = "shooter:crossbow 1 "..itemstack:get_wear()
local pos = user:get_pos()
local dir = user:get_look_dir()
local yaw = user:get_look_horizontal()
if pos and dir and yaw then
pos.y = pos.y + 1.5
local obj = minetest.add_entity(pos, "shooter:arrow_entity")
local ent = nil
if obj then
ent = obj:get_luaentity()
end
if ent then
ent.player = ent.player or user
ent.state = "flight"
ent.color = color
obj:set_properties({
textures = {get_texture("arrow_uv", color)}
})
minetest.sound_play("shooter_throw", {object=obj})
local frame = get_animation_frame(dir)
obj:set_yaw(yaw + math.pi)
obj:set_animation({x=frame, y=frame}, 0)
obj:set_velocity({x=dir.x * 14, y=dir.y * 14, z=dir.z * 14})
if pointed_thing.type ~= "nothing" then
local ppos = minetest.get_pointed_thing_position(pointed_thing, false)
local _, npos = minetest.line_of_sight(pos, ppos, 1)
if npos then
ppos = npos
pointed_thing.type = "node"
end
if pointed_thing.type == "object" then
ent:strike(pointed_thing.ref)
return itemstack
elseif pointed_thing.type == "node" then
local node = minetest.get_node(ppos)
local tpos = get_target_pos(pos, ppos, dir, 0.66)
minetest.after(0.2, function(object, pos, npos)
ent.node_pos = npos
ent.state = "stuck"
ent:stop(pos)
shooter:play_node_sound(node, npos)
end, obj, tpos, ppos)
return itemstack
end
end
obj:set_acceleration({x=dir.x * -3, y=-5, z=dir.z * -3})
end
end
return itemstack
end,
})
end
minetest.register_tool("shooter:crossbow", {
description = "Crossbow",
inventory_image = "shooter_crossbow.png",
on_use = function(itemstack, user, pointed_thing)
local inv = user:get_inventory()
local stack = inv:get_stack("main", user:get_wield_index() + 1)
local color = string.match(stack:get_name(), "shooter:arrow_(%a+)")
if color then
minetest.sound_play("shooter_reload", {object=user})
if not minetest.settings:get_bool("creative_mode") then
inv:remove_item("main", "shooter:arrow_"..color.." 1")
end
return "shooter:crossbow_loaded_"..color.." 1 "..itemstack:get_wear()
end
for _, color in pairs(dye_basecolors) do
if inv:contains_item("main", "shooter:arrow_"..color) then
minetest.sound_play("shooter_reload", {object=user})
if not minetest.settings:get_bool("creative_mode") then
inv:remove_item("main", "shooter:arrow_"..color.." 1")
end
return "shooter:crossbow_loaded_"..color.." 1 "..itemstack:get_wear()
end
end
minetest.sound_play("shooter_click", {object=user})
end,
})
if SHOOTER_ENABLE_CRAFTING == true then
minetest.register_craft({
output = "shooter:crossbow",
recipe = {
{"default:stick", "default:stick", "default:stick"},
{"default:stick", "default:stick", ""},
{"default:stick", "", "default:bronze_ingot"},
},
})
minetest.register_craft({
output = "shooter:arrow_white",
recipe = {
{"default:steel_ingot", "", ""},
{"", "default:stick", "default:paper"},
{"", "default:paper", "default:stick"},
},
})
for _, color in pairs(dye_basecolors) do
if color ~= "white" then
minetest.register_craft({
output = "shooter:arrow_"..color,
recipe = {
{"", "dye:" .. color, "shooter:arrow_white"},
},
})
end
end
end

@ -1,146 +0,0 @@
minetest.register_craftitem("shooter:flare", {
description = "Flare",
inventory_image = "shooter_flare_inv.png",
})
minetest.register_node("shooter:flare_light", {
drawtype = "glasslike",
tiles = {"shooter_flare_light.png"},
paramtype = "light",
groups = {not_in_creative_inventory=1},
drop = "",
walkable = false,
buildable_to = true,
sunlight_propagates = true,
light_source = LIGHT_MAX,
pointable = false,
})
minetest.register_abm({
nodenames = "shooter:flare_light",
interval = 5,
chance = 1,
action = function(pos, node)
local time = os.time()
local meta = minetest.get_meta(pos)
local init_time = meta:get_int("init_time") or 0
if time > init_time + 30 then
local id = meta:get_int("particle_id")
if id then
minetest.delete_particlespawner(id)
end
minetest.remove_node(pos)
end
end,
})
minetest.register_entity("shooter:flare_entity", {
physical = true,
timer = 0,
visual = "cube",
visual_size = {x=1/8, y=1/8},
textures = {
"shooter_flare.png",
"shooter_flare.png",
"shooter_flare.png",
"shooter_flare.png",
"shooter_flare.png",
"shooter_flare.png",
},
player = nil,
collisionbox = {-1/16,-1/16,-1/16, 1/16,1/16,1/16},
on_activate = function(self, staticdata)
if staticdata == "expired" then
self.object:remove()
end
end,
on_step = function(self, dtime)
self.timer = self.timer + dtime
if self.timer > 0.2 then
local pos = self.object:getpos()
local below = {x=pos.x, y=pos.y - 1, z=pos.z}
local node = minetest.get_node(below)
if node.name ~= "air" then
self.object:setvelocity({x=0, y=-10, z=0})
self.object:setacceleration({x=0, y=0, z=0})
if minetest.get_node(pos).name == "air" and
node.name ~= "default:water_source" and
node.name ~= "default:water_flowing" then
minetest.place_node(pos, {name="shooter:flare_light"})
local meta = minetest.get_meta(pos)
meta:set_int("particle_id", id)
meta:set_int("init_time", os.time())
pos.y = pos.y - 0.1
local id = minetest.add_particlespawner(
1000, 30, pos, pos,
{x=-1, y=1, z=-1}, {x=1, y=1, z=1},
{x=2, y=-2, z=-2}, {x=2, y=-2, z=2},
0.1, 0.75, 1, 8, false, "shooter_flare_particle.png"
)
local sound = minetest.sound_play("shooter_flare_burn", {
object = self.player,
loop = true,
})
minetest.after(30, function(sound)
minetest.sound_stop(sound)
end, sound)
end
self.object:remove()
end
self.timer = 0
end
end,
get_staticdata = function(self)
return "expired"
end,
})
minetest.register_tool("shooter:flaregun", {
description = "Flare Gun",
inventory_image = "shooter_flaregun.png",
on_use = function(itemstack, user, pointed_thing)
local inv = user:get_inventory()
if not inv:contains_item("main", "shooter:flare") then
minetest.sound_play("shooter_click", {object=user})
return itemstack
end
if not minetest.settings:get_bool("creative_mode") then
inv:remove_item("main", "shooter:flare 1")
itemstack:add_wear(65535/100)
end
local pos = user:getpos()
local dir = user:get_look_dir()
local yaw = user:get_look_yaw()
if pos and dir and yaw then
pos.y = pos.y + 1.5
local obj = minetest.add_entity(pos, "shooter:flare_entity")
if obj then
minetest.sound_play("shooter_flare_fire", {object=obj})
obj:setvelocity({x=dir.x * 16, y=dir.y * 16, z=dir.z * 16})
obj:setacceleration({x=dir.x * -3, y=-10, z=dir.z * -3})
obj:setyaw(yaw + math.pi)
local ent = obj:get_luaentity()
if ent then
ent.player = ent.player or user
end
end
end
return itemstack
end,
})
if SHOOTER_ENABLE_CRAFTING == true then
minetest.register_craft({
output = "shooter:flare",
recipe = {
{"tnt:gunpowder", "wool:red"},
},
})
minetest.register_craft({
output = "shooter:flaregun",
recipe = {
{"wool:red", "wool:red", "wool:red"},
{"", "", "default:steel_ingot"}
},
})
end

@ -1,136 +0,0 @@
local function throw_hook(itemstack, user, vel)
local inv = user:get_inventory()
local pos = user:getpos()
local dir = user:get_look_dir()
local yaw = user:get_look_yaw()
if pos and dir and yaw then
if not minetest.settings:get_bool("creative_mode") then
itemstack:add_wear(65535/100)
end
pos.y = pos.y + 1.5
local obj = minetest.add_entity(pos, "shooter:hook")
if obj then
minetest.sound_play("shooter_throw", {object=obj})
obj:setvelocity({x=dir.x * vel, y=dir.y * vel, z=dir.z * vel})
obj:setacceleration({x=dir.x * -3, y=-10, z=dir.z * -3})
obj:setyaw(yaw + math.pi)
local ent = obj:get_luaentity()
if ent then
ent.player = ent.player or user
ent.itemstack = itemstack
end
end
end
end
minetest.register_entity("shooter:hook", {
physical = true,
timer = 0,
visual = "wielditem",
visual_size = {x=1/2, y=1/2},
textures = {"shooter:grapple_hook"},
player = nil,
itemstack = "",
collisionbox = {-1/4,-1/4,-1/4, 1/4,1/4,1/4},
on_activate = function(self, staticdata)
self.object:set_armor_groups({fleshy=0})
if staticdata == "expired" then
self.object:remove()
end
end,
on_step = function(self, dtime)
if not self.player then
return
end
self.timer = self.timer + dtime
if self.timer > 0.25 then
local pos = self.object:getpos()
local below = {x=pos.x, y=pos.y - 1, z=pos.z}
local node = minetest.get_node(below)
if node.name ~= "air" then
self.object:setvelocity({x=0, y=-10, z=0})
self.object:setacceleration({x=0, y=0, z=0})
if minetest.get_item_group(node.name, "liquid") == 0 and
minetest.get_node(pos).name == "air" then
self.player:moveto(pos)
end
if minetest.get_item_group(node.name, "lava") == 0 then
minetest.add_item(pos, self.itemstack)
end
self.object:remove()
end
self.timer = 0
end
end,
get_staticdata = function(self)
return "expired"
end,
})
minetest.register_tool("shooter:grapple_hook", {
description = "Grappling Hook",
inventory_image = "shooter_hook.png",
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type ~= "nothing" then
return itemstack
end
itemstack:add_wear(65536 / 16)
throw_hook(itemstack, user, 14)
return ""
end,
})
minetest.register_tool("shooter:grapple_gun", {
description = "Grappling Gun",
inventory_image = "shooter_hook_gun.png",
on_use = function(itemstack, user, pointed_thing)
local ent = pointed_thing.ref and pointed_thing.ref:get_luaentity()
if ent and ent.name == "__builtin:item" then
return ent:on_punch(user)
end
local inv = user:get_inventory()
if inv:contains_item("main", "shooter:grapple_hook") then
minetest.sound_play("shooter_reload", {object=user})
local stack = inv:remove_item("main", "shooter:grapple_hook")
itemstack = ItemStack("shooter:grapple_gun_loaded 1 "..stack:get_wear())
else
minetest.sound_play("shooter_click", {object=user})
end
return itemstack
end,
})
minetest.register_tool("shooter:grapple_gun_loaded", {
description = "Grappling Gun",
inventory_image = "shooter_hook_gun_loaded.png",
groups = {not_in_creative_inventory=1},
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type ~= "nothing" then
return itemstack
end
minetest.sound_play("shooter_pistol", {object=user})
itemstack = ItemStack("shooter:grapple_hook 1 "..itemstack:get_wear())
itemstack:add_wear(65536 / 8)
throw_hook(itemstack, user, 20)
return "shooter:grapple_gun"
end,
})
if SHOOTER_ENABLE_CRAFTING == true then
minetest.register_craft({
output = "shooter:grapple_hook",
recipe = {
{"default:steel_ingot", "default:steel_ingot", "default:diamond"},
{"default:steel_ingot", "default:steel_ingot", ""},
{"default:diamond", "", "default:steel_ingot"},
},
})
minetest.register_craft({
output = "shooter:grapple_gun",
recipe = {
{"", "default:steel_ingot", "default:steel_ingot"},
{"", "", "default:diamond"},
},
})
end

@ -1,81 +0,0 @@
minetest.register_entity("shooter:grenade_entity", {
physical = false,
timer = 0,
visual = "cube",
visual_size = {x=1/8, y=1/8},
textures = {
"shooter_grenade.png",
"shooter_grenade.png",
"shooter_grenade.png",
"shooter_grenade.png",
"shooter_grenade.png",
"shooter_grenade.png",
},
player = nil,
player_name = nil,
collisionbox = {0,0,0, 0,0,0},
on_activate = function(self, staticdata)
if staticdata == "expired" then
self.object:remove()
end
end,
on_step = function(self, dtime)
self.timer = self.timer + dtime
if self.timer > 0.1 then
local pos = self.object:getpos()
local above = {x=pos.x, y=pos.y + 1, z=pos.z}
if minetest.get_node(pos).name ~= "air" then
self.object:remove()
shooter:blast(above, 2, 25, 5, self.player)
end
self.timer = 0
end
end,
get_staticdata = function(self)
return "expired"
end,
})
minetest.register_tool("shooter:grenade", {
description = "Grenade",
inventory_image = "shooter_hand_grenade.png",
on_use = function(itemstack, user, pointed_thing)
if not minetest.settings:get_bool("creative_mode") then
itemstack:take_item()
end
if pointed_thing.type ~= "nothing" then
local pointed = minetest.get_pointed_thing_position(pointed_thing)
if vector.distance(user:get_pos(), pointed) < 10 then
shooter:blast(pointed, 2, 25, 5)
return
end
end
local pos = user:get_pos()
local dir = user:get_look_dir()
local yaw = user:get_look_horizontal()
if pos and dir then
pos.y = pos.y + 1.5
local obj = minetest.add_entity(pos, "shooter:grenade_entity")
if obj then
obj:set_velocity({x = dir.x * 20, y = dir.y * 20, z = dir.z * 20})
obj:set_acceleration({x=dir.x * -3, y=-10, z=dir.z * -3})
obj:set_yaw(yaw + math.pi)
local ent = obj:get_luaentity()
if ent then
ent.player = ent.player or user
ent.player_name = user:get_player_name()
end
end
end
return itemstack
end,
})
if SHOOTER_ENABLE_CRAFTING == true then
minetest.register_craft({
output = "shooter:grenade",
recipe = {
{"tnt:gunpowder", "default:steel_ingot"},
},
})
end

@ -1,126 +0,0 @@
shooter:register_weapon("shooter:pistol", {
description = "Pistol",
inventory_image = "shooter_pistol.png",
rounds = 200,
spec = {
range = 100,
step = 20,
tool_caps = {full_punch_interval=0.5, damage_groups={fleshy=2}},
groups = {snappy=3, fleshy=3, oddly_breakable_by_hand=3},
sound = "shooter_pistol",
particle = "shooter_cap.png",
},
})
shooter:register_weapon("shooter:rifle", {
description = "Rifle",
inventory_image = "shooter_rifle.png",
rounds = 100,
spec = {
range = 200,
step = 30,
tool_caps = {full_punch_interval=1.0, damage_groups={fleshy=3}},
groups = {snappy=3, crumbly=3, choppy=3, fleshy=2, oddly_breakable_by_hand=2},
sound = "shooter_rifle",
particle = "shooter_bullet.png",
},
})
shooter:register_weapon("shooter:shotgun", {
description = "Shotgun",
inventory_image = "shooter_shotgun.png",
rounds = 50,
spec = {
range = 50,
step = 15,
tool_caps = {full_punch_interval=1.5, damage_groups={fleshy=6}},
groups = {cracky=3, snappy=2, crumbly=2, choppy=2, fleshy=1, oddly_breakable_by_hand=1},
sound = "shooter_shotgun",
particle = "smoke_puff.png",
},
})
shooter:register_weapon("shooter:machine_gun", {
description = "Sub Machine Gun",
inventory_image = "shooter_smgun.png",
rounds = 50,
shots = 4,
spec = {
range = 100,
step = 20,
tool_caps = {full_punch_interval=0.125, damage_groups={fleshy=2}},
groups = {snappy=3, fleshy=3, oddly_breakable_by_hand=3},
sound = "shooter_pistol",
particle = "shooter_cap.png",
},
})
minetest.register_craftitem("shooter:ammo", {
description = "Ammo pack",
inventory_image = "shooter_ammo.png",
})
if SHOOTER_ENABLE_CRAFTING == true then
minetest.register_craft({
output = "shooter:pistol 1 65535",
recipe = {
{"default:steel_ingot", "default:steel_ingot"},
{"", "default:mese_crystal"},
},
})
minetest.register_craft({
output = "shooter:rifle 1 65535",
recipe = {
{"default:steel_ingot", "", ""},
{"", "default:bronze_ingot", ""},
{"", "default:mese_crystal", "default:bronze_ingot"},
},
})
minetest.register_craft({
output = "shooter:shotgun 1 65535",
recipe = {
{"default:steel_ingot", "", ""},
{"", "default:steel_ingot", ""},
{"", "default:mese_crystal", "default:bronze_ingot"},
},
})
minetest.register_craft({
output = "shooter:machine_gun 1 65535",
recipe = {
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
{"", "default:bronze_ingot", "default:mese_crystal"},
{"", "default:bronze_ingot", ""},
},
})
minetest.register_craft({
output = "shooter:ammo",
recipe = {
{"tnt:gunpowder", "default:bronze_ingot"},
},
})
end
local rounds_update_time = 0
minetest.register_globalstep(function(dtime)
shooter.time = shooter.time + dtime
if shooter.time - rounds_update_time > SHOOTER_ROUNDS_UPDATE_TIME then
for i, round in ipairs(shooter.rounds) do
if shooter:process_round(round) or round.dist > round.def.range then
table.remove(shooter.rounds, i)
else
local v = vector.multiply(round.ray, round.def.step)
shooter.rounds[i].pos = vector.add(round.pos, v)
shooter.rounds[i].dist = round.dist + round.def.step
end
end
rounds_update_time = shooter.time
end
if shooter.time > 100000 then
shooter.shots = {}
rounds_update_time = 0
shooter.reload_time = 0
shooter.update_time = 0
shooter.time = 0
end
end)

@ -1,26 +0,0 @@
local modpath = minetest.get_modpath(minetest.get_current_modname())
dofile(modpath.."/shooter.lua")
if SHOOTER_ENABLE_CROSSBOW == true then
dofile(modpath.."/crossbow.lua")
end
if SHOOTER_ENABLE_GUNS == true then
dofile(modpath.."/guns.lua")
end
if SHOOTER_ENABLE_FLARES == true then
dofile(modpath.."/flaregun.lua")
end
if SHOOTER_ENABLE_HOOK == true then
dofile(modpath.."/grapple.lua")
end
if SHOOTER_ENABLE_GRENADES == true then
dofile(modpath.."/grenade.lua")
end
if SHOOTER_ENABLE_ROCKETS == true then
dofile(modpath.."/rocket.lua")
end
if SHOOTER_ENABLE_TURRETS == true then
dofile(modpath.."/turret.lua")
end

@ -1,3 +0,0 @@
name = shooter
depends = default
description = First person shooter mod. Adds firearms plus a few other fun items.