forked from MTSR/techage_modpack
built on 04/02/2023 15:45:23
This commit is contained in:
parent
e4f4a04f0b
commit
1088fb8bfb
@ -212,8 +212,12 @@ minetest.register_node("hyperloop:shaft2", {
|
|||||||
light_source = 2,
|
light_source = 2,
|
||||||
sunlight_propagates = true,
|
sunlight_propagates = true,
|
||||||
is_ground_content = false,
|
is_ground_content = false,
|
||||||
|
----- To be unbreakable -----
|
||||||
|
on_blast = function() end,
|
||||||
|
on_destruct = function () end,
|
||||||
|
can_dig = function() return false end,
|
||||||
diggable = false,
|
diggable = false,
|
||||||
groups = {cracky = 1, not_in_creative_inventory=1},
|
groups = {cracky = 1, not_in_creative_inventory=1, unbreakable=1},
|
||||||
sounds = default.node_sound_metal_defaults(),
|
sounds = default.node_sound_metal_defaults(),
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -255,8 +259,12 @@ minetest.register_node("hyperloop:shaftA2", {
|
|||||||
light_source = 2,
|
light_source = 2,
|
||||||
sunlight_propagates = true,
|
sunlight_propagates = true,
|
||||||
is_ground_content = false,
|
is_ground_content = false,
|
||||||
|
----- To be unbreakable -----
|
||||||
|
on_blast = function() end,
|
||||||
|
on_destruct = function () end,
|
||||||
|
can_dig = function() return false end,
|
||||||
diggable = false,
|
diggable = false,
|
||||||
groups = {cracky = 1, not_in_creative_inventory=1},
|
groups = {cracky = 1, not_in_creative_inventory=1, unbreakable=1},
|
||||||
sounds = default.node_sound_metal_defaults(),
|
sounds = default.node_sound_metal_defaults(),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -173,8 +173,12 @@ minetest.register_node("hyperloop:tubeS2", {
|
|||||||
light_source = 2,
|
light_source = 2,
|
||||||
sunlight_propagates = true,
|
sunlight_propagates = true,
|
||||||
is_ground_content = false,
|
is_ground_content = false,
|
||||||
|
----- To be unbreakable -----
|
||||||
|
on_blast = function() end,
|
||||||
|
on_destruct = function () end,
|
||||||
|
can_dig = function() return false end,
|
||||||
diggable = false,
|
diggable = false,
|
||||||
groups = {cracky = 1, not_in_creative_inventory=1},
|
groups = {cracky = 1, not_in_creative_inventory=1, unbreakable=1},
|
||||||
sounds = default.node_sound_metal_defaults(),
|
sounds = default.node_sound_metal_defaults(),
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -263,8 +267,12 @@ minetest.register_node("hyperloop:tubeA2", {
|
|||||||
light_source = 2,
|
light_source = 2,
|
||||||
sunlight_propagates = true,
|
sunlight_propagates = true,
|
||||||
is_ground_content = false,
|
is_ground_content = false,
|
||||||
|
----- To be unbreakable -----
|
||||||
|
on_blast = function() end,
|
||||||
|
on_destruct = function () end,
|
||||||
|
can_dig = function() return false end,
|
||||||
diggable = false,
|
diggable = false,
|
||||||
groups = {cracky = 1, not_in_creative_inventory=1},
|
groups = {cracky = 1, not_in_creative_inventory=1, unbreakable=1},
|
||||||
sounds = default.node_sound_metal_defaults(),
|
sounds = default.node_sound_metal_defaults(),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ The mod features are:
|
|||||||
- Ingame documentation (German and English), based on the mod "doc"
|
- Ingame documentation (German and English), based on the mod "doc"
|
||||||
- API to register carts from other mods
|
- API to register carts from other mods
|
||||||
- chat command '/mycart <num>' to output cart state and location
|
- chat command '/mycart <num>' to output cart state and location
|
||||||
|
- Command interface for Techage (Lua and ICTA) and for Beduino Controllers
|
||||||
|
|
||||||
|
|
||||||
Technical Background
|
Technical Background
|
||||||
@ -118,6 +119,45 @@ The "No speed limit" sign can be used to remove the speed limit.
|
|||||||
The speed limit signs must be placed next to the track so that they can
|
The speed limit signs must be placed next to the track so that they can
|
||||||
be read from the cart. This allows different speeds in each direction of travel.
|
be read from the cart. This allows different speeds in each direction of travel.
|
||||||
|
|
||||||
|
## Command Interface
|
||||||
|
|
||||||
|
### Techage ICTA Controller
|
||||||
|
|
||||||
|
The ICTA Controller support the conditions:
|
||||||
|
|
||||||
|
- "read cart state" (function returns "stopped" or "running")
|
||||||
|
- "read cart location" (function returns the distance or the station/buffer name)
|
||||||
|
|
||||||
|
See help page of the ICTA controller block.
|
||||||
|
|
||||||
|
### Techage Lua Controller
|
||||||
|
|
||||||
|
The Lua controller support the functions:
|
||||||
|
|
||||||
|
- `$cart_state(num)` (function returns "stopped" or "running")
|
||||||
|
- `$cart_location(num)` (function returns the distance or the station/buffer name)
|
||||||
|
|
||||||
|
See help page of the Lua controller block.
|
||||||
|
|
||||||
|
### Cart Terminal
|
||||||
|
|
||||||
|
The Cart Terminal has a Techage command interface with the commands:
|
||||||
|
|
||||||
|
| Command | Data | Description |
|
||||||
|
| ---------- | ---------- | ------------------------------------------------------- |
|
||||||
|
| `state` | \<cart-ID> | Returns `unknown`, `stopped`, or `running` |
|
||||||
|
| `distance` | \<cart-ID> | Returns the distance from the cart to the Cart Terminal |
|
||||||
|
|
||||||
|
### Beduino Controller
|
||||||
|
|
||||||
|
The Cart Terminal has a Beduino command interface with the commands:
|
||||||
|
|
||||||
|
| Command | Topic | Data | Response | Description |
|
||||||
|
| -------- | ----- | --------- | ---------- | ------------------------------------------------------- |
|
||||||
|
| State | 129 | [cart-id] | [state] | Returns 0 = UNKNOWN, 1 = STOPPED, 2 = RUNNING |
|
||||||
|
| Distance | 130 | [cart-id] | [distance] | Returns the distance from the cart to the Cart Terminal |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Migration to v2
|
Migration to v2
|
||||||
---------------
|
---------------
|
||||||
@ -153,3 +193,4 @@ History
|
|||||||
Speed limit signs and cart terminal added
|
Speed limit signs and cart terminal added
|
||||||
2021-09-02 V2.01 Chat command /stopcart added
|
2021-09-02 V2.01 Chat command /stopcart added
|
||||||
2021-10-18 V2.02 Cart reproduction bug fixed
|
2021-10-18 V2.02 Cart reproduction bug fixed
|
||||||
|
2023-01-04 V2.03 Techage and Beduino command interface added
|
93
minecart/beduino.lua
Normal file
93
minecart/beduino.lua
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
Minecart
|
||||||
|
========
|
||||||
|
|
||||||
|
Copyright (C) 2019-2023 Joachim Stolberg
|
||||||
|
|
||||||
|
MIT
|
||||||
|
See license.txt for more information
|
||||||
|
|
||||||
|
]]--
|
||||||
|
|
||||||
|
local minecart_lib = [[
|
||||||
|
// Minecart library for reading status and distance
|
||||||
|
// from running carts. To do this, a cart terminal
|
||||||
|
// must be connected to an I/O Module.
|
||||||
|
|
||||||
|
import "lib/techage.c"
|
||||||
|
|
||||||
|
var payload[1];
|
||||||
|
var resp[1];
|
||||||
|
|
||||||
|
|
||||||
|
// Read cart state.
|
||||||
|
// Parameters:
|
||||||
|
// - ip_port: IOM port to the Cart Terminal
|
||||||
|
// - card_id: Cart number
|
||||||
|
// Function returns:
|
||||||
|
// - 0 for unknown/missing
|
||||||
|
// - 1 for stopped
|
||||||
|
// - 2 for running
|
||||||
|
func mc_get_state(io_port, cart_id) {
|
||||||
|
var sts;
|
||||||
|
|
||||||
|
payload[0] = cart_id;
|
||||||
|
request_data(io_port, 129, payload, resp);
|
||||||
|
if(sts == 0) {
|
||||||
|
return resp[0];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read cart distance.
|
||||||
|
// Parameters:
|
||||||
|
// - ip_port: IOM port to the Cart Terminal
|
||||||
|
// - card_id: Cart number
|
||||||
|
// Function returns the distance between
|
||||||
|
// Cart Terminal and cart in meter.
|
||||||
|
func mc_get_distance(io_port, cart_id) {
|
||||||
|
var sts;
|
||||||
|
|
||||||
|
payload[0] = cart_id;
|
||||||
|
request_data(io_port, 130, payload, resp);
|
||||||
|
if(sts == 0) {
|
||||||
|
return resp[0];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
]]
|
||||||
|
|
||||||
|
local minecart_demo = [[
|
||||||
|
import "sys/stdio.asm"
|
||||||
|
import "sys/os.c"
|
||||||
|
import "lib/minecart.c"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
setstdout(1); // use terminal window for stdout
|
||||||
|
putstr("### Minecart Demo ###\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
func cart_state(io_port, cart_id) {
|
||||||
|
putstr("Cart #");
|
||||||
|
putnum(cart_id);
|
||||||
|
putstr(": state = ");
|
||||||
|
putnum(mc_get_state(io_port, cart_id));
|
||||||
|
putstr(", distance = ");
|
||||||
|
putnum(mc_get_distance(io_port, cart_id));
|
||||||
|
putstr("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
func loop() {
|
||||||
|
// Adapt IO port and cart ID to your needs
|
||||||
|
cart_state(0, 1);
|
||||||
|
sleep(20);
|
||||||
|
}
|
||||||
|
]]
|
||||||
|
|
||||||
|
minetest.register_on_mods_loaded(function()
|
||||||
|
if minetest.global_exists("vm16") and minetest.global_exists("beduino") then
|
||||||
|
vm16.register_ro_file("beduino", "lib/minecart.c", minecart_lib)
|
||||||
|
vm16.register_ro_file("beduino", "demo/minecart.c", minecart_demo)
|
||||||
|
end
|
||||||
|
end)
|
@ -94,8 +94,8 @@ function minecart.untake_items(pos, param2, stack)
|
|||||||
local def = RegisteredInventories[node.name]
|
local def = RegisteredInventories[node.name]
|
||||||
local inv = minetest.get_inventory({type="node", pos=npos})
|
local inv = minetest.get_inventory({type="node", pos=npos})
|
||||||
|
|
||||||
if def and inv and def.put_listname then
|
if def and inv and def.take_listname then
|
||||||
return inv:add_item(def.put_listname, stack)
|
return inv:add_item(def.take_listname, stack)
|
||||||
elseif def and def.untake_item then
|
elseif def and def.untake_item then
|
||||||
return def.untake_item(npos, stack)
|
return def.untake_item(npos, stack)
|
||||||
else
|
else
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
Minecart
|
Minecart
|
||||||
========
|
========
|
||||||
|
|
||||||
Copyright (C) 2019-2021 Joachim Stolberg
|
Copyright (C) 2019-2023 Joachim Stolberg
|
||||||
|
|
||||||
MIT
|
MIT
|
||||||
See license.txt for more information
|
See license.txt for more information
|
||||||
@ -13,7 +13,7 @@
|
|||||||
minecart = {}
|
minecart = {}
|
||||||
|
|
||||||
-- Version for compatibility checks, see readme.md/history
|
-- Version for compatibility checks, see readme.md/history
|
||||||
minecart.version = 2.02
|
minecart.version = 2.03
|
||||||
|
|
||||||
minecart.hopper_enabled = minetest.settings:get_bool("minecart_hopper_enabled") ~= false
|
minecart.hopper_enabled = minetest.settings:get_bool("minecart_hopper_enabled") ~= false
|
||||||
minecart.teleport_enabled = minetest.settings:get_bool("minecart_teleport_enabled") == true
|
minecart.teleport_enabled = minetest.settings:get_bool("minecart_teleport_enabled") == true
|
||||||
@ -39,6 +39,7 @@ dofile(MP .. "/protection.lua")
|
|||||||
dofile(MP .. "/signs.lua")
|
dofile(MP .. "/signs.lua")
|
||||||
dofile(MP .. "/terminal.lua")
|
dofile(MP .. "/terminal.lua")
|
||||||
dofile(MP .. "/pusher.lua")
|
dofile(MP .. "/pusher.lua")
|
||||||
|
dofile(MP .. "/beduino.lua")
|
||||||
|
|
||||||
if minecart.hopper_enabled then
|
if minecart.hopper_enabled then
|
||||||
dofile(MP .. "/hopper.lua")
|
dofile(MP .. "/hopper.lua")
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
Minecart
|
Minecart
|
||||||
========
|
========
|
||||||
|
|
||||||
Copyright (C) 2019-2021 Joachim Stolberg
|
Copyright (C) 2019-2023 Joachim Stolberg
|
||||||
|
|
||||||
MIT
|
MIT
|
||||||
See license.txt for more information
|
See license.txt for more information
|
||||||
@ -90,7 +90,22 @@ local function get_cart_state_and_loc(name, userID, query_pos)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
return "unknown", 0, "unknown"
|
return "unknown", 0, "unknown"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Return the cart distance to the query_pos.
|
||||||
|
local function get_cart_distance(name, userID, query_pos)
|
||||||
|
if tCartsOnRail[name] and tCartsOnRail[name][userID] then
|
||||||
|
local cart = tCartsOnRail[name][userID]
|
||||||
|
if cart.last_pos or cart.pos then
|
||||||
|
if cart.objID == 0 then -- stopped
|
||||||
|
return math.floor(vector.distance(cart.pos or cart.last_pos, query_pos))
|
||||||
|
else
|
||||||
|
return math.floor(vector.distance(cart.last_pos or cart.pos, query_pos))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
local function get_cart_info(owner, userID, query_pos)
|
local function get_cart_info(owner, userID, query_pos)
|
||||||
local state, loc, name = get_cart_state_and_loc(owner, userID, query_pos)
|
local state, loc, name = get_cart_state_and_loc(owner, userID, query_pos)
|
||||||
@ -318,6 +333,10 @@ function minecart.cmnd_cart_location(name, userID, query_pos)
|
|||||||
return loc
|
return loc
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function minecart.cmnd_cart_distance(name, userID, query_pos)
|
||||||
|
return get_cart_distance(name, userID, query_pos)
|
||||||
|
end
|
||||||
|
|
||||||
function minecart.get_cart_list(pos, name)
|
function minecart.get_cart_list(pos, name)
|
||||||
local userIDs = {}
|
local userIDs = {}
|
||||||
local carts = {}
|
local carts = {}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
Minecart
|
Minecart
|
||||||
========
|
========
|
||||||
|
|
||||||
Copyright (C) 2019-2021 Joachim Stolberg
|
Copyright (C) 2019-2023 Joachim Stolberg
|
||||||
|
|
||||||
MIT
|
MIT
|
||||||
See license.txt for more information
|
See license.txt for more information
|
||||||
@ -59,6 +59,11 @@ minetest.register_node("minecart:terminal", {
|
|||||||
local meta = M(pos)
|
local meta = M(pos)
|
||||||
meta:set_string("owner", placer:get_player_name())
|
meta:set_string("owner", placer:get_player_name())
|
||||||
meta:set_string("formspec", formspec(pos, ""))
|
meta:set_string("formspec", formspec(pos, ""))
|
||||||
|
if minetest.global_exists("techage") then
|
||||||
|
local number = techage.add_node(pos, "minecart:terminal")
|
||||||
|
meta:set_string("node_number", number)
|
||||||
|
meta:set_string("infotext", "Cart Terminal " .. number)
|
||||||
|
end
|
||||||
minetest.get_node_timer(pos):start(2)
|
minetest.get_node_timer(pos):start(2)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@ -88,3 +93,42 @@ minetest.register_craft({
|
|||||||
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
|
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_on_mods_loaded(function()
|
||||||
|
if minetest.global_exists("techage") then
|
||||||
|
techage.register_node({"minecart:terminal"}, {
|
||||||
|
on_recv_message = function(pos, src, topic, payload)
|
||||||
|
local number = tonumber(payload)
|
||||||
|
if number then
|
||||||
|
local owner = M(pos):get_string("owner")
|
||||||
|
if topic == "state" then
|
||||||
|
return minecart.cmnd_cart_state(owner, number)
|
||||||
|
elseif topic == "distance" then
|
||||||
|
return minecart.cmnd_cart_distance(owner, number, pos)
|
||||||
|
else
|
||||||
|
return "unsupported"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
on_beduino_receive_cmnd = function(pos, src, topic, payload)
|
||||||
|
return 2 -- unknown or invalid topic
|
||||||
|
end,
|
||||||
|
on_beduino_request_data = function(pos, src, topic, payload)
|
||||||
|
if topic == 128 then
|
||||||
|
return 0, "minecart:terminal"
|
||||||
|
elseif topic == 129 then -- state
|
||||||
|
local owner = M(pos):get_string("owner")
|
||||||
|
local STATE = {unknown = 0, stopped = 1, running = 2}
|
||||||
|
local state = STATE[minecart.cmnd_cart_state(owner, payload[1])] or 0
|
||||||
|
return 0, {state}
|
||||||
|
elseif topic == 130 then -- distance
|
||||||
|
local owner = M(pos):get_string("owner")
|
||||||
|
local dist = minecart.cmnd_cart_distance(owner, payload[1], pos)
|
||||||
|
return 0, {dist}
|
||||||
|
else
|
||||||
|
return 2, "" -- topic is unknown or invalid
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end)
|
@ -268,9 +268,11 @@ signs_bot.register_botcommand("fall_down", {
|
|||||||
local sts, pos3 = minetest.line_of_sight(pos1, pos2)
|
local sts, pos3 = minetest.line_of_sight(pos1, pos2)
|
||||||
if sts == false then
|
if sts == false then
|
||||||
sts, _ = minetest.spawn_falling_node(mem.robot_pos)
|
sts, _ = minetest.spawn_falling_node(mem.robot_pos)
|
||||||
|
mem.stored_node = get_node_lvm(pos3)
|
||||||
|
minetest.swap_node(pos3, {name="air"})
|
||||||
if sts then
|
if sts then
|
||||||
mem.bot_falling = 2
|
mem.bot_falling = 2
|
||||||
mem.robot_pos = {x=pos3.x, y=pos3.y+1, z=pos3.z}
|
mem.robot_pos = {x=pos3.x, y=pos3.y, z=pos3.z}
|
||||||
return signs_bot.BUSY
|
return signs_bot.BUSY
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -52,7 +52,7 @@ end
|
|||||||
if farming.mod == "redo" then
|
if farming.mod == "redo" then
|
||||||
local fp_grows = function(def, step)
|
local fp_grows = function(def, step)
|
||||||
local crop = def.crop .. "_" .. step
|
local crop = def.crop .. "_" .. step
|
||||||
local node = minetest.registered_nodes[crop]
|
local node = minetest.registered_nodes[crop]
|
||||||
if node then
|
if node then
|
||||||
fp(def.seed, def.crop .. "_1", crop, def.trellis)
|
fp(def.seed, def.crop .. "_1", crop, def.trellis)
|
||||||
return node.groups and node.groups.growing
|
return node.groups and node.groups.growing
|
||||||
@ -63,7 +63,9 @@ if farming.mod == "redo" then
|
|||||||
-- everything except cocoa (these can only be placed on jungletree)
|
-- everything except cocoa (these can only be placed on jungletree)
|
||||||
if name ~= "farming:cocoa_beans" then
|
if name ~= "farming:cocoa_beans" then
|
||||||
local step = def.steps
|
local step = def.steps
|
||||||
while fp_grows(def, step) do step = step + 1 end
|
if step then
|
||||||
|
while fp_grows(def, step) do step = step + 1 end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -89,6 +89,19 @@ Available worlds will be converted to 'lsqlite3', but there is no way back, so:
|
|||||||
|
|
||||||
### History
|
### History
|
||||||
|
|
||||||
|
**2023-02-04 V1.10**
|
||||||
|
- Improve flycontroller
|
||||||
|
- Remove handover for movecontroller
|
||||||
|
- Rename "techage:signal_lamp" to "techage:color_lamp"
|
||||||
|
- Rename "techage:signal_lamp2" to "techage:color_lamp2"
|
||||||
|
- Add countdown mode to TA4 Detector
|
||||||
|
- Adapt to new beduino and minecart versions
|
||||||
|
- Improve manuals
|
||||||
|
- flycontroller/movecontroller: Allow moving blocks through unloaded areas
|
||||||
|
- playerdetector: Add wrench menu to configure search radius
|
||||||
|
- Default furnace: Don't use items filled from the top as fuel
|
||||||
|
- Many further improvements and bug fixes from joe7575 and Niklp09
|
||||||
|
|
||||||
**2022-09-03 V1.09**
|
**2022-09-03 V1.09**
|
||||||
- Change the way items are pushed
|
- Change the way items are pushed
|
||||||
- Add "Flow Limiter" mode to TA4 pump and TA4 pusher
|
- Add "Flow Limiter" mode to TA4 pump and TA4 pusher
|
||||||
|
@ -266,6 +266,11 @@ if techage.max_num_forceload_blocks > 0 then
|
|||||||
output = "techage:forceloadtile",
|
output = "techage:forceloadtile",
|
||||||
recipe = {"techage:forceload"},
|
recipe = {"techage:forceload"},
|
||||||
})
|
})
|
||||||
|
minetest.register_craft({
|
||||||
|
type = "shapeless",
|
||||||
|
output = "techage:forceload",
|
||||||
|
recipe = {"techage:forceloadtile"},
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_on_joinplayer(function(player)
|
minetest.register_on_joinplayer(function(player)
|
||||||
|
@ -17,7 +17,7 @@ local M = minetest.get_meta
|
|||||||
local S = techage.S
|
local S = techage.S
|
||||||
|
|
||||||
-- Consumer Related Data
|
-- Consumer Related Data
|
||||||
local CRD = function(pos) return (minetest.registered_nodes[techage.get_node_lvm(pos).name] or {}).consumer end
|
local CRD = function(pos) return (minetest.registered_nodes[techage.get_node_lvm(pos).name] or {}).consumer or {} end
|
||||||
|
|
||||||
local STANDBY_TICKS = 3
|
local STANDBY_TICKS = 3
|
||||||
local COUNTDOWN_TICKS = 4
|
local COUNTDOWN_TICKS = 4
|
||||||
|
@ -341,7 +341,7 @@ local tubing = {
|
|||||||
CRD(pos).State:stop(pos, nvm)
|
CRD(pos).State:stop(pos, nvm)
|
||||||
config_item(pos, payload)
|
config_item(pos, payload)
|
||||||
return 0
|
return 0
|
||||||
elseif topic == 68 then -- Set push limit
|
elseif topic == 68 or topic == 20 then -- Set push limit
|
||||||
local nvm = techage.get_nvm(pos)
|
local nvm = techage.get_nvm(pos)
|
||||||
CRD(pos).State:stop(pos, nvm)
|
CRD(pos).State:stop(pos, nvm)
|
||||||
set_limit(pos, nvm, payload[1])
|
set_limit(pos, nvm, payload[1])
|
||||||
|
@ -196,6 +196,9 @@ local function quarry_task(pos, crd, nvm)
|
|||||||
pos1.y = y_curr
|
pos1.y = y_curr
|
||||||
pos2.y = y_curr
|
pos2.y = y_curr
|
||||||
|
|
||||||
|
-- Restarting the server can detach the coroutine data.
|
||||||
|
-- Therefore, read nvm again.
|
||||||
|
nvm = techage.get_nvm(pos)
|
||||||
nvm.level = y_first - y_curr
|
nvm.level = y_first - y_curr
|
||||||
|
|
||||||
if minetest.is_area_protected(pos1, pos2, owner, 5) then
|
if minetest.is_area_protected(pos1, pos2, owner, 5) then
|
||||||
@ -382,6 +385,11 @@ local tubing = {
|
|||||||
end,
|
end,
|
||||||
on_node_load = function(pos)
|
on_node_load = function(pos)
|
||||||
CRD(pos).State:on_node_load(pos)
|
CRD(pos).State:on_node_load(pos)
|
||||||
|
local nvm = techage.get_nvm(pos)
|
||||||
|
if nvm.techage_state == techage.RUNNING then
|
||||||
|
stop_sound(pos)
|
||||||
|
play_sound(pos)
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,6 +346,20 @@ local function count_number_of_chests(pos)
|
|||||||
M(pos):set_int("stacksize", STACK_SIZE * cnt)
|
M(pos):set_int("stacksize", STACK_SIZE * cnt)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function dummy_chest_behind(pos, node)
|
||||||
|
local dir = techage.side_to_outdir("B", node.param2)
|
||||||
|
local pos1 = tubelib2.get_pos(pos, dir)
|
||||||
|
node = techage.get_node_lvm(pos1)
|
||||||
|
return node.name == "techage:ta4_chest_dummy"
|
||||||
|
end
|
||||||
|
|
||||||
|
local function part_of_a_chain(pos, node)
|
||||||
|
local dir = techage.side_to_outdir("F", node.param2)
|
||||||
|
local pos1 = tubelib2.get_pos(pos, dir)
|
||||||
|
node = techage.get_node_lvm(pos1)
|
||||||
|
return node.name == "techage:ta4_chest_dummy" or node.name == "techage:ta4_chest"
|
||||||
|
end
|
||||||
|
|
||||||
local function search_chest_in_front(pos, node)
|
local function search_chest_in_front(pos, node)
|
||||||
local dir = techage.side_to_outdir("F", node.param2)
|
local dir = techage.side_to_outdir("F", node.param2)
|
||||||
local pos1 = tubelib2.get_pos(pos, dir)
|
local pos1 = tubelib2.get_pos(pos, dir)
|
||||||
@ -529,6 +543,10 @@ minetest.register_node("techage:ta4_chest", {
|
|||||||
|
|
||||||
after_place_node = function(pos, placer)
|
after_place_node = function(pos, placer)
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
|
if dummy_chest_behind(pos, node) then
|
||||||
|
minetest.remove_node(pos)
|
||||||
|
return true
|
||||||
|
end
|
||||||
if search_chest_in_front(pos, node) then
|
if search_chest_in_front(pos, node) then
|
||||||
node.name = "techage:ta4_chest_dummy"
|
node.name = "techage:ta4_chest_dummy"
|
||||||
minetest.swap_node(pos, node)
|
minetest.swap_node(pos, node)
|
||||||
@ -667,6 +685,18 @@ techage.register_node({"techage:ta4_chest_dummy"}, {
|
|||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_lbm({
|
||||||
|
label = "Repair Dummy Chests",
|
||||||
|
name = "techage:chest_dummy",
|
||||||
|
nodenames = {"techage:ta4_chest_dummy"},
|
||||||
|
run_at_every_load = true,
|
||||||
|
action = function(pos, node)
|
||||||
|
if not part_of_a_chain(pos, node) then
|
||||||
|
minetest.swap_node(pos, {name = "techage:ta4_chest", param2 = node.param2})
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
type = "shapeless",
|
type = "shapeless",
|
||||||
output = "techage:ta4_chest",
|
output = "techage:ta4_chest",
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
TechAge
|
TechAge
|
||||||
=======
|
=======
|
||||||
|
|
||||||
Copyright (C) 2020-2022 Joachim Stolberg
|
Copyright (C) 2020-2023 Joachim Stolberg
|
||||||
|
|
||||||
AGPL v3
|
AGPL v3
|
||||||
See LICENSE.txt for more information
|
See LICENSE.txt for more information
|
||||||
@ -30,26 +30,6 @@ local function lvect_add_vec(lvect1, offs)
|
|||||||
return lvect2
|
return lvect2
|
||||||
end
|
end
|
||||||
|
|
||||||
local function lvect_add(lvect1, lvect2)
|
|
||||||
if not lvect1 or not lvect2 then return end
|
|
||||||
|
|
||||||
local lvect3 = {}
|
|
||||||
for i, v in ipairs(lvect1) do
|
|
||||||
lvect3[#lvect3 + 1] = vector.add(v, lvect2[i])
|
|
||||||
end
|
|
||||||
return lvect3
|
|
||||||
end
|
|
||||||
|
|
||||||
local function lvect_subtract(lvect1, lvect2)
|
|
||||||
if not lvect1 or not lvect2 then return end
|
|
||||||
|
|
||||||
local lvect3 = {}
|
|
||||||
for i, v in ipairs(lvect1) do
|
|
||||||
lvect3[#lvect3 + 1] = vector.subtract(v, lvect2[i])
|
|
||||||
end
|
|
||||||
return lvect3
|
|
||||||
end
|
|
||||||
|
|
||||||
-- yaw in radiant
|
-- yaw in radiant
|
||||||
local function rotate(v, yaw)
|
local function rotate(v, yaw)
|
||||||
local sinyaw = math.sin(yaw)
|
local sinyaw = math.sin(yaw)
|
||||||
@ -61,7 +41,6 @@ local function set_node(item)
|
|||||||
local dest_pos = item.dest_pos
|
local dest_pos = item.dest_pos
|
||||||
local name = item.name or "air"
|
local name = item.name or "air"
|
||||||
local param2 = item.param2 or 0
|
local param2 = item.param2 or 0
|
||||||
local metadata = item.metadata or {}
|
|
||||||
local nvm = techage.get_nvm(item.base_pos)
|
local nvm = techage.get_nvm(item.base_pos)
|
||||||
local node = techage.get_node_lvm(dest_pos)
|
local node = techage.get_node_lvm(dest_pos)
|
||||||
local ndef1 = minetest.registered_nodes[name]
|
local ndef1 = minetest.registered_nodes[name]
|
||||||
@ -100,7 +79,7 @@ local function push(item)
|
|||||||
queue[last] = item
|
queue[last] = item
|
||||||
end
|
end
|
||||||
|
|
||||||
local function pop(nvm, time)
|
local function pop()
|
||||||
if first > last then return end
|
if first > last then return end
|
||||||
local item = queue[first]
|
local item = queue[first]
|
||||||
queue[first] = nil -- to allow garbage collection
|
queue[first] = nil -- to allow garbage collection
|
||||||
@ -408,6 +387,9 @@ local function entity_to_node(pos, obj)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Create a node entitiy.
|
||||||
|
-- * base_pos is controller block related
|
||||||
|
-- * start_pos and dest_pos are entity positions
|
||||||
local function node_to_entity(base_pos, start_pos, dest_pos)
|
local function node_to_entity(base_pos, start_pos, dest_pos)
|
||||||
local meta = M(start_pos)
|
local meta = M(start_pos)
|
||||||
local node, metadata
|
local node, metadata
|
||||||
@ -464,9 +446,9 @@ local function determine_dir(pos1, pos2)
|
|||||||
return {x=0, y=0, z=0}
|
return {x=0, y=0, z=0}
|
||||||
end
|
end
|
||||||
|
|
||||||
local function move_entity(obj, dest_pos, dir, is_corner)
|
local function move_entity(obj, next_pos, dir, is_corner)
|
||||||
local self = obj:get_luaentity()
|
local self = obj:get_luaentity()
|
||||||
self.dest_pos = dest_pos
|
self.next_pos = next_pos
|
||||||
self.dir = dir
|
self.dir = dir
|
||||||
if is_corner then
|
if is_corner then
|
||||||
local vel = vector.multiply(dir, math.min(CORNER_SPEED, self.max_speed))
|
local vel = vector.multiply(dir, math.min(CORNER_SPEED, self.max_speed))
|
||||||
@ -477,7 +459,7 @@ local function move_entity(obj, dest_pos, dir, is_corner)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function moveon_entity(obj, self, pos1)
|
local function moveon_entity(obj, self, pos1)
|
||||||
local pos2 = next_path_pos(pos1, self.lpath, self.path_idx)
|
local pos2 = next_path_pos(pos1, self.lmove, self.path_idx)
|
||||||
if pos2 then
|
if pos2 then
|
||||||
self.path_idx = self.path_idx + 1
|
self.path_idx = self.path_idx + 1
|
||||||
local dir = determine_dir(pos1, pos2)
|
local dir = determine_dir(pos1, pos2)
|
||||||
@ -486,43 +468,6 @@ local function moveon_entity(obj, self, pos1)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Handover the entity to the next movecontroller
|
|
||||||
local function handover_to(obj, self, pos1)
|
|
||||||
if self.handover then
|
|
||||||
local info = techage.get_node_info(self.handover)
|
|
||||||
if info and info.name == "techage:ta4_movecontroller" then
|
|
||||||
local meta = M(info.pos)
|
|
||||||
if self.move2to1 then
|
|
||||||
self.handover = meta:contains("handoverA") and meta:get_string("handoverA") or nil
|
|
||||||
else
|
|
||||||
self.handover = meta:contains("handoverB") and meta:get_string("handoverB") or nil
|
|
||||||
end
|
|
||||||
|
|
||||||
self.lpath = flylib.to_path(meta:get_string("path"))
|
|
||||||
if pos1 and self.lpath then
|
|
||||||
self.path_idx = 2
|
|
||||||
if self.move2to1 then
|
|
||||||
self.lpath[1] = vector.multiply(self.lpath[1], - 1)
|
|
||||||
end
|
|
||||||
local pos2 = next_path_pos(pos1, self.lpath, 1)
|
|
||||||
local dir = determine_dir(pos1, pos2)
|
|
||||||
if not self.handover then
|
|
||||||
local nvm = techage.get_nvm(info.pos)
|
|
||||||
nvm.lpos1 = nvm.lpos1 or {}
|
|
||||||
if self.move2to1 then
|
|
||||||
nvm.lpos1[self.pos1_idx] = pos2
|
|
||||||
|
|
||||||
else
|
|
||||||
nvm.lpos1[self.pos1_idx] = pos1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
move_entity(obj, pos2, dir)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_entity("techage:move_item", {
|
minetest.register_entity("techage:move_item", {
|
||||||
initial_properties = {
|
initial_properties = {
|
||||||
pointable = true,
|
pointable = true,
|
||||||
@ -538,62 +483,47 @@ minetest.register_entity("techage:move_item", {
|
|||||||
|
|
||||||
on_step = function(self, dtime, moveresult)
|
on_step = function(self, dtime, moveresult)
|
||||||
local stop_obj = function(obj, self)
|
local stop_obj = function(obj, self)
|
||||||
local dest_pos = self.dest_pos
|
local next_pos = self.next_pos
|
||||||
obj:move_to(self.dest_pos, true)
|
obj:move_to(self.next_pos, true)
|
||||||
obj:set_acceleration({x=0, y=0, z=0})
|
obj:set_acceleration({x=0, y=0, z=0})
|
||||||
obj:set_velocity({x=0, y=0, z=0})
|
obj:set_velocity({x=0, y=0, z=0})
|
||||||
self.dest_pos = nil
|
self.next_pos = nil
|
||||||
self.old_dist = nil
|
self.old_dist = nil
|
||||||
return dest_pos
|
return next_pos
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.dest_pos then
|
if self.next_pos then
|
||||||
local obj = self.object
|
local obj = self.object
|
||||||
local pos = obj:get_pos()
|
local pos = obj:get_pos()
|
||||||
local dist = vector.distance(pos, self.dest_pos)
|
local dist = vector.distance(pos, self.next_pos)
|
||||||
local speed = calc_speed(obj:get_velocity())
|
local speed = calc_speed(obj:get_velocity())
|
||||||
self.old_dist = self.old_dist or dist
|
self.old_dist = self.old_dist or dist
|
||||||
|
|
||||||
-- Landing
|
if self.lmove and self.lmove[self.path_idx] then
|
||||||
if self.lpath and self.lpath[self.path_idx] then
|
|
||||||
if dist < 1 or dist > self.old_dist then
|
if dist < 1 or dist > self.old_dist then
|
||||||
local dest_pos = stop_obj(obj, self)
|
-- change of direction
|
||||||
if not moveon_entity(obj, self, dest_pos) then
|
local next_pos = stop_obj(obj, self)
|
||||||
minetest.after(0.5, entity_to_node, dest_pos, obj)
|
if not moveon_entity(obj, self, next_pos) then
|
||||||
|
minetest.after(0.5, entity_to_node, next_pos, obj)
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
elseif self.handover and dist < 0.2 or dist > self.old_dist then
|
elseif dist < 0.05 or dist > self.old_dist then
|
||||||
local dest_pos = stop_obj(obj, self)
|
-- Landing
|
||||||
if not handover_to(obj, self, dest_pos) then
|
local next_pos = stop_obj(obj, self)
|
||||||
minetest.after(0.5, entity_to_node, dest_pos, obj)
|
local dest_pos = self.item.dest_pos or next_pos
|
||||||
end
|
minetest.after(0.5, entity_to_node, dest_pos, obj)
|
||||||
return
|
return
|
||||||
else
|
|
||||||
if dist < 0.05 or dist > self.old_dist then
|
|
||||||
local dest_pos = stop_obj(obj, self)
|
|
||||||
minetest.after(0.5, entity_to_node, dest_pos, obj)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
self.old_dist = dist
|
self.old_dist = dist
|
||||||
|
|
||||||
-- Braking or limit max speed
|
-- Braking or limit max speed
|
||||||
if self.handover then
|
if speed > (dist * 2) or speed > self.max_speed then
|
||||||
if speed > (dist * 4) or speed > self.max_speed then
|
speed = math.min(speed, math.max(dist * 2, MIN_SPEED))
|
||||||
speed = math.min(speed, math.max(dist * 4, MIN_SPEED))
|
local vel = vector.multiply(self.dir,speed)
|
||||||
local vel = vector.multiply(self.dir,speed)
|
obj:set_velocity(vel)
|
||||||
obj:set_velocity(vel)
|
obj:set_acceleration({x=0, y=0, z=0})
|
||||||
obj:set_acceleration({x=0, y=0, z=0})
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if speed > (dist * 2) or speed > self.max_speed then
|
|
||||||
speed = math.min(speed, math.max(dist * 2, MIN_SPEED))
|
|
||||||
local vel = vector.multiply(self.dir,speed)
|
|
||||||
obj:set_velocity(vel)
|
|
||||||
obj:set_acceleration({x=0, y=0, z=0})
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
monitoring_trigger_entity(self.item)
|
monitoring_trigger_entity(self.item)
|
||||||
@ -618,30 +548,34 @@ local function is_simple_node(pos)
|
|||||||
return not techage.is_air_like(node.name) and techage.can_dig_node(node.name, ndef)
|
return not techage.is_air_like(node.name) and techage.can_dig_node(node.name, ndef)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function move_node(pos, pos1_idx, start_pos, lpath, max_speed, height, move2to1, handover, cpos)
|
-- Move node from 'pos1' to the destination, calculated by means of 'lmove'
|
||||||
local pos2 = next_path_pos(start_pos, lpath, 1)
|
-- * pos and meta are controller block related
|
||||||
|
-- * lmove is the movement as a list of `moves`
|
||||||
|
-- * height is move block height as value between 0 and 1 and used to calculate the offset
|
||||||
|
-- for the attached object (player).
|
||||||
|
local function move_node(pos, meta, pos1, lmove, max_speed, height)
|
||||||
|
local pos2 = next_path_pos(pos1, lmove, 1)
|
||||||
|
local offs = dest_offset(lmove)
|
||||||
|
local dest_pos = vector.add(pos1, offs)
|
||||||
-- optional for non-player objects
|
-- optional for non-player objects
|
||||||
local yoffs = M(pos):get_float("offset")
|
local yoffs = meta:get_float("offset")
|
||||||
|
|
||||||
if pos2 then
|
if pos2 then
|
||||||
local dir = determine_dir(start_pos, pos2)
|
local dir = determine_dir(pos1, pos2)
|
||||||
local obj = node_to_entity(pos, start_pos, pos2)
|
local obj = node_to_entity(pos, pos1, dest_pos)
|
||||||
|
|
||||||
if obj then
|
if obj then
|
||||||
local offs = {x=0, y=height or 1, z=0}
|
local offs = {x=0, y=height or 1, z=0}
|
||||||
attach_objects(start_pos, offs, obj, yoffs)
|
attach_objects(pos1, offs, obj, yoffs)
|
||||||
if dir.y == 0 then
|
if dir.y == 0 then
|
||||||
if (dir.x ~= 0 and dir.z == 0) or (dir.x == 0 and dir.z ~= 0) then
|
if (dir.x ~= 0 and dir.z == 0) or (dir.x == 0 and dir.z ~= 0) then
|
||||||
attach_objects(start_pos, dir, obj, yoffs)
|
attach_objects(pos1, dir, obj, yoffs)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local self = obj:get_luaentity()
|
local self = obj:get_luaentity()
|
||||||
self.path_idx = 2
|
self.path_idx = 2
|
||||||
self.pos1_idx = pos1_idx
|
self.lmove = lmove
|
||||||
self.lpath = lpath
|
|
||||||
self.max_speed = max_speed
|
self.max_speed = max_speed
|
||||||
self.move2to1 = move2to1
|
|
||||||
self.handover = handover
|
|
||||||
self.yoffs = yoffs
|
self.yoffs = yoffs
|
||||||
move_entity(obj, pos2, dir)
|
move_entity(obj, pos2, dir)
|
||||||
return true
|
return true
|
||||||
@ -651,14 +585,20 @@ local function move_node(pos, pos1_idx, start_pos, lpath, max_speed, height, mov
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function move_nodes(pos, meta, nvm, lpath, max_speed, height, move2to1, handover)
|
-- Move the nodes from nvm.lpos1 to nvm.lpos2
|
||||||
|
-- * nvm.lpos1 is a list of nodes
|
||||||
|
-- * lmove is the movement as a list of `moves`
|
||||||
|
-- * pos, meta, and nvm are controller block related
|
||||||
|
--- height is move block height as value between 0 and 1 and used to calculate the offset
|
||||||
|
-- for the attached object (player).
|
||||||
|
local function multi_move_nodes(pos, meta, nvm, lmove, max_speed, height, move2to1)
|
||||||
local owner = meta:get_string("owner")
|
local owner = meta:get_string("owner")
|
||||||
techage.counting_add(owner, #lpath, #nvm.lpos1 * #lpath)
|
techage.counting_add(owner, #lmove, #nvm.lpos1 * #lmove)
|
||||||
|
|
||||||
for idx = 1, #nvm.lpos1 do
|
for idx = 1, #nvm.lpos1 do
|
||||||
local pos1 = nvm.lpos1[idx]
|
local pos1 = nvm.lpos1[idx]
|
||||||
local pos2 = nvm.lpos2[idx]
|
local pos2 = nvm.lpos2[idx]
|
||||||
--print("move_nodes", idx, P2S(pos1), P2S(pos2))
|
--print("multi_move_nodes", idx, P2S(pos1), P2S(pos2))
|
||||||
|
|
||||||
if move2to1 then
|
if move2to1 then
|
||||||
pos1, pos2 = pos2, pos1
|
pos1, pos2 = pos2, pos1
|
||||||
@ -666,7 +606,7 @@ local function move_nodes(pos, meta, nvm, lpath, max_speed, height, move2to1, ha
|
|||||||
|
|
||||||
if not minetest.is_protected(pos1, owner) and not minetest.is_protected(pos2, owner) then
|
if not minetest.is_protected(pos1, owner) and not minetest.is_protected(pos2, owner) then
|
||||||
if is_simple_node(pos1) and is_valid_dest(pos2) then
|
if is_simple_node(pos1) and is_valid_dest(pos2) then
|
||||||
if move_node(pos, idx, pos1, lpath, max_speed, height, move2to1, handover) == false then
|
if move_node(pos, meta, pos1, lmove, max_speed, height) == false then
|
||||||
meta:set_string("status", S("No valid node at the start position"))
|
meta:set_string("status", S("No valid node at the start position"))
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
@ -691,21 +631,27 @@ local function move_nodes(pos, meta, nvm, lpath, max_speed, height, move2to1, ha
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Move nodes from lpos1 by the given x/y/z 'line'
|
-- Move the nodes from lpos1 to lpos2.
|
||||||
local function move_nodes2(pos, meta, lpos1, line, max_speed, height)
|
-- * lpos1 is a list of nodes
|
||||||
|
-- * lpos2 = lpos1 + move
|
||||||
|
-- * pos and meta are controller block related
|
||||||
|
-- * height is move block height as value between 0 and 1 and used to calculate the offset
|
||||||
|
-- for the attached object (player).
|
||||||
|
local function move_nodes(pos, meta, lpos1, move, max_speed, height)
|
||||||
local owner = meta:get_string("owner")
|
local owner = meta:get_string("owner")
|
||||||
|
lpos1 = lpos1 or {}
|
||||||
techage.counting_add(owner, #lpos1)
|
techage.counting_add(owner, #lpos1)
|
||||||
|
|
||||||
local lpos2 = {}
|
local lpos2 = {}
|
||||||
for idx = 1, #lpos1 do
|
for idx = 1, #lpos1 do
|
||||||
|
|
||||||
local pos1 = lpos1[idx]
|
local pos1 = lpos1[idx]
|
||||||
local pos2 = vector.add(lpos1[idx], line)
|
local pos2 = vector.add(lpos1[idx], move)
|
||||||
lpos2[idx] = pos2
|
lpos2[idx] = pos2
|
||||||
|
|
||||||
if not minetest.is_protected(pos1, owner) and not minetest.is_protected(pos2, owner) then
|
if not minetest.is_protected(pos1, owner) and not minetest.is_protected(pos2, owner) then
|
||||||
if is_simple_node(pos1) and is_valid_dest(pos2) then
|
if is_simple_node(pos1) and is_valid_dest(pos2) then
|
||||||
move_node(pos, idx, pos1, {line}, max_speed, height, false, false)
|
move_node(pos, meta, pos1, {move}, max_speed, height)
|
||||||
else
|
else
|
||||||
if not is_simple_node(pos1) then
|
if not is_simple_node(pos1) then
|
||||||
meta:set_string("status", S("No valid node at the start position"))
|
meta:set_string("status", S("No valid node at the start position"))
|
||||||
@ -728,13 +674,14 @@ local function move_nodes2(pos, meta, lpos1, line, max_speed, height)
|
|||||||
return true, lpos2
|
return true, lpos2
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- move2to1 is the direction and is true for 'from pos2 to pos1'
|
||||||
|
-- Move path and other data is stored as meta data of pos
|
||||||
function flylib.move_to_other_pos(pos, move2to1)
|
function flylib.move_to_other_pos(pos, move2to1)
|
||||||
local meta = M(pos)
|
local meta = M(pos)
|
||||||
local nvm = techage.get_nvm(pos)
|
local nvm = techage.get_nvm(pos)
|
||||||
local lpath, err = flylib.to_path(meta:get_string("path")) or {}
|
local lmove, err = flylib.to_path(meta:get_string("path")) or {}
|
||||||
local max_speed = meta:contains("max_speed") and meta:get_int("max_speed") or MAX_SPEED
|
local max_speed = meta:contains("max_speed") and meta:get_int("max_speed") or MAX_SPEED
|
||||||
local height = meta:contains("height") and meta:get_float("height") or 1
|
local height = meta:contains("height") and meta:get_float("height") or 1
|
||||||
local handover
|
|
||||||
|
|
||||||
if err or nvm.running then return false end
|
if err or nvm.running then return false end
|
||||||
|
|
||||||
@ -742,33 +689,28 @@ function flylib.move_to_other_pos(pos, move2to1)
|
|||||||
max_speed = techage.in_range(max_speed, MIN_SPEED, MAX_SPEED)
|
max_speed = techage.in_range(max_speed, MIN_SPEED, MAX_SPEED)
|
||||||
nvm.lpos1 = nvm.lpos1 or {}
|
nvm.lpos1 = nvm.lpos1 or {}
|
||||||
|
|
||||||
local offs = dest_offset(lpath)
|
local offs = dest_offset(lmove)
|
||||||
if move2to1 then
|
if move2to1 then
|
||||||
lpath = reverse_path(lpath)
|
lmove = reverse_path(lmove)
|
||||||
end
|
end
|
||||||
-- calc destination positions
|
-- calc destination positions
|
||||||
nvm.lpos2 = lvect_add_vec(nvm.lpos1, offs)
|
nvm.lpos2 = lvect_add_vec(nvm.lpos1, offs)
|
||||||
|
|
||||||
if move2to1 then
|
nvm.running = multi_move_nodes(pos, meta, nvm, lmove, max_speed, height, move2to1)
|
||||||
handover = meta:contains("handoverA") and meta:get_string("handoverA") or nil
|
|
||||||
else
|
|
||||||
handover = meta:contains("handoverB") and meta:get_string("handoverB") or nil
|
|
||||||
end
|
|
||||||
nvm.running = move_nodes(pos, meta, nvm, lpath, max_speed, height, move2to1, handover)
|
|
||||||
nvm.moveBA = nvm.running and not move2to1
|
nvm.moveBA = nvm.running and not move2to1
|
||||||
return nvm.running
|
return nvm.running
|
||||||
end
|
end
|
||||||
|
|
||||||
function flylib.move_to(pos, line)
|
-- `move` the movement as a vector
|
||||||
|
function flylib.move_to(pos, move)
|
||||||
local meta = M(pos)
|
local meta = M(pos)
|
||||||
local nvm = techage.get_nvm(pos)
|
local nvm = techage.get_nvm(pos)
|
||||||
local height = techage.in_range(meta:contains("height") and meta:get_float("height") or 1, 0, 1)
|
local height = techage.in_range(meta:contains("height") and meta:get_float("height") or 1, 0, 1)
|
||||||
local max_speed = meta:contains("max_speed") and meta:get_int("max_speed") or MAX_SPEED
|
local max_speed = meta:contains("max_speed") and meta:get_int("max_speed") or MAX_SPEED
|
||||||
local resp
|
|
||||||
|
|
||||||
if nvm.running then return false end
|
if nvm.running then return false end
|
||||||
|
|
||||||
nvm.running, nvm.lastpos = move_nodes2(pos, meta, nvm.lastpos or nvm.lpos1, line, max_speed, height)
|
nvm.running, nvm.lastpos = move_nodes(pos, meta, nvm.lastpos or nvm.lpos1, move, max_speed, height)
|
||||||
return nvm.running
|
return nvm.running
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -782,27 +724,28 @@ function flylib.reset_move(pos)
|
|||||||
|
|
||||||
if nvm.lpos1 and nvm.lpos1[1] then
|
if nvm.lpos1 and nvm.lpos1[1] then
|
||||||
local move = vector.subtract(nvm.lpos1[1], (nvm.lastpos or nvm.lpos1)[1])
|
local move = vector.subtract(nvm.lpos1[1], (nvm.lastpos or nvm.lpos1)[1])
|
||||||
local resp
|
|
||||||
|
|
||||||
nvm.running, nvm.lastpos = move_nodes2(pos, meta, nvm.lastpos or nvm.lpos1, move, max_speed, height)
|
nvm.running, nvm.lastpos = move_nodes(pos, meta, nvm.lastpos or nvm.lpos1, move, max_speed, height)
|
||||||
return nvm.running
|
return nvm.running
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- pos is the controller block pos
|
||||||
|
-- lpos is a list of node positions to be moved
|
||||||
-- rot is one of "l", "r", "2l", "2r"
|
-- rot is one of "l", "r", "2l", "2r"
|
||||||
-- cpos is the center pos (optional)
|
function flylib.rotate_nodes(pos, lpos, rot)
|
||||||
function flylib.rotate_nodes(pos, posses1, rot)
|
|
||||||
local meta = M(pos)
|
local meta = M(pos)
|
||||||
local owner = meta:get_string("owner")
|
local owner = meta:get_string("owner")
|
||||||
|
-- cpos is the center pos
|
||||||
local cpos = meta:contains("center") and flylib.to_vector(meta:get_string("center"))
|
local cpos = meta:contains("center") and flylib.to_vector(meta:get_string("center"))
|
||||||
local posses2 = techage.rotate_around_center(posses1, rot, cpos)
|
local lpos2 = techage.rotate_around_center(lpos, rot, cpos)
|
||||||
local param2
|
local param2
|
||||||
local nodes2 = {}
|
local nodes2 = {}
|
||||||
|
|
||||||
techage.counting_add(owner, #posses1 * 2)
|
techage.counting_add(owner, #lpos * 2)
|
||||||
|
|
||||||
for i, pos1 in ipairs(posses1) do
|
for i, pos1 in ipairs(lpos) do
|
||||||
local node = techage.get_node_lvm(pos1)
|
local node = techage.get_node_lvm(pos1)
|
||||||
if rot == "l" then
|
if rot == "l" then
|
||||||
param2 = techage.param2_turn_right(node.param2)
|
param2 = techage.param2_turn_right(node.param2)
|
||||||
@ -813,7 +756,7 @@ function flylib.rotate_nodes(pos, posses1, rot)
|
|||||||
end
|
end
|
||||||
if not minetest.is_protected(pos1, owner) and is_simple_node(pos1) then
|
if not minetest.is_protected(pos1, owner) and is_simple_node(pos1) then
|
||||||
minetest.remove_node(pos1)
|
minetest.remove_node(pos1)
|
||||||
nodes2[#nodes2 + 1] = {pos = posses2[i], name = node.name, param2 = param2}
|
nodes2[#nodes2 + 1] = {pos = lpos2[i], name = node.name, param2 = param2}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for _,item in ipairs(nodes2) do
|
for _,item in ipairs(nodes2) do
|
||||||
@ -821,7 +764,7 @@ function flylib.rotate_nodes(pos, posses1, rot)
|
|||||||
minetest.add_node(item.pos, {name = item.name, param2 = item.param2})
|
minetest.add_node(item.pos, {name = item.name, param2 = item.param2})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return posses2
|
return lpos2
|
||||||
end
|
end
|
||||||
|
|
||||||
function flylib.exchange_node(pos, name, param2)
|
function flylib.exchange_node(pos, name, param2)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
TechAge
|
TechAge
|
||||||
=======
|
=======
|
||||||
|
|
||||||
Copyright (C) 2019-2022 Joachim Stolberg
|
Copyright (C) 2019-2023 Joachim Stolberg
|
||||||
|
|
||||||
AGPL v3
|
AGPL v3
|
||||||
See LICENSE.txt for more information
|
See LICENSE.txt for more information
|
||||||
@ -520,6 +520,20 @@ function NodeStates:on_beduino_request_data(pos, topic, payload)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function NodeStates.get_beduino_state(pos)
|
||||||
|
local node = minetest.get_node(pos)
|
||||||
|
local nvm = techage.get_nvm(pos)
|
||||||
|
if node.name == "ignore" then -- unloaded node?
|
||||||
|
return 0, {techage.UNLOADED}
|
||||||
|
elseif nvm.techage_state == RUNNING then
|
||||||
|
local ttl = (nvm.last_active or 0) + MAX_CYCLE_TIME
|
||||||
|
if ttl < minetest.get_gametime() then
|
||||||
|
return 0, {techage.INACTIVE}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return 0, {nvm.techage_state or STOPPED}
|
||||||
|
end
|
||||||
|
|
||||||
-- restart timer
|
-- restart timer
|
||||||
function NodeStates:on_node_load(pos)
|
function NodeStates:on_node_load(pos)
|
||||||
local nvm = techage.get_nvm(pos)
|
local nvm = techage.get_nvm(pos)
|
||||||
|
@ -55,6 +55,6 @@ minetest.register_on_mods_loaded(function()
|
|||||||
beduino.lib.register_SystemHandler(0x140, ta_kv_init)
|
beduino.lib.register_SystemHandler(0x140, ta_kv_init)
|
||||||
beduino.lib.register_SystemHandler(0x141, ta_kv_add)
|
beduino.lib.register_SystemHandler(0x141, ta_kv_add)
|
||||||
beduino.lib.register_SystemHandler(0x142, ta_kv_get)
|
beduino.lib.register_SystemHandler(0x142, ta_kv_get)
|
||||||
vm16.register_ro_file("beduino", "ta_kvstore.c", kvstore_c)
|
vm16.register_ro_file("beduino", "lib/ta_kvstore.c", kvstore_c)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
@ -30,7 +30,7 @@ local TOTAL_MAX = INV_SIZE * FUEL_STACK_MAX
|
|||||||
|
|
||||||
local function count_coal(metadata)
|
local function count_coal(metadata)
|
||||||
local total = 0
|
local total = 0
|
||||||
for _,stack in pairs(metadata.inventory.fuel) do
|
for _,stack in pairs(metadata.inventory.fuel or {}) do
|
||||||
total = total + stack:get_count()
|
total = total + stack:get_count()
|
||||||
end
|
end
|
||||||
return total
|
return total
|
||||||
|
@ -115,7 +115,7 @@ techage.Items = {
|
|||||||
ta3_sequencer = "techage:ta3_sequencer",
|
ta3_sequencer = "techage:ta3_sequencer",
|
||||||
ta3_timer = "techage:ta3_timer",
|
ta3_timer = "techage:ta3_timer",
|
||||||
ta3_terminal = "techage:terminal2",
|
ta3_terminal = "techage:terminal2",
|
||||||
ta3_signallamp = "techage:signal_lamp_off",
|
ta3_colorlamp = "techage:color_lamp_off",
|
||||||
ta3_doorblock = "techage:doorblock20",
|
ta3_doorblock = "techage:doorblock20",
|
||||||
ta3_programmer = "techage:programmer",
|
ta3_programmer = "techage:programmer",
|
||||||
ta3_doorcontroller = "techage:ta3_doorcontroller",
|
ta3_doorcontroller = "techage:ta3_doorcontroller",
|
||||||
|
@ -113,7 +113,7 @@ techage.manual_DE.aTitel = {
|
|||||||
"3,TA3 Sequenzer / Sequencer",
|
"3,TA3 Sequenzer / Sequencer",
|
||||||
"3,TA3 Timer",
|
"3,TA3 Timer",
|
||||||
"3,TA3 Terminal",
|
"3,TA3 Terminal",
|
||||||
"3,TechAge Signallampe / Signal Lamp",
|
"3,TechAge Farblampe / Color Lamp",
|
||||||
"3,Tür/Tor Blöcke / Door/Gate Blocks",
|
"3,Tür/Tor Blöcke / Door/Gate Blocks",
|
||||||
"3,TA3 Tür Controller / Door Controller",
|
"3,TA3 Tür Controller / Door Controller",
|
||||||
"3,TA3 Tür Controller II / Door Controller II",
|
"3,TA3 Tür Controller II / Door Controller II",
|
||||||
@ -1133,7 +1133,7 @@ techage.manual_DE.aText = {
|
|||||||
"\n"..
|
"\n"..
|
||||||
"\n"..
|
"\n"..
|
||||||
"\n",
|
"\n",
|
||||||
"Die Signallampe kann mit 'on'/'off' Kommando ein- bzw. ausgeschaltet werden. Diese Lampe braucht keinen Strom und\n"..
|
"Die Farblampe kann mit 'on'/'off' Kommando ein- bzw. ausgeschaltet werden. Diese Lampe braucht keinen Strom und\n"..
|
||||||
"kann mit der Spritzpistole aus der Mod \"Unified Dyes\" und über Lua/Beduino Kommandos eingefärbt werden.\n"..
|
"kann mit der Spritzpistole aus der Mod \"Unified Dyes\" und über Lua/Beduino Kommandos eingefärbt werden.\n"..
|
||||||
"\n"..
|
"\n"..
|
||||||
"Mit dem Chat-Kommando '/ta_color' wird die Farbpalette mit den Werten für die Lua/Beduino Kommandos angezeigt und mit '/ta_send color <num>' kann die Farbe geändert werden.\n"..
|
"Mit dem Chat-Kommando '/ta_color' wird die Farbpalette mit den Werten für die Lua/Beduino Kommandos angezeigt und mit '/ta_send color <num>' kann die Farbe geändert werden.\n"..
|
||||||
@ -2282,7 +2282,7 @@ techage.manual_DE.aItemName = {
|
|||||||
"ta3_sequencer",
|
"ta3_sequencer",
|
||||||
"ta3_timer",
|
"ta3_timer",
|
||||||
"ta3_terminal",
|
"ta3_terminal",
|
||||||
"ta3_signallamp",
|
"ta3_colorlamp",
|
||||||
"ta3_doorblock",
|
"ta3_doorblock",
|
||||||
"ta3_doorcontroller",
|
"ta3_doorcontroller",
|
||||||
"ta3_doorcontroller",
|
"ta3_doorcontroller",
|
||||||
|
@ -113,7 +113,7 @@ techage.manual_EN.aTitel = {
|
|||||||
"3,TA3 Sequencer",
|
"3,TA3 Sequencer",
|
||||||
"3,TA3 Timer",
|
"3,TA3 Timer",
|
||||||
"3,TA3 Terminal",
|
"3,TA3 Terminal",
|
||||||
"3,TechAge Signal Lamp",
|
"3,TechAge Color Lamp",
|
||||||
"3,Door/Gate Blocks",
|
"3,Door/Gate Blocks",
|
||||||
"3,TA3 Door Controller",
|
"3,TA3 Door Controller",
|
||||||
"3,TA3 Door Controller II",
|
"3,TA3 Door Controller II",
|
||||||
@ -2286,7 +2286,7 @@ techage.manual_EN.aItemName = {
|
|||||||
"ta3_sequencer",
|
"ta3_sequencer",
|
||||||
"ta3_timer",
|
"ta3_timer",
|
||||||
"ta3_terminal",
|
"ta3_terminal",
|
||||||
"ta3_signallamp",
|
"ta3_colorlamp",
|
||||||
"ta3_doorblock",
|
"ta3_doorblock",
|
||||||
"ta3_doorcontroller",
|
"ta3_doorcontroller",
|
||||||
"ta3_doorcontroller",
|
"ta3_doorcontroller",
|
||||||
|
@ -217,7 +217,6 @@ minetest.register_node("techage:ta5_fr_controller_pas", {
|
|||||||
on_timer = node_timer,
|
on_timer = node_timer,
|
||||||
after_dig_node = after_dig_node,
|
after_dig_node = after_dig_node,
|
||||||
on_receive_fields = on_receive_fields,
|
on_receive_fields = on_receive_fields,
|
||||||
drawtype = "nodebox",
|
|
||||||
paramtype2 = "facedir",
|
paramtype2 = "facedir",
|
||||||
groups = {choppy=2, cracky=2, crumbly=2},
|
groups = {choppy=2, cracky=2, crumbly=2},
|
||||||
is_ground_content = false,
|
is_ground_content = false,
|
||||||
@ -257,7 +256,6 @@ minetest.register_node("techage:ta5_fr_controller_act", {
|
|||||||
on_timer = node_timer,
|
on_timer = node_timer,
|
||||||
after_dig_node = after_dig_node,
|
after_dig_node = after_dig_node,
|
||||||
on_receive_fields = on_receive_fields,
|
on_receive_fields = on_receive_fields,
|
||||||
drawtype = "nodebox",
|
|
||||||
paramtype2 = "facedir",
|
paramtype2 = "facedir",
|
||||||
groups = {choppy=2, cracky=2, crumbly=2, not_in_creative_inventory=1},
|
groups = {choppy=2, cracky=2, crumbly=2, not_in_creative_inventory=1},
|
||||||
drop = "",
|
drop = "",
|
||||||
|
@ -54,7 +54,6 @@ minetest.register_node("techage:ta5_magnet1", {
|
|||||||
Cable:after_dig_node(pos)
|
Cable:after_dig_node(pos)
|
||||||
techage.del_mem(pos)
|
techage.del_mem(pos)
|
||||||
end,
|
end,
|
||||||
drawtype = "nodebox",
|
|
||||||
paramtype2 = "facedir",
|
paramtype2 = "facedir",
|
||||||
groups = {choppy=2, cracky=2, crumbly=2},
|
groups = {choppy=2, cracky=2, crumbly=2},
|
||||||
is_ground_content = false,
|
is_ground_content = false,
|
||||||
@ -88,7 +87,6 @@ minetest.register_node("techage:ta5_magnet2", {
|
|||||||
Cable:after_dig_node(pos)
|
Cable:after_dig_node(pos)
|
||||||
techage.del_mem(pos)
|
techage.del_mem(pos)
|
||||||
end,
|
end,
|
||||||
drawtype = "nodebox",
|
|
||||||
paramtype2 = "facedir",
|
paramtype2 = "facedir",
|
||||||
groups = {choppy=2, cracky=2, crumbly=2},
|
groups = {choppy=2, cracky=2, crumbly=2},
|
||||||
is_ground_content = false,
|
is_ground_content = false,
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
TechAge
|
TechAge
|
||||||
=======
|
=======
|
||||||
|
|
||||||
Copyright (C) 2019-2022 Joachim Stolberg
|
Copyright (C) 2019-2023 Joachim Stolberg
|
||||||
|
|
||||||
AGPL v3
|
AGPL v3
|
||||||
See LICENSE.txt for more information
|
See LICENSE.txt for more information
|
||||||
@ -13,7 +13,7 @@
|
|||||||
techage = {}
|
techage = {}
|
||||||
|
|
||||||
-- Version for compatibility checks, see readme.md/history
|
-- Version for compatibility checks, see readme.md/history
|
||||||
techage.version = 1.08
|
techage.version = 1.10
|
||||||
|
|
||||||
if minetest.global_exists("tubelib") then
|
if minetest.global_exists("tubelib") then
|
||||||
minetest.log("error", "[techage] Techage can't be used together with the mod tubelib!")
|
minetest.log("error", "[techage] Techage can't be used together with the mod tubelib!")
|
||||||
@ -27,8 +27,8 @@ elseif minetest.global_exists("techpack") then
|
|||||||
elseif minetest.global_exists("tubelib2") and tubelib2.version < 2.2 then
|
elseif minetest.global_exists("tubelib2") and tubelib2.version < 2.2 then
|
||||||
minetest.log("error", "[techage] Techage requires tubelib2 version 2.2 or newer!")
|
minetest.log("error", "[techage] Techage requires tubelib2 version 2.2 or newer!")
|
||||||
return
|
return
|
||||||
elseif minetest.global_exists("minecart") and minecart.version < 1.08 then
|
elseif minetest.global_exists("minecart") and minecart.version < 2.03 then
|
||||||
minetest.log("error", "[techage] Techage requires minecart version 1.08 or newer!")
|
minetest.log("error", "[techage] Techage requires minecart version 2.03 or newer!")
|
||||||
return
|
return
|
||||||
elseif minetest.global_exists("lcdlib") and lcdlib.version < 1.01 then
|
elseif minetest.global_exists("lcdlib") and lcdlib.version < 1.01 then
|
||||||
minetest.log("error", "[techage] Techage requires lcdlib version 1.01 or newer!")
|
minetest.log("error", "[techage] Techage requires lcdlib version 1.01 or newer!")
|
||||||
|
@ -43,6 +43,13 @@ else
|
|||||||
sounds = default.node_sound_stone_defaults(),
|
sounds = default.node_sound_stone_defaults(),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
-- Needs to be a techage recipe, not to overwrite the clay/bakedclay recipe
|
||||||
|
techage.furnace.register_recipe({
|
||||||
|
output = "techage:cement_block",
|
||||||
|
recipe = {
|
||||||
|
"default:clay",
|
||||||
|
},
|
||||||
|
})
|
||||||
techage.add_grinder_recipe({input="techage:cement_block", output="techage:cement_powder"})
|
techage.add_grinder_recipe({input="techage:cement_block", output="techage:cement_powder"})
|
||||||
techage.add_grinder_recipe({input="bakedclay:white", output="techage:cement_powder"})
|
techage.add_grinder_recipe({input="bakedclay:white", output="techage:cement_powder"})
|
||||||
end
|
end
|
||||||
|
@ -30,16 +30,16 @@ if minetest.global_exists("mesecon") then
|
|||||||
},
|
},
|
||||||
time = 6,
|
time = 6,
|
||||||
})
|
})
|
||||||
else
|
|
||||||
techage.furnace.register_recipe({
|
|
||||||
output = "techage:ta4_silicon_wafer 16",
|
|
||||||
recipe = {
|
|
||||||
"basic_materials:silicon",
|
|
||||||
"basic_materials:silicon",
|
|
||||||
"basic_materials:silicon",
|
|
||||||
"techage:baborium_ingot"
|
|
||||||
},
|
|
||||||
time = 6,
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
|
techage.furnace.register_recipe({
|
||||||
|
output = "techage:ta4_silicon_wafer 16",
|
||||||
|
recipe = {
|
||||||
|
"basic_materials:silicon",
|
||||||
|
"basic_materials:silicon",
|
||||||
|
"basic_materials:silicon",
|
||||||
|
"techage:baborium_ingot"
|
||||||
|
},
|
||||||
|
time = 6,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -171,11 +171,26 @@ minetest.register_craft({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
local function contains(table, element)
|
||||||
|
for _, value in pairs(table) do
|
||||||
|
if value == element then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
function techage.register_flower(name)
|
function techage.register_flower(name)
|
||||||
|
if contains(Flowers, name) then
|
||||||
|
return
|
||||||
|
end
|
||||||
Flowers[#Flowers+1] = name
|
Flowers[#Flowers+1] = name
|
||||||
end
|
end
|
||||||
|
|
||||||
function techage.register_plant(name)
|
function techage.register_plant(name)
|
||||||
|
if contains(Plants, name) then
|
||||||
|
return
|
||||||
|
end
|
||||||
Plants[name] = true
|
Plants[name] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -201,4 +216,5 @@ minetest.after(1, function()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
-- print(dump(Flowers))
|
||||||
end)
|
end)
|
||||||
|
@ -343,7 +343,7 @@ techage.register_node({"techage:t4_pump", "techage:t4_pump_on"}, {
|
|||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
on_beduino_receive_cmnd = function(pos, src, topic, payload)
|
on_beduino_receive_cmnd = function(pos, src, topic, payload)
|
||||||
if topic == 69 and payload then -- Set pump limit
|
if (topic == 69 or topic == 21) and payload then -- Set pump limit
|
||||||
local nvm = techage.get_nvm(pos)
|
local nvm = techage.get_nvm(pos)
|
||||||
State4:stop(pos, nvm)
|
State4:stop(pos, nvm)
|
||||||
if payload[1] > 0 then
|
if payload[1] > 0 then
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
TechAge
|
TechAge
|
||||||
=======
|
=======
|
||||||
|
|
||||||
Copyright (C) 2017-2020 Joachim Stolberg
|
Copyright (C) 2017-2023 Joachim Stolberg
|
||||||
|
|
||||||
AGPL v3
|
AGPL v3
|
||||||
See LICENSE.txt for more information
|
See LICENSE.txt for more information
|
||||||
@ -394,11 +394,16 @@ minetest.register_craft({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
techage.register_node({"techage:ta3_button_off", "techage:ta3_button_on"}, {})
|
||||||
|
|
||||||
techage.register_node({
|
techage.register_node({
|
||||||
"techage:ta4_button_off", "techage:ta4_button_on",
|
"techage:ta4_button_off", "techage:ta4_button_on",
|
||||||
}, {
|
}, {
|
||||||
on_recv_message = function(pos, src, topic, payload)
|
on_recv_message = function(pos, src, topic, payload)
|
||||||
if topic == "name" then
|
if topic == "state" then
|
||||||
|
local name = techage.get_node_lvm(pos).name
|
||||||
|
return name == "techage:ta4_button_on" and "on" or "off"
|
||||||
|
elseif topic == "name" then
|
||||||
local mem = techage.get_mem(pos)
|
local mem = techage.get_mem(pos)
|
||||||
return mem.clicker or ""
|
return mem.clicker or ""
|
||||||
elseif topic == "time" then
|
elseif topic == "time" then
|
||||||
@ -409,7 +414,10 @@ techage.register_node({
|
|||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
on_beduino_request_data = function(pos, src, topic, payload)
|
on_beduino_request_data = function(pos, src, topic, payload)
|
||||||
if topic == 144 then -- Player Name
|
if topic == 131 then -- State
|
||||||
|
local name = techage.get_node_lvm(pos).name
|
||||||
|
return 0, name == "techage:ta4_button_on" and {1} or {0}
|
||||||
|
elseif topic == 144 then -- Player Name
|
||||||
local mem = techage.get_mem(pos)
|
local mem = techage.get_mem(pos)
|
||||||
return 0, mem.clicker
|
return 0, mem.clicker
|
||||||
elseif topic == 149 then --time
|
elseif topic == 149 then --time
|
||||||
|
@ -244,6 +244,8 @@ minetest.register_node("techage:ta4_button_2x", {
|
|||||||
sounds = default.node_sound_glass_defaults(),
|
sounds = default.node_sound_glass_defaults(),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
techage.register_node({"techage:ta4_button_2x"}, {})
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
output = "techage:ta4_button_2x",
|
output = "techage:ta4_button_2x",
|
||||||
recipe = {
|
recipe = {
|
||||||
@ -252,3 +254,12 @@ minetest.register_craft({
|
|||||||
{"", "", ""},
|
{"", "", ""},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "techage:ta4_button_off 2",
|
||||||
|
recipe = {
|
||||||
|
{"", "", ""},
|
||||||
|
{"", "techage:ta4_button_2x", ""},
|
||||||
|
{"", "", ""},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
@ -300,6 +300,8 @@ minetest.register_node("techage:ta4_button_4x", {
|
|||||||
sounds = default.node_sound_glass_defaults(),
|
sounds = default.node_sound_glass_defaults(),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
techage.register_node({"techage:ta4_button_4x"}, {})
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
output = "techage:ta4_button_4x",
|
output = "techage:ta4_button_4x",
|
||||||
recipe = {
|
recipe = {
|
||||||
@ -308,3 +310,12 @@ minetest.register_craft({
|
|||||||
{"", "", ""},
|
{"", "", ""},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "techage:ta4_button_off 4",
|
||||||
|
recipe = {
|
||||||
|
{"", "", ""},
|
||||||
|
{"", "techage:ta4_button_4x", ""},
|
||||||
|
{"", "", ""},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
TechAge
|
TechAge
|
||||||
=======
|
=======
|
||||||
|
|
||||||
Copyright (C) 2017-2022 Joachim Stolberg
|
Copyright (C) 2017-2023 Joachim Stolberg
|
||||||
|
|
||||||
AGPL v3
|
AGPL v3
|
||||||
See LICENSE.txt for more information
|
See LICENSE.txt for more information
|
||||||
@ -21,7 +21,7 @@ local logic = techage.logic
|
|||||||
local BLOCKING_TIME = 8 -- seconds
|
local BLOCKING_TIME = 8 -- seconds
|
||||||
local ON_TIME = 1
|
local ON_TIME = 1
|
||||||
|
|
||||||
local WRENCH_MENU = {
|
local WRENCH_MENU3 = {
|
||||||
{
|
{
|
||||||
type = "dropdown",
|
type = "dropdown",
|
||||||
choices = "1,2,4,6,8,12,16",
|
choices = "1,2,4,6,8,12,16",
|
||||||
@ -47,6 +47,46 @@ local WRENCH_MENU = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local WRENCH_MENU4 = {
|
||||||
|
{
|
||||||
|
type = "dropdown",
|
||||||
|
choices = "1,2,4,6,8,12,16",
|
||||||
|
name = "ontime",
|
||||||
|
label = S("On Time") .. " [s]",
|
||||||
|
tooltip = S("The time between the 'on' and 'off' commands."),
|
||||||
|
default = "1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type = "dropdown",
|
||||||
|
choices = "2,4,6,8,12,16,20",
|
||||||
|
name = "blockingtime",
|
||||||
|
label = S("Blocking Time") .. " [s]",
|
||||||
|
tooltip = S("The time after the 'off' command\nuntil the next 'on' command is accepted."),
|
||||||
|
default = "8",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type = "number",
|
||||||
|
name = "countdown",
|
||||||
|
label = S("Countdown"),
|
||||||
|
tooltip = S("Counts down the number of items passed through\nand only triggers an 'on' command when it reaches zero."),
|
||||||
|
default = "0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type = "output",
|
||||||
|
name = "countdown",
|
||||||
|
label = S("Current countdown"),
|
||||||
|
tooltip = S("Current countdown value."),
|
||||||
|
default = "0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type = "items",
|
||||||
|
name = "config",
|
||||||
|
label = S("Configured Items"),
|
||||||
|
tooltip = S("Items which generate an 'on' command.\nIf empty, all passed items generate an 'on' command."),
|
||||||
|
size = 4,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
local function switch_on(pos)
|
local function switch_on(pos)
|
||||||
local mem = techage.get_mem(pos)
|
local mem = techage.get_mem(pos)
|
||||||
local t = minetest.get_gametime()
|
local t = minetest.get_gametime()
|
||||||
@ -122,6 +162,17 @@ local function after_dig_node(pos, oldnode, oldmetadata, digger)
|
|||||||
techage.del_mem(pos)
|
techage.del_mem(pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function ta_after_formspec(pos, fields, playername)
|
||||||
|
if fields.save then
|
||||||
|
local nvm = techage.get_nvm(pos)
|
||||||
|
local val = M(pos):get_int("countdown") or 0
|
||||||
|
if val > 0 then
|
||||||
|
nvm.countdown = val
|
||||||
|
else
|
||||||
|
nvm.countdown = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
minetest.register_node("techage:ta3_detector_off", {
|
minetest.register_node("techage:ta3_detector_off", {
|
||||||
description = S("TA3 Detector"),
|
description = S("TA3 Detector"),
|
||||||
@ -139,7 +190,7 @@ minetest.register_node("techage:ta3_detector_off", {
|
|||||||
on_receive_fields = on_receive_fields,
|
on_receive_fields = on_receive_fields,
|
||||||
techage_set_numbers = techage_set_numbers,
|
techage_set_numbers = techage_set_numbers,
|
||||||
after_dig_node = after_dig_node,
|
after_dig_node = after_dig_node,
|
||||||
ta3_formspec = WRENCH_MENU,
|
ta3_formspec = WRENCH_MENU3,
|
||||||
|
|
||||||
on_rotate = screwdriver.disallow,
|
on_rotate = screwdriver.disallow,
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
@ -167,7 +218,7 @@ minetest.register_node("techage:ta3_detector_on", {
|
|||||||
on_rotate = screwdriver.disallow,
|
on_rotate = screwdriver.disallow,
|
||||||
techage_set_numbers = techage_set_numbers,
|
techage_set_numbers = techage_set_numbers,
|
||||||
after_dig_node = after_dig_node,
|
after_dig_node = after_dig_node,
|
||||||
ta3_formspec = WRENCH_MENU,
|
ta3_formspec = WRENCH_MENU3,
|
||||||
|
|
||||||
paramtype2 = "facedir",
|
paramtype2 = "facedir",
|
||||||
groups = {choppy=2, cracky=2, crumbly=2, not_in_creative_inventory=1},
|
groups = {choppy=2, cracky=2, crumbly=2, not_in_creative_inventory=1},
|
||||||
@ -192,7 +243,8 @@ minetest.register_node("techage:ta4_detector_off", {
|
|||||||
on_receive_fields = on_receive_fields,
|
on_receive_fields = on_receive_fields,
|
||||||
techage_set_numbers = techage_set_numbers,
|
techage_set_numbers = techage_set_numbers,
|
||||||
after_dig_node = after_dig_node,
|
after_dig_node = after_dig_node,
|
||||||
ta3_formspec = WRENCH_MENU,
|
ta4_formspec = WRENCH_MENU4,
|
||||||
|
ta_after_formspec = ta_after_formspec,
|
||||||
|
|
||||||
on_rotate = screwdriver.disallow,
|
on_rotate = screwdriver.disallow,
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
@ -220,7 +272,8 @@ minetest.register_node("techage:ta4_detector_on", {
|
|||||||
on_rotate = screwdriver.disallow,
|
on_rotate = screwdriver.disallow,
|
||||||
techage_set_numbers = techage_set_numbers,
|
techage_set_numbers = techage_set_numbers,
|
||||||
after_dig_node = after_dig_node,
|
after_dig_node = after_dig_node,
|
||||||
ta3_formspec = WRENCH_MENU,
|
ta4_formspec = WRENCH_MENU4,
|
||||||
|
ta_after_formspec = ta_after_formspec,
|
||||||
|
|
||||||
paramtype2 = "facedir",
|
paramtype2 = "facedir",
|
||||||
groups = {choppy=2, cracky=2, crumbly=2, not_in_creative_inventory=1},
|
groups = {choppy=2, cracky=2, crumbly=2, not_in_creative_inventory=1},
|
||||||
@ -268,13 +321,22 @@ techage.register_node({"techage:ta4_detector_off", "techage:ta4_detector_on"}, {
|
|||||||
if leftover then
|
if leftover then
|
||||||
local inv = minetest.get_inventory({type = "node", pos = pos})
|
local inv = minetest.get_inventory({type = "node", pos = pos})
|
||||||
if not inv or inv:is_empty("cfg") or inv:contains_item("cfg", ItemStack(stack:get_name())) then
|
if not inv or inv:is_empty("cfg") or inv:contains_item("cfg", ItemStack(stack:get_name())) then
|
||||||
switch_on(pos)
|
|
||||||
local nvm = techage.get_nvm(pos)
|
local nvm = techage.get_nvm(pos)
|
||||||
if leftover == true then
|
local num_moved = stack:get_count()
|
||||||
nvm.counter = (nvm.counter or 0) + stack:get_count()
|
if leftover ~= true then
|
||||||
else
|
num_moved = num_moved - leftover:get_count()
|
||||||
nvm.counter = (nvm.counter or 0) + stack:get_count() - leftover:get_count()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if nvm.countdown and nvm.countdown > 0 then
|
||||||
|
nvm.countdown = nvm.countdown - num_moved
|
||||||
|
if nvm.countdown <= 0 then
|
||||||
|
M(pos):set_int("countdown", 0)
|
||||||
|
switch_on(pos)
|
||||||
|
end
|
||||||
|
elseif nvm.countdown == nil then
|
||||||
|
switch_on(pos)
|
||||||
|
end
|
||||||
|
nvm.counter = (nvm.counter or 0) + num_moved
|
||||||
end
|
end
|
||||||
return leftover
|
return leftover
|
||||||
end
|
end
|
||||||
@ -286,9 +348,15 @@ techage.register_node({"techage:ta4_detector_off", "techage:ta4_detector_on"}, {
|
|||||||
if topic == "count" then
|
if topic == "count" then
|
||||||
local nvm = techage.get_nvm(pos)
|
local nvm = techage.get_nvm(pos)
|
||||||
return nvm.counter or 0
|
return nvm.counter or 0
|
||||||
|
elseif topic == "countdown" then
|
||||||
|
local nvm = techage.get_nvm(pos)
|
||||||
|
nvm.countdown = tonumber(payload) or 0
|
||||||
|
M(pos):set_int("countdown", nvm.countdown)
|
||||||
|
return true
|
||||||
elseif topic == "reset" then
|
elseif topic == "reset" then
|
||||||
local nvm = techage.get_nvm(pos)
|
local nvm = techage.get_nvm(pos)
|
||||||
nvm.counter = 0
|
nvm.counter = 0
|
||||||
|
nvm.countdown = nil
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
return "unsupported"
|
return "unsupported"
|
||||||
@ -298,6 +366,12 @@ techage.register_node({"techage:ta4_detector_off", "techage:ta4_detector_on"}, {
|
|||||||
if topic == 6 then -- Detector Block Reset
|
if topic == 6 then -- Detector Block Reset
|
||||||
local nvm = techage.get_nvm(pos)
|
local nvm = techage.get_nvm(pos)
|
||||||
nvm.counter = 0
|
nvm.counter = 0
|
||||||
|
nvm.countdown = nil
|
||||||
|
return 0
|
||||||
|
elseif topic == 5 then -- Detector Block Countdown
|
||||||
|
local nvm = techage.get_nvm(pos)
|
||||||
|
nvm.countdown = tonumber(payload[1]) or 0
|
||||||
|
M(pos):set_int("countdown", nvm.countdown)
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
return 2
|
return 2
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
TechAge
|
TechAge
|
||||||
=======
|
=======
|
||||||
|
|
||||||
Copyright (C) 2022 Joachim Stolberg
|
Copyright (C) 2022-2023 Joachim Stolberg
|
||||||
|
|
||||||
AGPL v3
|
AGPL v3
|
||||||
See LICENSE.txt for more information
|
See LICENSE.txt for more information
|
||||||
@ -104,7 +104,6 @@ local function register_signallamp(name, description, tiles_off, tiles_on, node_
|
|||||||
|
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
paramtype2 = "color",
|
paramtype2 = "color",
|
||||||
--palette = "techage_palette256.png",
|
|
||||||
palette = COLORED and "unifieddyes_palette_extended.png" or "techage_palette256.png",
|
palette = COLORED and "unifieddyes_palette_extended.png" or "techage_palette256.png",
|
||||||
groups = {choppy=2, cracky=1, not_in_creative_inventory=1, ud_param2_colorable = 1},
|
groups = {choppy=2, cracky=1, not_in_creative_inventory=1, ud_param2_colorable = 1},
|
||||||
|
|
||||||
@ -148,7 +147,7 @@ local function register_signallamp(name, description, tiles_off, tiles_on, node_
|
|||||||
local node = techage.get_node_lvm(pos)
|
local node = techage.get_node_lvm(pos)
|
||||||
switch_off(pos, node)
|
switch_off(pos, node)
|
||||||
return 0
|
return 0
|
||||||
elseif topic == 70 then
|
elseif topic == 70 or topic == 22 then
|
||||||
local node = techage.get_node_lvm(pos)
|
local node = techage.get_node_lvm(pos)
|
||||||
switch_on(pos, node, nil, payload[1])
|
switch_on(pos, node, nil, payload[1])
|
||||||
return 0
|
return 0
|
||||||
@ -196,8 +195,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
register_signallamp("techage:signal_lamp",
|
register_signallamp("techage:color_lamp",
|
||||||
S("TechAge Signal Lamp"),
|
S("TechAge Color Lamp"),
|
||||||
{"techage_signal_lamp.png^[colorize:#000000:80"},
|
{"techage_signal_lamp.png^[colorize:#000000:80"},
|
||||||
{"techage_signal_lamp.png"},
|
{"techage_signal_lamp.png"},
|
||||||
{
|
{
|
||||||
@ -209,8 +208,8 @@ register_signallamp("techage:signal_lamp",
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
register_signallamp("techage:signal_lamp2",
|
register_signallamp("techage:color_lamp2",
|
||||||
S("TechAge Signal Lamp 2 "),
|
S("TechAge Color Lamp 2"),
|
||||||
{"techage_signallamp2.png^[colorize:#000000:80"},
|
{"techage_signallamp2.png^[colorize:#000000:80"},
|
||||||
{"techage_signallamp2.png"}
|
{"techage_signallamp2.png"}
|
||||||
)
|
)
|
||||||
@ -232,3 +231,8 @@ minetest.register_craft({
|
|||||||
{"", "techage:vacuum_tube", ""},
|
{"", "techage:vacuum_tube", ""},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_alias("techage:signal_lamp_off", "techage:color_lamp_off")
|
||||||
|
minetest.register_alias("techage:signal_lamp2_off", "techage:color_lamp2_off")
|
||||||
|
minetest.register_alias("techage:signal_lamp_on", "techage:color_lamp_on")
|
||||||
|
minetest.register_alias("techage:signal_lamp2_on", "techage:color_lamp2_on")
|
||||||
|
@ -628,14 +628,14 @@ Im privaten Modus (private) kann das Terminal nur von Spielern verwendet werden,
|
|||||||
[ta3_terminal|image]
|
[ta3_terminal|image]
|
||||||
|
|
||||||
|
|
||||||
### TechAge Signallampe / Signal Lamp
|
### TechAge Farblampe / Color Lamp
|
||||||
|
|
||||||
Die Signallampe kann mit `on`/`off` Kommando ein- bzw. ausgeschaltet werden. Diese Lampe braucht keinen Strom und
|
Die Farblampe kann mit `on`/`off` Kommando ein- bzw. ausgeschaltet werden. Diese Lampe braucht keinen Strom und
|
||||||
kann mit der Spritzpistole aus der Mod "Unified Dyes" und über Lua/Beduino Kommandos eingefärbt werden.
|
kann mit der Spritzpistole aus der Mod "Unified Dyes" und über Lua/Beduino Kommandos eingefärbt werden.
|
||||||
|
|
||||||
Mit dem Chat-Kommando `/ta_color` wird die Farbpalette mit den Werten für die Lua/Beduino Kommandos angezeigt und mit `/ta_send color <num>` kann die Farbe geändert werden.
|
Mit dem Chat-Kommando `/ta_color` wird die Farbpalette mit den Werten für die Lua/Beduino Kommandos angezeigt und mit `/ta_send color <num>` kann die Farbe geändert werden.
|
||||||
|
|
||||||
[ta3_signallamp|image]
|
[ta3_colorlamp|image]
|
||||||
|
|
||||||
|
|
||||||
### Tür/Tor Blöcke / Door/Gate Blocks
|
### Tür/Tor Blöcke / Door/Gate Blocks
|
||||||
|
@ -627,13 +627,13 @@ In public mode, all players can use the preconfigured keys.
|
|||||||
[ta3_terminal|image]
|
[ta3_terminal|image]
|
||||||
|
|
||||||
|
|
||||||
### TechAge Signal Lamp
|
### TechAge Color Lamp
|
||||||
|
|
||||||
The signal lamp can be switched on or off with the `on` / `off` command. This lamp does not need electricity and can be colored with the airbrush tool from the mod Unified Dyes" and via Lua/Beduino commands.
|
The signal lamp can be switched on or off with the `on` / `off` command. This lamp does not need electricity and can be colored with the airbrush tool from the mod Unified Dyes" and via Lua/Beduino commands.
|
||||||
|
|
||||||
With the chat command `/ta_color` the color palette with the values for the Lua/Beduino commands is displayed and with `/ta_send color <num>` the color can be changed.
|
With the chat command `/ta_color` the color palette with the values for the Lua/Beduino commands is displayed and with `/ta_send color <num>` the color can be changed.
|
||||||
|
|
||||||
[ta3_signallamp|image]
|
[ta3_colorlamp|image]
|
||||||
|
|
||||||
|
|
||||||
### Door/Gate Blocks
|
### Door/Gate Blocks
|
||||||
|
@ -363,6 +363,7 @@ Please note, that this is not a technical distinction, only a logical.
|
|||||||
| "state" | one of: "running", "stopped", "blocked", "standby", "fault", or "unloaded" | Techage machine state, used by many machines |
|
| "state" | one of: "running", "stopped", "blocked", "standby", "fault", or "unloaded" | Techage machine state, used by many machines |
|
||||||
| "state" | one of: "red", "amber", "green", "off" | Signal Tower state |
|
| "state" | one of: "red", "amber", "green", "off" | Signal Tower state |
|
||||||
| "state" | one of: "empty", "loaded", "full" | State of a chest or Sensor Chest |
|
| "state" | one of: "empty", "loaded", "full" | State of a chest or Sensor Chest |
|
||||||
|
| "state" | one of: "on", "off" | State of a TA4 Button |
|
||||||
| "fuel" | number | fuel value of a fuel consuming block |
|
| "fuel" | number | fuel value of a fuel consuming block |
|
||||||
| "depth" | number | Read the current depth value of a quarry block (1..80) |
|
| "depth" | number | Read the current depth value of a quarry block (1..80) |
|
||||||
| "load" | number | Read the load value in percent (0..100) of a tank, silo, accu, or battery block, or from the Signs Bot Box. Silo and tank return two values: The percentage value and the absolute value in units.<br /> Example: percent, absolute = $send_cmnd("223", "load") |
|
| "load" | number | Read the load value in percent (0..100) of a tank, silo, accu, or battery block, or from the Signs Bot Box. Silo and tank return two values: The percentage value and the absolute value in units.<br /> Example: percent, absolute = $send_cmnd("223", "load") |
|
||||||
@ -396,7 +397,8 @@ Please note, that this is not a technical distinction, only a logical.
|
|||||||
| "port" | string<br />`<color>=on/off` | Enable/disable a Distributor filter slot..<br />Example: `"yellow=on"`<br />colors: red, green, blue, yellow |
|
| "port" | string<br />`<color>=on/off` | Enable/disable a Distributor filter slot..<br />Example: `"yellow=on"`<br />colors: red, green, blue, yellow |
|
||||||
| "config" | "\<slot> \<item list>" | Configure a Distributor filter slot, like: "red default:dirt dye:blue" |
|
| "config" | "\<slot> \<item list>" | Configure a Distributor filter slot, like: "red default:dirt dye:blue" |
|
||||||
| "text" | text string | Text to be used for the Sensor Chest menu |
|
| "text" | text string | Text to be used for the Sensor Chest menu |
|
||||||
| "reset" | nil | Reset the item counter of the TA4 Item Detector block |
|
| "reset" | nil | Reset item and countdown counters of the TA4 Item Detector block |
|
||||||
|
| "countdown" | number | Set countdown counter of the TA4 Item Detector block to the given value and<br />start countdown mode. |
|
||||||
| "limit" | number | Configure a TA4 Pusher with the number of items that are allowed to be pushed ("flow limiter" mode)<br />limit = 0 turns off the "flow limiter" mode |
|
| "limit" | number | Configure a TA4 Pusher with the number of items that are allowed to be pushed ("flow limiter" mode)<br />limit = 0 turns off the "flow limiter" mode |
|
||||||
| "limit" | number | Configure a TA4 Pump with the number of liquid units that are allowed to be pumped ("flow limiter" mode)<br />limit = 0 turns off the "flow limiter" mode |
|
| "limit" | number | Configure a TA4 Pump with the number of liquid units that are allowed to be pumped ("flow limiter" mode)<br />limit = 0 turns off the "flow limiter" mode |
|
||||||
| "config" | item string | Configure the TA4 pusher.<br />Example: `wool:blue` |
|
| "config" | item string | Configure the TA4 pusher.<br />Example: `wool:blue` |
|
||||||
@ -417,7 +419,7 @@ Please note, that this is not a technical distinction, only a logical.
|
|||||||
| "stop" | nil | Stop command for the TA4 Sequencer. |
|
| "stop" | nil | Stop command for the TA4 Sequencer. |
|
||||||
| "gain" | volume | Set volume of the sound block (`volume` is a value between 0 and 1.0) |
|
| "gain" | volume | Set volume of the sound block (`volume` is a value between 0 and 1.0) |
|
||||||
| "sound" | index | Select sound sample of the sound block |
|
| "sound" | index | Select sound sample of the sound block |
|
||||||
| "color" | \<color> | Set the color of the TechAge Signal Lamp and TechAge Signal Lamp 2 (color = 0..255) |
|
| "color" | \<color> | Set the color of the TechAge Color Lamp and TechAge Color Lamp 2 (color = 0..255) |
|
||||||
|
|
||||||
### Server and Terminal Functions
|
### Server and Terminal Functions
|
||||||
|
|
||||||
|
@ -1,85 +0,0 @@
|
|||||||
# Techage/Beduino I/O Module
|
|
||||||
|
|
||||||
I/O modules support the following functions:
|
|
||||||
|
|
||||||
### event
|
|
||||||
|
|
||||||
Every signal that is sent to an I/O module triggers an event on the controller.
|
|
||||||
Events can be queried using the `event()` function.
|
|
||||||
If the function returns the value `1`, one or more signals have been received.
|
|
||||||
Calling `event()` resets the event flag.
|
|
||||||
|
|
||||||
```c
|
|
||||||
event()
|
|
||||||
```
|
|
||||||
|
|
||||||
### read
|
|
||||||
|
|
||||||
Read a value from a remote techage block.
|
|
||||||
|
|
||||||
- *port* is the I/O module port number
|
|
||||||
- *cmnd* is the command, like `IO_STATE` (see example code "ta_cmnd.c")
|
|
||||||
|
|
||||||
```c
|
|
||||||
read(port, cmnd)
|
|
||||||
```
|
|
||||||
|
|
||||||
### send_cmnd
|
|
||||||
|
|
||||||
Send a command to a techage block (see [commands](https://github.com/joe7575/beduino/blob/main/BEPs/bep-005_ta_cmnd.md)).
|
|
||||||
|
|
||||||
- *port* is the I/O module port number
|
|
||||||
- *topic* is a number from the list of [Beduino commands](https://github.com/joe7575/beduino/blob/main/BEPs/bep-005_ta_cmnd.md)
|
|
||||||
- *payload* is an array or a string with additional information, depending on the command. If no additional commands are required, "" can be used.
|
|
||||||
|
|
||||||
```c
|
|
||||||
send_cmnd(port, topic, payload)
|
|
||||||
```
|
|
||||||
|
|
||||||
### request_data
|
|
||||||
|
|
||||||
Request information from a techage block (see [commands](https://github.com/joe7575/beduino/blob/main/BEPs/bep-005_ta_cmnd.md)).
|
|
||||||
|
|
||||||
- *port* is the I/O module port number
|
|
||||||
- *topic* is a number from the list of [Beduino commands](https://github.com/joe7575/beduino/blob/main/BEPs/bep-005_ta_cmnd.md)
|
|
||||||
- *payload* is an array or a string with additional information, depending on the command. If no additional commands are required, "" can be used.
|
|
||||||
- *resp* is an array for the response data. The array must be defined large enough to hold the response data.
|
|
||||||
|
|
||||||
```c
|
|
||||||
request_data(port, topic, payload, resp)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Functions for TA4 Display and TA4 Display XL
|
|
||||||
|
|
||||||
### clear_screen
|
|
||||||
|
|
||||||
Clear the display.
|
|
||||||
|
|
||||||
- *port* is the I/O module port number
|
|
||||||
|
|
||||||
```c
|
|
||||||
clear_screen(port)
|
|
||||||
```
|
|
||||||
|
|
||||||
### append_line
|
|
||||||
|
|
||||||
Add a new line to the display.
|
|
||||||
- *port* is the I/O module port number
|
|
||||||
- *text* is the text for one line
|
|
||||||
|
|
||||||
```c
|
|
||||||
append_line(port, text)
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### write_line
|
|
||||||
|
|
||||||
Overwrite a text line with the given string.
|
|
||||||
|
|
||||||
- *port* is the I/O module port number
|
|
||||||
- *row* ist the display line/row (1-5)
|
|
||||||
- *text* is the text for one line
|
|
||||||
|
|
||||||
```c
|
|
||||||
write_line(port, row, text)
|
|
||||||
```
|
|
@ -5,8 +5,8 @@ The key/value store simplifies the handling/comparison of strings.
|
|||||||
The following example shows the use of the Key/Value Store, here to check the names from the Player Detector:
|
The following example shows the use of the Key/Value Store, here to check the names from the Player Detector:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
import "ta_kvstore.c"
|
import "lib/ta_kvstore.c"
|
||||||
import "ta_iom.c"
|
import "lib/ta_iom.c"
|
||||||
|
|
||||||
var s[16];
|
var s[16];
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@
|
|||||||
- [TA3 Sequenzer / Sequencer](./manual_ta3_DE.md#ta3-sequenzer--sequencer)
|
- [TA3 Sequenzer / Sequencer](./manual_ta3_DE.md#ta3-sequenzer--sequencer)
|
||||||
- [TA3 Timer](./manual_ta3_DE.md#ta3-timer)
|
- [TA3 Timer](./manual_ta3_DE.md#ta3-timer)
|
||||||
- [TA3 Terminal](./manual_ta3_DE.md#ta3-terminal)
|
- [TA3 Terminal](./manual_ta3_DE.md#ta3-terminal)
|
||||||
- [TechAge Signallampe / Signal Lamp](./manual_ta3_DE.md#techage-signallampe--signal-lamp)
|
- [TechAge Farblampe / Color Lamp](./manual_ta3_DE.md#techage-farblampe--color-lamp)
|
||||||
- [Tür/Tor Blöcke / Door/Gate Blocks](./manual_ta3_DE.md#türtor-blöcke--doorgate-blocks)
|
- [Tür/Tor Blöcke / Door/Gate Blocks](./manual_ta3_DE.md#türtor-blöcke--doorgate-blocks)
|
||||||
- [TA3 Tür Controller / Door Controller](./manual_ta3_DE.md#ta3-tür-controller--door-controller)
|
- [TA3 Tür Controller / Door Controller](./manual_ta3_DE.md#ta3-tür-controller--door-controller)
|
||||||
- [TA3 Tür Controller II / Door Controller II](./manual_ta3_DE.md#ta3-tür-controller-ii--door-controller-ii)
|
- [TA3 Tür Controller II / Door Controller II](./manual_ta3_DE.md#ta3-tür-controller-ii--door-controller-ii)
|
||||||
|
@ -112,7 +112,7 @@
|
|||||||
- [TA3 Sequencer](./manual_ta3_EN.md#ta3-sequencer)
|
- [TA3 Sequencer](./manual_ta3_EN.md#ta3-sequencer)
|
||||||
- [TA3 Timer](./manual_ta3_EN.md#ta3-timer)
|
- [TA3 Timer](./manual_ta3_EN.md#ta3-timer)
|
||||||
- [TA3 Terminal](./manual_ta3_EN.md#ta3-terminal)
|
- [TA3 Terminal](./manual_ta3_EN.md#ta3-terminal)
|
||||||
- [TechAge Signal Lamp](./manual_ta3_EN.md#techage-signal-lamp)
|
- [TechAge Color Lamp](./manual_ta3_EN.md#techage-color-lamp)
|
||||||
- [Door/Gate Blocks](./manual_ta3_EN.md#doorgate-blocks)
|
- [Door/Gate Blocks](./manual_ta3_EN.md#doorgate-blocks)
|
||||||
- [TA3 Door Controller](./manual_ta3_EN.md#ta3-door-controller)
|
- [TA3 Door Controller](./manual_ta3_EN.md#ta3-door-controller)
|
||||||
- [TA3 Door Controller II](./manual_ta3_EN.md#ta3-door-controller-ii)
|
- [TA3 Door Controller II](./manual_ta3_EN.md#ta3-door-controller-ii)
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
TechAge
|
TechAge
|
||||||
=======
|
=======
|
||||||
|
|
||||||
Copyright (C) 2020-2022 Joachim Stolberg
|
Copyright (C) 2020-2023 Joachim Stolberg
|
||||||
|
|
||||||
AGPL v3
|
AGPL v3
|
||||||
See LICENSE.txt for more information
|
See LICENSE.txt for more information
|
||||||
|
|
||||||
TA4 Move Controller
|
TA5 Fly Controller
|
||||||
|
|
||||||
]]--
|
]]--
|
||||||
|
|
||||||
@ -42,6 +42,13 @@ local WRENCH_MENU = {
|
|||||||
tooltip = S("Value in the range of 0.0 to 1.0"),
|
tooltip = S("Value in the range of 0.0 to 1.0"),
|
||||||
default = "1.0",
|
default = "1.0",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type = "float",
|
||||||
|
name = "offset",
|
||||||
|
label = S("Object offset"),
|
||||||
|
tooltip = S("Y-offset for non-player objects like vehicles (-0.5 to 0.5)"),
|
||||||
|
default = "0.0",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
local function formspec(nvm, meta)
|
local function formspec(nvm, meta)
|
||||||
@ -165,8 +172,6 @@ minetest.register_node("techage:ta5_flycontroller", {
|
|||||||
elseif fields.moveAB then
|
elseif fields.moveAB then
|
||||||
meta:set_string("status", "")
|
meta:set_string("status", "")
|
||||||
if fly.move_to_other_pos(pos, false) then
|
if fly.move_to_other_pos(pos, false) then
|
||||||
nvm.moveBA = true
|
|
||||||
nvm.running = true
|
|
||||||
meta:set_string("formspec", formspec(nvm, meta))
|
meta:set_string("formspec", formspec(nvm, meta))
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
mark.stop(name)
|
mark.stop(name)
|
||||||
@ -175,8 +180,6 @@ minetest.register_node("techage:ta5_flycontroller", {
|
|||||||
elseif fields.moveBA then
|
elseif fields.moveBA then
|
||||||
meta:set_string("status", "")
|
meta:set_string("status", "")
|
||||||
if fly.move_to_other_pos(pos, true) then
|
if fly.move_to_other_pos(pos, true) then
|
||||||
nvm.moveBA = false
|
|
||||||
nvm.running = true
|
|
||||||
meta:set_string("formspec", formspec(nvm, meta))
|
meta:set_string("formspec", formspec(nvm, meta))
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
mark.stop(name)
|
mark.stop(name)
|
||||||
@ -185,8 +188,6 @@ minetest.register_node("techage:ta5_flycontroller", {
|
|||||||
elseif fields.move then
|
elseif fields.move then
|
||||||
meta:set_string("status", "")
|
meta:set_string("status", "")
|
||||||
if fly.move_to_other_pos(pos, nvm.moveBA) then
|
if fly.move_to_other_pos(pos, nvm.moveBA) then
|
||||||
nvm.moveBA = nvm.moveBA == false
|
|
||||||
nvm.running = true
|
|
||||||
meta:set_string("formspec", formspec(nvm, meta))
|
meta:set_string("formspec", formspec(nvm, meta))
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
mark.stop(name)
|
mark.stop(name)
|
||||||
@ -219,17 +220,11 @@ techage.register_node({"techage:ta5_flycontroller"}, {
|
|||||||
elseif topic == "state" then
|
elseif topic == "state" then
|
||||||
return nvm.running and "running" or "stopped"
|
return nvm.running and "running" or "stopped"
|
||||||
elseif topic == "a2b" then
|
elseif topic == "a2b" then
|
||||||
nvm.moveBA = true
|
|
||||||
nvm.running = true
|
|
||||||
return fly.move_to_other_pos(pos, false)
|
return fly.move_to_other_pos(pos, false)
|
||||||
elseif topic == "b2a" then
|
elseif topic == "b2a" then
|
||||||
nvm.moveBA = false
|
|
||||||
nvm.running = true
|
|
||||||
return fly.move_to_other_pos(pos, true)
|
return fly.move_to_other_pos(pos, true)
|
||||||
elseif topic == "move" then
|
elseif topic == "move" then
|
||||||
nvm.moveBA = nvm.moveBA == false
|
return fly.move_to_other_pos(pos, nvm.moveBA)
|
||||||
nvm.running = true
|
|
||||||
return fly.move_to_other_pos(pos, nvm.moveBA == false)
|
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end,
|
end,
|
||||||
@ -237,17 +232,11 @@ techage.register_node({"techage:ta5_flycontroller"}, {
|
|||||||
local nvm = techage.get_nvm(pos)
|
local nvm = techage.get_nvm(pos)
|
||||||
if topic == 11 then
|
if topic == 11 then
|
||||||
if payload[1] == 1 then
|
if payload[1] == 1 then
|
||||||
nvm.moveBA = true
|
|
||||||
nvm.running = true
|
|
||||||
return fly.move_to_other_pos(pos, false) and 0 or 3
|
return fly.move_to_other_pos(pos, false) and 0 or 3
|
||||||
elseif payload[1] == 2 then
|
elseif payload[1] == 2 then
|
||||||
nvm.moveBA = false
|
|
||||||
nvm.running = true
|
|
||||||
return fly.move_to_other_pos(pos, true) and 0 or 3
|
return fly.move_to_other_pos(pos, true) and 0 or 3
|
||||||
elseif payload[1] == 3 then
|
elseif payload[1] == 3 then
|
||||||
nvm.moveBA = nvm.moveBA == false
|
return fly.move_to_other_pos(pos, nvm.moveBA) and 0 or 3
|
||||||
nvm.running = true
|
|
||||||
return fly.move_to_other_pos(pos, nvm.moveBA == false) and 0 or 3
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
return 2
|
return 2
|
||||||
@ -260,6 +249,10 @@ techage.register_node({"techage:ta5_flycontroller"}, {
|
|||||||
end
|
end
|
||||||
return 2, ""
|
return 2, ""
|
||||||
end,
|
end,
|
||||||
|
on_node_load = function(pos, node)
|
||||||
|
local nvm = techage.get_nvm(pos)
|
||||||
|
nvm.running = false
|
||||||
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
|
@ -34,22 +34,6 @@ local WRENCH_MENU = {
|
|||||||
tooltip = S("Maximum speed for moving blocks"),
|
tooltip = S("Maximum speed for moving blocks"),
|
||||||
default = "8",
|
default = "8",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
type = "number",
|
|
||||||
name = "handoverB",
|
|
||||||
label = S("Handover to B"),
|
|
||||||
tooltip = S("Number of the next movecontroller"),
|
|
||||||
default = "",
|
|
||||||
check = techage.check_number,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type = "number",
|
|
||||||
name = "handoverA",
|
|
||||||
label = S("Handover to A"),
|
|
||||||
tooltip = S("Number of the previous movecontroller"),
|
|
||||||
default = "",
|
|
||||||
check = techage.check_number,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
type = "float",
|
type = "float",
|
||||||
name = "height",
|
name = "height",
|
||||||
|
@ -116,8 +116,9 @@ techage.register_node({"techage:ta3_soundblock"}, {
|
|||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
on_beduino_receive_cmnd = function(pos, src, topic, payload)
|
on_beduino_receive_cmnd = function(pos, src, topic, payload)
|
||||||
|
print("ta3_soundblock", topic, payload[1], payload[2])
|
||||||
if topic == 1 then
|
if topic == 1 then
|
||||||
if payload[1] == 0 then
|
if payload[1] == 1 then
|
||||||
play_predefined_sound(pos)
|
play_predefined_sound(pos)
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
@ -28,6 +28,7 @@ techage.power = {}
|
|||||||
-- Helper function
|
-- Helper function
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
local function round(val)
|
local function round(val)
|
||||||
|
val = tonumber(val) or 0
|
||||||
if val > 100 then
|
if val > 100 then
|
||||||
return math.floor(val + 0.5)
|
return math.floor(val + 0.5)
|
||||||
elseif val > 10 then
|
elseif val > 10 then
|
||||||
|
@ -225,8 +225,8 @@ minetest.register_node("techage:tiny_generator", {
|
|||||||
meta:set_string("liquid_name", nvm.liquid.name)
|
meta:set_string("liquid_name", nvm.liquid.name)
|
||||||
meta:set_int("liquid_amount", nvm.liquid.amount)
|
meta:set_int("liquid_amount", nvm.liquid.amount)
|
||||||
meta:set_string("description", S("TA3 Tiny Power Generator") .. " (fuel: " ..
|
meta:set_string("description", S("TA3 Tiny Power Generator") .. " (fuel: " ..
|
||||||
tostring(nvm.liquid and nvm.liquid.amount or 0) .. "/" ..
|
tostring(nvm.liquid and nvm.liquid.amount or 0) .. "/" ..
|
||||||
tostring(fuel.CAPACITY) .. ")")
|
tostring(fuel.CAPACITY) .. ")")
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
@ -222,13 +222,29 @@ local function on_place(itemstack, placer, pointed_thing)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function repair(itemstack, placer, pointed_thing)
|
||||||
|
if pointed_thing.type == "node" then
|
||||||
|
local pos = pointed_thing.under
|
||||||
|
if not placer or minetest.is_protected(pos, placer:get_player_name()) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local number = techage.get_node_number(pos)
|
||||||
|
if number and not techage.get_node_info(number) then
|
||||||
|
techage.repair_number(pos)
|
||||||
|
minetest.chat_send_player(placer:get_player_name(), "Node repaired!")
|
||||||
|
itemstack:add_wear(65636/200)
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
minetest.register_tool("techage:repairkit", {
|
minetest.register_tool("techage:repairkit", {
|
||||||
description = S("TechAge Repair Kit"),
|
description = S("TechAge Repair Kit"),
|
||||||
inventory_image = "techage_repairkit.png",
|
inventory_image = "techage_repairkit.png",
|
||||||
wield_image = "techage_repairkit.png^[transformR270",
|
wield_image = "techage_repairkit.png^[transformR270",
|
||||||
groups = {cracky=1, book=1},
|
groups = {cracky=1, book=1},
|
||||||
--on_use = repair,
|
on_use = repair,
|
||||||
--on_place = repair,
|
on_place = repair,
|
||||||
node_placement_prediction = "",
|
node_placement_prediction = "",
|
||||||
stack_max = 1,
|
stack_max = 1,
|
||||||
})
|
})
|
||||||
@ -254,3 +270,12 @@ minetest.register_craft({
|
|||||||
{"default:steel_ingot", "", ""},
|
{"default:steel_ingot", "", ""},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
--minetest.register_craft({
|
||||||
|
-- output = "techage:repairkit",
|
||||||
|
-- recipe = {
|
||||||
|
-- {"", "", ""},
|
||||||
|
-- {"", "techage:end_wrench", ""},
|
||||||
|
-- {"", "", ""},
|
||||||
|
-- },
|
||||||
|
--})
|
||||||
|
@ -102,3 +102,16 @@ Other files from Wikimedia Commons:
|
|||||||
RealBadAngel: (CC-BY-4.0)
|
RealBadAngel: (CC-BY-4.0)
|
||||||
|
|
||||||
* Everything else.
|
* Everything else.
|
||||||
|
|
||||||
|
|
||||||
|
## Sounds
|
||||||
|
|
||||||
|
* [`bell.ogg`](https://freesound.org/people/bennstir/sounds/81072/) by bennstir, CC 4.0
|
||||||
|
* [`electricity.ogg`](https://freesound.org/people/Halleck/sounds/19486/) by Halleck, CC 4.0 (cut)
|
||||||
|
* [`pageflip1.ogg`](https://freesound.org/people/themfish/sounds/45823/) by themfish, CC 4.0 (cut, slowed down)
|
||||||
|
* `pageflip2.ogg` (derived from `pageflip1.ogg`)
|
||||||
|
* [`trash.ogg`](https://freesound.org/people/OwlStorm/sounds/151231/) by OwlStorm, CC 0 (speed up)
|
||||||
|
* [`trash_all.ogg`](https://freesound.org/people/abel_K/sounds/68280/) by abel_K, Sampling Plus 1.0 (speed up)
|
||||||
|
* [`ui_click.ogg`](https://freesound.org/people/lartti/sounds/527569/) by lartti, CC 0 (cut)
|
||||||
|
* [`ui_morning.ogg`](https://freesound.org/people/InspectorJ/sounds/439472/) by InspectorJ, CC 4.0
|
||||||
|
* [`ui_owl.ogg`](https://freesound.org/people/manda_g/sounds/54987/) by manda_g, Sampling Plus 1.0 (cut)
|
||||||
|
@ -145,50 +145,18 @@ minetest.after(0.01, function()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Step 1: group-indexed lookup table for items
|
-- Step 1: Initialize cache for looking up groups
|
||||||
local spec_matcher = {}
|
unified_inventory.init_matching_cache()
|
||||||
for _, name in ipairs(ui.items_list) do
|
|
||||||
-- we only need to care about groups, exact items are handled separately
|
|
||||||
for group, value in pairs(minetest.registered_items[name].groups) do
|
|
||||||
if value and value ~= 0 then
|
|
||||||
if not spec_matcher[group] then
|
|
||||||
spec_matcher[group] = {}
|
|
||||||
end
|
|
||||||
spec_matcher[group][name] = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Step 2: Find all matching items for the given spec (groups)
|
-- Step 2: Find all matching items for the given spec (groups)
|
||||||
local function get_matching_spec_items(specname)
|
local get_matching_spec_items = unified_inventory.get_matching_items
|
||||||
if specname:sub(1,6) ~= "group:" then
|
|
||||||
return { [specname] = true }
|
|
||||||
end
|
|
||||||
|
|
||||||
local accepted = {}
|
for outputitemname, recipes in pairs(ui.crafts_for.recipe) do
|
||||||
for i, group in ipairs(specname:sub(7):split(",")) do
|
|
||||||
if i == 1 then
|
|
||||||
-- First step: Copy all possible item names in this group
|
|
||||||
for name, _ in pairs(spec_matcher[group] or {}) do
|
|
||||||
accepted[name] = true
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- Perform filtering
|
|
||||||
if spec_matcher[group] then
|
|
||||||
for name, _ in pairs(accepted) do
|
|
||||||
accepted[name] = spec_matcher[group][name]
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- No matching items
|
|
||||||
return {}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return accepted
|
|
||||||
end
|
|
||||||
|
|
||||||
for _, recipes in pairs(ui.crafts_for.recipe) do
|
|
||||||
-- List of crafts that return this item string (variable "_")
|
-- List of crafts that return this item string (variable "_")
|
||||||
|
|
||||||
|
-- Problem: The group cache must be initialized after all mods finished loading
|
||||||
|
-- thus, invalid recipes might be indexed. Hence perform filtering with `new_recipe_list`
|
||||||
|
local new_recipe_list = {}
|
||||||
for _, recipe in ipairs(recipes) do
|
for _, recipe in ipairs(recipes) do
|
||||||
local ingredient_items = {}
|
local ingredient_items = {}
|
||||||
for _, spec in pairs(recipe.items) do
|
for _, spec in pairs(recipe.items) do
|
||||||
@ -204,7 +172,14 @@ minetest.after(0.01, function()
|
|||||||
end
|
end
|
||||||
table.insert(ui.crafts_for.usage[name], recipe)
|
table.insert(ui.crafts_for.usage[name], recipe)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if next(ingredient_items) then
|
||||||
|
-- There's at least one known ingredient: mark as good recipe
|
||||||
|
-- PS: What whatll be done about partially incomplete recipes?
|
||||||
|
table.insert(new_recipe_list, recipe)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
ui.crafts_for.recipe[outputitemname] = new_recipe_list
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, callback in ipairs(ui.initialized_callbacks) do
|
for _, callback in ipairs(ui.initialized_callbacks) do
|
||||||
|
@ -10,25 +10,26 @@ local F = minetest.formspec_escape
|
|||||||
local ui = unified_inventory
|
local ui = unified_inventory
|
||||||
|
|
||||||
ui.register_page("bags", {
|
ui.register_page("bags", {
|
||||||
get_formspec = function(player)
|
get_formspec = function(player, perplayer_formspec)
|
||||||
local player_name = player:get_player_name()
|
local player_name = player:get_player_name()
|
||||||
return { formspec = table.concat({
|
local std_inv_x = perplayer_formspec.std_inv_x
|
||||||
ui.style_full.standard_inv_bg,
|
local formspec = {
|
||||||
ui.single_slot(0.925, 1.5),
|
perplayer_formspec.standard_inv_bg,
|
||||||
ui.single_slot(3.425, 1.5),
|
"label[", perplayer_formspec.form_header_x, ",",
|
||||||
ui.single_slot(5.925, 1.5),
|
perplayer_formspec.form_header_y, ";", F(S("Bags")), "]",
|
||||||
ui.single_slot(8.425, 1.5),
|
|
||||||
"label["..ui.style_full.form_header_x..","..ui.style_full.form_header_y..";" .. F(S("Bags")) .. "]",
|
|
||||||
"button[0.6125,2.75;1.875,0.75;bag1;" .. F(S("Bag @1", 1)) .. "]",
|
|
||||||
"button[3.1125,2.75;1.875,0.75;bag2;" .. F(S("Bag @1", 2)) .. "]",
|
|
||||||
"button[5.6125,2.75;1.875,0.75;bag3;" .. F(S("Bag @1", 3)) .. "]",
|
|
||||||
"button[8.1125,2.75;1.875,0.75;bag4;" .. F(S("Bag @1", 4)) .. "]",
|
|
||||||
"listcolors[#00000000;#00000000]",
|
"listcolors[#00000000;#00000000]",
|
||||||
"list[detached:" .. F(player_name) .. "_bags;bag1;1.075,1.65;1,1;]",
|
}
|
||||||
"list[detached:" .. F(player_name) .. "_bags;bag2;3.575,1.65;1,1;]",
|
|
||||||
"list[detached:" .. F(player_name) .. "_bags;bag3;6.075,1.65;1,1;]",
|
for i = 1, 4 do
|
||||||
"list[detached:" .. F(player_name) .. "_bags;bag4;8.575,1.65;1,1;]"
|
local x = std_inv_x + i * 2.5
|
||||||
}) }
|
formspec[#formspec + 1] = ui.single_slot(x - 1.875, 1.5)
|
||||||
|
formspec[#formspec + 1] = string.format("list[detached:%s_bags;bag%i;%.3f,1.65;1,1;]",
|
||||||
|
F(player_name), i, x - 1.725)
|
||||||
|
formspec[#formspec + 1] = string.format("button[%.4f,2.75;1.875,0.75;bag%i;%s]",
|
||||||
|
x - 2.1875, i, F(S("Bag @1", i)))
|
||||||
|
end
|
||||||
|
|
||||||
|
return { formspec = table.concat(formspec) }
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -36,7 +37,6 @@ ui.register_button("bags", {
|
|||||||
type = "image",
|
type = "image",
|
||||||
image = "ui_bags_icon.png",
|
image = "ui_bags_icon.png",
|
||||||
tooltip = S("Bags"),
|
tooltip = S("Bags"),
|
||||||
hide_lite=true
|
|
||||||
})
|
})
|
||||||
|
|
||||||
local function get_player_bag_stack(player, i)
|
local function get_player_bag_stack(player, i)
|
||||||
@ -48,23 +48,38 @@ end
|
|||||||
|
|
||||||
for bag_i = 1, 4 do
|
for bag_i = 1, 4 do
|
||||||
ui.register_page("bag" .. bag_i, {
|
ui.register_page("bag" .. bag_i, {
|
||||||
get_formspec = function(player)
|
get_formspec = function(player, perplayer_formspec)
|
||||||
local stack = get_player_bag_stack(player, bag_i)
|
local stack = get_player_bag_stack(player, bag_i)
|
||||||
local image = stack:get_definition().inventory_image
|
local image = stack:get_definition().inventory_image
|
||||||
local slots = stack:get_definition().groups.bagslots
|
local slots = stack:get_definition().groups.bagslots
|
||||||
|
local std_inv_x = perplayer_formspec.std_inv_x
|
||||||
|
local lite_mode = perplayer_formspec.is_lite_mode
|
||||||
|
|
||||||
|
local bag_inv_y, header_x, header_y = 1.5, 0.3, 0.65
|
||||||
|
if lite_mode then
|
||||||
|
bag_inv_y = 0.5
|
||||||
|
header_x = perplayer_formspec.form_header_x
|
||||||
|
header_y = perplayer_formspec.form_header_y
|
||||||
|
end
|
||||||
|
|
||||||
local formspec = {
|
local formspec = {
|
||||||
ui.style_full.standard_inv_bg,
|
perplayer_formspec.standard_inv_bg,
|
||||||
ui.make_inv_img_grid(0.3, 1.5, 8, slots/8),
|
ui.make_inv_img_grid(std_inv_x, bag_inv_y, 8, slots/8),
|
||||||
"image[9.2,0.4;1,1;" .. image .. "]",
|
"label[", header_x, ",", header_y, ";", F(S("Bag @1", bag_i)), "]",
|
||||||
"label[0.3,0.65;" .. F(S("Bag @1", bag_i)) .. "]",
|
|
||||||
"listcolors[#00000000;#00000000]",
|
"listcolors[#00000000;#00000000]",
|
||||||
"listring[current_player;main]",
|
"listring[current_player;main]",
|
||||||
string.format("list[current_player;bag%icontents;%f,%f;8,3;]",
|
string.format("list[current_player;bag%icontents;%f,%f;8,3;]",
|
||||||
bag_i, 0.3 + ui.list_img_offset, 1.5 + ui.list_img_offset),
|
bag_i, std_inv_x + ui.list_img_offset, bag_inv_y + ui.list_img_offset),
|
||||||
"listring[current_name;bag" .. bag_i .. "contents]",
|
"listring[current_name;bag", bag_i, "contents]",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if lite_mode then
|
||||||
|
return { formspec = table.concat(formspec) }
|
||||||
|
end
|
||||||
|
|
||||||
local n = #formspec + 1
|
local n = #formspec + 1
|
||||||
|
formspec[n] = "image[" .. std_inv_x + 8.9 .. ",0.4;1,1;" .. image .. "]"
|
||||||
|
n = n + 1
|
||||||
|
|
||||||
local player_name = player:get_player_name() -- For if statement.
|
local player_name = player:get_player_name() -- For if statement.
|
||||||
if ui.trash_enabled
|
if ui.trash_enabled
|
||||||
|
@ -57,30 +57,47 @@ end)
|
|||||||
local function apply_new_filter(player, search_text, new_dir)
|
local function apply_new_filter(player, search_text, new_dir)
|
||||||
local player_name = player:get_player_name()
|
local player_name = player:get_player_name()
|
||||||
|
|
||||||
minetest.sound_play("click", {to_player=player_name, gain = 0.1})
|
minetest.sound_play("ui_click", {to_player=player_name, gain = 0.1})
|
||||||
ui.apply_filter(player, search_text, new_dir)
|
ui.apply_filter(player, search_text, new_dir)
|
||||||
ui.current_searchbox[player_name] = search_text
|
ui.current_searchbox[player_name] = search_text
|
||||||
ui.set_inventory_formspec(player, ui.current_page[player_name])
|
ui.set_inventory_formspec(player, ui.current_page[player_name])
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
-- Search box handling
|
||||||
|
local function receive_fields_searchbox(player, formname, fields)
|
||||||
local player_name = player:get_player_name()
|
local player_name = player:get_player_name()
|
||||||
|
|
||||||
local ui_peruser,draw_lite_mode = unified_inventory.get_per_player_formspec(player_name)
|
-- always take new search text, even if not searching on it yet
|
||||||
|
if fields.searchbox and fields.searchbox ~= ui.current_searchbox[player_name] then
|
||||||
|
ui.current_searchbox[player_name] = fields.searchbox
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.searchbutton
|
||||||
|
or fields.key_enter_field == "searchbox" then
|
||||||
|
|
||||||
|
if ui.current_searchbox[player_name] ~= ui.activefilter[player_name] then
|
||||||
|
ui.apply_filter(player, ui.current_searchbox[player_name], "nochange")
|
||||||
|
ui.set_inventory_formspec(player, ui.current_page[player_name])
|
||||||
|
minetest.sound_play("paperflip2",
|
||||||
|
{to_player=player_name, gain = 1.0})
|
||||||
|
end
|
||||||
|
elseif fields.searchresetbutton then
|
||||||
|
if ui.activefilter[player_name] ~= "" then
|
||||||
|
apply_new_filter(player, "", "nochange")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
if formname ~= "" then
|
if formname ~= "" then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- always take new search text, even if not searching on it yet
|
receive_fields_searchbox(player, formname, fields)
|
||||||
local dirty_search_filter = false
|
|
||||||
|
|
||||||
if fields.searchbox
|
local player_name = player:get_player_name()
|
||||||
and fields.searchbox ~= unified_inventory.current_searchbox[player_name] then
|
|
||||||
unified_inventory.current_searchbox[player_name] = fields.searchbox
|
|
||||||
dirty_search_filter = true
|
|
||||||
end
|
|
||||||
|
|
||||||
|
local ui_peruser,draw_lite_mode = unified_inventory.get_per_player_formspec(player_name)
|
||||||
|
|
||||||
local clicked_category
|
local clicked_category
|
||||||
for name, value in pairs(fields) do
|
for name, value in pairs(fields) do
|
||||||
@ -114,7 +131,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
for i, def in pairs(unified_inventory.buttons) do
|
for i, def in pairs(unified_inventory.buttons) do
|
||||||
if fields[def.name] then
|
if fields[def.name] then
|
||||||
def.action(player)
|
def.action(player)
|
||||||
minetest.sound_play("click",
|
minetest.sound_play("ui_click",
|
||||||
{to_player=player_name, gain = 0.1})
|
{to_player=player_name, gain = 0.1})
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -179,7 +196,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
if clicked_item then
|
if clicked_item then
|
||||||
minetest.sound_play("click",
|
minetest.sound_play("ui_click",
|
||||||
{to_player=player_name, gain = 0.1})
|
{to_player=player_name, gain = 0.1})
|
||||||
local page = unified_inventory.current_page[player_name]
|
local page = unified_inventory.current_page[player_name]
|
||||||
local player_creative = unified_inventory.is_creative(player_name)
|
local player_creative = unified_inventory.is_creative(player_name)
|
||||||
@ -201,25 +218,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if fields.searchbutton
|
|
||||||
or fields.key_enter_field == "searchbox" then
|
|
||||||
if dirty_search_filter then
|
|
||||||
ui.apply_filter(player, ui.current_searchbox[player_name], "nochange")
|
|
||||||
ui.set_inventory_formspec(player, ui.current_page[player_name])
|
|
||||||
minetest.sound_play("paperflip2",
|
|
||||||
{to_player=player_name, gain = 1.0})
|
|
||||||
end
|
|
||||||
elseif fields.searchresetbutton then
|
|
||||||
if ui.activefilter[player_name] ~= "" then
|
|
||||||
apply_new_filter(player, "", "nochange")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- alternate buttons
|
-- alternate buttons
|
||||||
if not (fields.alternate or fields.alternate_prev) then
|
if not (fields.alternate or fields.alternate_prev) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
minetest.sound_play("click",
|
minetest.sound_play("ui_click",
|
||||||
{to_player=player_name, gain = 0.1})
|
{to_player=player_name, gain = 0.1})
|
||||||
local item_name = unified_inventory.current_item[player_name]
|
local item_name = unified_inventory.current_item[player_name]
|
||||||
if not item_name then
|
if not item_name then
|
||||||
|
@ -24,7 +24,9 @@ Grouped by use-case, afterwards sorted alphabetically.
|
|||||||
Callbacks
|
Callbacks
|
||||||
---------
|
---------
|
||||||
|
|
||||||
Register a callback that will be run whenever a craft is registered via unified_inventory.register_craft:
|
Register a callback that will be run whenever a craft is registered via unified_inventory.register_craft.
|
||||||
|
This callback is run before any recipe ingredients checks, hence it is also executed on recipes that are
|
||||||
|
purged after all mods finished loading.
|
||||||
|
|
||||||
unified_inventory.register_on_craft_registered(
|
unified_inventory.register_on_craft_registered(
|
||||||
function (item_name, options)
|
function (item_name, options)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
local S = minetest.get_translator("unified_inventory")
|
local S = minetest.get_translator("unified_inventory")
|
||||||
|
local ui = unified_inventory
|
||||||
|
|
||||||
function unified_inventory.extract_groupnames(groupname)
|
function unified_inventory.extract_groupnames(groupname)
|
||||||
local specname = ItemStack(groupname):get_name()
|
local specname = ItemStack(groupname):get_name()
|
||||||
@ -26,6 +27,7 @@ end
|
|||||||
-- It may be a comma-separated list of group names. This is really a
|
-- It may be a comma-separated list of group names. This is really a
|
||||||
-- "group:..." ingredient specification, minus the "group:" prefix.
|
-- "group:..." ingredient specification, minus the "group:" prefix.
|
||||||
|
|
||||||
|
-- TODO Replace this with the more efficient spec matcher (below)
|
||||||
local function compute_group_item(group_name_list)
|
local function compute_group_item(group_name_list)
|
||||||
local group_names = group_name_list:split(",")
|
local group_names = group_name_list:split(",")
|
||||||
local candidate_items = {}
|
local candidate_items = {}
|
||||||
@ -84,3 +86,61 @@ function unified_inventory.get_group_item(group_name)
|
|||||||
return group_item_cache[group_name]
|
return group_item_cache[group_name]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--[[
|
||||||
|
This is for filtering known items by groups
|
||||||
|
e.g. find all items that match "group:flower,yellow" (flower AND yellow groups)
|
||||||
|
]]
|
||||||
|
local spec_matcher = {}
|
||||||
|
function unified_inventory.init_matching_cache()
|
||||||
|
for _, name in ipairs(ui.items_list) do
|
||||||
|
-- we only need to care about groups, exact items are handled separately
|
||||||
|
for group, value in pairs(minetest.registered_items[name].groups) do
|
||||||
|
if value and value ~= 0 then
|
||||||
|
if not spec_matcher[group] then
|
||||||
|
spec_matcher[group] = {}
|
||||||
|
end
|
||||||
|
spec_matcher[group][name] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Retrieves all matching items
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
specname (string): Item name or group(s) to filter
|
||||||
|
|
||||||
|
Output:
|
||||||
|
{
|
||||||
|
matchingitem1 = true,
|
||||||
|
...
|
||||||
|
}
|
||||||
|
]]
|
||||||
|
function unified_inventory.get_matching_items(specname)
|
||||||
|
if specname:sub(1,6) ~= "group:" then
|
||||||
|
return { [specname] = true }
|
||||||
|
end
|
||||||
|
|
||||||
|
local accepted = {}
|
||||||
|
for i, group in ipairs(specname:sub(7):split(",")) do
|
||||||
|
if i == 1 then
|
||||||
|
-- First step: Copy all possible item names in this group
|
||||||
|
for name, _ in pairs(spec_matcher[group] or {}) do
|
||||||
|
accepted[name] = true
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Perform filtering
|
||||||
|
if spec_matcher[group] then
|
||||||
|
for name, _ in pairs(accepted) do
|
||||||
|
accepted[name] = spec_matcher[group][name]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- No matching items
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return accepted
|
||||||
|
end
|
||||||
|
@ -274,9 +274,11 @@ local function formspec_add_item_browser(player, formspec, ui_peruser)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
formspec[n] = string.format("label[%f,%f;%s: %s]",
|
formspec[n] = "style[page_number;content_offset=0]"
|
||||||
ui_peruser.page_buttons_x + ui_peruser.btn_spc * (ui_peruser.is_lite_mode and 1 or 2),
|
formspec[n + 1] = string.format("image_button[%f,%f;%f,0.4;;page_number;%s: %s;false;false;]",
|
||||||
ui_peruser.page_buttons_y + 0.1 + ui_peruser.btn_spc * 2,
|
ui_peruser.page_buttons_x,
|
||||||
|
ui_peruser.page_buttons_y + ui_peruser.btn_spc * 2 - 0.1,
|
||||||
|
ui_peruser.btn_spc * (bn - 1) + ui_peruser.btn_size,
|
||||||
F(S("Page")), S("@1 of @2",page2,pagemax))
|
F(S("Page")), S("@1 of @2",page2,pagemax))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -126,25 +126,18 @@ Example output:
|
|||||||
}
|
}
|
||||||
--]]
|
--]]
|
||||||
function unified_inventory.find_usable_items(inv_items, craft_items)
|
function unified_inventory.find_usable_items(inv_items, craft_items)
|
||||||
local get_group = minetest.get_item_group
|
|
||||||
local result = {}
|
local result = {}
|
||||||
|
|
||||||
for craft_item in pairs(craft_items) do
|
for craft_item in pairs(craft_items) do
|
||||||
local group = craft_item:match("^group:(.+)")
|
-- may specify group:type1,type2
|
||||||
local found = {}
|
local items = unified_inventory.get_matching_items(craft_item)
|
||||||
|
|
||||||
if group ~= nil then
|
local found = {}
|
||||||
for inv_item in pairs(inv_items) do
|
for itemname, _ in pairs(items) do
|
||||||
if get_group(inv_item, group) > 0 then
|
if inv_items[itemname] then
|
||||||
found[inv_item] = true
|
found[itemname] = true
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if inv_items[craft_item] ~= nil then
|
|
||||||
found[craft_item] = true
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
result[craft_item] = found
|
result[craft_item] = found
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ ui.register_button("misc_set_day", {
|
|||||||
action = function(player)
|
action = function(player)
|
||||||
local player_name = player:get_player_name()
|
local player_name = player:get_player_name()
|
||||||
if minetest.check_player_privs(player_name, {settime=true}) then
|
if minetest.check_player_privs(player_name, {settime=true}) then
|
||||||
minetest.sound_play("birds",
|
minetest.sound_play("ui_morning",
|
||||||
{to_player=player_name, gain = 1.0})
|
{to_player=player_name, gain = 1.0})
|
||||||
minetest.set_timeofday((6000 % 24000) / 24000)
|
minetest.set_timeofday((6000 % 24000) / 24000)
|
||||||
minetest.chat_send_player(player_name,
|
minetest.chat_send_player(player_name,
|
||||||
@ -122,7 +122,7 @@ ui.register_button("misc_set_night", {
|
|||||||
action = function(player)
|
action = function(player)
|
||||||
local player_name = player:get_player_name()
|
local player_name = player:get_player_name()
|
||||||
if minetest.check_player_privs(player_name, {settime=true}) then
|
if minetest.check_player_privs(player_name, {settime=true}) then
|
||||||
minetest.sound_play("owl",
|
minetest.sound_play("ui_owl",
|
||||||
{to_player=player_name, gain = 1.0})
|
{to_player=player_name, gain = 1.0})
|
||||||
minetest.set_timeofday((21000 % 24000) / 24000)
|
minetest.set_timeofday((21000 % 24000) / 24000)
|
||||||
minetest.chat_send_player(player_name,
|
minetest.chat_send_player(player_name,
|
||||||
@ -183,14 +183,14 @@ ui.register_page("craft", {
|
|||||||
local n=#formspec+1
|
local n=#formspec+1
|
||||||
|
|
||||||
if ui.trash_enabled or ui.is_creative(player_name) or minetest.get_player_privs(player_name).give then
|
if ui.trash_enabled or ui.is_creative(player_name) or minetest.get_player_privs(player_name).give then
|
||||||
formspec[n] = string.format("label[%f,%f;%s]", craftx + 6.45, crafty + 2.4, F(S("Trash:")))
|
formspec[n] = string.format("label[%f,%f;%s]", craftx + 6.35, crafty + 2.3, F(S("Trash:")))
|
||||||
formspec[n+1] = ui.make_trash_slot(craftx + 6.25, crafty + 2.5)
|
formspec[n+1] = ui.make_trash_slot(craftx + 6.25, crafty + 2.5)
|
||||||
n=n + 2
|
n=n + 2
|
||||||
end
|
end
|
||||||
|
|
||||||
if ui.is_creative(player_name) then
|
if ui.is_creative(player_name) then
|
||||||
formspec[n] = ui.single_slot(craftx - 2.5, crafty + 2.5)
|
formspec[n] = ui.single_slot(craftx - 2.5, crafty + 2.5)
|
||||||
formspec[n+1] = string.format("label[%f,%f;%s]", craftx - 2.3, crafty + 2.4,F(S("Refill:")))
|
formspec[n+1] = string.format("label[%f,%f;%s]", craftx - 2.4, crafty + 2.3, F(S("Refill:")))
|
||||||
formspec[n+2] = string.format("list[detached:%srefill;main;%f,%f;1,1;]",
|
formspec[n+2] = string.format("list[detached:%srefill;main;%f,%f;1,1;]",
|
||||||
F(player_name), craftx - 2.5 + ui.list_img_offset, crafty + 2.5 + ui.list_img_offset)
|
F(player_name), craftx - 2.5 + ui.list_img_offset, crafty + 2.5 + ui.list_img_offset)
|
||||||
end
|
end
|
||||||
|
Binary file not shown.
Binary file not shown.
BIN
unified_inventory/sounds/ui_click.ogg
Normal file
BIN
unified_inventory/sounds/ui_click.ogg
Normal file
Binary file not shown.
BIN
unified_inventory/sounds/ui_morning.ogg
Normal file
BIN
unified_inventory/sounds/ui_morning.ogg
Normal file
Binary file not shown.
BIN
unified_inventory/sounds/ui_owl.ogg
Normal file
BIN
unified_inventory/sounds/ui_owl.ogg
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user