From 29c0daca0b4d95acebbb09b30be350f28bba9859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ki=C3=ABd=20Llaentenn?= Date: Mon, 29 May 2023 23:44:29 -0400 Subject: [PATCH] Add railgun cannons (#16) * feat: add purple and blue cannons (railguns) * fix: linter warnings * fix: last commit Seems I forgot to save some changes that were supposed to be part of the last commit. * feat: don't change cannon projectile range Avoid breaking builds on other servers --- ammo.lua | 13 ++++ cannon.lua | 97 +++++++++++++++++++++---- init.lua | 7 +- mod.conf | 5 +- textures/cannon_front_purple.png | Bin 0 -> 209 bytes textures/energycube_purple.png | Bin 0 -> 99 bytes textures/spacecannon_railgun_slug.png | Bin 0 -> 159 bytes util.lua | 98 +++++++++++++++++++------- 8 files changed, 178 insertions(+), 42 deletions(-) create mode 100644 ammo.lua create mode 100755 textures/cannon_front_purple.png create mode 100755 textures/energycube_purple.png create mode 100755 textures/spacecannon_railgun_slug.png diff --git a/ammo.lua b/ammo.lua new file mode 100644 index 0000000..95e54c3 --- /dev/null +++ b/ammo.lua @@ -0,0 +1,13 @@ +minetest.register_craftitem("spacecannon:railgun_slug", { + description = "Railgun slug", + inventory_image = "spacecannon_railgun_slug.png", +}) + +minetest.register_craft({ + output = "spacecannon:railgun_slug 2", + recipe = { + { "", "technic:uranium0_ingot", ""}, + {"basic_materials:carbon_steel_bar", "technic:stainless_steel_ingot", "basic_materials:carbon_steel_bar"}, + { "technic:stainless_steel_ingot", "technic:stainless_steel_ingot", "technic:stainless_steel_ingot"} + }, +}) diff --git a/cannon.lua b/cannon.lua index acf514c..492e084 100644 --- a/cannon.lua +++ b/cannon.lua @@ -1,3 +1,4 @@ +-- vi: noexpandtab local cable_entry = "^technic_cable_connection_overlay.png" @@ -23,6 +24,7 @@ local register_spacecannon = function(def) timer = 0, lifetime = 0, static_save = false, + penetrated = 0, on_step = function(self, dtime) self.timer = self.timer + dtime @@ -65,25 +67,33 @@ local register_spacecannon = function(def) local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 1) local collided = false for _, obj in pairs(objs) do - if obj:get_luaentity() ~= nil and obj:get_luaentity().name ~= self.name then + if obj:get_luaentity() ~= nil + and obj:get_luaentity().name ~= self.name + and obj:get_luaentity().name ~= "__builtin:item" + then collided = true obj:punch(self.object, 1.0, { full_punch_interval=1.0, - damage_groups={fleshy=def.range*2}, + damage_groups={fleshy=def.damage}, }, nil) end end if collided then spacecannon.destroy(pos, def.range, def.intensity) - self.object:remove() + self.penetrated = self.penetrated + 1 + if self.penetrated >= def.penetration then + self.object:remove() + end end else -- collision spacecannon.destroy(pos, def.range, def.intensity) - self.object:remove() - + self.penetrated = self.penetrated + 1 + if self.penetrated >= def.penetration then + self.object:remove() + end end end }) @@ -112,7 +122,7 @@ local register_spacecannon = function(def) action_on = function (pos) local meta = minetest.get_meta(pos) local owner = meta:get_string("owner") - spacecannon.fire(pos, owner, def.color, def.speed, def.range) + spacecannon.fire(pos, owner, def.color, def.speed, def.is_th, def.storage_require_mod) end }}, @@ -145,7 +155,13 @@ local register_spacecannon = function(def) -- Set default digiline channel (do before updating formspec). meta:set_string("channel", "spacecannon") - spacecannon.update_formspec(meta) + -- Set inventory (not used for thermal cannons) + if not def.is_th then + local inv = meta:get_inventory() + inv:set_size("src", 1) + end + + spacecannon.update_formspec(meta, def.is_th) end, technic_run = function(pos) @@ -154,13 +170,17 @@ local register_spacecannon = function(def) local demand = meta:get_int("HV_EU_demand") local store = meta:get_int("powerstorage") + local config_store = spacecannon.config.ki_powerstorage * def.storage_require_mod + if def.is_th then config_store = spacecannon.config.th_powerstorage * def.storage_require_mod end + local config_require = spacecannon.config.ki_powerrequirement + if def.is_th then config_require = spacecannon.config.th_powerrequirement end + meta:set_string("infotext", "Power: " .. eu_input .. "/" .. demand .. " Store: " .. store) - if store < spacecannon.config.powerstorage * def.range then + if store < config_store then -- charge - meta:set_int("HV_EU_demand", spacecannon.config.powerrequirement) - store = store + eu_input - meta:set_int("powerstorage", store) + meta:set_int("HV_EU_demand", config_require) + meta:set_int("powerstorage", store + eu_input) else -- charged meta:set_int("HV_EU_demand", 0) @@ -177,16 +197,21 @@ local register_spacecannon = function(def) local meta = minetest.get_meta(pos) if fields.fire then - spacecannon.fire(pos, playername, def.color, def.speed, def.range) + spacecannon.fire(pos, playername, def.color, def.speed, def.is_th, def.storage_require_mod) end if fields.set_digiline_channel and fields.digiline_channel then meta:set_string("channel", fields.digiline_channel) end - spacecannon.update_formspec(meta) - end + spacecannon.update_formspec(meta, def.is_th) + end, + after_dig_node = function(pos, _node, meta, _digger) + if meta.inventory and meta.inventory.src and meta.inventory.src[1] then + minetest.add_item(pos, ItemStack(meta.inventory.src[1])) + end + end }) technic.register_machine("HV", "spacecannon:cannon_" .. def.color, technic.receiver) @@ -205,31 +230,75 @@ local register_spacecannon = function(def) end register_spacecannon({ + is_th = true, color = "green", range = 1, + storage_require_mod = 1, + damage = 2, intensity = 1, timeout = 8, speed = 10, + penetration = 0, desc = "fast,low damage", ingredient = "default:mese_block" }) register_spacecannon({ + is_th = true, color = "yellow", range = 3, + storage_require_mod = 3, intensity = 2, + damage = 6, timeout = 8, speed = 5, + penetration = 0, desc = "medium speed, medium damage", ingredient = "spacecannon:cannon_green" }) register_spacecannon({ + is_th = true, color = "red", range = 5, + storage_require_mod = 5, intensity = 4, + damage = 10, timeout = 15, speed = 3, + penetration = 0, desc = "slow, heavy damage", ingredient = "spacecannon:cannon_yellow" }) + +-- Railguns + +-- Regular railgun +register_spacecannon({ + is_th = false, + color = "blue", + range = 0, + storage_require_mod = 1, + intensity = 2, + damage = 5, + timeout = 10, + speed = 9, + penetration = 2, + desc = "fast, 2x penetrating damage", + ingredient = "technic:copper_coil" +}) + +-- Helical railgun +register_spacecannon({ + is_th = false, + color = "purple", + range = 0, + storage_require_mod = 1.5, + intensity = 4, + damage = 10, + timeout = 15, + speed = 10, + penetration = 4, + desc = "fast, 4x penetrating damage", + ingredient = "spacecannon:cannon_blue" +}) diff --git a/init.lua b/init.lua index 0577546..6212f62 100644 --- a/init.lua +++ b/init.lua @@ -2,10 +2,12 @@ spacecannon = { config = { -- technic EU storage value - powerstorage = 10000, + th_powerstorage = 10000, + ki_powerstorage = 300, -- charge value in EU - powerrequirement = 2500 + th_powerrequirement = 2500, + ki_powerrequirement = 300 }, node_resilience = {} } @@ -15,6 +17,7 @@ local MP = minetest.get_modpath("spacecannon") dofile(MP.."/util.lua") dofile(MP.."/digiline.lua") dofile(MP.."/cannon.lua") +dofile(MP.."/ammo.lua") dofile(MP.."/node_resilience.lua") print("[OK] Spacecannon") diff --git a/mod.conf b/mod.conf index b6fa3ba..f9ee1cb 100644 --- a/mod.conf +++ b/mod.conf @@ -1,4 +1,7 @@ name = spacecannon -description = Adds three scifi/space cannons with various projectile-speed and explosion-strength +description = Adds five scifi/space cannons with various properties depends = default, technic optional_depends = mesecons, digilines +release = 6899 +author = BuckarooBanzay +title = Spacecannon diff --git a/textures/cannon_front_purple.png b/textures/cannon_front_purple.png new file mode 100755 index 0000000000000000000000000000000000000000..6af3e01140315bee2d9edfc6811102a7e3454809 GIT binary patch literal 209 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1SJ1Ryj={W7>k44ofy`glX(f`bbGouhIn)) zmlPBvq@|@PaR2%Hd-?(?F*Y`~=;-KAItmng)h7Q2DrE3<^>bP0l+XkKWsVyg literal 0 HcmV?d00001 diff --git a/textures/spacecannon_railgun_slug.png b/textures/spacecannon_railgun_slug.png new file mode 100755 index 0000000000000000000000000000000000000000..19302a5339c2a760bd8a0bd5c195685461ff5291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~{s5m4S0KG| z<;v{r?4Tf!j|U9dd_6jsHHH9 uG1Y9S0un-Jk`+_rgr(#)4jpOWXJ7~jWSFD<;KyR1Mg~t;KbLh*2~7a^wJhZT literal 0 HcmV?d00001 diff --git a/util.lua b/util.lua index 9797614..4fdc546 100644 --- a/util.lua +++ b/util.lua @@ -1,32 +1,58 @@ +-- vi: noexpandtab + local has_digilines = minetest.get_modpath("digilines") -spacecannon.update_formspec_digilines = function(meta) - local channel = meta:get_string("channel") or "" +spacecannon.update_formspec = function(meta, is_th) + local formspec = "" - local formspec = - "formspec_version[4]" .. - "size[6,4;]" .. + if not is_th then + formspec = formspec .. + "formspec_version[4]" .. + "size[10.5,9;]" - -- Digiline channel - "field[0.5,0.5;3.5,1;digiline_channel;Digiline Channel;" .. - channel .. "]" .. - "button_exit[4.5,0.5;1,1;set_digiline_channel;Set]" .. + -- Ammo inventory + formspec = formspec .. + "list[current_name;src;0.375,0.5;1,1;]" .. + "list[current_player;main;0.375,4;8,4;]" .. + "listring[]" .. + "label[1.75,1;Ammunition]" -- Manual "fire" button - "button_exit[0.5,2.5;5,1;fire;Fire]" + formspec = formspec .. + "button_exit[5.125,0.5;5,1;fire;Fire]" + + -- Digiline channel + if has_digilines then + local channel = meta:get_string("channel") or "" + formspec = formspec .. + "field[0.375,2.375;4,1;digiline_channel;Digiline Channel;" .. channel .. "]" .. + "button_exit[4.5,2.375;1,1;set_digiline_channel;Set]" + end + else + formspec = formspec .. "formspec_version[4]" + + if has_digilines then + formspec = formspec .. "size[6,4;]" + else + formspec = formspec .. "size[6,2;]" + end + + -- Manual "fire" button + formspec = formspec .. + "button_exit[0.5,0.5;5,1;fire;Fire]" + + -- Digiline channel + if has_digilines then + local channel = meta:get_string("channel") or "" + formspec = formspec .. + "field[0.5,2.5;3.5,1;digiline_channel;Digiline Channel;" .. channel .. "]" .. + "button_exit[4.5,2.5;1,1;set_digiline_channel;Set]" + end + end meta:set_string("formspec", formspec) end -spacecannon.update_formspec = function(meta) - if has_digilines then - spacecannon.update_formspec_digilines(meta) - else - meta:set_string("formspec", "size[8,2;]" .. - "button_exit[0,1;8,1;fire;Fire]") - end -end - spacecannon.can_shoot = function() -- arguments: pos, playername return true @@ -37,8 +63,7 @@ spacecannon.can_destroy = function() return true end -spacecannon.fire = function(pos, playername, color, speed, range) - +spacecannon.fire = function(pos, playername, color, speed, is_th, storage_require_mod) if not spacecannon.can_shoot(pos, playername) then return end @@ -46,13 +71,36 @@ spacecannon.fire = function(pos, playername, color, speed, range) -- check fuel/power local meta = minetest.get_meta(pos) - if meta:get_int("powerstorage") < spacecannon.config.powerstorage * range then + local config_store = spacecannon.config.ki_powerstorage * storage_require_mod + if is_th then config_store = spacecannon.config.th_powerstorage * storage_require_mod end + + if meta:get_int("powerstorage") < config_store then -- not enough power return + end - else - -- use power - meta:set_int("powerstorage", 0) + -- check ammunition + if not is_th then + local inv = meta:get_inventory() + if inv:is_empty("src") then + --minetest.chat_send_player(playername, "No ammunition loaded!") + return false + end + local src_stack = inv:get_list("src")[1] + if not src_stack or src_stack:get_name() ~= "spacecannon:railgun_slug" then + --minetest.chat_send_player(playername, "Incorrect ammunition!") + return + end + end + + -- use power + meta:set_int("powerstorage", 0) + + -- use ammo + if not is_th then + local src_stack = (meta:get_inventory()):get_list("src")[1] + src_stack:take_item(); + (meta:get_inventory()):set_stack("src", 1, src_stack) end minetest.sound_play("spacecannon_shoot", {