1
0
mirror of https://github.com/D00Med/scifi_nodes.git synced 2025-06-28 22:26:37 +02:00

31 Commits

Author SHA1 Message Date
fb1fdcf69e Merge remote-tracking branch 'upstream/master' 2025-03-20 12:50:24 +01:00
b682b2123d make crate game agnostic 2025-03-11 09:16:02 +01:00
c615237114 fix missing texture in plastic slope code 2025-03-11 08:36:18 +01:00
cb95483a12 fix player check, use builting code.is_player(obj) 2025-02-21 13:09:24 +01:00
e52a890883 add nil-check to door access card check 2025-02-10 17:54:29 +01:00
6fb3ded8ad Add access cards (#88)
* add access cards

* colored cards

* rename / recipes

* impl

* crafting fix

* indent fixes

* door groups fix (should not be diggable by hand)

---------

Co-authored-by: BuckarooBanzay <BuckarooBanzay@users.noreply.github.com>
2025-02-07 15:47:20 +01:00
373f06cd7c disable facedir param2type on weird looking nodes 2025-02-07 10:30:59 +01:00
d531ad4eda add ambience sounds and helper function (#87)
* add ambience sounds and helper function

* minor tweaks

* fix deps

---------

Co-authored-by: BuckarooBanzay <BuckarooBanzay@users.noreply.github.com>
2025-02-03 17:18:31 +01:00
f79e84b92d Merge remote-tracking branch 'upstream/master' 2024-09-15 09:47:44 +02:00
cc5f1bea5a Merge remote-tracking branch 'upstream/master' 2023-11-25 15:35:19 +01:00
e7864a4a86 Merge remote-tracking branch 'upstream/master' 2023-06-07 22:31:17 +02:00
c649c290ab Merge remote-tracking branch 'upstream/master' 2022-06-25 16:54:20 +02:00
4f2d2a304f Merge remote-tracking branch 'upstream/master' 2022-05-27 18:51:16 +02:00
8816db8ecf Merge remote-tracking branch 'upstream/master' 2021-11-01 10:41:33 +01:00
5b903a6e78 Merge remote-tracking branch 'upstream/master' 2021-10-04 21:49:01 +02:00
eb231d7ca7 Merge remote-tracking branch 'upstream/master' 2021-08-31 19:59:22 +02:00
2fd4de11c0 Merge remote-tracking branch 'upstream/master' 2021-08-16 18:18:21 +02:00
b88b7349a5 Merge remote-tracking branch 'upstream/master' 2021-06-20 17:30:14 +02:00
c30ae4b3bd Merge remote-tracking branch 'upstream/master' 2021-05-09 21:44:34 +02:00
6cf45fcd43 Merge remote-tracking branch 'upstream/master' 2021-03-25 21:58:42 +01:00
1ded358e04 Merge branch 'github' 2021-03-20 13:38:15 +01:00
ecfaa4714a Fix things to avoid warnings about use_texture_alpha
And optimize textures with optipng
2021-03-20 13:33:39 +01:00
c341cb8a20 Merge remote-tracking branch 'upstream/master' 2021-01-29 17:43:56 +01:00
d66e04f9b1 Merge remote-tracking branch 'upstream/master' 2020-12-24 21:10:26 +01:00
d3d6a7bf79 Merge remote-tracking branch 'upstream/master' 2020-12-18 12:21:17 +01:00
e34fdde795 Merge remote-tracking branch 'upstream/master' 2020-12-15 23:41:17 +01:00
1993068ed1 Merge remote-tracking branch 'upstream/master' 2020-11-12 22:04:59 +01:00
436f51ab0d Merge remote-tracking branch 'upstream/master' 2020-11-10 19:59:40 +01:00
749d59a530 Merge remote-tracking branch 'upstream/master' 2020-09-13 12:28:42 +02:00
bd58dbc48b Merge remote-tracking branch 'upstream/master' 2020-07-23 11:42:19 +02:00
4eaba4f6e1 Adds loading message in the Action Log 2020-07-21 11:52:47 +02:00
13 changed files with 395 additions and 25 deletions

View File

@ -49,6 +49,9 @@ CC BY 3.0
CC0
* scifi_nodes_digicode.ogg https://freesound.org/people/benjaminharveydesign/sounds/315921/
* scifi_nodes_ambience_fan.ogg https://freesound.org/people/itinerantmonk108/sounds/554430/
* scifi_nodes_ambience_vent.ogg https://freesound.org/people/kentspublicdomain/sounds/324665/
* scifi_nodes_ambience_engine.ogg https://freesound.org/people/firestorm185/sounds/423221/
# Contributors:

259
access_card.lua Normal file
View File

@ -0,0 +1,259 @@
local FORMSPEC_NAME = "scifi_nodes:access_card_configure"
local function create_id()
local template = "xxxxxx"
return string.gsub(template, '[x]', function ()
return string.format('%x', math.random(0, 0xf))
end)
end
local function get_door_access_table(meta)
local str = meta:get_string("access")
if str == "" then
-- no config
return {}
else
return minetest.deserialize(str) or {}
end
end
local function set_door_access_table(meta, at)
if next(at) then
meta:set_string("access", minetest.serialize(at))
else
meta:set_string("access", "")
end
end
function scifi_nodes.door_check_access_card(node_pos, itemstack, player)
local node_meta = minetest.get_meta(node_pos)
local access_table = get_door_access_table(node_meta)
if not next(access_table) then
-- access not restricted
return true
end
if not minetest.is_player(player) then
-- not a player, restrict access
return false
end
local playername = player:get_player_name()
if itemstack:get_name() ~= "scifi_nodes:access_card" then
minetest.chat_send_player(playername, minetest.colorize("#ff0000", "Access denied: no access card detected!"))
minetest.sound_play("scifi_nodes_scanner_refused", { pos = node_pos, max_hear_distance = 10 })
return false
end
local item_meta = itemstack:get_meta()
local id = item_meta:get_string("id")
if id == "" then
minetest.chat_send_player(playername, minetest.colorize("#ff0000", "Access denied: unconfigured access card"))
minetest.sound_play("scifi_nodes_scanner_refused", { pos = node_pos, max_hear_distance = 10 })
return false
end
if not access_table[id] then
minetest.chat_send_player(playername, minetest.colorize("#ff0000", "Access denied: invalid access card"))
minetest.sound_play("scifi_nodes_scanner_refused", { pos = node_pos, max_hear_distance = 10 })
return false
end
minetest.sound_play("scifi_nodes_scanner_granted", { pos = node_pos, max_hear_distance = 10 })
return true
end
-- using a card against a door toggles the access to it
local function on_use(itemstack, player, pointed_thing)
local playername = player:get_player_name()
local pos = pointed_thing.under
if not pos then
-- nothing selected
return
end
if minetest.is_protected(pos, playername) then
-- protected
return
end
local node = minetest.get_node(pos)
local node_def = minetest.registered_nodes[node.name]
if not node_def.groups or not node_def.groups.scifi_nodes_door then
-- incompatible node
return
end
local item_meta = itemstack:get_meta()
local card_id = item_meta:get_string("id")
if card_id == "" then
minetest.chat_send_player(playername, "Access card is unconfigured")
return
end
local card_name = item_meta:get_string("name")
local node_meta = minetest.get_meta(pos)
local access_table = get_door_access_table(node_meta)
if access_table[card_id] then
-- remove access
access_table[card_id] = nil
minetest.chat_send_player(playername, "Revoked access to card-id '" .. card_id .. "'")
minetest.sound_play("scifi_nodes_scanner_refused", { pos = pos, max_hear_distance = 10 })
else
-- grant access
access_table[card_id] = card_name
minetest.chat_send_player(playername, "Granted access to card-id '" .. card_id .. "'")
minetest.sound_play("scifi_nodes_scanner_granted", { pos = pos, max_hear_distance = 10 })
end
local msg = ""
if next(access_table) then
msg = msg .. "Current registered cards: "
for id, name in pairs(access_table) do
msg = msg .. "Name: '" .. name .. "' ID: '" .. id .. "' / "
end
else
-- access table is empty
msg = "No access-card left in access-table, door is free to use"
end
minetest.chat_send_player(playername, msg)
-- set new access table
set_door_access_table(node_meta, access_table)
end
local function configure_access_card(meta, name)
local id = meta:get_string("id")
if id == "" then
-- set new id
id = create_id()
meta:set_string("id", id)
end
meta:set_string("name", name)
meta:set_string("description", "Access card '" .. name .. "' (id: '" .. id .. "')")
end
-- right-click with a card for rename/configuration
local function on_secondary_use(itemstack, player, pointed_thing)
local meta = itemstack:get_meta()
if meta:get_string("id") == "" then
-- initial configuration
configure_access_card(meta, "")
end
local name = meta:get_string("name")
minetest.show_formspec(player:get_player_name(), FORMSPEC_NAME, [[
size[10,1.4]
real_coordinates[true]
field[0.1,0.4;7,0.8;name;Name;]] .. minetest.formspec_escape(name) .. [[]
button_exit[7.3,0.4;2.5,0.8;save;Save]
]])
return itemstack
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= FORMSPEC_NAME then
-- wrong formspec
return false
end
if not fields.save and not fields.key_enter_field then
-- quit
return true
end
local itemstack = player:get_wielded_item()
if itemstack:get_name() ~= "scifi_nodes:access_card" then
-- invalid item
return true
end
local meta = itemstack:get_meta()
configure_access_card(meta, fields.name or "")
player:set_wielded_item(itemstack)
end)
minetest.register_craftitem("scifi_nodes:access_card", {
description = "Access card (unconfigured)",
inventory_image = "scifi_nodes_access_card.png",
palette = "unifieddyes_palette_extended.png",
stack_max = 1,
paramtype2 = "color",
on_use = on_use,
on_secondary_use = on_secondary_use,
groups = {
ud_param2_colorable = 1
}
})
-- initial recipe
minetest.register_craft({
output = "scifi_nodes:access_card",
recipe = {
{"scifi_nodes:white2", "", ""},
{"scifi_nodes:white_pad", "", ""},
{"scifi_nodes:white2", "", ""}
}
})
-- copy recipe
minetest.register_craft({
output = "scifi_nodes:access_card",
recipe = {
{"scifi_nodes:access_card", "scifi_nodes:white_pad", ""},
{"", "", ""},
{"", "", ""}
}
})
minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv)
if itemstack:get_name() ~= "scifi_nodes:access_card" then
return
end
local original
local index
for i = 1, #old_craft_grid do
if old_craft_grid[i]:get_name() == "scifi_nodes:access_card" then
original = old_craft_grid[i]
index = i
break
end
end
if not original then
return
end
-- copy metadata
local src_meta = original:get_meta()
local dst_meta = itemstack:get_meta()
local copy_fields = {"id", "name", "description"}
for _, fieldname in ipairs(copy_fields) do
dst_meta:set_string(fieldname, src_meta:get_string(fieldname))
end
if old_craft_grid[2]:get_name() == "scifi_nodes:white_pad" then
-- keep original item if the copy-recipe is used
craft_inv:set_stack("craft", index, original)
end
end)
if minetest.get_modpath("unifieddyes") then
-- add colored crafts
unifieddyes.register_color_craft({
output = "scifi_nodes:access_card",
palette = "extended",
neutral_node = "scifi_nodes:access_card",
recipe = {
"NEUTRAL_NODE",
"MAIN_DYE"
},
type = "shapeless"
})
end

73
ambience.lua Normal file
View File

@ -0,0 +1,73 @@
-- currently playing sounds per mapblock
-- mapblock_pos[number]
local currently_playing = {}
-- clear the currently playing tracker every few seconds
local function clear_currently_playing()
currently_playing = {}
minetest.after(5, clear_currently_playing)
end
minetest.after(5, clear_currently_playing)
-- mapblock resolution
local function get_key(pos)
return minetest.pos_to_string(vector.round(vector.divide(pos, 16)))
end
local function add_currently_playing(pos, value)
local key = get_key(pos)
local count = currently_playing[key]
if not count then
-- new entry
count = value
else
-- update entry
count = count + value
end
currently_playing[key] = count
end
-- limit plaing sounds per mapblock
local function can_play(pos)
local count = currently_playing[get_key(pos)]
return not count or count < 25
end
-- register ambience sounds with node-timer
function scifi_nodes.register_ambience(nodename, soundname, opts)
assert(opts)
opts.interval = opts.interval or 60
local function play(pos)
minetest.sound_play(soundname ,{
max_hear_distance = opts.max_hear_distance or 16,
pos = pos,
gain = opts.gain or 0.7
})
end
minetest.override_item(nodename, {
on_timer = function(pos)
local timer = minetest.get_node_timer(pos)
if not can_play(pos) then
-- too many sounds playing, recheck again soon
timer:start(1)
return
end
-- increment usage count
add_currently_playing(pos, 1)
play(pos)
-- restart timer
timer:start(opts.interval)
end,
on_construct = function(pos)
play(pos)
local timer = minetest.get_node_timer(pos)
timer:start(opts.interval)
end
})
end

View File

@ -1,16 +1,17 @@
local has_default = minetest.get_modpath("default")
--chest code from default(Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>)
local chest_formspec =
"size[8,9]" ..
default.gui_bg ..
default.gui_bg_img ..
default.gui_slots ..
(has_default and default.gui_bg or "") ..
(has_default and default.gui_bg_img or "") ..
(has_default and default.gui_slots or "") ..
"list[current_name;main;0,0.3;8,4;]" ..
"list[current_player;main;0,4.85;8,1;]" ..
"list[current_player;main;0,6.08;8,3;8]" ..
"listring[current_name;main]" ..
"listring[current_player;main]" ..
default.get_hotbar_bg(0,4.85)
(has_default and default.get_hotbar_bg(0,4.85) or "")
-- Helper functions
local function drop_chest_stuff()

View File

@ -148,14 +148,18 @@ for _, current_door in ipairs(doors) do
local adjacent = minetest.get_node({x=x, y=y, z=z})
if adjacent.name == target_opposite then
minetest.set_node({x=x, y=y, z=z}, {name=target, param2 = adjacent.param2})
minetest.set_node({x=x, y=y+1, z=z}, {name=target_top, param2 = adjacent.param2})
minetest.swap_node({x=x, y=y, z=z}, {name=target, param2 = adjacent.param2})
minetest.swap_node({x=x, y=y+1, z=z}, {name=target_top, param2 = adjacent.param2})
end
end
end
local function open_door(pos, node)
local function open_door(pos, node, player, itemstack)
if not scifi_nodes.door_check_access_card(pos, itemstack, player) then
return
end
-- play sound
minetest.sound_play(sound,{
max_hear_distance = 16,
@ -165,8 +169,8 @@ for _, current_door in ipairs(doors) do
local timer = minetest.get_node_timer(pos)
minetest.set_node(pos, {name=opened, param2=node.param2})
minetest.set_node({x=pos.x,y=pos.y+1,z=pos.z}, {name=opened_top, param2=node.param2})
minetest.swap_node(pos, {name=opened, param2=node.param2})
minetest.swap_node({x=pos.x,y=pos.y+1,z=pos.z}, {name=opened_top, param2=node.param2})
change_adjacent(opened, pos, node)
@ -188,8 +192,8 @@ for _, current_door in ipairs(doors) do
local node = minetest.get_node(pos)
minetest.set_node(pos, {name=closed, param2=node.param2})
minetest.set_node({x=pos.x,y=pos.y+1,z=pos.z}, {name=closed_top, param2=node.param2})
minetest.swap_node(pos, {name=closed, param2=node.param2})
minetest.swap_node({x=pos.x,y=pos.y+1,z=pos.z}, {name=closed_top, param2=node.param2})
change_adjacent(closed, pos, node)
end
@ -242,7 +246,7 @@ for _, current_door in ipairs(doors) do
paramtype2 = "facedir",
groups = {
cracky = 3,
oddly_breakable_by_hand = 1,
dig_generic = 3,
scifi_nodes_door = 1,
door = 1
},

View File

@ -14,15 +14,17 @@ end
dofile(MP.."/common.lua")
if minetest.get_modpath("default") then
-- only load builder and chest if the default mod is available
-- only load builder if the default mod is available
-- the formspecs depend on it
dofile(MP.."/builder.lua")
dofile(MP.."/chest.lua")
end
dofile(MP.."/ambience.lua")
dofile(MP.."/chest.lua")
dofile(MP.."/plants.lua")
dofile(MP.."/models.lua")
dofile(MP.."/nodes.lua")
dofile(MP.."/access_card.lua")
dofile(MP.."/doors.lua")
dofile(MP.."/switch.lua")
dofile(MP.."/protected_switch.lua")
@ -46,4 +48,6 @@ end
if minetest.get_modpath("mtt") and mtt.enabled then
dofile(MP .. "/mtt.lua")
end
end
minetest.log("action", "[scifi_nodes] loaded.")

View File

@ -31,8 +31,8 @@ end
-- register some blocks in stairsplus if available (part of moreblocks)
scifi_nodes.register_slope("white2", "Plastic", {"scifi_nodes_white2.png",}, 0, "stone")
scifi_nodes.register_slope("super_white", "Super Plastic", {"scifi_nodes_super_white.png",}, 11, "stone")
scifi_nodes.register_slope("ultra_white", "Super Plastic", {"scifi_nodes_ultra_white.png",},minetest.LIGHT_MAX, "stone")
scifi_nodes.register_slope("super_white", "Super Plastic", {"scifi_nodes_white2.png",}, 11, "stone")
scifi_nodes.register_slope("ultra_white", "Super Plastic", {"scifi_nodes_white2.png",},minetest.LIGHT_MAX, "stone")
scifi_nodes.register_slope("black", "Black", {"scifi_nodes_black.png",}, 0)
scifi_nodes.register_slope("white", "White", {"scifi_nodes_white.png",}, 0)
scifi_nodes.register_slope("grey", "Grey", {"scifi_nodes_grey.png",}, 0)

View File

@ -25,7 +25,12 @@
"texture_name": "white2"
},
"engine": {
"description": "Engine"
"description": "Engine",
"ambience": {
"scifi_nodes_ambience_engine": {
"interval": 16.1
}
}
},
"wall": {
"description": "metal wall"
@ -58,7 +63,12 @@
"description": "transparent vent",
"texture_name": "vent2",
"texture_modifier": "^[makealpha:33,33,33",
"drawtype": "glasslike"
"drawtype": "glasslike",
"ambience": {
"scifi_nodes_ambience_vent": {
"interval": 4.2
}
}
},
"stripes": {
"description": "hazard stripes",
@ -85,7 +95,8 @@
"description": "black tile"
},
"blacktile2": {
"description": "black tile 2"
"description": "black tile 2",
"paramtype2": "none"
},
"blackvent": {
"description": "black vent"
@ -141,7 +152,8 @@
"description": "red metal block"
},
"grey_square": {
"description": "grey metal block"
"description": "grey metal block",
"paramtype2": "none"
},
"blue_square": {
"description": "blue metal block"
@ -234,7 +246,8 @@
},
"blackdmg": {
"description": "Damaged black wall",
"slat": true
"slat": true,
"paramtype2": "none"
},
"blackdmgstripe": {
"description": "Damaged black wall(stripes)"
@ -261,7 +274,12 @@
"light": 5
},
"fan": {
"description": "Fan"
"description": "Fan",
"ambience": {
"scifi_nodes_ambience_fan": {
"interval": 7
}
}
},
"ppllght": {
"description": "Purple wall light",
@ -301,6 +319,7 @@
"description": "Black vent"
},
"blackplate": {
"description": "Black plate"
"description": "Black plate",
"paramtype2": "none"
}
}

View File

@ -537,7 +537,8 @@ for name, def in pairs(nodes) do
end
-- register node
minetest.register_node("scifi_nodes:"..name, node_def)
local nodename = "scifi_nodes:" .. name
minetest.register_node(nodename , node_def)
-- unified dyes registration
if def.colorable and has_unifieddyes_mod then
@ -574,6 +575,12 @@ for name, def in pairs(nodes) do
})
end
if def.ambience then
for soundname, opts in pairs(def.ambience) do
scifi_nodes.register_ambience(nodename, soundname, opts)
end
end
-- advtrains platform registration
if has_advtrains_mod and def.advtrains_platform then
advtrains.register_platform("scifi_nodes", "scifi_nodes:" .. name)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB