From 4610d0b10a08ff379e4f27e7783c48b9065e1453 Mon Sep 17 00:00:00 2001 From: OgelGames Date: Thu, 24 Feb 2022 22:58:02 +1100 Subject: [PATCH] first working version --- .github/workflows/luacheck.yml | 13 ++ .luacheckrc | 8 + init.lua | 206 +++++++++++++++++++++ mod.conf | 4 + textures/headlamp_headlamp_off.png | Bin 0 -> 160 bytes textures/headlamp_headlamp_off_preview.png | Bin 0 -> 143 bytes textures/headlamp_headlamp_on.png | Bin 0 -> 220 bytes textures/headlamp_headlamp_on_preview.png | Bin 0 -> 165 bytes textures/headlamp_inv_headlamp_off.png | Bin 0 -> 165 bytes textures/headlamp_inv_headlamp_on.png | Bin 0 -> 216 bytes 10 files changed, 231 insertions(+) create mode 100644 .github/workflows/luacheck.yml create mode 100644 .luacheckrc create mode 100644 init.lua create mode 100644 mod.conf create mode 100644 textures/headlamp_headlamp_off.png create mode 100644 textures/headlamp_headlamp_off_preview.png create mode 100644 textures/headlamp_headlamp_on.png create mode 100644 textures/headlamp_headlamp_on_preview.png create mode 100644 textures/headlamp_inv_headlamp_off.png create mode 100644 textures/headlamp_inv_headlamp_on.png diff --git a/.github/workflows/luacheck.yml b/.github/workflows/luacheck.yml new file mode 100644 index 0000000..a13efa9 --- /dev/null +++ b/.github/workflows/luacheck.yml @@ -0,0 +1,13 @@ +name: luacheck +on: [push, pull_request] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: apt + run: sudo apt-get install -y luarocks + - name: luacheck install + run: luarocks install --local luacheck + - name: luacheck run + run: $HOME/.luarocks/bin/luacheck ./ diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 0000000..e7b076b --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,8 @@ + +read_globals = { + "minetest", + + table = {fields = {"copy"}}, + + "armor", "technic", +} diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..ce532cf --- /dev/null +++ b/init.lua @@ -0,0 +1,206 @@ + +local has_technic = minetest.get_modpath("technic") + +local drain_inv = minetest.settings:get_bool("headlamp_check_inventory", false) +local battery_life = tonumber(minetest.settings:get("headlamp_battery_life")) or 1 +local battery_drain = math.floor(65535 / (battery_life * 60)) * 5 + +-- Helper function to make code neater +local function merge(t1, t2) + local t = table.copy(t1) + for k, v in pairs(t2) do + t[k] = v + end + return t +end + +-- Battery draining logic +-------------------------------------------------- + +local function use_battery(stack) + if stack:get_wear() >= (65535 - battery_drain) then + stack:set_name("headlamp:headlamp_off") + return false + end + stack:add_wear(battery_drain) + return true +end + +local function update_wielded(player) + local stack = player:get_wielded_item() + if stack:get_name() == "headlamp:headlamp_on" then + use_battery(stack) + player:set_wielded_item(stack) + end +end + +local function update_inventory(player) + local inv = player:get_inventory() + if not inv:contains_item("main", "headlamp:headlamp_on") then + return -- Skip checking every stack + end + for i=1, inv:get_size("main") do + local stack = inv:get_stack("main", i) + if stack:get_name() == "headlamp:headlamp_on" then + use_battery(stack) + inv:set_stack("main", i, stack) + end + end +end + +local function update_armor(player) + local name, inv = armor:get_valid_player(player) + if not name then + return -- Armor not initialized yet + end + if not inv:contains_item("armor", "headlamp:headlamp_on") then + return -- Skip checking every stack + end + for i=1, inv:get_size("armor") do + local stack = inv:get_stack("armor", i) + if stack:get_name() == "headlamp:headlamp_on" then + local success = use_battery(stack) + inv:set_stack("armor", i, stack) + armor:save_armor_inventory(player) + if not success then + armor:set_player_armor(player) + end + return -- There can only be one + end + end +end + +local timer = 0 + +minetest.register_globalstep(function(dtime) + timer = timer + dtime + if timer < 5 then return end -- Doesn't need a fast update, every 5 seconds is enough + timer = 0 + for _, player in pairs(minetest.get_connected_players()) do + if not minetest.is_creative_enabled(player:get_player_name()) then + update_armor(player) + if drain_inv then + update_inventory(player) + else + update_wielded(player) + end + end + end +end) + +-- Item registration +-------------------------------------------------- + +local base_def = { + groups = {armor_head = 1, armor_heal = 0, armor_use = 0}, + armor_groups = {fleshy = 2}, -- Headlamp is terrible armor, but it's better than nothing + on_secondary_use = function(stack, player) + return armor:equip(player, stack) + end, + on_place = function(stack, player, pointed) + if pointed.type == "node" and player and not player:get_player_control().sneak then + local node = minetest.get_node(pointed.under) + local ndef = minetest.registered_nodes[node.name] + if ndef and ndef.on_rightclick then + return ndef.on_rightclick(pointed.under, node, player, stack, pointed) + end + end + return armor:equip(player, stack) + end, +} + +if has_technic then + -- Battery values are now charge values instead of wear + battery_life = battery_life * 60 + battery_drain = 5 + -- Different code for different APIs + if technic.plus then + use_battery = function(stack) + local charge = technic.get_RE_charge(stack) + if charge <= battery_drain then + stack:set_name("headlamp:headlamp_off") + return false + end + technic.set_RE_charge(stack, charge - battery_drain) + return true + end + base_def.max_charge = battery_life + else + use_battery = function(stack) + local meta = stack:get_meta() + local metadata = minetest.deserialize(meta:get_string("")) or {} + if not metadata.charge or metadata.charge <= battery_drain then + stack:set_name("headlamp:headlamp_off") + return false + end + metadata.charge = metadata.charge - battery_drain + meta:set_string("", minetest.serialize(metadata)) + technic.set_RE_wear(stack, metadata.charge, battery_life) + return true + end + base_def.wear_represents = "technic_RE_charge" + base_def.on_refill = technic.refill_RE_charge + end +end + +local off_def = merge(base_def, { + description = "Headlamp (Off)", + inventory_image = "headlamp_inv_headlamp_off.png", + on_use = function(stack, player) + -- Turn headlamp on if there is enough battery left + if minetest.is_creative_enabled(player:get_player_name()) or use_battery(stack) then + stack:set_name("headlamp:headlamp_on") + end + return stack + end, +}) + +local on_def = merge(base_def, { + description = "Headlamp (On)", + inventory_image = "headlamp_inv_headlamp_on.png", + light_source = 14, + on_use = function(stack) + -- Turn headlamp off + stack:set_name("headlamp:headlamp_off") + return stack + end, +}) + +if has_technic and technic.plus then + technic.register_power_tool("headlamp:headlamp_off", off_def) + technic.register_power_tool("headlamp:headlamp_on", on_def) +else + minetest.register_tool("headlamp:headlamp_off", off_def) + minetest.register_tool("headlamp:headlamp_on", on_def) + if has_technic then + technic.register_power_tool("headlamp:headlamp_off", battery_life) + technic.register_power_tool("headlamp:headlamp_on", battery_life) + end +end + +-- Crafting recipe +-------------------------------------------------- + +if minetest.get_modpath("farming") then + if has_technic then + -- Somewhat realistic recipe + minetest.register_craft({ + output = "headlamp:headlamp_off", + recipe = { + {"farming:string", "technic:battery", "farming:string"}, + {"technic:rubber", "technic:lv_led", "technic:rubber"}, + {"farming:string", "technic:stainless_steel_ingot", "farming:string"}, + } + }) + elseif minetest.get_modpath("default") then + -- Magic mese powered headlamp + minetest.register_craft({ + output = "headlamp:headlamp_off", + recipe = { + {"farming:string", "farming:string", "farming:string"}, + {"farming:string", "default:mese_crystal", "farming:string"}, + {"farming:string", "default:steel_ingot", "farming:string"}, + } + }) + end +end diff --git a/mod.conf b/mod.conf new file mode 100644 index 0000000..6ad80aa --- /dev/null +++ b/mod.conf @@ -0,0 +1,4 @@ +name = headlamp +depends = illumination, 3d_armor +optional_depends = default, farming, technic +min_minetest_version = 5.3.0 diff --git a/textures/headlamp_headlamp_off.png b/textures/headlamp_headlamp_off.png new file mode 100644 index 0000000000000000000000000000000000000000..a39d4517421597342475b0e54484dd9702ba3faa GIT binary patch literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBH0VEjOzbQrlDW;MjzhDN2vdL#HfV@ag7srr_ zTW>G!7Hm)uaS04^`&KI^wMdoQU^zn(*9MQb2QC`csPCVh=2p16l3q>gTe~ HDWM4f_~|$y literal 0 HcmV?d00001 diff --git a/textures/headlamp_headlamp_off_preview.png b/textures/headlamp_headlamp_off_preview.png new file mode 100644 index 0000000000000000000000000000000000000000..9f24dd0c7057eb4481d3375b91aa37283982fc7c GIT binary patch literal 143 zcmeAS@N?(olHy`uVBq!ia0vp^3P9|@0VEjWo@x~VDW;MjzhDN2vdL#HfIJUR7srr_ zTgeFyOxf3TA`D8i($$&u8p0bFDCoa$V(oJX2v^t9QE=GBq^KAdH{oMxsjKUrJvB8; ov?W*i{tRC<#i`=yoX0;V zY}EA8mMvbpS9144E{@`G(Rw+Jd65r~SbXCRT5?y_HzD?=gTe~DWM4fjiW`m literal 0 HcmV?d00001 diff --git a/textures/headlamp_headlamp_on_preview.png b/textures/headlamp_headlamp_on_preview.png new file mode 100644 index 0000000000000000000000000000000000000000..634babc5842f122367bfb9089c9ee77c19bc6659 GIT binary patch literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^3P9|@!2~3~ym|B!NU@a!`2_=MAjn(BJ`qSodAc}; zRNQ)dVJ~Mx01v}ModrKO&ndQO*vovwx*^)K;}GkSOHL0tzfaVg(ClKfA@OLFB4mCCXVQLbvo3EhWa!^}=VOsmgMx~lV4nZCgiPHqkdm3gQ z<5zO}P4YlKGPxX z!=-#|5A2zr%xAo@s(DAzlI~gC1Z$S7M=BJ5lbyG$dRj5x=}iZ!`LlI<3}-x-bavvZ z2$~S&#F5BuDfQ`Jun(jB)S&5;GyH@fWf%GX$y2&5o6_^qr=;s|RCbIobEKg9qvGys zQdw(nY~y{sOKuNKrO|}_f+mT=M=R{grUWS{dQZ4JA;svZ<@1LV{%?%?u|1(LVG>US P(5Vcbu6{1-oD!M<4=Gbn literal 0 HcmV?d00001