commit e4e2a9116d8ac41d32fd3de91784b7ec331b9744 Author: Migdyn Date: Mon Nov 21 16:12:22 2022 -0500 Initial commit (version 0.1-test) diff --git a/LICENSE.TXT b/LICENSE.TXT new file mode 100644 index 0000000..a0477b6 --- /dev/null +++ b/LICENSE.TXT @@ -0,0 +1 @@ +Please see the LICENSE.TXT file in each mod (every directory in the "mods" directory) for copyright information \ No newline at end of file diff --git a/README.TXT b/README.TXT new file mode 100644 index 0000000..7d2bce3 --- /dev/null +++ b/README.TXT @@ -0,0 +1,2 @@ +Submission to the 2022 Minetest Game Jam +Themes used: "Secrets", "Space" and "Story" \ No newline at end of file diff --git a/game.conf b/game.conf new file mode 100644 index 0000000..773ce33 --- /dev/null +++ b/game.conf @@ -0,0 +1,3 @@ +title = Insane Protestor +author = MCL +description = A game about a man who protests his country's government in a violent and somewhat unreasonable way. diff --git a/menu/background.png b/menu/background.png new file mode 100644 index 0000000..576fc9b Binary files /dev/null and b/menu/background.png differ diff --git a/menu/background.xcf b/menu/background.xcf new file mode 100644 index 0000000..66a1f32 Binary files /dev/null and b/menu/background.xcf differ diff --git a/menu/header.png b/menu/header.png new file mode 100644 index 0000000..4870651 Binary files /dev/null and b/menu/header.png differ diff --git a/menu/icon.png b/menu/icon.png new file mode 100644 index 0000000..6ea3b28 Binary files /dev/null and b/menu/icon.png differ diff --git a/mods/beds/README.txt b/mods/beds/README.txt new file mode 100644 index 0000000..7b35e14 --- /dev/null +++ b/mods/beds/README.txt @@ -0,0 +1,30 @@ +Minetest Game mod: beds +======================= +See license.txt for license information. + +Authors of source code +---------------------- +Originally by BlockMen (MIT) +Various Minetest developers and contributors (MIT) + +Authors of media (textures) +--------------------------- +BlockMen (CC BY-SA 3.0) + All textures unless otherwise noted + +TumeniNodes (CC BY-SA 3.0) + beds_bed_under.png + +This mod adds a bed to Minetest which allows players to skip the night. +To sleep, right click on the bed. If playing in singleplayer mode the night gets skipped +immediately. If playing multiplayer you get shown how many other players are in bed too, +if all players are sleeping the night gets skipped. The night skip can be forced if more +than half of the players are lying in bed and use this option. + +Another feature is a controlled respawning. If you have slept in bed (not just lying in +it) your respawn point is set to the beds location and you will respawn there after +death. +You can disable the respawn at beds by setting "enable_bed_respawn = false" in +minetest.conf. +You can disable the night skip feature by setting "enable_bed_night_skip = false" in +minetest.conf or by using the /set command in-game. diff --git a/mods/beds/api.lua b/mods/beds/api.lua new file mode 100644 index 0000000..4a9c667 --- /dev/null +++ b/mods/beds/api.lua @@ -0,0 +1,184 @@ + +local reverse = true + +local function destruct_bed(pos, n) + local node = minetest.get_node(pos) + local other + + if n == 2 then + local dir = minetest.facedir_to_dir(node.param2) + other = vector.subtract(pos, dir) + elseif n == 1 then + local dir = minetest.facedir_to_dir(node.param2) + other = vector.add(pos, dir) + end + + if reverse then + reverse = not reverse + minetest.remove_node(other) + minetest.check_for_falling(other) + beds.remove_spawns_at(pos) + beds.remove_spawns_at(other) + else + reverse = not reverse + end +end + +function beds.register_bed(name, def) + minetest.register_node(name .. "_bottom", { + description = def.description, + inventory_image = def.inventory_image, + wield_image = def.wield_image, + drawtype = "nodebox", + tiles = def.tiles.bottom, + use_texture_alpha = "clip", + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = false, + stack_max = 1, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 1}, + sounds = def.sounds or default.node_sound_wood_defaults(), + node_box = { + type = "fixed", + fixed = def.nodebox.bottom, + }, + selection_box = { + type = "fixed", + fixed = def.selectionbox, + }, + + on_place = function(itemstack, placer, pointed_thing) + local under = pointed_thing.under + local node = minetest.get_node(under) + local udef = minetest.registered_nodes[node.name] + if udef and udef.on_rightclick and + not (placer and placer:is_player() and + placer:get_player_control().sneak) then + return udef.on_rightclick(under, node, placer, itemstack, + pointed_thing) or itemstack + end + + local pos + if udef and udef.buildable_to then + pos = under + else + pos = pointed_thing.above + end + + local player_name = placer and placer:get_player_name() or "" + + if minetest.is_protected(pos, player_name) and + not minetest.check_player_privs(player_name, "protection_bypass") then + minetest.record_protection_violation(pos, player_name) + return itemstack + end + + local node_def = minetest.registered_nodes[minetest.get_node(pos).name] + if not node_def or not node_def.buildable_to then + return itemstack + end + + local dir = placer and placer:get_look_dir() and + minetest.dir_to_facedir(placer:get_look_dir()) or 0 + local botpos = vector.add(pos, minetest.facedir_to_dir(dir)) + + if minetest.is_protected(botpos, player_name) and + not minetest.check_player_privs(player_name, "protection_bypass") then + minetest.record_protection_violation(botpos, player_name) + return itemstack + end + + local botdef = minetest.registered_nodes[minetest.get_node(botpos).name] + if not botdef or not botdef.buildable_to then + return itemstack + end + + minetest.set_node(pos, {name = name .. "_bottom", param2 = dir}) + minetest.set_node(botpos, {name = name .. "_top", param2 = dir}) + + if not minetest.is_creative_enabled(player_name) then + itemstack:take_item() + end + return itemstack + end, + + on_destruct = function(pos) + destruct_bed(pos, 1) + end, + + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + beds.on_rightclick(pos, clicker) + return itemstack + end, + + on_rotate = function(pos, node, user, _, new_param2) + local dir = minetest.facedir_to_dir(node.param2) + local p = vector.add(pos, dir) + local node2 = minetest.get_node_or_nil(p) + if not node2 or not minetest.get_item_group(node2.name, "bed") == 2 or + not node.param2 == node2.param2 then + return false + end + if minetest.is_protected(p, user:get_player_name()) then + minetest.record_protection_violation(p, user:get_player_name()) + return false + end + if new_param2 % 32 > 3 then + return false + end + local newp = vector.add(pos, minetest.facedir_to_dir(new_param2)) + local node3 = minetest.get_node_or_nil(newp) + local node_def = node3 and minetest.registered_nodes[node3.name] + if not node_def or not node_def.buildable_to then + return false + end + if minetest.is_protected(newp, user:get_player_name()) then + minetest.record_protection_violation(newp, user:get_player_name()) + return false + end + node.param2 = new_param2 + -- do not remove_node here - it will trigger destroy_bed() + minetest.set_node(p, {name = "air"}) + minetest.set_node(pos, node) + minetest.set_node(newp, {name = name .. "_top", param2 = new_param2}) + return true + end, + can_dig = function(pos, player) + return beds.can_dig(pos) + end, + }) + + minetest.register_node(name .. "_top", { + drawtype = "nodebox", + tiles = def.tiles.top, + use_texture_alpha = "clip", + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = false, + pointable = false, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 2, + not_in_creative_inventory = 1}, + sounds = def.sounds or default.node_sound_wood_defaults(), + drop = name .. "_bottom", + node_box = { + type = "fixed", + fixed = def.nodebox.top, + }, + on_destruct = function(pos) + destruct_bed(pos, 2) + end, + can_dig = function(pos, player) + local node = minetest.get_node(pos) + local dir = minetest.facedir_to_dir(node.param2) + local p = vector.add(pos, dir) + return beds.can_dig(p) + end, + }) + + minetest.register_alias(name, name .. "_bottom") + + minetest.register_craft({ + output = name, + recipe = def.recipe + }) +end diff --git a/mods/beds/beds.lua b/mods/beds/beds.lua new file mode 100644 index 0000000..dc044a3 --- /dev/null +++ b/mods/beds/beds.lua @@ -0,0 +1,109 @@ +-- beds/beds.lua + +-- support for MT game translation. +local S = beds.get_translator + +-- Fancy shaped bed + +beds.register_bed("beds:fancy_bed", { + description = S("Fancy Bed"), + inventory_image = "beds_bed_fancy.png", + wield_image = "beds_bed_fancy.png", + tiles = { + bottom = { + "beds_bed_top1.png", + "beds_bed_under.png", + "beds_bed_side1.png", + "beds_bed_side1.png^[transformFX", + "beds_bed_foot.png", + "beds_bed_foot.png", + }, + top = { + "beds_bed_top2.png", + "beds_bed_under.png", + "beds_bed_side2.png", + "beds_bed_side2.png^[transformFX", + "beds_bed_head.png", + "beds_bed_head.png", + } + }, + nodebox = { + bottom = { + {-0.5, -0.5, -0.5, -0.375, -0.065, -0.4375}, + {0.375, -0.5, -0.5, 0.5, -0.065, -0.4375}, + {-0.5, -0.375, -0.5, 0.5, -0.125, -0.4375}, + {-0.5, -0.375, -0.5, -0.4375, -0.125, 0.5}, + {0.4375, -0.375, -0.5, 0.5, -0.125, 0.5}, + {-0.4375, -0.3125, -0.4375, 0.4375, -0.0625, 0.5}, + }, + top = { + {-0.5, -0.5, 0.4375, -0.375, 0.1875, 0.5}, + {0.375, -0.5, 0.4375, 0.5, 0.1875, 0.5}, + {-0.5, 0, 0.4375, 0.5, 0.125, 0.5}, + {-0.5, -0.375, 0.4375, 0.5, -0.125, 0.5}, + {-0.5, -0.375, -0.5, -0.4375, -0.125, 0.5}, + {0.4375, -0.375, -0.5, 0.5, -0.125, 0.5}, + {-0.4375, -0.3125, -0.5, 0.4375, -0.0625, 0.4375}, + } + }, + selectionbox = {-0.5, -0.5, -0.5, 0.5, 0.06, 1.5}, + recipe = { + {"", "", "group:stick"}, + {"wool:white", "wool:white", "wool:white"}, + {"group:wood", "group:wood", "group:wood"}, + }, +}) + +-- Simple shaped bed + +beds.register_bed("beds:bed", { + description = S("Simple Bed"), + inventory_image = "beds_bed.png", + wield_image = "beds_bed.png", + tiles = { + bottom = { + "beds_bed_top_bottom.png^[transformR90", + "beds_bed_under.png", + "beds_bed_side_bottom_r.png", + "beds_bed_side_bottom_r.png^[transformfx", + "beds_transparent.png", + "beds_bed_side_bottom.png" + }, + top = { + "beds_bed_top_top.png^[transformR90", + "beds_bed_under.png", + "beds_bed_side_top_r.png", + "beds_bed_side_top_r.png^[transformfx", + "beds_bed_side_top.png", + "beds_transparent.png", + } + }, + nodebox = { + bottom = {-0.5, -0.5, -0.5, 0.5, 0.0625, 0.5}, + top = {-0.5, -0.5, -0.5, 0.5, 0.0625, 0.5}, + }, + selectionbox = {-0.5, -0.5, -0.5, 0.5, 0.0625, 1.5}, + recipe = { + {"wool:white", "wool:white", "wool:white"}, + {"group:wood", "group:wood", "group:wood"} + }, +}) + +-- Aliases for PilzAdam's beds mod + +minetest.register_alias("beds:bed_bottom_red", "beds:bed_bottom") +minetest.register_alias("beds:bed_top_red", "beds:bed_top") + +-- Fuel + +minetest.register_craft({ + type = "fuel", + recipe = "beds:fancy_bed_bottom", + burntime = 13, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "beds:bed_bottom", + burntime = 12, +}) diff --git a/mods/beds/functions.lua b/mods/beds/functions.lua new file mode 100644 index 0000000..409aa37 --- /dev/null +++ b/mods/beds/functions.lua @@ -0,0 +1,300 @@ +local pi = math.pi +local is_sp = minetest.is_singleplayer() +local enable_respawn = minetest.settings:get_bool("enable_bed_respawn") +if enable_respawn == nil then + enable_respawn = true +end + +-- support for MT game translation. +local S = beds.get_translator + +-- Helper functions + +local function get_look_yaw(pos) + local rotation = minetest.get_node(pos).param2 + if rotation > 3 then + rotation = rotation % 4 -- Mask colorfacedir values + end + if rotation == 1 then + return pi / 2, rotation + elseif rotation == 3 then + return -pi / 2, rotation + elseif rotation == 0 then + return pi, rotation + else + return 0, rotation + end +end + +local function is_night_skip_enabled() + local enable_night_skip = minetest.settings:get_bool("enable_bed_night_skip") + if enable_night_skip == nil then + enable_night_skip = true + end + return enable_night_skip +end + +local function check_in_beds(players) + local in_bed = beds.player + if not players then + players = minetest.get_connected_players() + end + + for n, player in ipairs(players) do + local name = player:get_player_name() + if not in_bed[name] then + return false + end + end + + return #players > 0 +end + +local function lay_down(player, pos, bed_pos, state, skip) + local name = player:get_player_name() + local hud_flags = player:hud_get_flags() + + if not player or not name then + return + end + + -- stand up + if state ~= nil and not state then + if not beds.player[name] then + -- player not in bed, do nothing + return false + end + beds.bed_position[name] = nil + -- skip here to prevent sending player specific changes (used for leaving players) + if skip then + return + end + player:set_pos(beds.pos[name]) + + -- physics, eye_offset, etc + local physics_override = beds.player[name].physics_override + beds.player[name] = nil + player:set_physics_override({ + speed = physics_override.speed, + jump = physics_override.jump, + gravity = physics_override.gravity + }) + player:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0}) + player:set_look_horizontal(math.random(1, 180) / 100) + player_api.player_attached[name] = false + hud_flags.wielditem = true + player_api.set_animation(player, "stand" , 30) + + -- lay down + else + + -- Check if bed is occupied + for _, other_pos in pairs(beds.bed_position) do + if vector.distance(bed_pos, other_pos) < 0.1 then + minetest.chat_send_player(name, S("This bed is already occupied!")) + return false + end + end + + -- Check if player is moving + if vector.length(player:get_velocity()) > 0.001 then + minetest.chat_send_player(name, S("You have to stop moving before going to bed!")) + return false + end + + -- Check if player is attached to an object + if player:get_attach() then + return false + end + + if beds.player[name] then + -- player already in bed, do nothing + return false + end + + beds.pos[name] = pos + beds.bed_position[name] = bed_pos + beds.player[name] = {physics_override = player:get_physics_override()} + + local yaw, param2 = get_look_yaw(bed_pos) + player:set_look_horizontal(yaw) + local dir = minetest.facedir_to_dir(param2) + -- p.y is just above the nodebox height of the 'Simple Bed' (the highest bed), + -- to avoid sinking down through the bed. + local p = { + x = bed_pos.x + dir.x / 2, + y = bed_pos.y + 0.07, + z = bed_pos.z + dir.z / 2 + } + player:set_physics_override({speed = 0, jump = 0, gravity = 0}) + player:set_pos(p) + player_api.player_attached[name] = true + hud_flags.wielditem = false + player_api.set_animation(player, "lay" , 0) + end + + player:hud_set_flags(hud_flags) +end + +local function get_player_in_bed_count() + local c = 0 + for _, _ in pairs(beds.player) do + c = c + 1 + end + return c +end + +local function update_formspecs(finished) + local ges = #minetest.get_connected_players() + local player_in_bed = get_player_in_bed_count() + local is_majority = (ges / 2) < player_in_bed + + local form_n + local esc = minetest.formspec_escape + if finished then + form_n = beds.formspec .. "label[2.7,9;" .. esc(S("Good morning.")) .. "]" + else + form_n = beds.formspec .. "label[2.2,9;" .. + esc(S("@1 of @2 players are in bed", player_in_bed, ges)) .. "]" + if is_majority and is_night_skip_enabled() then + form_n = form_n .. "button_exit[2,6;4,0.75;force;" .. + esc(S("Force night skip")) .. "]" + end + end + + for name,_ in pairs(beds.player) do + minetest.show_formspec(name, "beds_form", form_n) + end +end + + +-- Public functions + +function beds.kick_players() + for name, _ in pairs(beds.player) do + local player = minetest.get_player_by_name(name) + lay_down(player, nil, nil, false) + end +end + +function beds.skip_night() + minetest.set_timeofday(0.23) +end + +function beds.on_rightclick(pos, player) + local name = player:get_player_name() + local ppos = player:get_pos() + local tod = minetest.get_timeofday() + + if tod > 0.2 and tod < 0.805 then + if beds.player[name] then + lay_down(player, nil, nil, false) + end + minetest.chat_send_player(name, S("You can only sleep at night.")) + return + end + + -- move to bed + if not beds.player[name] then + lay_down(player, ppos, pos) + beds.set_spawns() -- save respawn positions when entering bed + else + lay_down(player, nil, nil, false) + end + + if not is_sp then + update_formspecs(false) + end + + -- skip the night and let all players stand up + if check_in_beds() then + minetest.after(2, function() + if not is_sp then + update_formspecs(is_night_skip_enabled()) + end + if is_night_skip_enabled() then + beds.skip_night() + beds.kick_players() + end + end) + end +end + +function beds.can_dig(bed_pos) + -- Check all players in bed which one is at the expected position + for _, player_bed_pos in pairs(beds.bed_position) do + if vector.equals(bed_pos, player_bed_pos) then + return false + end + end + return true +end + +-- Callbacks +-- Only register respawn callback if respawn enabled +if enable_respawn then + -- respawn player at bed if enabled and valid position is found + minetest.register_on_respawnplayer(function(player) + local name = player:get_player_name() + local pos = beds.spawn[name] + if pos then + player:set_pos(pos) + return true + end + end) +end + +minetest.register_on_leaveplayer(function(player) + local name = player:get_player_name() + lay_down(player, nil, nil, false, true) + beds.player[name] = nil + if check_in_beds() then + minetest.after(2, function() + update_formspecs(is_night_skip_enabled()) + if is_night_skip_enabled() then + beds.skip_night() + beds.kick_players() + end + end) + end +end) + +minetest.register_on_dieplayer(function(player) + local name = player:get_player_name() + local in_bed = beds.player + local pos = player:get_pos() + local yaw = get_look_yaw(pos) + + if in_bed[name] then + lay_down(player, nil, pos, false) + player:set_look_horizontal(yaw) + player:set_pos(pos) + end +end) + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "beds_form" then + return + end + + -- Because "Force night skip" button is a button_exit, it will set fields.quit + -- and lay_down call will change value of player_in_bed, so it must be taken + -- earlier. + local last_player_in_bed = get_player_in_bed_count() + + if fields.quit or fields.leave then + lay_down(player, nil, nil, false) + update_formspecs(false) + end + + if fields.force then + local is_majority = (#minetest.get_connected_players() / 2) < last_player_in_bed + if is_majority and is_night_skip_enabled() then + update_formspecs(true) + beds.skip_night() + beds.kick_players() + else + update_formspecs(false) + end + end +end) diff --git a/mods/beds/init.lua b/mods/beds/init.lua new file mode 100644 index 0000000..a1a46ce --- /dev/null +++ b/mods/beds/init.lua @@ -0,0 +1,26 @@ +-- beds/init.lua + +-- Load support for MT game translation. +local S = minetest.get_translator("beds") +local esc = minetest.formspec_escape + +beds = {} +beds.player = {} +beds.bed_position = {} +beds.pos = {} +beds.spawn = {} +beds.get_translator = S + +beds.formspec = "size[8,11;true]" .. + "no_prepend[]" .. + "bgcolor[#080808BB;true]" .. + "button_exit[2,10;4,0.75;leave;" .. esc(S("Leave Bed")) .. "]" + +local modpath = minetest.get_modpath("beds") + +-- Load files + +dofile(modpath .. "/functions.lua") +dofile(modpath .. "/api.lua") +dofile(modpath .. "/beds.lua") +dofile(modpath .. "/spawns.lua") diff --git a/mods/beds/license.txt b/mods/beds/license.txt new file mode 100644 index 0000000..f3c517f --- /dev/null +++ b/mods/beds/license.txt @@ -0,0 +1,61 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2014-2016 BlockMen +Copyright (C) 2014-2016 Various Minetest developers and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media (textures) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2014-2016 BlockMen +Copyright (C) 2018 TumeniNodes + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/mods/beds/locale/beds.de.tr b/mods/beds/locale/beds.de.tr new file mode 100644 index 0000000..3f2c959 --- /dev/null +++ b/mods/beds/locale/beds.de.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Schickes Bett +Simple Bed=Schlichtes Bett +This bed is already occupied!=Dieses Bett ist bereits belegt! +You have to stop moving before going to bed!=Sie müssen stehen bleiben, bevor Sie zu Bett gehen können! +Good morning.=Guten Morgen. +@1 of @2 players are in bed=@1 von @2 Spielern sind im Bett +Force night skip=Überspringen der Nacht erzwingen +You can only sleep at night.=Sie können nur nachts schlafen. +Leave Bed=Bett verlassen diff --git a/mods/beds/locale/beds.eo.tr b/mods/beds/locale/beds.eo.tr new file mode 100644 index 0000000..6acb83d --- /dev/null +++ b/mods/beds/locale/beds.eo.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Luksa Lito +Simple Bed=Simpla Lito +This bed is already occupied!=Tiu lito jam estas okupata! +You have to stop moving before going to bed!=Vi ĉesu moviĝi por enlitiĝi! +Good morning.=Bonan matenon. +@1 of @2 players are in bed=@1 el @2 ludantoj estas en lito +Force night skip=Devigi noktan salton +You can only sleep at night.=Vi povas dormi nur nokte. +Leave Bed=Ellitiĝi diff --git a/mods/beds/locale/beds.es.tr b/mods/beds/locale/beds.es.tr new file mode 100644 index 0000000..8ef0db7 --- /dev/null +++ b/mods/beds/locale/beds.es.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Cama de lujo +Simple Bed=Cama sencilla +This bed is already occupied!=Esta cama esta ocupada +You have to stop moving before going to bed!=Deja de moverte o no podras acostarte +Good morning.=Buenos días. +@1 of @2 players are in bed=@1 de @2 jugadores están durmiendo +Force night skip=Forzar hacer de dia +You can only sleep at night.=Sólo puedes dormir por la noche. +Leave Bed=Levantarse diff --git a/mods/beds/locale/beds.fr.tr b/mods/beds/locale/beds.fr.tr new file mode 100644 index 0000000..43c06e3 --- /dev/null +++ b/mods/beds/locale/beds.fr.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Lit chic +Simple Bed=Lit simple +This bed is already occupied!=Ce lit est déjà occupé ! +You have to stop moving before going to bed!=Vous devez arrêter de bouger avant de vous coucher ! +Good morning.=Bonjour. +@1 of @2 players are in bed=@1 joueur(s) sur @2 sont au lit +Force night skip=Forcer le passage de la nuit +You can only sleep at night.=Vous ne pouvez dormir que la nuit. +Leave Bed=Se lever du lit diff --git a/mods/beds/locale/beds.id.tr b/mods/beds/locale/beds.id.tr new file mode 100644 index 0000000..7bcbb5d --- /dev/null +++ b/mods/beds/locale/beds.id.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Ranjang Mewah +Simple Bed=Ranjang Sederhana +This bed is already occupied!= +You have to stop moving before going to bed!= +Good morning.=Selamat pagi. +@1 of @2 players are in bed=@1 dari @2 pemain sedang tidur +Force night skip=Paksa lewati malam +You can only sleep at night.=Anda hanya dapat tidur pada waktu malam. +Leave Bed=Tinggalkan Ranjang diff --git a/mods/beds/locale/beds.it.tr b/mods/beds/locale/beds.it.tr new file mode 100644 index 0000000..8f4e14e --- /dev/null +++ b/mods/beds/locale/beds.it.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Letto decorato +Simple Bed=Letto semplice +This bed is already occupied!= +You have to stop moving before going to bed!= +Good morning.= +@1 of @2 players are in bed= +Force night skip= +You can only sleep at night.= +Leave Bed=Alzati dal letto diff --git a/mods/beds/locale/beds.ja.tr b/mods/beds/locale/beds.ja.tr new file mode 100644 index 0000000..5034456 --- /dev/null +++ b/mods/beds/locale/beds.ja.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=ファンシーなベッド +Simple Bed=シンプルなベッド +This bed is already occupied!=ベッドはすでに使われています! +You have to stop moving before going to bed!=寝るときは動かないでください! +Good morning.=おはようございます。 +@1 of @2 players are in bed=ベッドに@1 / @2人います +Force night skip=強制的に夜をスキップします +You can only sleep at night.=夜しか寝れません。 +Leave Bed=ベッドから出ます diff --git a/mods/beds/locale/beds.jbo.tr b/mods/beds/locale/beds.jbo.tr new file mode 100644 index 0000000..a72f686 --- /dev/null +++ b/mods/beds/locale/beds.jbo.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=lo selja'i ckana +Simple Bed=lo sampu ckana +This bed is already occupied!=.i lo ti ckana cu canlu +You have to stop moving before going to bed!=lo nu do cando cu sarcu lo nu do sipna +Good morning.=.i .uise'inai cerni +@1 of @2 players are in bed=.i @1 cmima be lu'i @2 le pilno cu vreta lo ckana +Force night skip=bapli le nu co'u nicte +You can only sleep at night.=.i steci le ka nicte kei fa le ka do kakne le ka sipna ca pa ckaji be ce'u +Leave Bed=cliva lo ckana diff --git a/mods/beds/locale/beds.ms.tr b/mods/beds/locale/beds.ms.tr new file mode 100644 index 0000000..4d4310a --- /dev/null +++ b/mods/beds/locale/beds.ms.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Katil Beragam +Simple Bed=Katil Biasa +This bed is already occupied!= +You have to stop moving before going to bed!= +Good morning.=Selamat pagi. +@1 of @2 players are in bed=@1 daripada @2 pemain sedang tidur +Force night skip=Paksa langkau malam +You can only sleep at night.=Anda hanya boleh tidur pada waktu malam. +Leave Bed=Bangun diff --git a/mods/beds/locale/beds.pl.tr b/mods/beds/locale/beds.pl.tr new file mode 100644 index 0000000..2bc03c6 --- /dev/null +++ b/mods/beds/locale/beds.pl.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Fantazyjne łóżko +Simple Bed=Proste łóżko +This bed is already occupied!=To łóżko jest już zajęte! +You have to stop moving before going to bed!=Musisz się zatrzymać aby wejść do łóżka +Good morning.=Dzień dobry. +@1 of @2 players are in bed=@1 z @2 graczy śpią +Force night skip=Wymuś pominięcie nocy +You can only sleep at night.=Możesz spać tylko w nocy. +Leave Bed=Opuść łóżko diff --git a/mods/beds/locale/beds.pt_BR.tr b/mods/beds/locale/beds.pt_BR.tr new file mode 100644 index 0000000..47fb1b9 --- /dev/null +++ b/mods/beds/locale/beds.pt_BR.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Cama Bonita +Simple Bed=Cama Simples +This bed is already occupied!=Esta cama já está ocupada! +You have to stop moving before going to bed!=Você precisa parar de se mover antes de ir para cama! +Good morning.=Bom dia. +@1 of @2 players are in bed=@1 de @2 jogadores estão na cama +Force night skip=Forçar o amanhecer +You can only sleep at night.=Você só pode dormir à noite +Leave Bed=Sair da Cama diff --git a/mods/beds/locale/beds.ru.tr b/mods/beds/locale/beds.ru.tr new file mode 100644 index 0000000..73db735 --- /dev/null +++ b/mods/beds/locale/beds.ru.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Детализированная Кровать +Simple Bed=Обычная Кровать +This bed is already occupied!=Эта кровать уже занята! +You have to stop moving before going to bed!=Нельзя воспользоваться кроватью на ходу! +Good morning.=Доброе утро. +@1 of @2 players are in bed=@1 из @2 игроков в кровати +Force night skip=Пропустить ночь +You can only sleep at night.=Вы можете спать только ночью. +Leave Bed=Встать с кровати diff --git a/mods/beds/locale/beds.sk.tr b/mods/beds/locale/beds.sk.tr new file mode 100644 index 0000000..5f31f0f --- /dev/null +++ b/mods/beds/locale/beds.sk.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Pekná posteľ +Simple Bed=Jednoduchá posteľ +This bed is already occupied!=Táto posteľ je už obsadená +You have to stop moving before going to bed!=Predtým ako si ľahneš do postele, sa musíš prestať pohybovať! +Good morning.=Dobré ráno. +@1 of @2 players are in bed=@1 z @2 hráčov sú v posteli +Force night skip=Nútene preskočiť noc +You can only sleep at night.=Môžeš spať len v noci. +Leave Bed=Opusti posteľ diff --git a/mods/beds/locale/beds.sv.tr b/mods/beds/locale/beds.sv.tr new file mode 100644 index 0000000..3b737b4 --- /dev/null +++ b/mods/beds/locale/beds.sv.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Fin säng +Simple Bed=Enkel säng +This bed is already occupied!=Den här sängen används redan! +You have to stop moving before going to bed!=Du måste stanna innan du kan lägga dig! +Good morning.=God morgon. +@1 of @2 players are in bed=@1 av @2 spelare försöker sova. +Force night skip=Tvinga att hoppa över natt +You can only sleep at night.=Du kan bara sova på natten. +Leave Bed=Lämna säng diff --git a/mods/beds/locale/beds.uk.tr b/mods/beds/locale/beds.uk.tr new file mode 100644 index 0000000..f95da70 --- /dev/null +++ b/mods/beds/locale/beds.uk.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Деталізована Постіль +Simple Bed=Звичайна Постіль +This bed is already occupied!=Ця постіль вже зайнята! +You have to stop moving before going to bed!=Не можна скористатись постіллю на ходу! +Good morning.=Доброго ранку. +@1 of @2 players are in bed=@1 з @2 гравців в ліжку +Force night skip=Пропустити ніч +You can only sleep at night.=Ви можете спати тільки вночі. +Leave Bed=Встати з ліжка diff --git a/mods/beds/locale/beds.zh_CN.tr b/mods/beds/locale/beds.zh_CN.tr new file mode 100644 index 0000000..7e6cfc7 --- /dev/null +++ b/mods/beds/locale/beds.zh_CN.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=花式床 +Simple Bed=简易床 +This bed is already occupied!=床上已有人! +You have to stop moving before going to bed!=上床前要停止移动! +Good morning.=早安! +@1 of @2 players are in bed=@2位玩家中的@1位在床上 +Force night skip=强制跳过夜晚 +You can only sleep at night.=你只能在晚上睡觉。 +Leave Bed=离开床 diff --git a/mods/beds/locale/beds.zh_TW.tr b/mods/beds/locale/beds.zh_TW.tr new file mode 100644 index 0000000..b19b481 --- /dev/null +++ b/mods/beds/locale/beds.zh_TW.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=花式床 +Simple Bed=簡易床 +This bed is already occupied!= +You have to stop moving before going to bed!= +Good morning.=早安! +@1 of @2 players are in bed=@2位玩家中的@1位在床上 +Force night skip=強制跳過夜晚 +You can only sleep at night.=你只能在晚上睡覺。 +Leave Bed=離開床 diff --git a/mods/beds/locale/template.txt b/mods/beds/locale/template.txt new file mode 100644 index 0000000..a965787 --- /dev/null +++ b/mods/beds/locale/template.txt @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed= +Simple Bed= +This bed is already occupied!= +You have to stop moving before going to bed!= +Good morning.= +@1 of @2 players are in bed= +Force night skip= +You can only sleep at night.= +Leave Bed= diff --git a/mods/beds/mod.conf b/mods/beds/mod.conf new file mode 100644 index 0000000..037481a --- /dev/null +++ b/mods/beds/mod.conf @@ -0,0 +1,3 @@ +name = beds +description = Minetest Game mod: beds +depends = sounds diff --git a/mods/beds/spawns.lua b/mods/beds/spawns.lua new file mode 100644 index 0000000..1a2ce81 --- /dev/null +++ b/mods/beds/spawns.lua @@ -0,0 +1,72 @@ +local world_path = minetest.get_worldpath() +local org_file = world_path .. "/beds_spawns" +local file = world_path .. "/beds_spawns" +local bkwd = false + +-- check for PA's beds mod spawns +local cf = io.open(world_path .. "/beds_player_spawns", "r") +if cf ~= nil then + io.close(cf) + file = world_path .. "/beds_player_spawns" + bkwd = true +end + +function beds.read_spawns() + local spawns = beds.spawn + local input = io.open(file, "r") + if input and not bkwd then + repeat + local x = input:read("*n") + if x == nil then + break + end + local y = input:read("*n") + local z = input:read("*n") + local name = input:read("*l") + spawns[name:sub(2)] = {x = x, y = y, z = z} + until input:read(0) == nil + io.close(input) + elseif input and bkwd then + beds.spawn = minetest.deserialize(input:read("*all")) + input:close() + beds.save_spawns() + os.rename(file, file .. ".backup") + file = org_file + end +end + +beds.read_spawns() + +function beds.save_spawns() + if not beds.spawn then + return + end + local data = {} + local output = io.open(org_file, "w") + for k, v in pairs(beds.spawn) do + table.insert(data, string.format("%.1f %.1f %.1f %s\n", v.x, v.y, v.z, k)) + end + output:write(table.concat(data)) + io.close(output) +end + +function beds.set_spawns() + for name,_ in pairs(beds.player) do + local player = minetest.get_player_by_name(name) + local p = player:get_pos() + -- but don't change spawn location if borrowing a bed + if not minetest.is_protected(p, name) then + beds.spawn[name] = p + end + end + beds.save_spawns() +end + +function beds.remove_spawns_at(pos) + for name, p in pairs(beds.spawn) do + if vector.equals(vector.round(p), pos) then + beds.spawn[name] = nil + end + end + beds.save_spawns() +end diff --git a/mods/beds/textures/beds_bed.png b/mods/beds/textures/beds_bed.png new file mode 100644 index 0000000..d4b02e7 Binary files /dev/null and b/mods/beds/textures/beds_bed.png differ diff --git a/mods/beds/textures/beds_bed_fancy.png b/mods/beds/textures/beds_bed_fancy.png new file mode 100644 index 0000000..1c9fde9 Binary files /dev/null and b/mods/beds/textures/beds_bed_fancy.png differ diff --git a/mods/beds/textures/beds_bed_foot.png b/mods/beds/textures/beds_bed_foot.png new file mode 100644 index 0000000..af510bb Binary files /dev/null and b/mods/beds/textures/beds_bed_foot.png differ diff --git a/mods/beds/textures/beds_bed_head.png b/mods/beds/textures/beds_bed_head.png new file mode 100644 index 0000000..b98b110 Binary files /dev/null and b/mods/beds/textures/beds_bed_head.png differ diff --git a/mods/beds/textures/beds_bed_side1.png b/mods/beds/textures/beds_bed_side1.png new file mode 100644 index 0000000..8ded54f Binary files /dev/null and b/mods/beds/textures/beds_bed_side1.png differ diff --git a/mods/beds/textures/beds_bed_side2.png b/mods/beds/textures/beds_bed_side2.png new file mode 100644 index 0000000..a6bdb99 Binary files /dev/null and b/mods/beds/textures/beds_bed_side2.png differ diff --git a/mods/beds/textures/beds_bed_side_bottom.png b/mods/beds/textures/beds_bed_side_bottom.png new file mode 100644 index 0000000..ed80f75 Binary files /dev/null and b/mods/beds/textures/beds_bed_side_bottom.png differ diff --git a/mods/beds/textures/beds_bed_side_bottom_r.png b/mods/beds/textures/beds_bed_side_bottom_r.png new file mode 100644 index 0000000..2d86532 Binary files /dev/null and b/mods/beds/textures/beds_bed_side_bottom_r.png differ diff --git a/mods/beds/textures/beds_bed_side_top.png b/mods/beds/textures/beds_bed_side_top.png new file mode 100644 index 0000000..04b2ba1 Binary files /dev/null and b/mods/beds/textures/beds_bed_side_top.png differ diff --git a/mods/beds/textures/beds_bed_side_top_r.png b/mods/beds/textures/beds_bed_side_top_r.png new file mode 100644 index 0000000..c3c07b1 Binary files /dev/null and b/mods/beds/textures/beds_bed_side_top_r.png differ diff --git a/mods/beds/textures/beds_bed_top1.png b/mods/beds/textures/beds_bed_top1.png new file mode 100644 index 0000000..2b3ae8d Binary files /dev/null and b/mods/beds/textures/beds_bed_top1.png differ diff --git a/mods/beds/textures/beds_bed_top2.png b/mods/beds/textures/beds_bed_top2.png new file mode 100644 index 0000000..b80353c Binary files /dev/null and b/mods/beds/textures/beds_bed_top2.png differ diff --git a/mods/beds/textures/beds_bed_top_bottom.png b/mods/beds/textures/beds_bed_top_bottom.png new file mode 100644 index 0000000..43dcc64 Binary files /dev/null and b/mods/beds/textures/beds_bed_top_bottom.png differ diff --git a/mods/beds/textures/beds_bed_top_top.png b/mods/beds/textures/beds_bed_top_top.png new file mode 100644 index 0000000..9b3d08f Binary files /dev/null and b/mods/beds/textures/beds_bed_top_top.png differ diff --git a/mods/beds/textures/beds_bed_under.png b/mods/beds/textures/beds_bed_under.png new file mode 100644 index 0000000..1a67367 Binary files /dev/null and b/mods/beds/textures/beds_bed_under.png differ diff --git a/mods/beds/textures/beds_transparent.png b/mods/beds/textures/beds_transparent.png new file mode 100644 index 0000000..bd36820 Binary files /dev/null and b/mods/beds/textures/beds_transparent.png differ diff --git a/mods/bucket/README.txt b/mods/bucket/README.txt new file mode 100644 index 0000000..58997b2 --- /dev/null +++ b/mods/bucket/README.txt @@ -0,0 +1,13 @@ +Minetest Game mod: bucket +========================= +See license.txt for license information. + +Authors of source code +---------------------- +Kahrl (LGPLv2.1+) +celeron55, Perttu Ahola (LGPLv2.1+) +Various Minetest developers and contributors (LGPLv2.1+) + +Authors of media (textures) +--------------------------- +ElementW (CC BY-SA 3.0) diff --git a/mods/bucket/init.lua b/mods/bucket/init.lua new file mode 100644 index 0000000..ebdf2e7 --- /dev/null +++ b/mods/bucket/init.lua @@ -0,0 +1,240 @@ +-- Minetest 0.4 mod: bucket +-- See README.txt for licensing and other information. + +-- Load support for MT game translation. +local S = minetest.get_translator("bucket") + + +minetest.register_alias("bucket", "bucket:bucket_empty") +minetest.register_alias("bucket_water", "bucket:bucket_water") +minetest.register_alias("bucket_lava", "bucket:bucket_lava") + +minetest.register_craft({ + output = "bucket:bucket_empty 1", + recipe = { + {"default:steel_ingot", "", "default:steel_ingot"}, + {"", "default:steel_ingot", ""}, + } +}) + +bucket = {} +bucket.liquids = {} + +local function check_protection(pos, name, text) + if minetest.is_protected(pos, name) then + minetest.log("action", (name ~= "" and name or "A mod") + .. " tried to " .. text + .. " at protected position " + .. minetest.pos_to_string(pos) + .. " with a bucket") + minetest.record_protection_violation(pos, name) + return true + end + return false +end + +-- Register a new liquid +-- source = name of the source node +-- flowing = name of the flowing node +-- itemname = name of the new bucket item (or nil if liquid is not takeable) +-- inventory_image = texture of the new bucket item (ignored if itemname == nil) +-- name = text description of the bucket item +-- groups = (optional) groups of the bucket item, for example {water_bucket = 1} +-- force_renew = (optional) bool. Force the liquid source to renew if it has a +-- source neighbour, even if defined as 'liquid_renewable = false'. +-- Needed to avoid creating holes in sloping rivers. +-- This function can be called from any mod (that depends on bucket). +function bucket.register_liquid(source, flowing, itemname, inventory_image, name, + groups, force_renew) + bucket.liquids[source] = { + source = source, + flowing = flowing, + itemname = itemname, + force_renew = force_renew, + } + bucket.liquids[flowing] = bucket.liquids[source] + + if itemname ~= nil then + minetest.register_craftitem(itemname, { + description = name, + inventory_image = inventory_image, + stack_max = 1, + liquids_pointable = true, + groups = groups, + + on_place = function(itemstack, user, pointed_thing) + -- Must be pointing to node + if pointed_thing.type ~= "node" then + return + end + + local node = minetest.get_node_or_nil(pointed_thing.under) + local ndef = node and minetest.registered_nodes[node.name] + + -- Call on_rightclick if the pointed node defines it + if ndef and ndef.on_rightclick and + not (user and user:is_player() and + user:get_player_control().sneak) then + return ndef.on_rightclick( + pointed_thing.under, + node, user, + itemstack) + end + + local lpos + + -- Check if pointing to a buildable node + if ndef and ndef.buildable_to then + -- buildable; replace the node + lpos = pointed_thing.under + else + -- not buildable to; place the liquid above + -- check if the node above can be replaced + + lpos = pointed_thing.above + node = minetest.get_node_or_nil(lpos) + local above_ndef = node and minetest.registered_nodes[node.name] + + if not above_ndef or not above_ndef.buildable_to then + -- do not remove the bucket with the liquid + return itemstack + end + end + + if check_protection(lpos, user + and user:get_player_name() + or "", "place "..source) then + return + end + + minetest.set_node(lpos, {name = source}) + return ItemStack("bucket:bucket_empty") + end + }) + end +end + +minetest.register_craftitem("bucket:bucket_empty", { + description = S("Empty Bucket"), + inventory_image = "bucket.png", + groups = {tool = 1}, + liquids_pointable = true, + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type == "object" then + pointed_thing.ref:punch(user, 1.0, { full_punch_interval=1.0 }, nil) + return user:get_wielded_item() + elseif pointed_thing.type ~= "node" then + -- do nothing if it's neither object nor node + return + end + -- Check if pointing to a liquid source + local node = minetest.get_node(pointed_thing.under) + local liquiddef = bucket.liquids[node.name] + local item_count = user:get_wielded_item():get_count() + + if liquiddef ~= nil + and liquiddef.itemname ~= nil + and node.name == liquiddef.source then + if check_protection(pointed_thing.under, + user:get_player_name(), + "take ".. node.name) then + return + end + + -- default set to return filled bucket + local giving_back = liquiddef.itemname + + -- check if holding more than 1 empty bucket + if item_count > 1 then + + -- if space in inventory add filled bucked, otherwise drop as item + local inv = user:get_inventory() + if inv:room_for_item("main", {name=liquiddef.itemname}) then + inv:add_item("main", liquiddef.itemname) + else + local pos = user:get_pos() + pos.y = math.floor(pos.y + 0.5) + minetest.add_item(pos, liquiddef.itemname) + end + + -- set to return empty buckets minus 1 + giving_back = "bucket:bucket_empty "..tostring(item_count-1) + + end + + -- force_renew requires a source neighbour + local source_neighbor = false + if liquiddef.force_renew then + source_neighbor = + minetest.find_node_near(pointed_thing.under, 1, liquiddef.source) + end + if not (source_neighbor and liquiddef.force_renew) then + minetest.add_node(pointed_thing.under, {name = "air"}) + end + + return ItemStack(giving_back) + else + -- non-liquid nodes will have their on_punch triggered + local node_def = minetest.registered_nodes[node.name] + if node_def then + node_def.on_punch(pointed_thing.under, node, user, pointed_thing) + end + return user:get_wielded_item() + end + end, +}) + +bucket.register_liquid( + "default:water_source", + "default:water_flowing", + "bucket:bucket_water", + "bucket_water.png", + S("Water Bucket"), + {tool = 1, water_bucket = 1} +) + +-- River water source is 'liquid_renewable = false' to avoid horizontal spread +-- of water sources in sloping rivers that can cause water to overflow +-- riverbanks and cause floods. +-- River water source is instead made renewable by the 'force renew' option +-- used here. + +bucket.register_liquid( + "default:river_water_source", + "default:river_water_flowing", + "bucket:bucket_river_water", + "bucket_river_water.png", + S("River Water Bucket"), + {tool = 1, water_bucket = 1}, + true +) + +bucket.register_liquid( + "default:lava_source", + "default:lava_flowing", + "bucket:bucket_lava", + "bucket_lava.png", + S("Lava Bucket"), + {tool = 1} +) + +minetest.register_craft({ + type = "fuel", + recipe = "bucket:bucket_lava", + burntime = 60, + replacements = {{"bucket:bucket_lava", "bucket:bucket_empty"}}, +}) + +-- Register buckets as dungeon loot +if minetest.global_exists("dungeon_loot") then + dungeon_loot.register({ + {name = "bucket:bucket_empty", chance = 0.55}, + -- water in deserts/ice or above ground, lava otherwise + {name = "bucket:bucket_water", chance = 0.45, + types = {"sandstone", "desert", "ice"}}, + {name = "bucket:bucket_water", chance = 0.45, y = {0, 32768}, + types = {"normal"}}, + {name = "bucket:bucket_lava", chance = 0.45, y = {-32768, -1}, + types = {"normal"}}, + }) +end diff --git a/mods/bucket/license.txt b/mods/bucket/license.txt new file mode 100644 index 0000000..a5156ae --- /dev/null +++ b/mods/bucket/license.txt @@ -0,0 +1,51 @@ +License of source code +---------------------- + +GNU Lesser General Public License, version 2.1 +Copyright (C) 2011-2016 Kahrl +Copyright (C) 2011-2016 celeron55, Perttu Ahola +Copyright (C) 2011-2016 Various Minetest developers and contributors + +This program is free software; you can redistribute it and/or modify it under the terms +of the GNU Lesser General Public License as published by the Free Software Foundation; +either version 2.1 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU Lesser General Public License for more details: +https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html + + +Licenses of media (textures) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2015-2016 ElementW + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/mods/bucket/locale/bucket.de.tr b/mods/bucket/locale/bucket.de.tr new file mode 100644 index 0000000..570dff1 --- /dev/null +++ b/mods/bucket/locale/bucket.de.tr @@ -0,0 +1,5 @@ +# textdomain: bucket +Empty Bucket=Leerer Eimer +Water Bucket=Wassereimer +River Water Bucket=Flusswassereimer +Lava Bucket=Lavaeimer diff --git a/mods/bucket/locale/bucket.eo.tr b/mods/bucket/locale/bucket.eo.tr new file mode 100644 index 0000000..b6266a1 --- /dev/null +++ b/mods/bucket/locale/bucket.eo.tr @@ -0,0 +1,5 @@ +# textdomain: bucket +Empty Bucket=Malplena Sitelo +Water Bucket=Sitelo da Akvo +River Water Bucket=Sitelo da Rivera Akvo +Lava Bucket=Sitelo da Lafo diff --git a/mods/bucket/locale/bucket.es.tr b/mods/bucket/locale/bucket.es.tr new file mode 100644 index 0000000..91a0623 --- /dev/null +++ b/mods/bucket/locale/bucket.es.tr @@ -0,0 +1,5 @@ +# textdomain: bucket +Empty Bucket=Cubo vacío +Water Bucket=Cubo con agua +River Water Bucket=Cubo con agua de río +Lava Bucket=Cubo con lava diff --git a/mods/bucket/locale/bucket.fr.tr b/mods/bucket/locale/bucket.fr.tr new file mode 100644 index 0000000..5065150 --- /dev/null +++ b/mods/bucket/locale/bucket.fr.tr @@ -0,0 +1,5 @@ +# textdomain: bucket +Empty Bucket=Seau vide +Water Bucket=Seau d'eau +River Water Bucket=Seau d'eau de rivière +Lava Bucket=Seau de lave diff --git a/mods/bucket/locale/bucket.id.tr b/mods/bucket/locale/bucket.id.tr new file mode 100644 index 0000000..5662563 --- /dev/null +++ b/mods/bucket/locale/bucket.id.tr @@ -0,0 +1,5 @@ +# textdomain: bucket +Empty Bucket=Ember Kosong +Water Bucket=Ember Air +River Water Bucket=Ember Air Sungai +Lava Bucket=Ember Lava diff --git a/mods/bucket/locale/bucket.it.tr b/mods/bucket/locale/bucket.it.tr new file mode 100644 index 0000000..beca28c --- /dev/null +++ b/mods/bucket/locale/bucket.it.tr @@ -0,0 +1,5 @@ +# textdomain: bucket +Empty Bucket=Secchio vuoto +Water Bucket=Secchio d'acqua +River Water Bucket=Secchio d'acqua di fiume +Lava Bucket=Secchio di lava diff --git a/mods/bucket/locale/bucket.ja.tr b/mods/bucket/locale/bucket.ja.tr new file mode 100644 index 0000000..df3bbb6 --- /dev/null +++ b/mods/bucket/locale/bucket.ja.tr @@ -0,0 +1,5 @@ +# textdomain: bucket +Empty Bucket=空のバケツ +Water Bucket=水入りバケツ +River Water Bucket=川の水入りバケツ +Lava Bucket=溶岩入りバケツ diff --git a/mods/bucket/locale/bucket.jbo.tr b/mods/bucket/locale/bucket.jbo.tr new file mode 100644 index 0000000..e40d2b9 --- /dev/null +++ b/mods/bucket/locale/bucket.jbo.tr @@ -0,0 +1,5 @@ +# textdomain: bucket +Empty Bucket=lo baktu be no da +Water Bucket=lo baktu be lo djacu +River Water Bucket=lo baktu be lo rirxe djacu +Lava Bucket=lo baktu be lo likro'i diff --git a/mods/bucket/locale/bucket.ms.tr b/mods/bucket/locale/bucket.ms.tr new file mode 100644 index 0000000..02ba38a --- /dev/null +++ b/mods/bucket/locale/bucket.ms.tr @@ -0,0 +1,5 @@ +# textdomain: bucket +Empty Bucket=Baldi Kosong +Water Bucket=Baldi Air +River Water Bucket=Baldi Air Sungai +Lava Bucket=Baldi Lava diff --git a/mods/bucket/locale/bucket.pl.tr b/mods/bucket/locale/bucket.pl.tr new file mode 100644 index 0000000..31600f1 --- /dev/null +++ b/mods/bucket/locale/bucket.pl.tr @@ -0,0 +1,5 @@ +# textdomain: bucket +Empty Bucket=Puste wiadro +Water Bucket=Wiadro z wodą +River Water Bucket=Wiadro z rzeczną wodą +Lava Bucket=Wiadro z lawą diff --git a/mods/bucket/locale/bucket.pt_BR.tr b/mods/bucket/locale/bucket.pt_BR.tr new file mode 100644 index 0000000..429acac --- /dev/null +++ b/mods/bucket/locale/bucket.pt_BR.tr @@ -0,0 +1,5 @@ +# textdomain: bucket +Empty Bucket=Balde Vazio +Water Bucket=Balde de Água +River Water Bucket=Balde de Água do Rio +Lava Bucket=Balde de Lava diff --git a/mods/bucket/locale/bucket.ru.tr b/mods/bucket/locale/bucket.ru.tr new file mode 100644 index 0000000..8ede280 --- /dev/null +++ b/mods/bucket/locale/bucket.ru.tr @@ -0,0 +1,5 @@ +# textdomain: bucket +Empty Bucket=Пустое Ведро +Water Bucket=Ведро с Водой +River Water Bucket=Ведро с Речной Водой +Lava Bucket=Ведро с Лавой diff --git a/mods/bucket/locale/bucket.sk.tr b/mods/bucket/locale/bucket.sk.tr new file mode 100644 index 0000000..0327b20 --- /dev/null +++ b/mods/bucket/locale/bucket.sk.tr @@ -0,0 +1,5 @@ +# textdomain: bucket +Empty Bucket=Prázdne vedro +Water Bucket=Vedro s vodou +River Water Bucket=Vedro s vodou z rieky +Lava Bucket=Vedro s lávou diff --git a/mods/bucket/locale/bucket.sv.tr b/mods/bucket/locale/bucket.sv.tr new file mode 100644 index 0000000..59ee62d --- /dev/null +++ b/mods/bucket/locale/bucket.sv.tr @@ -0,0 +1,5 @@ +# textdomain: bucket +Empty Bucket=Tom hink +Water Bucket=Vattenhink +River Water Bucket=Flodvattenshink +Lava Bucket=Lavahink diff --git a/mods/bucket/locale/bucket.uk.tr b/mods/bucket/locale/bucket.uk.tr new file mode 100644 index 0000000..a5251a5 --- /dev/null +++ b/mods/bucket/locale/bucket.uk.tr @@ -0,0 +1,5 @@ +# textdomain: bucket +Empty Bucket=Пусте Відро +Water Bucket=Відро З Водою +River Water Bucket=Відро З Річною Водою +Lava Bucket=Відро З Лавою diff --git a/mods/bucket/locale/bucket.zh_CN.tr b/mods/bucket/locale/bucket.zh_CN.tr new file mode 100644 index 0000000..fda5bfc --- /dev/null +++ b/mods/bucket/locale/bucket.zh_CN.tr @@ -0,0 +1,5 @@ +# textdomain: bucket +Empty Bucket=空桶 +Water Bucket=水桶 +River Water Bucket=河水桶 +Lava Bucket=岩浆桶 diff --git a/mods/bucket/locale/bucket.zh_TW.tr b/mods/bucket/locale/bucket.zh_TW.tr new file mode 100644 index 0000000..965d657 --- /dev/null +++ b/mods/bucket/locale/bucket.zh_TW.tr @@ -0,0 +1,5 @@ +# textdomain: bucket +Empty Bucket=空桶 +Water Bucket=水桶 +River Water Bucket=河水桶 +Lava Bucket=岩漿桶 diff --git a/mods/bucket/locale/template.txt b/mods/bucket/locale/template.txt new file mode 100644 index 0000000..a37c103 --- /dev/null +++ b/mods/bucket/locale/template.txt @@ -0,0 +1,5 @@ +# textdomain: bucket +Empty Bucket= +Water Bucket= +River Water Bucket= +Lava Bucket= diff --git a/mods/bucket/mod.conf b/mods/bucket/mod.conf new file mode 100644 index 0000000..fef4687 --- /dev/null +++ b/mods/bucket/mod.conf @@ -0,0 +1,4 @@ +name = bucket +description = Minetest Game mod: bucket +depends = default +optional_depends = dungeon_loot diff --git a/mods/bucket/textures/bucket.png b/mods/bucket/textures/bucket.png new file mode 100644 index 0000000..17b0c49 Binary files /dev/null and b/mods/bucket/textures/bucket.png differ diff --git a/mods/bucket/textures/bucket_lava.png b/mods/bucket/textures/bucket_lava.png new file mode 100644 index 0000000..ac6108d Binary files /dev/null and b/mods/bucket/textures/bucket_lava.png differ diff --git a/mods/bucket/textures/bucket_river_water.png b/mods/bucket/textures/bucket_river_water.png new file mode 100644 index 0000000..d4648bb Binary files /dev/null and b/mods/bucket/textures/bucket_river_water.png differ diff --git a/mods/bucket/textures/bucket_water.png b/mods/bucket/textures/bucket_water.png new file mode 100644 index 0000000..5af836b Binary files /dev/null and b/mods/bucket/textures/bucket_water.png differ diff --git a/mods/cops/init.lua b/mods/cops/init.lua new file mode 100644 index 0000000..a6142e4 --- /dev/null +++ b/mods/cops/init.lua @@ -0,0 +1,194 @@ +-- Pig spawner +minetest.register_node("cops:pig_spawner", { + walkable = false; + --[[on_timer = function(pos) + minetest.add_entity(pos, "cops:cop_regular_female") + return true + end, + + on_construct = function(pos) + minetest.get_node_timer(pos):start(20) + end,]] +}) + +--[[ +minetest.register_abm({ + nodenames = {"cops:pig_spawner"}, + --neighbors = {"default:water_source", "default:water_flowing"}, + interval = 30, -- Run every 10 seconds + chance = 5, -- One node has a chance of 1 in 50 to get selected + action = function(pos, node, active_object_count, active_object_count_wider) + minetest.add_entity(pos, "cops:cop_regular_female") + end +})]] + +-- Cops +mobs:register_mob("cops:cop_regular_female", { + type = "monster", + passive = false, + attack_type = "dogfight", + pathfinding = true, + reach = 2, + damage = 3, + hp_min = 16, + hp_max = 25, + armor = 100, + collisionbox = + { + -.4, 0, -.4, .4, 2, .4 + }, + pushable = true, + visual = "mesh", + mesh = "character.b3d", + textures = + { + {"cop_regular_female.png"}, + }, + + makes_footstep_sound = true, + sounds = + { + random = "female_noise", + }, + + walk_velocity = 2, + run_velocity = 8, + jump_height = 1, + stepheight = 0, + floats = 0, + view_range = 45, + fall_damage = true, + drops = + { + {name = "cops:badge", chance = 4, min = 0, max = 1}, + {name = "cops:handcuffs", chance = 3, min = 0, max = 1}, + {name = "cops:electric_weapon_broken", chance = 3, min = 0, max = 1} + }, + + animation = + { + speed_normal = 30, + speed_run = 50, + stand_start = 0, + stand_end = 79, + walk_start = 168, + walk_end = 187, + run_start = 168, + run_end = 187, + punch_start = 200, + punch_end = 219 + }, +}) + +mobs:register_mob("cops:cop_regular_male", { + type = "monster", + passive = false, + attack_type = "dogfight", + pathfinding = true, + reach = 2, + damage = 3, + hp_min = 21, + hp_max = 25, + armor = 100, + collisionbox = + { + -.4, 0, -.4, .4, 2, .4 + }, + pushable = true, + visual = "mesh", + mesh = "character.b3d", + textures = + { + {"cop_regular_male.png"}, + }, + + makes_footstep_sound = true, + sounds = + { + random = "male_noise", + }, + + walk_velocity = 2, + run_velocity = 8, + jump_height = 1, + stepheight = 0, + floats = 0, + view_range = 45, + fall_damage = true, + drops = + { + {name = "cops:badge", chance = 4, min = 0, max = 1}, + {name = "cops:handcuffs", chance = 3, min = 0, max = 1}, + {name = "cops:electric_weapon_broken", chance = 3, min = 0, max = 1} + }, + + animation = + { + speed_normal = 30, + speed_run = 50, + stand_start = 0, + stand_end = 79, + walk_start = 168, + walk_end = 187, + run_start = 168, + run_end = 187, + punch_start = 200, + punch_end = 219 + }, +}) + +mobs:register_mob("cops:cop_armedthug", { + type = "monster", + passive = false, + attack_type = "dogfight", + pathfinding = true, + reach = 3, + damage = 5, + hp_min = 46, + hp_max = 50, + armor = 100, + collisionbox = + { + -.4, 0, -.4, .4, 2, .4 + }, + pushable = true, + visual = "mesh", + mesh = "character.b3d", + textures = + { + {"cop_armedthug.png"}, + }, + + makes_footstep_sound = true, + sounds = + { + random = "male_noise", + }, + + walk_velocity = 2, + run_velocity = 8, + jump_height = 1, + stepheight = 0, + floats = 0, + view_range = 45, + fall_damage = true, + drops = + { + {name = "cops:badge", chance = 3, min = 0, max = 1}, + {name = "cops:handcuffs", chance = 4, min = 1, max = 2}, + }, + + animation = + { + speed_normal = 30, + speed_run = 50, + stand_start = 0, + stand_end = 79, + walk_start = 168, + walk_end = 187, + run_start = 168, + run_end = 187, + punch_start = 200, + punch_end = 219 + }, +}) \ No newline at end of file diff --git a/mods/cops/mod.conf b/mods/cops/mod.conf new file mode 100644 index 0000000..94cbe59 --- /dev/null +++ b/mods/cops/mod.conf @@ -0,0 +1,2 @@ +name = cops +depends = mobs \ No newline at end of file diff --git a/mods/cops/textures/cop_armedthug.png b/mods/cops/textures/cop_armedthug.png new file mode 100644 index 0000000..178bb0f Binary files /dev/null and b/mods/cops/textures/cop_armedthug.png differ diff --git a/mods/cops/textures/cop_regular_female.png b/mods/cops/textures/cop_regular_female.png new file mode 100644 index 0000000..0c256f8 Binary files /dev/null and b/mods/cops/textures/cop_regular_female.png differ diff --git a/mods/cops/textures/cop_regular_male.png b/mods/cops/textures/cop_regular_male.png new file mode 100644 index 0000000..2dc2341 Binary files /dev/null and b/mods/cops/textures/cop_regular_male.png differ diff --git a/mods/cops/textures/cops_badge.png b/mods/cops/textures/cops_badge.png new file mode 100644 index 0000000..3095157 Binary files /dev/null and b/mods/cops/textures/cops_badge.png differ diff --git a/mods/cops/textures/cops_baton.png b/mods/cops/textures/cops_baton.png new file mode 100644 index 0000000..6416462 Binary files /dev/null and b/mods/cops/textures/cops_baton.png differ diff --git a/mods/cops/textures/cops_electric_weapon_broken.png b/mods/cops/textures/cops_electric_weapon_broken.png new file mode 100644 index 0000000..908f91d Binary files /dev/null and b/mods/cops/textures/cops_electric_weapon_broken.png differ diff --git a/mods/cops/textures/cops_handcuffs.png b/mods/cops/textures/cops_handcuffs.png new file mode 100644 index 0000000..c08e8f7 Binary files /dev/null and b/mods/cops/textures/cops_handcuffs.png differ diff --git a/mods/creative/README.txt b/mods/creative/README.txt new file mode 100644 index 0000000..32e8d22 --- /dev/null +++ b/mods/creative/README.txt @@ -0,0 +1,17 @@ +Minetest Game mod: creative +=========================== +See license.txt for license information. + +Authors of source code +---------------------- +Originally by Perttu Ahola (celeron55) (MIT) +Jean-Patrick G. (kilbith) (MIT) + +Author of media (textures) +-------------------------- +paramat (CC BY-SA 3.0): +* creative_prev_icon.png +* creative_next_icon.png +* creative_search_icon.png +* creative_clear_icon.png +* creative_trash_icon.png derived from a texture by kilbith (CC BY-SA 3.0) diff --git a/mods/creative/init.lua b/mods/creative/init.lua new file mode 100644 index 0000000..f313485 --- /dev/null +++ b/mods/creative/init.lua @@ -0,0 +1,101 @@ +-- creative/init.lua + +-- Load support for MT game translation. +local S = minetest.get_translator("creative") + +creative = {} +creative.get_translator = S + +local function update_sfinv(name) + minetest.after(0, function() + local player = minetest.get_player_by_name(name) + if player then + if sfinv.get_page(player):sub(1, 9) == "creative:" then + sfinv.set_page(player, sfinv.get_homepage_name(player)) + else + sfinv.set_player_inventory_formspec(player) + end + end + end) +end + +minetest.register_privilege("creative", { + description = S("Allow player to use creative inventory"), + give_to_singleplayer = false, + give_to_admin = false, + on_grant = update_sfinv, + on_revoke = update_sfinv, +}) + +-- Override the engine's creative mode function +local old_is_creative_enabled = minetest.is_creative_enabled + +function minetest.is_creative_enabled(name) + if name == "" then + return old_is_creative_enabled(name) + end + return minetest.check_player_privs(name, {creative = true}) or + old_is_creative_enabled(name) +end + +-- For backwards compatibility: +function creative.is_enabled_for(name) + return minetest.is_creative_enabled(name) +end + +dofile(minetest.get_modpath("creative") .. "/inventory.lua") + +if minetest.is_creative_enabled("") then + -- Dig time is modified according to difference (leveldiff) between tool + -- 'maxlevel' and node 'level'. Digtime is divided by the larger of + -- leveldiff and 1. + -- To speed up digging in creative, hand 'maxlevel' and 'digtime' have been + -- increased such that nodes of differing levels have an insignificant + -- effect on digtime. + local digtime = 42 + local caps = {times = {digtime, digtime, digtime}, uses = 0, maxlevel = 256} + + -- Override the hand tool + minetest.override_item("", { + range = 10, + tool_capabilities = { + full_punch_interval = 0.5, + max_drop_level = 3, + groupcaps = { + crumbly = caps, + cracky = caps, + snappy = caps, + choppy = caps, + oddly_breakable_by_hand = caps, + -- dig_immediate group doesn't use value 1. Value 3 is instant dig + dig_immediate = + {times = {[2] = digtime, [3] = 0}, uses = 0, maxlevel = 256}, + }, + damage_groups = {fleshy = 10}, + } + }) +end + +-- Unlimited node placement +minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack) + if placer and placer:is_player() then + return minetest.is_creative_enabled(placer:get_player_name()) + end +end) + +-- Don't pick up if the item is already in the inventory +local old_handle_node_drops = minetest.handle_node_drops +function minetest.handle_node_drops(pos, drops, digger) + if not digger or not digger:is_player() or + not minetest.is_creative_enabled(digger:get_player_name()) then + return old_handle_node_drops(pos, drops, digger) + end + local inv = digger:get_inventory() + if inv then + for _, item in ipairs(drops) do + if not inv:contains_item("main", item, true) then + inv:add_item("main", item) + end + end + end +end diff --git a/mods/creative/inventory.lua b/mods/creative/inventory.lua new file mode 100644 index 0000000..1f9a1d5 --- /dev/null +++ b/mods/creative/inventory.lua @@ -0,0 +1,256 @@ +-- creative/inventory.lua + +-- support for MT game translation. +local S = creative.get_translator + +local player_inventory = {} +local inventory_cache = {} + +local function init_creative_cache(items) + inventory_cache[items] = {} + local i_cache = inventory_cache[items] + + for name, def in pairs(items) do + if def.groups.not_in_creative_inventory ~= 1 and + def.description and def.description ~= "" then + i_cache[name] = def + end + end + table.sort(i_cache) + return i_cache +end + +function creative.init_creative_inventory(player) + local player_name = player:get_player_name() + player_inventory[player_name] = { + size = 0, + filter = "", + start_i = 0, + old_filter = nil, -- use only for caching in update_creative_inventory + old_content = nil + } + + minetest.create_detached_inventory("creative_" .. player_name, { + allow_move = function(inv, from_list, from_index, to_list, to_index, count, player2) + local name = player2 and player2:get_player_name() or "" + if not minetest.is_creative_enabled(name) or + to_list == "main" then + return 0 + end + return count + end, + allow_put = function(inv, listname, index, stack, player2) + return 0 + end, + allow_take = function(inv, listname, index, stack, player2) + local name = player2 and player2:get_player_name() or "" + if not minetest.is_creative_enabled(name) then + return 0 + end + return -1 + end, + on_move = function(inv, from_list, from_index, to_list, to_index, count, player2) + end, + on_take = function(inv, listname, index, stack, player2) + if stack and stack:get_count() > 0 then + minetest.log("action", player_name .. " takes " .. stack:get_name().. " from creative inventory") + end + end, + }, player_name) + + return player_inventory[player_name] +end + +local NO_MATCH = 999 +local function match(s, filter) + if filter == "" then + return 0 + end + if s:lower():find(filter, 1, true) then + return #s - #filter + end + return NO_MATCH +end + +local function description(def, lang_code) + local s = def.description + if lang_code then + s = minetest.get_translated_string(lang_code, s) + end + return s:gsub("\n.*", "") -- First line only +end + +function creative.update_creative_inventory(player_name, tab_content) + local inv = player_inventory[player_name] or + creative.init_creative_inventory(minetest.get_player_by_name(player_name)) + local player_inv = minetest.get_inventory({type = "detached", name = "creative_" .. player_name}) + + if inv.filter == inv.old_filter and tab_content == inv.old_content then + return + end + inv.old_filter = inv.filter + inv.old_content = tab_content + + local items = inventory_cache[tab_content] or init_creative_cache(tab_content) + + local lang + local player_info = minetest.get_player_information(player_name) + if player_info and player_info.lang_code ~= "" then + lang = player_info.lang_code + end + + local creative_list = {} + local order = {} + for name, def in pairs(items) do + local m = match(description(def), inv.filter) + if m > 0 then + m = math.min(m, match(description(def, lang), inv.filter)) + end + if m > 0 then + m = math.min(m, match(name, inv.filter)) + end + + if m < NO_MATCH then + creative_list[#creative_list+1] = name + -- Sort by match value first so closer matches appear earlier + order[name] = string.format("%02d", m) .. name + end + end + + table.sort(creative_list, function(a, b) return order[a] < order[b] end) + + player_inv:set_size("main", #creative_list) + player_inv:set_list("main", creative_list) + inv.size = #creative_list +end + +-- Create the trash field +local trash = minetest.create_detached_inventory("trash", { + -- Allow the stack to be placed and remove it in on_put() + -- This allows the creative inventory to restore the stack + allow_put = function(inv, listname, index, stack, player) + return stack:get_count() + end, + on_put = function(inv, listname) + inv:set_list(listname, {}) + end, +}) +trash:set_size("main", 1) + +creative.formspec_add = "" + +function creative.register_tab(name, title, items) + sfinv.register_page("creative:" .. name, { + title = title, + is_in_nav = function(self, player, context) + return minetest.is_creative_enabled(player:get_player_name()) + end, + get = function(self, player, context) + local player_name = player:get_player_name() + creative.update_creative_inventory(player_name, items) + local inv = player_inventory[player_name] + local pagenum = math.floor(inv.start_i / (4*8) + 1) + local pagemax = math.ceil(inv.size / (4*8)) + local esc = minetest.formspec_escape + return sfinv.make_formspec(player, context, + "label[5.8,4.15;" .. minetest.colorize("#FFFF00", tostring(pagenum)) .. " / " .. tostring(pagemax) .. "]" .. + [[ + image[4.08,4.2;0.8,0.8;creative_trash_icon.png] + listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF] + list[detached:trash;main;4.02,4.1;1,1;] + listring[] + image_button[5,4.05;0.8,0.8;creative_prev_icon.png;creative_prev;] + image_button[7.2,4.05;0.8,0.8;creative_next_icon.png;creative_next;] + image_button[2.63,4.05;0.8,0.8;creative_search_icon.png;creative_search;] + image_button[3.25,4.05;0.8,0.8;creative_clear_icon.png;creative_clear;] + ]] .. + "tooltip[creative_search;" .. esc(S("Search")) .. "]" .. + "tooltip[creative_clear;" .. esc(S("Reset")) .. "]" .. + "tooltip[creative_prev;" .. esc(S("Previous page")) .. "]" .. + "tooltip[creative_next;" .. esc(S("Next page")) .. "]" .. + "listring[current_player;main]" .. + "field_close_on_enter[creative_filter;false]" .. + "field[0.3,4.2;2.8,1.2;creative_filter;;" .. esc(inv.filter) .. "]" .. + "listring[detached:creative_" .. player_name .. ";main]" .. + "list[detached:creative_" .. player_name .. ";main;0,0;8,4;" .. tostring(inv.start_i) .. "]" .. + creative.formspec_add, true) + end, + on_enter = function(self, player, context) + local player_name = player:get_player_name() + local inv = player_inventory[player_name] + if inv then + inv.start_i = 0 + end + end, + on_player_receive_fields = function(self, player, context, fields) + local player_name = player:get_player_name() + local inv = player_inventory[player_name] + assert(inv) + + if fields.creative_clear then + inv.start_i = 0 + inv.filter = "" + sfinv.set_player_inventory_formspec(player, context) + elseif fields.creative_search or + fields.key_enter_field == "creative_filter" then + inv.start_i = 0 + inv.filter = fields.creative_filter:lower() + sfinv.set_player_inventory_formspec(player, context) + elseif not fields.quit then + local start_i = inv.start_i or 0 + + if fields.creative_prev then + start_i = start_i - 4*8 + if start_i < 0 then + start_i = inv.size - (inv.size % (4*8)) + if inv.size == start_i then + start_i = math.max(0, inv.size - (4*8)) + end + end + elseif fields.creative_next then + start_i = start_i + 4*8 + if start_i >= inv.size then + start_i = 0 + end + end + + inv.start_i = start_i + sfinv.set_player_inventory_formspec(player, context) + end + end + }) +end + +-- Sort registered items +local registered_nodes = {} +local registered_tools = {} +local registered_craftitems = {} + +minetest.register_on_mods_loaded(function() + for name, def in pairs(minetest.registered_items) do + local group = def.groups or {} + + local nogroup = not (group.node or group.tool or group.craftitem) + if group.node or (nogroup and minetest.registered_nodes[name]) then + registered_nodes[name] = def + elseif group.tool or (nogroup and minetest.registered_tools[name]) then + registered_tools[name] = def + elseif group.craftitem or (nogroup and minetest.registered_craftitems[name]) then + registered_craftitems[name] = def + end + end +end) + +creative.register_tab("all", S("All"), minetest.registered_items) +creative.register_tab("nodes", S("Nodes"), registered_nodes) +creative.register_tab("tools", S("Tools"), registered_tools) +creative.register_tab("craftitems", S("Items"), registered_craftitems) + +local old_homepage_name = sfinv.get_homepage_name +function sfinv.get_homepage_name(player) + if minetest.is_creative_enabled(player:get_player_name()) then + return "creative:all" + else + return old_homepage_name(player) + end +end diff --git a/mods/creative/license.txt b/mods/creative/license.txt new file mode 100644 index 0000000..50ff9c7 --- /dev/null +++ b/mods/creative/license.txt @@ -0,0 +1,61 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 Perttu Ahola (celeron55) +Copyright (C) 2015-2016 Jean-Patrick G. (kilbith) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media (textures) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2016 Jean-Patrick G. (kilbith) +Copyright (C) 2018 paramat + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/mods/creative/locale/creative.de.tr b/mods/creative/locale/creative.de.tr new file mode 100644 index 0000000..02b0277 --- /dev/null +++ b/mods/creative/locale/creative.de.tr @@ -0,0 +1,10 @@ +# textdomain: creative +Allow player to use creative inventory=Spieler erlauben, das Kreativinventar zu benutzen +Search=Suchen +Reset=Zurücksetzen +Previous page=Vorherige Seite +Next page=Nächste Seite +All=Alles +Nodes=Blöcke +Tools=Werkzeuge +Items=Gegenstände diff --git a/mods/creative/locale/creative.eo.tr b/mods/creative/locale/creative.eo.tr new file mode 100644 index 0000000..1bb4fdc --- /dev/null +++ b/mods/creative/locale/creative.eo.tr @@ -0,0 +1,10 @@ +# textdomain: creative +Allow player to use creative inventory=Permesi ke la ludanto uzu la kreeman stokon +Search=Serĉi +Reset=Rekomencigi +Previous page=Antaŭa paĝo +Next page=Sekva paĝo +All=Ĉio +Nodes=Nodoj +Tools=Iloj +Items=Objektoj diff --git a/mods/creative/locale/creative.es.tr b/mods/creative/locale/creative.es.tr new file mode 100644 index 0000000..f4e39a7 --- /dev/null +++ b/mods/creative/locale/creative.es.tr @@ -0,0 +1,10 @@ +# textdomain: creative +Allow player to use creative inventory=Permitir al jugador usar el inventario creativo +Search=Buscar +Reset=Resetear +Previous page=Pág. siguiente +Next page=Pág. anterior +All=Todos +Nodes=Nodos +Tools=Herramientas +Items=Objetos diff --git a/mods/creative/locale/creative.fr.tr b/mods/creative/locale/creative.fr.tr new file mode 100644 index 0000000..695c0a1 --- /dev/null +++ b/mods/creative/locale/creative.fr.tr @@ -0,0 +1,10 @@ +# textdomain: creative +Allow player to use creative inventory=Permettre aux joueurs d'utiliser l'inventaire du mode créatif +Search=Rechercher +Reset=Réinitialiser +Previous page=Page précédente +Next page=Page suivante +All=Tout +Nodes=Nœuds +Tools=Outils +Items=Article diff --git a/mods/creative/locale/creative.id.tr b/mods/creative/locale/creative.id.tr new file mode 100644 index 0000000..613ab13 --- /dev/null +++ b/mods/creative/locale/creative.id.tr @@ -0,0 +1,10 @@ +# textdomain: creative +Allow player to use creative inventory=Bolehkan pemain memakai inventaris kreatif +Search=Cari +Reset=Atur ulang +Previous page=Halaman sebelumnya +Next page=Halaman selanjutnya +All=Semua +Nodes=Nodus +Tools=Perkakas +Items=Barang diff --git a/mods/creative/locale/creative.it.tr b/mods/creative/locale/creative.it.tr new file mode 100644 index 0000000..32f540d --- /dev/null +++ b/mods/creative/locale/creative.it.tr @@ -0,0 +1,10 @@ +# textdomain: creative +Allow player to use creative inventory=Permette al giocatore di usare l'inventario creativo +Search=Cerca +Reset=Azzera +Previous page=Pagina precedente +Next page=Pagina successiva +All=Tutto +Nodes=Nodi +Tools=Strumenti +Items=Oggetti diff --git a/mods/creative/locale/creative.ja.tr b/mods/creative/locale/creative.ja.tr new file mode 100644 index 0000000..1c215bb --- /dev/null +++ b/mods/creative/locale/creative.ja.tr @@ -0,0 +1,10 @@ +# textdomain: creative +Allow player to use creative inventory=プレーヤーにクリエイティブ インベントリーの使用を許可する +Search=検索 +Reset=リセット +Previous page=前のページ +Next page=次のページ +All=すべて +Nodes=ブロック +Tools=道具 +Items=アイテム diff --git a/mods/creative/locale/creative.jbo.tr b/mods/creative/locale/creative.jbo.tr new file mode 100644 index 0000000..6d0b736 --- /dev/null +++ b/mods/creative/locale/creative.jbo.tr @@ -0,0 +1,10 @@ +# textdomain: creative +Allow player to use creative inventory=zifre le ka pilno le finti ke dacti liste +Search=sisku +Reset=kraga'igau +Previous page=lidne +Next page=selyli'e +All=ro dacti +Nodes=bliku +Tools=tutci +Items=dacti diff --git a/mods/creative/locale/creative.ms.tr b/mods/creative/locale/creative.ms.tr new file mode 100644 index 0000000..a2aef80 --- /dev/null +++ b/mods/creative/locale/creative.ms.tr @@ -0,0 +1,10 @@ +# textdomain: creative +Allow player to use creative inventory=Benarkan pemain menggunakan inventori kreatif +Search=Cari +Reset=Set semula +Previous page=Halaman sebelumnya +Next page=Halaman seterusnya +All=Semua +Nodes=Nod +Tools=Alatan +Items=Item diff --git a/mods/creative/locale/creative.pl.tr b/mods/creative/locale/creative.pl.tr new file mode 100644 index 0000000..7844cd6 --- /dev/null +++ b/mods/creative/locale/creative.pl.tr @@ -0,0 +1,10 @@ +# textdomain: creative +Allow player to use creative inventory=Zezwól graczom na używanie kreatywnego ekwipunku +Search=Wyszukaj +Reset=Zresetuj +Previous page=Poprzednia strona +Next page=Następna strona +All=Wszystko +Nodes=Bloki +Tools=Narzędzia +Items=Przedmioty diff --git a/mods/creative/locale/creative.pt_BR.tr b/mods/creative/locale/creative.pt_BR.tr new file mode 100644 index 0000000..c8a04bd --- /dev/null +++ b/mods/creative/locale/creative.pt_BR.tr @@ -0,0 +1,10 @@ +# textdomain: creative +Allow player to use creative inventory=Permitir o jogador usar o inventário criativo +Search=Pesquisar +Reset=Redefinir +Previous page=Página anterior +Next page=Próxima página +All=Todos +Nodes=Blocos +Tools=Ferramentas +Items=Itens diff --git a/mods/creative/locale/creative.ru.tr b/mods/creative/locale/creative.ru.tr new file mode 100644 index 0000000..f649dbc --- /dev/null +++ b/mods/creative/locale/creative.ru.tr @@ -0,0 +1,10 @@ +# textdomain: creative +Allow player to use creative inventory=Разрешить игроку использовать творческий инвентарь +Search=Поиск +Reset=Сброс +Previous page=Предыдущая страница +Next page=Следующая страница +All=Всё +Nodes=Ноды +Tools=Инструменты +Items=Предметы diff --git a/mods/creative/locale/creative.sk.tr b/mods/creative/locale/creative.sk.tr new file mode 100644 index 0000000..935c780 --- /dev/null +++ b/mods/creative/locale/creative.sk.tr @@ -0,0 +1,10 @@ +# textdomain: creative +Allow player to use creative inventory=Povolí hráčovi použivať kreatívny inventár +Search=Hľadaj +Reset=Vrátiť späť +Previous page=Predchádzajúca stránka +Next page=Nasledujúca stránka +All=Všetko +Nodes=Kocky +Tools=Nástroje +Items=Veci diff --git a/mods/creative/locale/creative.sv.tr b/mods/creative/locale/creative.sv.tr new file mode 100644 index 0000000..a9a741f --- /dev/null +++ b/mods/creative/locale/creative.sv.tr @@ -0,0 +1,10 @@ +# textdomain: creative +Allow player to use creative inventory=Tillåt spelare att använda kreativa saker +Search=Sök +Reset=Återställ +Previous page=Förra sida +Next page=Nästa sida +All=Alla +Nodes=Noder +Tools=Verktyg +Items=Saker diff --git a/mods/creative/locale/creative.uk.tr b/mods/creative/locale/creative.uk.tr new file mode 100644 index 0000000..4e68caa --- /dev/null +++ b/mods/creative/locale/creative.uk.tr @@ -0,0 +1,10 @@ +# textdomain: creative +Allow player to use creative inventory=Дозволити гравцеві використати творчий інвентар +Search=Пошук +Reset=Скинути +Previous page=Попередня сторінка +Next page=Наступна сторінка +All=Все +Nodes=Ноди +Tools=Інструменти +Items=Предмети diff --git a/mods/creative/locale/creative.zh_CN.tr b/mods/creative/locale/creative.zh_CN.tr new file mode 100644 index 0000000..1ca424e --- /dev/null +++ b/mods/creative/locale/creative.zh_CN.tr @@ -0,0 +1,10 @@ +# textdomain: creative +Allow player to use creative inventory=允许玩家使用创造模式物品栏 +Search=搜索 +Reset=重置 +Previous page=上一页 +Next page=下一页 +All=所有 +Nodes=节点 +Tools=工具 +Items=物品 diff --git a/mods/creative/locale/creative.zh_TW.tr b/mods/creative/locale/creative.zh_TW.tr new file mode 100644 index 0000000..c5746d4 --- /dev/null +++ b/mods/creative/locale/creative.zh_TW.tr @@ -0,0 +1,10 @@ +# textdomain: creative +Allow player to use creative inventory=允許玩家使用創造模式物品欄 +Search=搜索 +Reset=重置 +Previous page=上一頁 +Next page=下一頁 +All=所有 +Nodes=節點 +Tools=工具 +Items=物品 diff --git a/mods/creative/locale/template.txt b/mods/creative/locale/template.txt new file mode 100644 index 0000000..3e79730 --- /dev/null +++ b/mods/creative/locale/template.txt @@ -0,0 +1,10 @@ +# textdomain: creative +Allow player to use creative inventory= +Search= +Reset= +Previous page= +Next page= +All= +Nodes= +Tools= +Items= diff --git a/mods/creative/mod.conf b/mods/creative/mod.conf new file mode 100644 index 0000000..0b3f745 --- /dev/null +++ b/mods/creative/mod.conf @@ -0,0 +1,3 @@ +name = creative +description = Minetest Game mod: creative +depends = default, sfinv diff --git a/mods/creative/textures/creative_clear_icon.png b/mods/creative/textures/creative_clear_icon.png new file mode 100644 index 0000000..ab421d9 Binary files /dev/null and b/mods/creative/textures/creative_clear_icon.png differ diff --git a/mods/creative/textures/creative_next_icon.png b/mods/creative/textures/creative_next_icon.png new file mode 100644 index 0000000..4a3637d Binary files /dev/null and b/mods/creative/textures/creative_next_icon.png differ diff --git a/mods/creative/textures/creative_prev_icon.png b/mods/creative/textures/creative_prev_icon.png new file mode 100644 index 0000000..d5e3c27 Binary files /dev/null and b/mods/creative/textures/creative_prev_icon.png differ diff --git a/mods/creative/textures/creative_search_icon.png b/mods/creative/textures/creative_search_icon.png new file mode 100644 index 0000000..421b833 Binary files /dev/null and b/mods/creative/textures/creative_search_icon.png differ diff --git a/mods/creative/textures/creative_trash_icon.png b/mods/creative/textures/creative_trash_icon.png new file mode 100644 index 0000000..a0f6d23 Binary files /dev/null and b/mods/creative/textures/creative_trash_icon.png differ diff --git a/mods/destruction_counter/init.lua b/mods/destruction_counter/init.lua new file mode 100644 index 0000000..691936a --- /dev/null +++ b/mods/destruction_counter/init.lua @@ -0,0 +1,59 @@ +local modpath = minetest.get_modpath("destruction_counter") + +destruction_counter = {} +destruction_counter.nodesDestroyed = 0 +local nodesDestroyedByHand = 0 + +local idText +local idMeter +minetest.register_on_joinplayer(function(player) + meta = player:get_meta() + + + idText = player:hud_add({ + hud_elem_type = "text", + position = {x = .5, y = .5}, + offset = {x = 0, y = 0}, + text = nodesDestroyed, + alignment = {x = 0, y = 0}, -- center aligned + scale = {x = 100, y = 100}, -- covered later + }) + + player:hud_add({ + hud_elem_type = "image", + position = {x = 1, y = .5}, + offset = {x = -515, y = 23}, + text = "destruction_counter_meter_empty.png", + scale = {x = 4, y = 4}, + alignment = {x = 1, y = 0}, + }) + + idMeter = player:hud_add({ + hud_elem_type = "image", + position = {x = 1, y = .5}, + offset = {x = -510, y = 23}, + text = "destruction_counter_meter_full.png", + scale = {x = 0, y = 4}, + alignment = {x = 1, y = 0}, + }) +end) + +minetest.register_on_dignode(function(pos, oldnode, digger) + nodesDestroyedByHand = nodesDestroyedByHand + 1 + destruction_counter.updateCounter(digger) +end) + +function destruction_counter.updateCounter(player) + if not player then + return + end + + local totalDestruction = destruction_counter.nodesDestroyed + math.floor(nodesDestroyedByHand / 10) + local percentage = (totalDestruction / 1000 * 4) + if percentage > 100 then + percentage = 100 + end + player:hud_change(idText, "text", "Destruction meter: " .. totalDestruction) + player:hud_change(idMeter, "scale", {x = percentage, y = 4}) +end + diff --git a/mods/destruction_counter/mod.conf b/mods/destruction_counter/mod.conf new file mode 100644 index 0000000..2edf341 --- /dev/null +++ b/mods/destruction_counter/mod.conf @@ -0,0 +1,4 @@ +name = destruction_counter +description = Adds a HUD counter that shows how much shit you've destroyed. +author = MCL +title = Destruction Counter diff --git a/mods/destruction_counter/textures/destruction_counter_meter_empty.png b/mods/destruction_counter/textures/destruction_counter_meter_empty.png new file mode 100644 index 0000000..ab77b8f Binary files /dev/null and b/mods/destruction_counter/textures/destruction_counter_meter_empty.png differ diff --git a/mods/destruction_counter/textures/destruction_counter_meter_full.png b/mods/destruction_counter/textures/destruction_counter_meter_full.png new file mode 100644 index 0000000..65891df Binary files /dev/null and b/mods/destruction_counter/textures/destruction_counter_meter_full.png differ diff --git a/mods/doors/README.txt b/mods/doors/README.txt new file mode 100644 index 0000000..f9caaff --- /dev/null +++ b/mods/doors/README.txt @@ -0,0 +1,87 @@ +Minetest Game mod: doors +======================== +See license.txt for license information. + +Authors of source code +---------------------- +Originally by PilzAdam (MIT) + +Modified by BlockMen (MIT): Added sounds, glass doors (glass, obsidian glass) and trapdoor. + +Modified by sofar (sofar@foo-projects.org) (MIT): +Added Steel trapdoor. +Re-implemented most of the door algorithms, added meshes, UV wrapped texture. +Added doors API to facilitate coding mods accessing and operating doors. +Added Fence Gate model, code, and sounds. + +Various Minetest developers and contributors (MIT) + + +Authors of media (textures) +--------------------------- +Following textures created by Fernando Zapata (CC BY-SA 3.0): + door_wood.png + door_wood_a.png + door_wood_a_r.png + door_wood_b.png + door_wood_b_r.png + +Following textures created by BlockMen (CC BY-SA 3.0): + door_trapdoor.png + door_obsidian_glass_side.png + +Following textures created by celeron55 (CC BY-SA 3.0): + door_glass_a.png + door_glass_b.png + +Following textures created by PenguinDad (CC BY-SA 4.0): + door_glass.png + door_obsidian_glass.png + +Following textures created by sofar (CC-BY-SA-3.0): + doors_trapdoor_steel.png + +Following textures created by paramat (CC-BY-SA-3.0): + door_trapdoor_side.png + doors_trapdoor_steel_side.png + +Obsidian door textures by red-001 based on textures by Pilzadam and BlockMen (CC BY-SA 3.0): + door_obsidian_glass.png + +Glass door textures by Krock and paramat based on textures by VanessaE (CC BY-SA 3.0): + doors_door_glass.png + doors_item_glass.png + +All other textures (created by PilzAdam) (CC BY-SA 3.0): + +Door textures were converted to the new texture map by sofar, paramat and +red-001, under the same license as the originals. + + +Authors of media (models) +------------------------- +Door 3d models by sofar (CC-BY-SA-3.0) + - door_a.obj + - door_b.obj +Fence gate models by sofar (CC-BY-SA-3.0) + - fencegate_open.obj + - fencegate_closed.obj + + +Authors of media (sounds) +------------------------- +Opening-Sound created by CGEffex (CC BY 3.0), modified by BlockMen + door_open.ogg +Closing-Sound created by bennstir (CC BY 3.0) + door_close.ogg +fencegate_open.ogg: + http://www.freesound.org/people/mhtaylor67/sounds/126041/ - (CC0 1.0) +fencegate_close.ogg: + http://www.freesound.org/people/BarkersPinhead/sounds/274807/ - (CC-BY-3.0) + http://www.freesound.org/people/rivernile7/sounds/249573/ - (CC-BY-3.0) +Steel door sounds open & close (CC-BY-3.0) by HazMatt + - http://www.freesound.org/people/HazMattt/sounds/187283/ + doors_steel_door_open.ogg + doors_steel_door_close.ogg +doors_glass_door_open.ogg, doors_glass_door_close.ogg: + https://www.freesound.org/people/SkeetMasterFunk69/sounds/235546/ (CC0 1.0) diff --git a/mods/doors/init.lua b/mods/doors/init.lua new file mode 100644 index 0000000..2b09c2e --- /dev/null +++ b/mods/doors/init.lua @@ -0,0 +1,860 @@ +-- doors/init.lua + +-- our API object +doors = {} + +doors.registered_doors = {} +doors.registered_trapdoors = {} + +-- Load support for MT game translation. +local S = minetest.get_translator("doors") + + +local function replace_old_owner_information(pos) + local meta = minetest.get_meta(pos) + local owner = meta:get_string("doors_owner") + if owner and owner ~= "" then + meta:set_string("owner", owner) + meta:set_string("doors_owner", "") + end +end + +-- returns an object to a door object or nil +function doors.get(pos) + local node_name = minetest.get_node(pos).name + if doors.registered_doors[node_name] then + -- A normal upright door + return { + pos = pos, + open = function(self, player) + if self:state() then + return false + end + return doors.door_toggle(self.pos, nil, player) + end, + close = function(self, player) + if not self:state() then + return false + end + return doors.door_toggle(self.pos, nil, player) + end, + toggle = function(self, player) + return doors.door_toggle(self.pos, nil, player) + end, + state = function(self) + local state = minetest.get_meta(self.pos):get_int("state") + return state %2 == 1 + end + } + elseif doors.registered_trapdoors[node_name] then + -- A trapdoor + return { + pos = pos, + open = function(self, player) + if self:state() then + return false + end + return doors.trapdoor_toggle(self.pos, nil, player) + end, + close = function(self, player) + if not self:state() then + return false + end + return doors.trapdoor_toggle(self.pos, nil, player) + end, + toggle = function(self, player) + return doors.trapdoor_toggle(self.pos, nil, player) + end, + state = function(self) + return minetest.get_node(self.pos).name:sub(-5) == "_open" + end + } + else + return nil + end +end + +-- this hidden node is placed on top of the bottom, and prevents +-- nodes from being placed in the top half of the door. +minetest.register_node("doors:hidden", { + description = S("Hidden Door Segment"), + inventory_image = "doors_hidden_segment.png^default_invisible_node_overlay.png", + wield_image = "doors_hidden_segment.png^default_invisible_node_overlay.png", + drawtype = "airlike", + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + -- has to be walkable for falling nodes to stop falling. + walkable = true, + pointable = false, + diggable = false, + buildable_to = false, + floodable = false, + drop = "", + groups = {not_in_creative_inventory = 1}, + on_blast = function() end, + -- 1px block inside door hinge near node top + collision_box = { + type = "fixed", + fixed = {-15/32, 13/32, -15/32, -13/32, 1/2, -13/32}, + }, +}) + +-- table used to aid door opening/closing +local transform = { + { + {v = "_a", param2 = 3}, + {v = "_a", param2 = 0}, + {v = "_a", param2 = 1}, + {v = "_a", param2 = 2}, + }, + { + {v = "_c", param2 = 1}, + {v = "_c", param2 = 2}, + {v = "_c", param2 = 3}, + {v = "_c", param2 = 0}, + }, + { + {v = "_b", param2 = 1}, + {v = "_b", param2 = 2}, + {v = "_b", param2 = 3}, + {v = "_b", param2 = 0}, + }, + { + {v = "_d", param2 = 3}, + {v = "_d", param2 = 0}, + {v = "_d", param2 = 1}, + {v = "_d", param2 = 2}, + }, +} + +function doors.door_toggle(pos, node, clicker) + local meta = minetest.get_meta(pos) + node = node or minetest.get_node(pos) + local def = minetest.registered_nodes[node.name] + local name = def.door.name + + local state = meta:get_string("state") + if state == "" then + -- fix up lvm-placed right-hinged doors, default closed + if node.name:sub(-2) == "_b" then + state = 2 + else + state = 0 + end + else + state = tonumber(state) + end + + replace_old_owner_information(pos) + + + + -- until Lua-5.2 we have no bitwise operators :( + if state % 2 == 1 then + state = state - 1 + else + state = state + 1 + end + + local dir = node.param2 + + -- It's possible param2 is messed up, so, validate before using + -- the input data. This indicates something may have rotated + -- the door, even though that is not supported. + if not transform[state + 1] or not transform[state + 1][dir + 1] then + return false + end + + if state % 2 == 0 then + minetest.sound_play(def.door.sounds[1], + {pos = pos, gain = def.door.gains[1], max_hear_distance = 10}, true) + else + minetest.sound_play(def.door.sounds[2], + {pos = pos, gain = def.door.gains[2], max_hear_distance = 10}, true) + end + + minetest.swap_node(pos, { + name = name .. transform[state + 1][dir+1].v, + param2 = transform[state + 1][dir+1].param2 + }) + meta:set_int("state", state) + + return true +end + + +local function on_place_node(place_to, newnode, + placer, oldnode, itemstack, pointed_thing) + -- Run script hook + for _, callback in ipairs(minetest.registered_on_placenodes) do + -- Deepcopy pos, node and pointed_thing because callback can modify them + local place_to_copy = {x = place_to.x, y = place_to.y, z = place_to.z} + local newnode_copy = + {name = newnode.name, param1 = newnode.param1, param2 = newnode.param2} + local oldnode_copy = + {name = oldnode.name, param1 = oldnode.param1, param2 = oldnode.param2} + local pointed_thing_copy = { + type = pointed_thing.type, + above = vector.new(pointed_thing.above), + under = vector.new(pointed_thing.under), + ref = pointed_thing.ref, + } + callback(place_to_copy, newnode_copy, placer, + oldnode_copy, itemstack, pointed_thing_copy) + end +end + + +function doors.register(name, def) + if not name:find(":") then + name = "doors:" .. name + end + + -- replace old doors of this type automatically + minetest.register_lbm({ + name = ":doors:replace_" .. name:gsub(":", "_"), + nodenames = {name.."_b_1", name.."_b_2"}, + action = function(pos, node) + local l = tonumber(node.name:sub(-1)) + local meta = minetest.get_meta(pos) + local h = meta:get_int("right") + 1 + local p2 = node.param2 + local replace = { + {{type = "a", state = 0}, {type = "a", state = 3}}, + {{type = "b", state = 1}, {type = "b", state = 2}} + } + local new = replace[l][h] + -- retain infotext and doors_owner fields + minetest.swap_node(pos, {name = name .. "_" .. new.type, param2 = p2}) + meta:set_int("state", new.state) + -- properly place doors:hidden at the right spot + local p3 = p2 + if new.state >= 2 then + p3 = (p3 + 3) % 4 + end + if new.state % 2 == 1 then + if new.state >= 2 then + p3 = (p3 + 1) % 4 + else + p3 = (p3 + 3) % 4 + end + end + -- wipe meta on top node as it's unused + minetest.set_node({x = pos.x, y = pos.y + 1, z = pos.z}, + {name = "doors:hidden", param2 = p3}) + end + }) + + minetest.register_craftitem(":" .. name, { + description = def.description, + inventory_image = def.inventory_image, + groups = table.copy(def.groups), + + on_place = function(itemstack, placer, pointed_thing) + local pos + + if pointed_thing.type ~= "node" then + return itemstack + end + + local doorname = itemstack:get_name() + local node = minetest.get_node(pointed_thing.under) + local pdef = minetest.registered_nodes[node.name] + if pdef and pdef.on_rightclick and + not (placer and placer:is_player() and + placer:get_player_control().sneak) then + return pdef.on_rightclick(pointed_thing.under, + node, placer, itemstack, pointed_thing) + end + + if pdef and pdef.buildable_to then + pos = pointed_thing.under + else + pos = pointed_thing.above + node = minetest.get_node(pos) + pdef = minetest.registered_nodes[node.name] + if not pdef or not pdef.buildable_to then + return itemstack + end + end + + local above = {x = pos.x, y = pos.y + 1, z = pos.z} + local top_node = minetest.get_node_or_nil(above) + local topdef = top_node and minetest.registered_nodes[top_node.name] + + if not topdef or not topdef.buildable_to then + return itemstack + end + + local pn = placer and placer:get_player_name() or "" + if minetest.is_protected(pos, pn) or minetest.is_protected(above, pn) then + return itemstack + end + + local dir = placer and minetest.dir_to_facedir(placer:get_look_dir()) or 0 + + local ref = { + {x = -1, y = 0, z = 0}, + {x = 0, y = 0, z = 1}, + {x = 1, y = 0, z = 0}, + {x = 0, y = 0, z = -1}, + } + + local aside = { + x = pos.x + ref[dir + 1].x, + y = pos.y + ref[dir + 1].y, + z = pos.z + ref[dir + 1].z, + } + + local state = 0 + if minetest.get_item_group(minetest.get_node(aside).name, "door") == 1 then + state = state + 2 + minetest.set_node(pos, {name = doorname .. "_b", param2 = dir}) + minetest.set_node(above, {name = "doors:hidden", param2 = (dir + 3) % 4}) + else + minetest.set_node(pos, {name = doorname .. "_a", param2 = dir}) + minetest.set_node(above, {name = "doors:hidden", param2 = dir}) + end + + local meta = minetest.get_meta(pos) + meta:set_int("state", state) + + if def.protected then + meta:set_string("owner", pn) + meta:set_string("infotext", def.description .. "\n" .. S("Owned by @1", pn)) + end + + if not minetest.is_creative_enabled(pn) then + itemstack:take_item() + end + + + + on_place_node(pos, minetest.get_node(pos), + placer, node, itemstack, pointed_thing) + + return itemstack + end + }) + def.inventory_image = nil + + if def.recipe then + minetest.register_craft({ + output = name, + recipe = def.recipe, + }) + end + def.recipe = nil + + + + if not def.sound_open then + def.sound_open = "doors_door_open" + end + + if not def.sound_close then + def.sound_close = "doors_door_close" + end + + if not def.gain_open then + def.gain_open = 0.3 + end + + if not def.gain_close then + def.gain_close = 0.3 + end + + def.groups.not_in_creative_inventory = 1 + def.groups.door = 1 + def.drop = name + def.door = { + name = name, + sounds = {def.sound_close, def.sound_open}, + gains = {def.gain_close, def.gain_open}, + } + if not def.on_rightclick then + def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + doors.door_toggle(pos, node, clicker) + return itemstack + end + end + def.after_dig_node = function(pos, node, meta, digger) + minetest.remove_node({x = pos.x, y = pos.y + 1, z = pos.z}) + minetest.check_for_falling({x = pos.x, y = pos.y + 1, z = pos.z}) + end + def.on_rotate = function(pos, node, user, mode, new_param2) + return false + end + + if def.protected then + def.can_dig = can_dig_door + def.on_blast = function() end + def.on_key_use = function(pos, player) + local door = doors.get(pos) + door:toggle(player) + end + def.on_skeleton_key_use = function(pos, player, newsecret) + replace_old_owner_information(pos) + local meta = minetest.get_meta(pos) + local owner = meta:get_string("owner") + local pname = player:get_player_name() + + -- verify placer is owner of lockable door + if owner ~= pname then + minetest.record_protection_violation(pos, pname) + minetest.chat_send_player(pname, S("You do not own this locked door.")) + return nil + end + + local secret = meta:get_string("key_lock_secret") + if secret == "" then + secret = newsecret + meta:set_string("key_lock_secret", secret) + end + + return secret, S("a locked door"), owner + end + def.node_dig_prediction = "" + else + def.on_blast = function(pos, intensity) + minetest.remove_node(pos) + -- hidden node doesn't get blasted away. + minetest.remove_node({x = pos.x, y = pos.y + 1, z = pos.z}) + return {name} + end + end + + def.on_destruct = function(pos) + minetest.remove_node({x = pos.x, y = pos.y + 1, z = pos.z}) + end + + def.drawtype = "mesh" + def.paramtype = "light" + def.paramtype2 = "facedir" + def.sunlight_propagates = true + def.walkable = true + def.is_ground_content = false + def.buildable_to = false + def.selection_box = {type = "fixed", fixed = {-1/2,-1/2,-1/2,1/2,3/2,-6/16}} + def.collision_box = {type = "fixed", fixed = {-1/2,-1/2,-1/2,1/2,3/2,-6/16}} + def.use_texture_alpha = def.use_texture_alpha or "clip" + + def.mesh = "door_a.b3d" + minetest.register_node(":" .. name .. "_a", table.copy(def)) + + def.mesh = "door_b.b3d" + minetest.register_node(":" .. name .. "_b", table.copy(def)) + + def.mesh = "door_b.b3d" + minetest.register_node(":" .. name .. "_c", table.copy(def)) + + def.mesh = "door_a.b3d" + minetest.register_node(":" .. name .. "_d", table.copy(def)) + + doors.registered_doors[name .. "_a"] = true + doors.registered_doors[name .. "_b"] = true + doors.registered_doors[name .. "_c"] = true + doors.registered_doors[name .. "_d"] = true +end + +doors.register("door_wood", { + tiles = {{ name = "doors_door_wood.png", backface_culling = true }}, + description = S("Wooden Door"), + inventory_image = "doors_item_wood.png", + groups = {node = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + gain_open = 0.06, + gain_close = 0.13, + recipe = { + {"group:wood", "group:wood"}, + {"group:wood", "group:wood"}, + {"group:wood", "group:wood"}, + } +}) + +doors.register("door_steel", { + tiles = {{name = "doors_door_steel.png", backface_culling = true}}, + description = S("Steel Door"), + inventory_image = "doors_item_steel.png", + protected = true, + groups = {node = 1, cracky = 1, level = 2}, + sounds = default.node_sound_metal_defaults(), + sound_open = "doors_steel_door_open", + sound_close = "doors_steel_door_close", + gain_open = 0.2, + gain_close = 0.2, + +}) + +doors.register("door_glass", { + tiles = {"doors_door_glass.png"}, + description = S("Glass Door"), + inventory_image = "doors_item_glass.png", + groups = {node = 1, cracky=3, oddly_breakable_by_hand=3}, + sounds = default.node_sound_glass_defaults(), + sound_open = "doors_glass_door_open", + sound_close = "doors_glass_door_close", + gain_open = 0.3, + gain_close = 0.25, + +}) + +doors.register("door_obsidian_glass", { + tiles = {"doors_door_obsidian_glass.png"}, + description = S("Obsidian Glass Door"), + inventory_image = "doors_item_obsidian_glass.png", + groups = {node = 1, cracky=3}, + sounds = default.node_sound_glass_defaults(), + sound_open = "doors_glass_door_open", + sound_close = "doors_glass_door_close", + gain_open = 0.3, + gain_close = 0.25, + +}) + +-- Capture mods using the old API as best as possible. +function doors.register_door(name, def) + if def.only_placer_can_open then + def.protected = true + end + def.only_placer_can_open = nil + + local i = name:find(":") + local modname = name:sub(1, i - 1) + if not def.tiles then + if def.protected then + def.tiles = {{name = "doors_door_steel.png", backface_culling = true}} + else + def.tiles = {{name = "doors_door_wood.png", backface_culling = true}} + end + minetest.log("warning", modname .. " registered door \"" .. name .. "\" " .. + "using deprecated API method \"doors.register_door()\" but " .. + "did not provide the \"tiles\" parameter. A fallback tiledef " .. + "will be used instead.") + end + + doors.register(name, def) +end + +----trapdoor---- + +function doors.trapdoor_toggle(pos, node, clicker) + node = node or minetest.get_node(pos) + + replace_old_owner_information(pos) + + + + local def = minetest.registered_nodes[node.name] + + if string.sub(node.name, -5) == "_open" then + minetest.sound_play(def.sound_close, + {pos = pos, gain = def.gain_close, max_hear_distance = 10}, true) + minetest.swap_node(pos, {name = string.sub(node.name, 1, + string.len(node.name) - 5), param1 = node.param1, param2 = node.param2}) + else + minetest.sound_play(def.sound_open, + {pos = pos, gain = def.gain_open, max_hear_distance = 10}, true) + minetest.swap_node(pos, {name = node.name .. "_open", + param1 = node.param1, param2 = node.param2}) + end +end + +function doors.register_trapdoor(name, def) + if not name:find(":") then + name = "doors:" .. name + end + + local name_closed = name + local name_opened = name.."_open" + + def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + doors.trapdoor_toggle(pos, node, clicker) + return itemstack + end + + -- Common trapdoor configuration + def.drawtype = "nodebox" + def.paramtype = "light" + def.paramtype2 = "facedir" + def.is_ground_content = false + def.use_texture_alpha = def.use_texture_alpha or "clip" + + if def.protected then + def.can_dig = can_dig_door + def.after_place_node = function(pos, placer, itemstack, pointed_thing) + local pn = placer:get_player_name() + local meta = minetest.get_meta(pos) + meta:set_string("owner", pn) + meta:set_string("infotext", def.description .. "\n" .. S("Owned by @1", pn)) + + return minetest.is_creative_enabled(pn) + end + + def.on_blast = function() end + def.on_key_use = function(pos, player) + local door = doors.get(pos) + door:toggle(player) + end + def.on_skeleton_key_use = function(pos, player, newsecret) + replace_old_owner_information(pos) + local meta = minetest.get_meta(pos) + local owner = meta:get_string("owner") + local pname = player:get_player_name() + + -- verify placer is owner of lockable door + if owner ~= pname then + minetest.record_protection_violation(pos, pname) + minetest.chat_send_player(pname, S("You do not own this trapdoor.")) + return nil + end + + local secret = meta:get_string("key_lock_secret") + if secret == "" then + secret = newsecret + meta:set_string("key_lock_secret", secret) + end + + return secret, S("a locked trapdoor"), owner + end + def.node_dig_prediction = "" + else + def.on_blast = function(pos, intensity) + minetest.remove_node(pos) + return {name} + end + end + + if not def.sounds then + --def.sounds = default.node_sound_wood_defaults() + end + + if not def.sound_open then + def.sound_open = "doors_door_open" + end + + if not def.sound_close then + def.sound_close = "doors_door_close" + end + + if not def.gain_open then + def.gain_open = 0.3 + end + + if not def.gain_close then + def.gain_close = 0.3 + end + + local def_opened = table.copy(def) + local def_closed = table.copy(def) + + if def.nodebox_closed and def.nodebox_opened then + def_closed.node_box = def.nodebox_closed + else + def_closed.node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -6/16, 0.5} + } + end + def_closed.selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -6/16, 0.5} + } + def_closed.tiles = { + def.tile_front, + def.tile_front .. '^[transformFY', + def.tile_side, + def.tile_side, + def.tile_side, + def.tile_side + } + + if def.nodebox_opened and def.nodebox_closed then + def_opened.node_box = def.nodebox_opened + else + def_opened.node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 6/16, 0.5, 0.5, 0.5} + } + end + def_opened.selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, 6/16, 0.5, 0.5, 0.5} + } + def_opened.tiles = { + def.tile_side, + def.tile_side .. '^[transform2', + def.tile_side .. '^[transform3', + def.tile_side .. '^[transform1', + def.tile_front .. '^[transform46', + def.tile_front .. '^[transform6' + } + + def_opened.drop = name_closed + def_opened.groups.not_in_creative_inventory = 1 + + minetest.register_node(name_opened, def_opened) + minetest.register_node(name_closed, def_closed) + + doors.registered_trapdoors[name_opened] = true + doors.registered_trapdoors[name_closed] = true +end + +doors.register_trapdoor("doors:trapdoor", { + description = S("Wooden Trapdoor"), + inventory_image = "doors_trapdoor.png", + wield_image = "doors_trapdoor.png", + tile_front = "doors_trapdoor.png", + tile_side = "doors_trapdoor_side.png", + gain_open = 0.06, + gain_close = 0.13, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, door = 1}, +}) + +doors.register_trapdoor("doors:trapdoor_steel", { + description = S("Steel Trapdoor"), + inventory_image = "doors_trapdoor_steel.png", + wield_image = "doors_trapdoor_steel.png", + tile_front = "doors_trapdoor_steel.png", + tile_side = "doors_trapdoor_steel_side.png", + protected = true, + --sounds = default.node_sound_metal_defaults(), + sound_open = "doors_steel_door_open", + sound_close = "doors_steel_door_close", + gain_open = 0.2, + gain_close = 0.2, + groups = {cracky = 1, level = 2, door = 1}, +}) + + + + +----fence gate---- +local fence_collision_extra = minetest.settings:get_bool("enable_fence_tall") and 3/8 or 0 + +function doors.register_fencegate(name, def) + local fence = { + description = def.description, + drawtype = "mesh", + tiles = {}, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + is_ground_content = false, + drop = name .. "_closed", + connect_sides = {"left", "right"}, + groups = def.groups, + sounds = def.sounds, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local node_def = minetest.registered_nodes[node.name] + minetest.swap_node(pos, {name = node_def._gate, param2 = node.param2}) + minetest.sound_play(node_def._gate_sound, {pos = pos, gain = 0.15, + max_hear_distance = 8}, true) + return itemstack + end, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/4, 1/2, 1/2, 1/4} + }, + } + + + if type(def.texture) == "string" then + fence.tiles[1] = {name = def.texture, backface_culling = true} + elseif def.texture.backface_culling == nil then + fence.tiles[1] = table.copy(def.texture) + fence.tiles[1].backface_culling = true + else + fence.tiles[1] = def.texture + end + + if not fence.sounds then + --fence.sounds = default.node_sound_wood_defaults() + end + + fence.groups.fence = 1 + + local fence_closed = table.copy(fence) + fence_closed.mesh = "doors_fencegate_closed.obj" + fence_closed._gate = name .. "_open" + fence_closed._gate_sound = "doors_fencegate_open" + fence_closed.collision_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/8, 1/2, 1/2 + fence_collision_extra, 1/8} + } + + local fence_open = table.copy(fence) + fence_open.mesh = "doors_fencegate_open.obj" + fence_open._gate = name .. "_closed" + fence_open._gate_sound = "doors_fencegate_close" + fence_open.groups.not_in_creative_inventory = 1 + fence_open.collision_box = { + type = "fixed", + fixed = {{-1/2, -1/2, -1/8, -3/8, 1/2 + fence_collision_extra, 1/8}, + {-1/2, -3/8, -1/2, -3/8, 3/8, 0 }} + } + + minetest.register_node(":" .. name .. "_closed", fence_closed) + minetest.register_node(":" .. name .. "_open", fence_open) + + minetest.register_craft({ + output = name .. "_closed", + recipe = { + {"group:stick", def.material, "group:stick"}, + {"group:stick", def.material, "group:stick"} + } + }) +end + +doors.register_fencegate("doors:gate_steel", { + description = S("Apple Wood Fence Gate"), + texture = "main_block_iron.png", + material = "default:wood", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2} +}) + + + +----fuels---- + +minetest.register_craft({ + type = "fuel", + recipe = "doors:trapdoor", + burntime = 7, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "doors:door_wood", + burntime = 14, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "doors:gate_wood_closed", + burntime = 7, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "doors:gate_acacia_wood_closed", + burntime = 8, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "doors:gate_junglewood_closed", + burntime = 9, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "doors:gate_pine_wood_closed", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "doors:gate_aspen_wood_closed", + burntime = 5, +}) diff --git a/mods/doors/license.txt b/mods/doors/license.txt new file mode 100644 index 0000000..8ce73c4 --- /dev/null +++ b/mods/doors/license.txt @@ -0,0 +1,164 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 PilzAdam +Copyright (C) 2014-2016 BlockMen +Copyright (C) 2015-2016 sofar (sofar@foo-projects.org) +Copyright (C) 2012-2016 Various Minetest developers and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media (textures, models and sounds) +----------------------------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2011-2016 Fernando Zapata +Copyright (C) 2014-2016 celeron55 +Copyright (C) 2012-2016 PilzAdam +Copyright (C) 2014-2016 BlockMen +Copyright (C) 2015-2016 sofar +Copyright (C) 2016 red-001 +Copyright (C) 2016 paramat + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ + +----------------------- + +Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) +Copyright (C) 2014-2016 PenguinDad + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/4.0/ + +----------------------- + +Attribution 3.0 Unported (CC BY 3.0) +Copyright (C) 2014 CGEffex +Copyright (C) 2014 bennstir +Copyright (C) 2016 BarkersPinhead +Copyright (C) 2016 rivernile7 +Copyright (C) 2016 HazMatt + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by/3.0/ + +----------------------- + +CC0 1.0 Universal (CC0 1.0) Public Domain Dedication +mhtaylor67 +SkeetMasterFunk69 + +No Copyright + +The person who associated a work with this deed has dedicated the work to the public +domain by waiving all of his or her rights to the work worldwide under copyright law, +including all related and neighboring rights, to the extent allowed by law. + +You can copy, modify, distribute and perform the work, even for commercial purposes, all +without asking permission. See Other Information below. + +Other Information + +In no way are the patent or trademark rights of any person affected by CC0, nor are the +rights that other persons may have in the work or in how the work is used, such as +publicity or privacy rights. +Unless expressly stated otherwise, the person who associated a work with this deed makes +no warranties about the work, and disclaims liability for all uses of the work, to the +fullest extent permitted by applicable law. +When using or citing the work, you should not imply endorsement by the author or the +affirmer. + +For more details: +https://creativecommons.org/publicdomain/zero/1.0/ diff --git a/mods/doors/mod.conf b/mods/doors/mod.conf new file mode 100644 index 0000000..d7a7f6f --- /dev/null +++ b/mods/doors/mod.conf @@ -0,0 +1,4 @@ +name = doors +description = Minetest Game mod: doors +depends = sounds +optional_depends = screwdriver diff --git a/mods/doors/models/door.blend b/mods/doors/models/door.blend new file mode 100644 index 0000000..56047b1 Binary files /dev/null and b/mods/doors/models/door.blend differ diff --git a/mods/doors/models/door_a.b3d b/mods/doors/models/door_a.b3d new file mode 100644 index 0000000..7f9249f Binary files /dev/null and b/mods/doors/models/door_a.b3d differ diff --git a/mods/doors/models/door_b.b3d b/mods/doors/models/door_b.b3d new file mode 100644 index 0000000..77a1a16 Binary files /dev/null and b/mods/doors/models/door_b.b3d differ diff --git a/mods/doors/models/doors_fencegate_closed.obj b/mods/doors/models/doors_fencegate_closed.obj new file mode 100644 index 0000000..0050f70 --- /dev/null +++ b/mods/doors/models/doors_fencegate_closed.obj @@ -0,0 +1,106 @@ +# Blender v2.76 (sub 0) OBJ File: 'gate_closed.blend' +# www.blender.org +mtllib gate_closed.mtl +o Cube_Cube.001 +v -0.625000 -0.500000 0.125000 +v -0.625000 0.500100 0.125000 +v -0.625000 -0.500000 -0.125000 +v -0.625000 0.500100 -0.125000 +v -0.375000 -0.500000 0.125000 +v -0.375000 0.500100 0.125000 +v -0.375000 -0.500000 -0.125000 +v -0.375000 0.500100 -0.125000 +v 0.375000 -0.500000 0.125000 +v 0.375000 0.500100 0.125000 +v 0.375000 -0.500000 -0.125000 +v 0.375000 0.500100 -0.125000 +v 0.625000 -0.500000 0.125000 +v 0.625000 0.500100 0.125000 +v 0.625000 -0.500000 -0.125000 +v 0.625000 0.500100 -0.125000 +v -0.375000 0.187500 0.062500 +v -0.375000 0.312500 0.062500 +v -0.375000 0.187500 -0.062500 +v -0.375000 0.312500 -0.062500 +v 0.375000 0.187500 0.062500 +v 0.375000 0.312500 0.062500 +v 0.375000 0.187500 -0.062500 +v 0.375000 0.312500 -0.062500 +v -0.374831 0.187348 0.062500 +v -0.156342 0.187363 0.062500 +v -0.374831 0.187348 -0.062500 +v -0.156342 0.187363 -0.062500 +v 0.374981 -0.343683 0.062500 +v 0.375065 -0.187304 0.062500 +v 0.374981 -0.343683 -0.062500 +v 0.375065 -0.187304 -0.062500 +vt 0.000000 0.750000 +vt 0.000000 0.500000 +vt 1.000000 0.500000 +vt 1.000000 0.750000 +vt 1.000000 1.000000 +vt -0.000000 1.000000 +vt 1.000000 -0.000000 +vt 1.000000 0.250000 +vt 0.000000 0.250000 +vt -0.000000 0.000000 +vt 0.250000 0.000000 +vt 0.250000 0.250000 +vt 0.250000 0.750000 +vt 0.250000 1.000000 +vt 0.500000 -0.000000 +vt 0.500000 0.250000 +vt 0.500000 0.750000 +vt 0.500000 1.000000 +vt 1.000000 0.625000 +vt 0.000000 0.625000 +vt 1.000000 0.875000 +vt 0.000000 0.875000 +vt -0.000000 0.687500 +vt 0.000000 0.562500 +vt 1.000000 0.562500 +vt 1.000000 0.687500 +vt 0.813740 0.249033 +vt 0.201557 0.249293 +vt 0.120995 0.125498 +vt 0.987404 0.125469 +vt 0.125000 0.375000 +vt 0.812500 0.375000 +vt 0.937500 0.500000 +vt 0.062500 0.500000 +vt 0.000000 0.125000 +vt 1.000000 0.125000 +vt 0.312500 0.437500 +vt 0.312500 0.312500 +vt 1.000000 0.312500 +vt 1.000000 0.437500 +vn -1.000000 0.000000 0.000000 +vn 0.000000 0.000000 -1.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn -0.578000 -0.816100 0.000000 +vn 0.576200 0.817300 0.000000 +usemtl None +s off +f 2/1/1 4/2/1 3/3/1 1/4/1 +f 4/4/2 8/5/2 7/6/2 3/1/2 +f 8/7/3 6/8/3 5/9/3 7/10/3 +f 6/2/4 2/9/4 1/8/4 5/3/4 +f 1/9/5 3/10/5 7/11/5 5/12/5 +f 6/6/6 8/1/6 4/13/6 2/14/6 +f 10/1/1 12/2/1 11/3/1 9/4/1 +f 12/2/2 16/9/2 15/8/2 11/3/2 +f 16/7/3 14/8/3 13/9/3 15/10/3 +f 14/4/4 10/5/4 9/6/4 13/1/4 +f 9/12/5 11/11/5 15/15/5 13/16/5 +f 14/14/6 16/13/6 12/17/6 10/18/6 +f 20/2/2 24/3/2 23/19/2 19/20/2 +f 22/1/4 18/4/4 17/21/4 21/22/4 +f 17/23/5 19/24/5 23/25/5 21/26/5 +f 22/21/6 24/5/6 20/6/6 18/22/6 +f 28/27/2 32/28/2 31/29/2 27/30/2 +f 30/31/4 26/32/4 25/33/4 29/34/4 +f 25/35/7 27/10/7 31/7/7 29/36/7 +f 30/37/8 32/38/8 28/39/8 26/40/8 diff --git a/mods/doors/models/doors_fencegate_open.obj b/mods/doors/models/doors_fencegate_open.obj new file mode 100644 index 0000000..3fb727f --- /dev/null +++ b/mods/doors/models/doors_fencegate_open.obj @@ -0,0 +1,112 @@ +# Blender v2.76 (sub 0) OBJ File: 'gate_open.blend' +# www.blender.org +mtllib gate_open.mtl +o Cube_Cube.001 +v -0.625000 -0.500000 0.125000 +v -0.625000 0.500100 0.125000 +v -0.625000 -0.500000 -0.125000 +v -0.625000 0.500100 -0.125000 +v -0.375000 -0.500000 0.125000 +v -0.375000 0.500100 0.125000 +v -0.375000 -0.500000 -0.125000 +v -0.375000 0.500100 -0.125000 +v 0.375000 -0.500000 0.125000 +v 0.375000 0.500100 0.125000 +v 0.375000 -0.500000 -0.125000 +v 0.375000 0.500100 -0.125000 +v 0.625000 -0.500000 0.125000 +v 0.625000 0.500100 0.125000 +v 0.625000 -0.500000 -0.125000 +v 0.625000 0.500100 -0.125000 +v 0.434859 0.187500 -0.872359 +v 0.434859 0.312500 -0.872359 +v 0.559859 0.187500 -0.872359 +v 0.559859 0.312500 -0.872359 +v 0.434859 0.187500 -0.122359 +v 0.434859 0.312500 -0.122359 +v 0.559859 0.187500 -0.122359 +v 0.559859 0.312500 -0.122359 +v 0.434859 0.187348 -0.872190 +v 0.434859 0.187363 -0.653701 +v 0.559859 0.187348 -0.872190 +v 0.559859 0.187363 -0.653701 +v 0.434859 -0.343683 -0.122379 +v 0.434859 -0.187304 -0.122294 +v 0.559859 -0.343683 -0.122379 +v 0.559859 -0.187304 -0.122294 +v 0.499560 -0.442900 0.005495 +vt 0.000000 0.750000 +vt 0.000000 0.500000 +vt 1.000000 0.500000 +vt 1.000000 0.750000 +vt 1.000000 1.000000 +vt -0.000000 1.000000 +vt 1.000000 -0.000000 +vt 1.000000 0.250000 +vt 0.000000 0.250000 +vt -0.000000 0.000000 +vt 0.250000 0.000000 +vt 0.250000 0.250000 +vt 0.250000 0.750000 +vt 0.250000 1.000000 +vt 0.500000 -0.000000 +vt 0.500000 0.250000 +vt 0.500000 0.750000 +vt 0.500000 1.000000 +vt 1.000000 0.625000 +vt 0.000000 0.625000 +vt 1.000000 0.875000 +vt 0.000000 0.875000 +vt -0.000000 0.687500 +vt 0.000000 0.562500 +vt 1.000000 0.562500 +vt 1.000000 0.687500 +vt 0.813740 0.249033 +vt 0.201557 0.249293 +vt 0.120995 0.125498 +vt 0.987404 0.125469 +vt 0.125000 0.375000 +vt 0.812500 0.375000 +vt 0.937500 0.500000 +vt 0.062500 0.500000 +vt 0.000000 0.125000 +vt 1.000000 0.125000 +vt 0.312500 0.437500 +vt 0.312500 0.312500 +vt 1.000000 0.312500 +vt 1.000000 0.437500 +vt 0.312500 0.625000 +vt 0.312500 0.500000 +vt 0.187500 0.500000 +vt 0.187500 0.625000 +vn -1.000000 0.000000 0.000000 +vn 0.000000 0.000000 -1.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 -0.816100 -0.578000 +vn 0.000000 0.817300 0.576200 +usemtl None +s off +f 2/1/1 4/2/1 3/3/1 1/4/1 +f 4/4/2 8/5/2 7/6/2 3/1/2 +f 8/7/3 6/8/3 5/9/3 7/10/3 +f 6/2/4 2/9/4 1/8/4 5/3/4 +f 1/9/5 3/10/5 7/11/5 5/12/5 +f 6/6/6 8/1/6 4/13/6 2/14/6 +f 10/1/1 12/2/1 11/3/1 9/4/1 +f 12/2/2 16/9/2 15/8/2 11/3/2 +f 16/7/3 14/8/3 13/9/3 15/10/3 +f 14/4/4 10/5/4 9/6/4 13/1/4 +f 9/12/5 11/11/5 15/15/5 13/16/5 +f 14/14/6 16/13/6 12/17/6 10/18/6 +f 20/2/3 24/3/3 23/19/3 19/20/3 +f 22/1/1 18/4/1 17/21/1 21/22/1 +f 17/23/5 19/24/5 23/25/5 21/26/5 +f 22/21/6 24/5/6 20/6/6 18/22/6 +f 28/27/3 32/28/3 31/29/3 27/30/3 +f 30/31/1 26/32/1 25/33/1 29/34/1 +f 25/35/7 27/10/7 31/7/7 29/36/7 +f 30/37/8 32/38/8 28/39/8 26/40/8 +f 17/41/2 18/42/2 20/43/2 19/44/2 diff --git a/mods/doors/sounds/doors_door_close.ogg b/mods/doors/sounds/doors_door_close.ogg new file mode 100644 index 0000000..fede4af Binary files /dev/null and b/mods/doors/sounds/doors_door_close.ogg differ diff --git a/mods/doors/sounds/doors_door_open.ogg b/mods/doors/sounds/doors_door_open.ogg new file mode 100644 index 0000000..9a4c4f1 Binary files /dev/null and b/mods/doors/sounds/doors_door_open.ogg differ diff --git a/mods/doors/sounds/doors_fencegate_close.ogg b/mods/doors/sounds/doors_fencegate_close.ogg new file mode 100644 index 0000000..d42590f Binary files /dev/null and b/mods/doors/sounds/doors_fencegate_close.ogg differ diff --git a/mods/doors/sounds/doors_fencegate_open.ogg b/mods/doors/sounds/doors_fencegate_open.ogg new file mode 100644 index 0000000..f6dfd1d Binary files /dev/null and b/mods/doors/sounds/doors_fencegate_open.ogg differ diff --git a/mods/doors/sounds/doors_glass_door_close.ogg b/mods/doors/sounds/doors_glass_door_close.ogg new file mode 100644 index 0000000..b3c1355 Binary files /dev/null and b/mods/doors/sounds/doors_glass_door_close.ogg differ diff --git a/mods/doors/sounds/doors_glass_door_open.ogg b/mods/doors/sounds/doors_glass_door_open.ogg new file mode 100644 index 0000000..66e6812 Binary files /dev/null and b/mods/doors/sounds/doors_glass_door_open.ogg differ diff --git a/mods/doors/sounds/doors_steel_door_close.ogg b/mods/doors/sounds/doors_steel_door_close.ogg new file mode 100644 index 0000000..aea7be6 Binary files /dev/null and b/mods/doors/sounds/doors_steel_door_close.ogg differ diff --git a/mods/doors/sounds/doors_steel_door_open.ogg b/mods/doors/sounds/doors_steel_door_open.ogg new file mode 100644 index 0000000..de87477 Binary files /dev/null and b/mods/doors/sounds/doors_steel_door_open.ogg differ diff --git a/mods/doors/textures/doors_door_glass.png b/mods/doors/textures/doors_door_glass.png new file mode 100644 index 0000000..ea6fdc1 Binary files /dev/null and b/mods/doors/textures/doors_door_glass.png differ diff --git a/mods/doors/textures/doors_door_obsidian_glass.png b/mods/doors/textures/doors_door_obsidian_glass.png new file mode 100644 index 0000000..fab25b3 Binary files /dev/null and b/mods/doors/textures/doors_door_obsidian_glass.png differ diff --git a/mods/doors/textures/doors_door_steel.png b/mods/doors/textures/doors_door_steel.png new file mode 100644 index 0000000..9e33ff1 Binary files /dev/null and b/mods/doors/textures/doors_door_steel.png differ diff --git a/mods/doors/textures/doors_door_wood.png b/mods/doors/textures/doors_door_wood.png new file mode 100644 index 0000000..c073faf Binary files /dev/null and b/mods/doors/textures/doors_door_wood.png differ diff --git a/mods/doors/textures/doors_hidden_segment.png b/mods/doors/textures/doors_hidden_segment.png new file mode 100644 index 0000000..b3b6f34 Binary files /dev/null and b/mods/doors/textures/doors_hidden_segment.png differ diff --git a/mods/doors/textures/doors_item_glass.png b/mods/doors/textures/doors_item_glass.png new file mode 100644 index 0000000..fcdb153 Binary files /dev/null and b/mods/doors/textures/doors_item_glass.png differ diff --git a/mods/doors/textures/doors_item_obsidian_glass.png b/mods/doors/textures/doors_item_obsidian_glass.png new file mode 100644 index 0000000..5780ad8 Binary files /dev/null and b/mods/doors/textures/doors_item_obsidian_glass.png differ diff --git a/mods/doors/textures/doors_item_steel.png b/mods/doors/textures/doors_item_steel.png new file mode 100644 index 0000000..dd99e13 Binary files /dev/null and b/mods/doors/textures/doors_item_steel.png differ diff --git a/mods/doors/textures/doors_item_wood.png b/mods/doors/textures/doors_item_wood.png new file mode 100644 index 0000000..d3a62ab Binary files /dev/null and b/mods/doors/textures/doors_item_wood.png differ diff --git a/mods/doors/textures/doors_trapdoor.png b/mods/doors/textures/doors_trapdoor.png new file mode 100644 index 0000000..e92c8b2 Binary files /dev/null and b/mods/doors/textures/doors_trapdoor.png differ diff --git a/mods/doors/textures/doors_trapdoor_side.png b/mods/doors/textures/doors_trapdoor_side.png new file mode 100644 index 0000000..55981ea Binary files /dev/null and b/mods/doors/textures/doors_trapdoor_side.png differ diff --git a/mods/doors/textures/doors_trapdoor_steel.png b/mods/doors/textures/doors_trapdoor_steel.png new file mode 100644 index 0000000..4ba507d Binary files /dev/null and b/mods/doors/textures/doors_trapdoor_steel.png differ diff --git a/mods/doors/textures/doors_trapdoor_steel_side.png b/mods/doors/textures/doors_trapdoor_steel_side.png new file mode 100644 index 0000000..e29c59e Binary files /dev/null and b/mods/doors/textures/doors_trapdoor_steel_side.png differ diff --git a/mods/dye/README.txt b/mods/dye/README.txt new file mode 100644 index 0000000..a2fbdd2 --- /dev/null +++ b/mods/dye/README.txt @@ -0,0 +1,13 @@ +Minetest Game mod: dye +====================== +See license.txt for license information. +See init.lua for documentation. + +Authors of source code +---------------------- +Originally by Perttu Ahola (celeron55) (MIT) +Various Minetest developers and contributors (MIT) + +Authors of media (textures) +--------------------------- +Perttu Ahola (celeron55) (CC BY-SA 3.0) diff --git a/mods/dye/init.lua b/mods/dye/init.lua new file mode 100644 index 0000000..f0affe8 --- /dev/null +++ b/mods/dye/init.lua @@ -0,0 +1,127 @@ +-- dye/init.lua + +dye = {} + +-- Load support for MT game translation. +local S = minetest.get_translator("dye") + +-- Make dye names and descriptions available globally + +dye.dyes = { + {"white", "White"}, + {"grey", "Grey"}, + {"dark_grey", "Dark Grey"}, + {"black", "Black"}, + {"violet", "Violet"}, + {"blue", "Blue"}, + {"cyan", "Cyan"}, + {"dark_green", "Dark Green"}, + {"green", "Green"}, + {"yellow", "Yellow"}, + {"brown", "Brown"}, + {"orange", "Orange"}, + {"red", "Red"}, + {"magenta", "Magenta"}, + {"pink", "Pink"}, +} + +-- Define items + +for _, row in ipairs(dye.dyes) do + local name = row[1] + local description = row[2] + local groups = {dye = 1} + groups["color_" .. name] = 1 + + minetest.register_craftitem("dye:" .. name, { + inventory_image = "dye_" .. name .. ".png", + description = S(description .. " Dye"), + groups = groups + }) + + minetest.register_craft({ + output = "dye:" .. name .. " 4", + recipe = { + {"group:flower,color_" .. name} + }, + }) +end + +-- Manually add coal -> black dye + +minetest.register_craft({ + output = "dye:black 4", + recipe = { + {"group:coal"} + }, +}) + +-- Manually add blueberries->violet dye + +minetest.register_craft({ + output = "dye:violet 2", + recipe = { + {"default:blueberries"} + }, +}) + +-- Mix recipes + +local dye_recipes = { + -- src1, src2, dst + -- RYB mixes + {"red", "blue", "violet"}, -- "purple" + {"yellow", "red", "orange"}, + {"yellow", "blue", "green"}, + -- RYB complementary mixes + {"yellow", "violet", "dark_grey"}, + {"blue", "orange", "dark_grey"}, + -- CMY mixes - approximation + {"cyan", "yellow", "green"}, + {"cyan", "magenta", "blue"}, + {"yellow", "magenta", "red"}, + -- other mixes that result in a color we have + {"red", "green", "brown"}, + {"magenta", "blue", "violet"}, + {"green", "blue", "cyan"}, + {"pink", "violet", "magenta"}, + -- mixes with black + {"white", "black", "grey"}, + {"grey", "black", "dark_grey"}, + {"green", "black", "dark_green"}, + {"orange", "black", "brown"}, + -- mixes with white + {"white", "red", "pink"}, + {"white", "dark_grey", "grey"}, + {"white", "dark_green", "green"}, +} + +for _, mix in pairs(dye_recipes) do + minetest.register_craft({ + type = "shapeless", + output = "dye:" .. mix[3] .. " 2", + recipe = {"dye:" .. mix[1], "dye:" .. mix[2]}, + }) +end + +-- Dummy calls to S() to allow translation scripts to detect the strings. +-- To update this run: +-- for _,e in ipairs(dye.dyes) do print(("S(%q)"):format(e[2].." Dye")) end + +--[[ +S("White Dye") +S("Grey Dye") +S("Dark Grey Dye") +S("Black Dye") +S("Violet Dye") +S("Blue Dye") +S("Cyan Dye") +S("Dark Green Dye") +S("Green Dye") +S("Yellow Dye") +S("Brown Dye") +S("Orange Dye") +S("Red Dye") +S("Magenta Dye") +S("Pink Dye") +--]] diff --git a/mods/dye/license.txt b/mods/dye/license.txt new file mode 100644 index 0000000..bf9d350 --- /dev/null +++ b/mods/dye/license.txt @@ -0,0 +1,60 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 Perttu Ahola (celeron55) +Copyright (C) 2012-2016 Various Minetest developers and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media (textures) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2012-2016 Perttu Ahola (celeron55) + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/mods/dye/locale/dye.de.tr b/mods/dye/locale/dye.de.tr new file mode 100644 index 0000000..f73fb57 --- /dev/null +++ b/mods/dye/locale/dye.de.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=Weißer Farbstoff +Grey Dye=Grauer Farbstoff +Dark Grey Dye=Dunkelgrauer Farbstoff +Black Dye=Schwarzer Farbstoff +Violet Dye=Violetter Farbstoff +Blue Dye=Blauer Farbstoff +Cyan Dye=Türkiser Farbstoff +Dark Green Dye=Dunkelgrüner Farbstoff +Green Dye=Grüner Farbstoff +Yellow Dye=Gelber Farbstoff +Brown Dye=Brauner Farbstoff +Orange Dye=Orange Farbstoff +Red Dye=Roter Farbstoff +Magenta Dye=Magenta Farbstoff +Pink Dye=Rosa Farbstoff diff --git a/mods/dye/locale/dye.eo.tr b/mods/dye/locale/dye.eo.tr new file mode 100644 index 0000000..e0fda93 --- /dev/null +++ b/mods/dye/locale/dye.eo.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=Blanka Tinkturo +Grey Dye=Griza Tinkturo +Dark Grey Dye=Malhela Griza Tinkturo +Black Dye=Nigra Tinkturo +Violet Dye=Violkolora Tinkturo +Blue Dye=Blua Tinkturo +Cyan Dye=Bluverda Tinkturo +Dark Green Dye=Malhela Verda Tinkturo +Green Dye=Verda Tinkturo +Yellow Dye=Flava Tinkturo +Brown Dye=Bruna Tinkturo +Orange Dye=Oranĝkolora Tinkturo +Red Dye=Ruĝa Tinkturo +Magenta Dye=Fiksina Tinkturo +Pink Dye=Rozkolora Tinkturo diff --git a/mods/dye/locale/dye.es.tr b/mods/dye/locale/dye.es.tr new file mode 100644 index 0000000..bd04ef4 --- /dev/null +++ b/mods/dye/locale/dye.es.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=Tinte blanco +Grey Dye=Tinte gris +Dark Grey Dye=Tinte gris oscuro +Black Dye=Tinte negro +Violet Dye=Tinte violeta +Blue Dye=Tinte azul +Cyan Dye=Tinte cián +Dark Green Dye=Tinte verde oscuro +Green Dye=Tinte verde +Yellow Dye=Tinte amarillo +Brown Dye=Tinte marrón +Orange Dye=Tinte naranja +Red Dye=Tinte rojo +Magenta Dye=Tinte magenta +Pink Dye=Tinte rosa diff --git a/mods/dye/locale/dye.fr.tr b/mods/dye/locale/dye.fr.tr new file mode 100644 index 0000000..390fa07 --- /dev/null +++ b/mods/dye/locale/dye.fr.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=Colorant blanc +Grey Dye=Colorant gris +Dark Grey Dye=Colorant gris foncé +Black Dye=Colorant noir +Violet Dye=Colorant violet +Blue Dye=Colorant bleu +Cyan Dye=Colorant cyan +Dark Green Dye=Colorant vert foncé +Green Dye=Colorant vert +Yellow Dye=Colorant jaune +Brown Dye=Colorant marron +Orange Dye=Colorant orange +Red Dye=Colorant rouge +Magenta Dye=Colorant magenta +Pink Dye=Colorant rose diff --git a/mods/dye/locale/dye.id.tr b/mods/dye/locale/dye.id.tr new file mode 100644 index 0000000..4122875 --- /dev/null +++ b/mods/dye/locale/dye.id.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=Pewarna Putih +Grey Dye=Pewarna Abu +Dark Grey Dye=Pewarna Abu Tua +Black Dye=Pewarna Hitam +Violet Dye=Pewarna Ungu +Blue Dye=Pewarna Biru +Cyan Dye=Pewarna Sian +Dark Green Dye=Pewarna Hijau Tua +Green Dye=Pewarna Hijau +Yellow Dye=Pewarna Kuning +Brown Dye=Pewarna Cokelat +Orange Dye=Pewarna Oranye +Red Dye=Pewarna Merah +Magenta Dye=Pewarna Magenta +Pink Dye=Pewarna Merah Jambu diff --git a/mods/dye/locale/dye.it.tr b/mods/dye/locale/dye.it.tr new file mode 100644 index 0000000..9deb385 --- /dev/null +++ b/mods/dye/locale/dye.it.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=Tintura bianca +Grey Dye=Tintura grigia +Dark Grey Dye=Tintura grigia scura +Black Dye=Tintura nera +Violet Dye=Tintura viola +Blue Dye=Tintura blu +Cyan Dye=Tintura ciano +Dark Green Dye=Tintura verde scura +Green Dye=Tintura verde +Yellow Dye=Tintura gialla +Brown Dye=Tintura marrone +Orange Dye=Tintura arancione +Red Dye=Tintura rossa +Magenta Dye=Tintura magenta +Pink Dye=Tintura rosa diff --git a/mods/dye/locale/dye.ja.tr b/mods/dye/locale/dye.ja.tr new file mode 100644 index 0000000..d7ae306 --- /dev/null +++ b/mods/dye/locale/dye.ja.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=白色の染料 +Grey Dye=灰色の染料 +Dark Grey Dye=濃灰色の染料 +Black Dye=黒色の染料 +Violet Dye=紫色の染料 +Blue Dye=青色の染料 +Cyan Dye=青緑色の染料 +Dark Green Dye=濃緑色の染料 +Green Dye=緑色の染料 +Yellow Dye=黄色の染料 +Brown Dye=茶色の染料 +Orange Dye=橙色の染料 +Red Dye=赤色の染料 +Magenta Dye=赤紫色の染料 +Pink Dye=桃色の染料 diff --git a/mods/dye/locale/dye.jbo.tr b/mods/dye/locale/dye.jbo.tr new file mode 100644 index 0000000..39ec7ab --- /dev/null +++ b/mods/dye/locale/dye.jbo.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=lo blabi xinmo +Grey Dye=lo grusi xinmo +Dark Grey Dye=lo xekri grusi xinmo +Black Dye=lo xekri xinmo +Violet Dye=lo zirpu xinmo +Blue Dye=lo blanu xinmo +Cyan Dye=lo cicna xinmo +Dark Green Dye=lo xekri crino xinmo +Green Dye=lo crino xinmo +Yellow Dye=lo pelxu xinmo +Brown Dye=lo bunre xinmo +Orange Dye=lo narju xinmo +Red Dye=lo xunre xinmo +Magenta Dye=lo nukni xinmo +Pink Dye=lo xunblabi xinmo diff --git a/mods/dye/locale/dye.ms.tr b/mods/dye/locale/dye.ms.tr new file mode 100644 index 0000000..50c0473 --- /dev/null +++ b/mods/dye/locale/dye.ms.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=Pewarna Putih +Grey Dye=Pewarna Kelabu +Dark Grey Dye=Pewarna Kelabu Gelap +Black Dye=Pewarna Hitam +Violet Dye=Pewarna Ungu +Blue Dye=Pewarna Biru +Cyan Dye=Pewarna Biru Kehijauan +Dark Green Dye=Pewarna Hijau Gelap +Green Dye=Pewarna Hijau +Yellow Dye=Pewarna Kuning +Brown Dye=Pewarna Perang +Orange Dye=Pewarna Jingga +Red Dye=Pewarna Merah +Magenta Dye=Pewarna Merah Lembayung +Pink Dye=Pewarna Merah Jambu diff --git a/mods/dye/locale/dye.pl.tr b/mods/dye/locale/dye.pl.tr new file mode 100644 index 0000000..a4bfa64 --- /dev/null +++ b/mods/dye/locale/dye.pl.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=Biały barwnik +Grey Dye=Szary barwnik +Dark Grey Dye=Ciemnoszary barwnik +Black Dye=Czarny barwnik +Violet Dye=Fioletowy barwnik +Blue Dye=Niebieski barwnik +Cyan Dye=Cyjanowy barwnik +Dark Green Dye=Ciemnozielony barwnik +Green Dye=Zielony barwnik +Yellow Dye=Żółty barwnik +Brown Dye=Brązowy barwnik +Orange Dye=Pomarańczowy barwnik +Red Dye=Czerwony barwnik +Magenta Dye=Karmazynowy barwnik +Pink Dye=Różowy barwnik diff --git a/mods/dye/locale/dye.pt_BR.tr b/mods/dye/locale/dye.pt_BR.tr new file mode 100644 index 0000000..29e98da --- /dev/null +++ b/mods/dye/locale/dye.pt_BR.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=Tinta Branca +Grey Dye=Tinta Cinza +Dark Grey Dye=Tinta Cinza-escuro +Black Dye=Tinta Preta +Violet Dye=Tinta Violeta +Blue Dye=Tinta Azul +Cyan Dye=Tinta Ciano +Dark Green Dye=Tinta Verde-escuro +Green Dye=Tinta Verde +Yellow Dye=Tinta Amarela +Brown Dye=Tinta Marrom +Orange Dye=Tinta Laranja +Red Dye=Tinta Vermelha +Magenta Dye=Tinta Magenta +Pink Dye=Tinta Rosa diff --git a/mods/dye/locale/dye.ru.tr b/mods/dye/locale/dye.ru.tr new file mode 100644 index 0000000..fa3c5c4 --- /dev/null +++ b/mods/dye/locale/dye.ru.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=Белая Краска +Grey Dye=Серая Краска +Dark Grey Dye=Тёмно-Серая Краска +Black Dye=Черная Краска +Violet Dye=Фиолетовая Краска +Blue Dye=Синяя Краска +Cyan Dye=Голубая Краска +Dark Green Dye=Тёмно-Зелёная Краска +Green Dye=Зелёная Краска +Yellow Dye=Жёлтая Краска +Brown Dye=Бурая Краска +Orange Dye=Оранжевая Краска +Red Dye=Красная Краска +Magenta Dye=Пурпурная Краска +Pink Dye=Розовая Краска diff --git a/mods/dye/locale/dye.sk.tr b/mods/dye/locale/dye.sk.tr new file mode 100644 index 0000000..625804c --- /dev/null +++ b/mods/dye/locale/dye.sk.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=Biele farbivo +Grey Dye=Šedé farbivo +Dark Grey Dye=Tmavo šedé farbivo +Black Dye=Čierne farbivo +Violet Dye=Fialové farbivo +Blue Dye=Modré farbivo +Cyan Dye=Tyrkysové farbivo +Dark Green Dye=Tmavozelené farbivo +Green Dye=Zelené farbivo +Yellow Dye=Žlté farbivo +Brown Dye=Hnedé farbivo +Orange Dye=Oranžové farbivo +Red Dye=Červené farbivo +Magenta Dye=Purpurové farbivo +Pink Dye=Ružové farbivo diff --git a/mods/dye/locale/dye.sv.tr b/mods/dye/locale/dye.sv.tr new file mode 100644 index 0000000..ecde443 --- /dev/null +++ b/mods/dye/locale/dye.sv.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=Vit färg +Grey Dye=Grå färg +Dark Grey Dye=Mörkgrå färg +Black Dye=Svart färg +Violet Dye=Violett färg +Blue Dye=Blå färg +Cyan Dye=Cyan färg +Dark Green Dye=Mörkgrön färg +Green Dye=Grön färg +Yellow Dye=Gul färg +Brown Dye=Brun färg +Orange Dye=Orange färg +Red Dye=Röd färg +Magenta Dye=Magenta färg +Pink Dye=Rosa färg diff --git a/mods/dye/locale/dye.uk.tr b/mods/dye/locale/dye.uk.tr new file mode 100644 index 0000000..e3698b0 --- /dev/null +++ b/mods/dye/locale/dye.uk.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=Біла Фарба +Grey Dye=Сіра Фарба +Dark Grey Dye=Темно-Сіра фарба +Black Dye=Чорна Фарба +Violet Dye=Фіолетова Фарба +Blue Dye=Синя Фарба +Cyan Dye=Синьо-Зелена Фарба +Dark Green Dye=Темно-Зелена Фарба +Green Dye=Зелена Фарба +Yellow Dye=Жовта Фарба +Brown Dye=Коричнева Фарба +Orange Dye=Помаранчева Фарба +Red Dye=Червона Фарба +Magenta Dye=Пурпурна Фарба +Pink Dye=Рожева Фарба diff --git a/mods/dye/locale/dye.zh_CN.tr b/mods/dye/locale/dye.zh_CN.tr new file mode 100644 index 0000000..11bf9cb --- /dev/null +++ b/mods/dye/locale/dye.zh_CN.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=白色染料 +Grey Dye=灰色染料 +Dark Grey Dye=暗灰染料 +Black Dye=黑色染料 +Violet Dye=紫色染料 +Blue Dye=蓝色染料 +Cyan Dye=青色染料 +Dark Green Dye=暗绿染料 +Green Dye=绿色染料 +Yellow Dye=黄色染料 +Brown Dye=棕色染料 +Orange Dye=橙色染料 +Red Dye=红色染料 +Magenta Dye=品红染料 +Pink Dye=粉红染料 diff --git a/mods/dye/locale/dye.zh_TW.tr b/mods/dye/locale/dye.zh_TW.tr new file mode 100644 index 0000000..b84d07e --- /dev/null +++ b/mods/dye/locale/dye.zh_TW.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=白色染料 +Grey Dye=灰色染料 +Dark Grey Dye=暗灰染料 +Black Dye=黑色染料 +Violet Dye=紫色染料 +Blue Dye=藍色染料 +Cyan Dye=青色染料 +Dark Green Dye=暗綠染料 +Green Dye=綠色染料 +Yellow Dye=黃色染料 +Brown Dye=棕色染料 +Orange Dye=橙色染料 +Red Dye=紅色染料 +Magenta Dye=品紅染料 +Pink Dye=粉紅染料 diff --git a/mods/dye/locale/template.txt b/mods/dye/locale/template.txt new file mode 100644 index 0000000..c20bab5 --- /dev/null +++ b/mods/dye/locale/template.txt @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye= +Grey Dye= +Dark Grey Dye= +Black Dye= +Violet Dye= +Blue Dye= +Cyan Dye= +Dark Green Dye= +Green Dye= +Yellow Dye= +Brown Dye= +Orange Dye= +Red Dye= +Magenta Dye= +Pink Dye= diff --git a/mods/dye/mod.conf b/mods/dye/mod.conf new file mode 100644 index 0000000..32bb816 --- /dev/null +++ b/mods/dye/mod.conf @@ -0,0 +1,2 @@ +name = dye +description = Minetest Game mod: dye diff --git a/mods/dye/textures/dye_black.png b/mods/dye/textures/dye_black.png new file mode 100644 index 0000000..1055b6c Binary files /dev/null and b/mods/dye/textures/dye_black.png differ diff --git a/mods/dye/textures/dye_blue.png b/mods/dye/textures/dye_blue.png new file mode 100644 index 0000000..d1377c6 Binary files /dev/null and b/mods/dye/textures/dye_blue.png differ diff --git a/mods/dye/textures/dye_brown.png b/mods/dye/textures/dye_brown.png new file mode 100644 index 0000000..77d475c Binary files /dev/null and b/mods/dye/textures/dye_brown.png differ diff --git a/mods/dye/textures/dye_cyan.png b/mods/dye/textures/dye_cyan.png new file mode 100644 index 0000000..7ecafcc Binary files /dev/null and b/mods/dye/textures/dye_cyan.png differ diff --git a/mods/dye/textures/dye_dark_green.png b/mods/dye/textures/dye_dark_green.png new file mode 100644 index 0000000..9606ccf Binary files /dev/null and b/mods/dye/textures/dye_dark_green.png differ diff --git a/mods/dye/textures/dye_dark_grey.png b/mods/dye/textures/dye_dark_grey.png new file mode 100644 index 0000000..060737b Binary files /dev/null and b/mods/dye/textures/dye_dark_grey.png differ diff --git a/mods/dye/textures/dye_green.png b/mods/dye/textures/dye_green.png new file mode 100644 index 0000000..0d99ee1 Binary files /dev/null and b/mods/dye/textures/dye_green.png differ diff --git a/mods/dye/textures/dye_grey.png b/mods/dye/textures/dye_grey.png new file mode 100644 index 0000000..5efb028 Binary files /dev/null and b/mods/dye/textures/dye_grey.png differ diff --git a/mods/dye/textures/dye_magenta.png b/mods/dye/textures/dye_magenta.png new file mode 100644 index 0000000..c84df62 Binary files /dev/null and b/mods/dye/textures/dye_magenta.png differ diff --git a/mods/dye/textures/dye_orange.png b/mods/dye/textures/dye_orange.png new file mode 100644 index 0000000..0844907 Binary files /dev/null and b/mods/dye/textures/dye_orange.png differ diff --git a/mods/dye/textures/dye_pink.png b/mods/dye/textures/dye_pink.png new file mode 100644 index 0000000..c3dec22 Binary files /dev/null and b/mods/dye/textures/dye_pink.png differ diff --git a/mods/dye/textures/dye_red.png b/mods/dye/textures/dye_red.png new file mode 100644 index 0000000..14eafbf Binary files /dev/null and b/mods/dye/textures/dye_red.png differ diff --git a/mods/dye/textures/dye_violet.png b/mods/dye/textures/dye_violet.png new file mode 100644 index 0000000..600cbb4 Binary files /dev/null and b/mods/dye/textures/dye_violet.png differ diff --git a/mods/dye/textures/dye_white.png b/mods/dye/textures/dye_white.png new file mode 100644 index 0000000..2a840a4 Binary files /dev/null and b/mods/dye/textures/dye_white.png differ diff --git a/mods/dye/textures/dye_yellow.png b/mods/dye/textures/dye_yellow.png new file mode 100644 index 0000000..fe75775 Binary files /dev/null and b/mods/dye/textures/dye_yellow.png differ diff --git a/mods/elevator/LICENSE b/mods/elevator/LICENSE new file mode 100644 index 0000000..9cecc1d --- /dev/null +++ b/mods/elevator/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/mods/elevator/README.md b/mods/elevator/README.md new file mode 100644 index 0000000..835e70a --- /dev/null +++ b/mods/elevator/README.md @@ -0,0 +1,39 @@ +# Travelnet + +[![luacheck](https://github.com/mt-mods/travelnet/workflows/luacheck/badge.svg)](https://github.com/mt-mods/travelnet/actions?query=workflow%3Aluacheck) +[![Integration test](https://github.com/mt-mods/travelnet/workflows/integration-test/badge.svg)](https://github.com/mt-mods/travelnet/actions?query=workflow%3Aintegration-test) +[![ContentDB](https://content.minetest.net/packages/mt-mods/travelnet/shields/downloads/)](https://content.minetest.net/packages/mt-mods/travelnet/) + +## How this works + +- craft it by filling the right and left row with glass; place in the middle row (from top to bottom): steel, mese, steel +- place the travelnet box somewhere +- right-click on it; enter name of the station (e.g. "my house", "center of desert city") and name of the network (e.g. "intresting towns","my buildings") +- punch it to update the list of stations on that network +- right-click to use the travelbox + +An unconfigured travelnet box can be configured by anyone. If it is misconfigured, just dig it and place it anew. +All stations that have the same network name set and are owned by the same user connect to the same network. + +## Documentation + +* [API](./doc/api.md) + +## Screenshots + +![](screenshot.png) +![](screenshot_day.png) +![](screenshot_night.png) + +## License + +The mod was written by me, Sokomine, and includes small contributions from other contributors. +License: GPLv3 (see [`LICENSE`](https://github.com/mt-mods/travelnet/blob/master/LICENSE) for more information) + +The models and textures as found in the textures/ and models/ folders where created by VanessaE +and are provided under the [CC0](https://creativecommons.org/publicdomain/zero/1.0/) license. + +Exceptions: + +* `textures/travelnet_top.png` [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) https://github.com/minetest/minetest_game (`default_steel_block.png`) +* `textures/travelnet_bottom.png` [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) https://github.com/minetest/minetest_game (`default_clay.png`) diff --git a/mods/elevator/add_target.lua b/mods/elevator/add_target.lua new file mode 100644 index 0000000..00f5922 --- /dev/null +++ b/mods/elevator/add_target.lua @@ -0,0 +1,110 @@ +local S = minetest.get_translator("elevator") + + +local function is_falsey_string(str) + return not str or str == "" +end + +-- add a new target; meta is optional +function elevator.add_target(station_name, network_name, pos, player_name, meta, owner_name) + + if not player_name then return end -- this should never happen, but just in case + + if not minetest.check_player_privs(player_name, { interact=true }) then + elevator.show_message(pos, player_name, S("Error"), + S("There is no player with interact privilege named '@1'. Aborting.", player_name)) + return + end + + -- if it is an elevator, determine the network name through x and z coordinates + local this_node = minetest.get_node(pos) + local is_elevator = elevator.is_elevator(this_node.name) + + if is_elevator then + network_name = elevator.elevator_network(pos) + if is_falsey_string(station_name) then + station_name = S("Unnamed elevator", tostring(pos.y)) + end + end + + if is_falsey_string(station_name) then + elevator.show_message(pos, player_name, S("Error"), S("Please provide a name for this station.")) + return + end + + if is_falsey_string(network_name) then + elevator.show_message(pos, player_name, S("Error"), + S("Please provide the name of the network this station ought to be connected to.")) + return + end + + if is_falsey_string(owner_name) or owner_name == player_name or is_elevator then -- elevator networks + owner_name = player_name + elseif not minetest.check_player_privs(player_name, { elevator_attach=true }) + and not elevator.allow_attach(player_name, owner_name, network_name) + then + elevator.show_message(pos, player_name, S("Error"), + S("You do not have the elevator_attach priv which is required to attach your box to " .. + "the network of someone else. Aborting.")) + return + end + + local network = elevator.get_or_create_network(owner_name, network_name) + + -- lua doesn't allow efficient counting here + local station_count = 1 -- start at one, assume the station about to be created already exists + for existing_station_name in pairs(network) do + if existing_station_name == station_name then + elevator.show_message(pos, player_name, S("Error"), + S("A station named '@1' already exists on this network. Please choose a different name!", station_name)) + return + end + station_count = station_count+1 + end + + -- we don't want too many stations in the same network because that would get confusing when displaying the targets + if station_count > elevator.MAX_STATIONS_PER_NETWORK then + elevator.show_message(pos, player_name, S("Error"), + S("Network '@1', already contains the maximum number (@2) of allowed stations per network. " .. + "Please choose a different/new network name.", network_name, elevator.MAX_STATIONS_PER_NETWORK)) + return + end + + -- add this station + local creation_timestamp = os.time() + network[station_name] = { + pos = pos, + timestamp = creation_timestamp + } + + -- do we have a new node to set up? (and are not just reading from a safefile?) + if meta then + minetest.chat_send_player(player_name, + S("Station '@1'" .. " " .. + "has been added to the network '@2'" .. + ", which now consists of @3 station(s).", station_name, network_name, station_count)) + + meta:set_string("station_name", station_name) + meta:set_string("station_network", network_name) + meta:set_string("owner", owner_name) + meta:set_int ("timestamp", creation_timestamp) + + meta:set_string("formspec", + ([[ + size[12,10] + field[0.3,0.6;6,0.7;station_name;%s;%s] + field[0.3,3.6;6,0.7;station_network;%s;%s] + ]]):format( + S("Station:"), + minetest.formspec_escape(station_name), + S("Network:"), + minetest.formspec_escape(network_name) + )) + + -- display a list of all stations that can be reached from here + elevator.update_formspec(pos, player_name, nil) + + -- save the updated network data in a savefile over server restart + elevator.save_data() + end +end diff --git a/mods/elevator/config.lua b/mods/elevator/config.lua new file mode 100644 index 0000000..36122e7 --- /dev/null +++ b/mods/elevator/config.lua @@ -0,0 +1,103 @@ + +elevator.MAX_STATIONS_PER_NETWORK = 24 + +-- set this to true if you want a simulated beam effect +elevator.elevator_effect_enabled = false +-- set this to true if you want a sound to be played when the elevator is used +elevator.elevator_sound_enabled = false + +-- if you set this to false, elevators cannot be created +-- (this may be useful if you want nothing but the elevators on your server) +elevator.elevator_enabled = true +-- if you set elevator.elevator_enabled to false, you will not be able to +-- craft, place or use elevators +elevator.elevator_enabled = true +-- if you set this to false, doors will be disabled +elevator.doors_enabled = true + +-- starts an abm which re-adds elevator stations to networks in case the savefile got lost +elevator.abm_enabled = false + +-- change these if you want other receipes for elevator or elevator +elevator.elevator_recipe = { + { "default:glass", "default:steel_ingot", "default:glass" }, + { "default:glass", "default:mese", "default:glass" }, + { "default:glass", "default:steel_ingot", "default:glass" } +} +elevator.elevator_recipe = { + { "default:steel_ingot", "default:glass", "default:steel_ingot" }, + { "default:steel_ingot", "", "default:steel_ingot" }, + { "default:steel_ingot", "default:glass", "default:steel_ingot" } +} +elevator.tiles_elevator = { + "elevator_front.png", + "elevator_panel.png", + "elevator_outside.png", + "elevator_ceiling.png", + "elevator_floor.png", + "main_block_iron.png" +} +elevator.elevator_inventory_image = "elevator_elevator_inv.png" + +if minetest.registered_nodes["mcl_core:wood"] then + elevator.elevator_recipe = { + { "mcl_stairs:slab_wood", "mcl_stairs:slab_wood", "mcl_stairs:slab_wood" }, + { "mesecons_torch:mesecon_torch_on", "mcl_chests:chest", "mesecons_torch:mesecon_torch_on" }, + { "mesecons_torch:mesecon_torch_on", "mcl_chests:chest", "mesecons_torch:mesecon_torch_on" }, + -- { "core:glass", "mcl_core:iron_ingot", "mcl_core:glass" }, + -- { "mcl_core:glass", "mesecons_torch:redstoneblock", "mcl_core:glass" }, + -- { "mcl_core:glass", "mcl_core:iron_ingot", "mcl_core:glass" } + } + elevator.elevator_recipe = { + { "mcl_stairs:slab_wood", "mcl_stairs:slab_wood", "mcl_stairs:slab_wood" }, + { "mesecons_torch:mesecon_torch_on", "", "mesecons_torch:mesecon_torch_on" }, + { "mesecons_torch:mesecon_torch_on", "", "mesecons_torch:mesecon_torch_on" }, + -- { "mcl_core:iron_ingot", "mcl_core:glass", "mcl_core:iron_ingot" }, + -- { "mcl_core:iron_ingot", "", "mcl_core:iron_ingot" }, + -- { "mcl_core:iron_ingot", "mcl_core:glass", "mcl_core:iron_ingot" } + } + elevator.tiles_elevator = { + "mcl_core_planks_big_oak.png^[transformR90", -- front + "mcl_core_planks_big_oak.png^[transformR90", -- inside + "mcl_core_planks_big_oak.png^[transformR90", -- sides outside + "mcl_core_planks_big_oak.png^[transformR90", -- inside ceiling + "mcl_core_planks_big_oak.png^[transformR90", -- inside floor + "mcl_core_planks_big_oak.png^[transformR90", -- top + } + elevator.elevator_inventory_image = nil +end + +-- if this function returns true, the player with the name player_name is +-- allowed to add a box to the network named network_name, which is owned +-- by the player owner_name; +-- if you want to allow *everybody* to attach stations to all nets, let the +-- function always return true; +-- if the function returns false, players with the elevator_attach priv +-- can still add stations to that network +-- params: player_name, owner_name, network_name +elevator.allow_attach = function() + return false +end + + +-- if this returns true, a player named player_name can remove a elevator station +-- from network_name (owned by owner_name) even though he is neither the owner nor +-- has the elevator_remove priv +-- params: player_name, owner_name, network_name, pos +elevator.allow_dig = function() + return false +end + + +-- if this function returns false, then player player_name will not be allowed to use +-- the elevator station_name_start on networ network_name owned by owner_name to travel to +-- the station station_name_target on the same network; +-- if this function returns true, the player will be transfered to the target station; +-- you can use this code to i.e. charge the player money for the transfer or to limit +-- usage of stations to players in the same fraction on PvP servers +-- params: player_name, owner_name, network_name, station_name_start, station_name_target +elevator.allow_travel = function() + return true +end + +elevator.elevator_sound_enabled = true diff --git a/mods/elevator/doors.lua b/mods/elevator/doors.lua new file mode 100644 index 0000000..70b271c --- /dev/null +++ b/mods/elevator/doors.lua @@ -0,0 +1,145 @@ +-- Doors that are especially useful for elevator elevators but can also be used in other situations. +-- All doors (not only these here) in front of a elevator or elevator are opened automaticly when a player arrives +-- and are closed when a player departs from the elevator or elevator. +-- Autor: Sokomine +local S = minetest.get_translator("elevator") + + +doors.register("elevator:swing_door", { + tiles = { + {name = "elevator_door.png", backface_culling = true} + }, + description = "Swinging Elevator Door", + inventory_image = "elevator_door.png", + groups = {cracky = 2, door = 1}, +}) + +doors.register("elevator:swing_door_aqua", { + tiles = { + {name = "elevator_door1.png", backface_culling = true} + }, + description = "Swinging Elevator Door", + inventory_image = "elevator_door1.png", + groups = {cracky = 2, door = 1}, +}) + +function elevator.register_door(node_base_name, def_tiles, material) + local closed_door = node_base_name .. "_closed" + local open_door = node_base_name .. "_open" + + minetest.register_node(open_door, { + description = S("elevator door (open)"), + drawtype = "nodebox", + tiles = def_tiles, + use_texture_alpha = "clip", + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = true, + -- only the closed variant is in creative inventory + groups = { + snappy = 2, + choppy = 2, + oddly_breakable_by_hand = 2, + not_in_creative_inventory = 1 + }, + -- larger than one node but slightly smaller than a half node so + -- that wallmounted torches pose no problem + node_box = { + type = "fixed", + fixed = { + { -0.90, -0.5, 0.4, -0.49, 1.5, 0.5 }, + { 0.49, -0.5, 0.4, 0.9, 1.5, 0.5 }, + }, + }, + selection_box = { + type = "fixed", + fixed = { + { -0.9, -0.5, 0.4, 0.9, 1.5, 0.5 }, + }, + }, + drop = closed_door, + on_rightclick = function(pos, node) + minetest.add_node(pos, { + name = closed_door, + param2 = node.param2 + }) + end, + }) + + minetest.register_node(closed_door, { + description = S("elevator door (closed)"), + drawtype = "nodebox", + tiles = def_tiles, + use_texture_alpha = "clip", + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = true, + groups = { + snappy = 2, + choppy = 2, + oddly_breakable_by_hand = 2 + }, + node_box = { + type = "fixed", + fixed = { + { -0.5, -0.5, 0.4, -0.01, 1.5, 0.5 }, + { 0.01, -0.5, 0.4, 0.5, 1.5, 0.5 }, + }, + }, + selection_box = { + type = "fixed", + fixed = { + { -0.5, -0.5, 0.4, 0.5, 1.5, 0.5 }, + }, + }, + on_rightclick = function(pos, node) + minetest.add_node(pos, { + name = open_door, + param2 = node.param2 + }) + end, + }) + + -- add a craft receipe for the door + minetest.register_craft({ + output = closed_door, + recipe = { + { material, "", material }, + { material, "", material }, + { material, "", material } + } + }) + + + -- Make doors reacts to mesecons + if minetest.get_modpath("mesecons") then + local mesecons = { + effector = { + action_on = function(pos, node) + minetest.add_node(pos, { + name = open_door, + param2 = node.param2 + }) + end, + action_off = function(pos, node) + minetest.add_node(pos, { + name = closed_door, + param2 = node.param2 + }) + end, + rules = mesecon.rules.pplate + } + } + + minetest.override_item(closed_door, { mesecons=mesecons }) + minetest.override_item(open_door, { mesecons=mesecons }) + end +end + +-- actually register the doors +-- (but only if the materials for them exist) +if minetest.get_modpath("default") then + elevator.register_door("elevator:elevator_door_steel", { "default_stone.png" }, "default:steel_ingot") + elevator.register_door("elevator:elevator_door_glass", { "elevator_elevator_door_glass.png" }, "default:glass") + elevator.register_door("elevator:elevator_door_tin", { "default_clay.png" }, "default:tin_ingot") +end diff --git a/mods/elevator/elevator.lua b/mods/elevator/elevator.lua new file mode 100644 index 0000000..d98c87e --- /dev/null +++ b/mods/elevator/elevator.lua @@ -0,0 +1,170 @@ +-- This version of the elevator box allows to move up or down only. +-- The network name is determined automaticly from the position (x/z coordinates). +-- >utor: Sokomine +local S = minetest.get_translator("elevator") + + + + +function elevator.show_nearest_elevator(pos, owner_name, param2) + if not pos or not pos.x or not pos.z or not owner_name then + return + end + + if not elevator.targets[owner_name] then + minetest.chat_send_player(owner_name, + S("Congratulations! This is your first elevator. " .. + "You can build an elevator network by placing further elevators somewhere above " .. + "or below this one. Just make sure that the x and z coordinate are the same.")) + return + end + + local network_name = elevator.elevator_network(pos) + -- will this be an elevator that will be added to an existing network? + if elevator.targets[owner_name][network_name] + -- does the network have any members at all? + and next(elevator.targets[owner_name][network_name], nil) + then + minetest.chat_send_player(owner_name, + S("This elevator will automaticly connect to the " .. + "other elevators you have placed at different heights. Just enter a station name " .. + "and click on \"store\" to set it up. Or just punch it to set the height as station " .. + "name.")) + return + end + + local nearest_name, nearest_dist = elevator.find_nearest_elevator_network(pos, owner_name) + + if not nearest_name then + minetest.chat_send_player(owner_name, + S("This is your first elevator. It differs from " .. + "elevator networks by only allowing movement in vertical direction (up or down). " .. + "All further elevators which you will place at the same x,z coordinates at differnt " .. + "heights will be able to connect to this elevator.")) + return + end + + local direction_strings = { + S("m to the right"), + S("m behind this elevator and"), + S("m to the left"), + S("m in front of this elevator and") + } + local direction_indexes = { x=param2+1, z=((param2+1) % 4)+1 } + + -- Should X or Z be displayed first? + local direction_order = ({ [0]={"z","x"}, [1]={"x","z"} })[param2 % 2] + + local text = S("Your nearest elevator network is located") .. " " + + for index, direction in ipairs(direction_order) do + local nearest_dist_direction = nearest_dist[direction] + local direction_index = direction_indexes[direction] + if nearest_dist_direction < 0 then + direction_index = ((direction_indexes[direction]+1) % 4)+1 + end + text = text .. tostring(math.abs(nearest_dist_direction)) .. " " .. direction_strings[direction_index] + if index == 1 then text = text .. " " end + end + + minetest.chat_send_player(owner_name, text .. S(", located at x") .. + ("=%f, z=%f. "):format(pos.x + nearest_dist.x, pos.z + nearest_dist.z) .. + S("This elevator here will start a new shaft/network.")) +end + + +minetest.register_node("elevator:elevator", { + description = S("Elevator"), + drawtype = "mesh", + mesh = "elevator_elevator.obj", + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "facedir", + wield_scale = { x=0.6, y=0.6, z=0.6 }, + + selection_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 } + }, + + collision_box = { + type = "fixed", + fixed = { + + { 0.48, -0.5,-0.5, 0.5, 0.5, 0.5}, + {-0.5 , -0.5, 0.48, 0.48, 0.5, 0.5}, + {-0.5, -0.5,-0.5 ,-0.48, 0.5, 0.5}, + + --groundplate to stand on + { -0.5,-0.5,-0.5,0.5,-0.48, 0.5}, + }, + }, + + tiles = elevator.tiles_elevator, + + inventory_image = elevator.elevator_inventory_image, + groups = { + elevator = 1 + }, + + light_source = 10, + + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", S("Elevator (unconfigured)")) + meta:set_string("station_name", "") + meta:set_string("station_network","") + meta:set_string("owner", placer:get_player_name()) + + -- request initial data + meta:set_string("formspec", ([[ + size[12,10] + field[0.3,5.6;6,0.7;station_name;%s;] + button_exit[6.3,6.2;1.7,0.7;station_set;%s] + ]]):format(S("Name of this station:"), S("Store"))) + + minetest.set_node(vector.add(pos, { x=0, y=1, z=0 }), { name="elevator:hidden_top" }) + elevator.show_nearest_elevator(pos, placer:get_player_name(), minetest.dir_to_facedir(placer:get_look_dir())) + end, + + on_receive_fields = elevator.on_receive_fields, + on_punch = function(pos, _, puncher) + elevator.update_formspec(pos, puncher:get_player_name()) + end, + + can_dig = function(pos, player) + return elevator.can_dig(pos, player, "elevator") + end, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + elevator.remove_box(pos, oldnode, oldmetadata, digger) + end, + + -- TNT and overenthusiastic DMs do not destroy elevators either + on_blast = function() + end, + + -- taken from VanessaEs homedecor fridge + on_place = function(itemstack, placer, pointed_thing) + local node = minetest.get_node(vector.add(pointed_thing.above, { x=0, y=1, z=0 })) + local def = minetest.registered_nodes[node.name] + -- leftover top nodes can be removed by placing a new elevator underneath + if (not def or not def.buildable_to) and node.name ~= "elevator:hidden_top" then + minetest.chat_send_player( + placer:get_player_name(), + S("Not enough vertical space to place the elevator box!") + ) + return + end + return minetest.item_place(itemstack, placer, pointed_thing) + end, + + on_destruct = function(pos) + minetest.remove_node(vector.add(pos, { x=0, y=1, z=0 })) + end +}) + +minetest.register_craft({ + output = "elevator:elevator", + recipe = elevator.elevator_recipe, +}) diff --git a/mods/elevator/formspecs.lua b/mods/elevator/formspecs.lua new file mode 100644 index 0000000..03b4b88 --- /dev/null +++ b/mods/elevator/formspecs.lua @@ -0,0 +1,105 @@ +local S = minetest.get_translator("elevator") + +local elevator_form_name = "elevator:show" + +-- minetest.chat_send_player is sometimes not so well visible +function elevator.show_message(pos, player_name, title, message) + if not pos or not player_name or not message then + return + end + local formspec = ([[ + size[8,3] + label[3,0;%s] + textlist[0,0.5;8,1.5;;%s;] + button_exit[3.5,2.5;1.0,0.5;back;%s] + button_exit[6.8,2.5;1.0,0.5;station_exit;%s] + field[20,20;0.1,0.1;pos2str;Pos;%s] + ]]):format( + minetest.formspec_escape(title or S("Error")), + minetest.formspec_escape(message or "- nothing -"), + S("Back"), + S("Exit"), + minetest.pos_to_string(pos) + ) + minetest.show_formspec(player_name, elevator_form_name, formspec) +end + +-- show the player the formspec they would see when right-clicking the node; +-- needs to be simulated this way as calling on_rightclick would not do +function elevator.show_current_formspec(pos, meta, player_name) + if not pos or not meta or not player_name then + return + end + -- we need to supply the position of the elevator box + local formspec = meta:get_string("formspec") .. + ("field[20,20;0.1,0.1;pos2str;Pos;%s]"):format(minetest.pos_to_string(pos)) + -- show the formspec manually + minetest.show_formspec(player_name, elevator_form_name, formspec) +end + +-- a player clicked on something in the formspec hse was manually shown +-- (back from help page, moved elevator up or down etc.) +function elevator.form_input_handler(player, formname, fields) + if formname ~= elevator_form_name then return end + if fields and fields.pos2str then + local pos = minetest.string_to_pos(fields.pos2str) + if not pos then + return + end + + -- back button leads back to the main menu + if fields.back and fields.back ~= "" then + return elevator.show_current_formspec(pos, + minetest.get_meta(pos), player:get_player_name()) + end + return elevator.on_receive_fields(pos, formname, fields, player) + end +end + +-- most formspecs the elevator uses are stored in the elevator node itself, +-- but some may require some "back"-button functionality (i.e. help page, +-- move up/down etc.) +minetest.register_on_player_receive_fields(elevator.form_input_handler) + + +function elevator.reset_formspec(meta) + if not meta then return end + + meta:set_string("infotext", S("elevator-box (unconfigured)")) + meta:set_string("station_name", "") + meta:set_string("station_network","") + meta:set_string("owner", "") + + -- some players seem to be confused with entering network names at first; provide them + -- with a default name + local default_network = "net1" + + -- request initinal data + meta:set_string("formspec", + ([[ + size[10,6.0] + label[2.0,0.0;--> %s <--] + button_exit[8.0,0.0;2.2,0.7;station_dig;%s] + field[0.3,1.2;9,0.9;station_name;%s:;] + label[0.3,1.5;%s] + field[0.3,2.8;9,0.9;station_network;%s;%s] + label[0.3,3.1;%s] + field[0.3,4.4;9,0.9;owner;%s;] + label[0.3,4.7;%s] + button_exit[3.8,5.3;1.7,0.7;station_set;%s] + button_exit[6.3,5.3;1.7,0.7;station_exit;%s] + ]]):format( + S("Configure this elevator station"), + S("Remove station"), + S("Name of this station"), + S("How do you call this place here? Example: \"my first house\", \"mine\", \"shop\"..."), + S("Assign to Network:"), + default_network, + S("You can have more than one network. If unsure, use \"@1\".", default_network), + S("Owned by:"), + S("Unless you know what you are doing, leave this empty."), + S("Save"), + S("Exit") + ) + ) +end diff --git a/mods/elevator/functions.lua b/mods/elevator/functions.lua new file mode 100644 index 0000000..15a86c4 --- /dev/null +++ b/mods/elevator/functions.lua @@ -0,0 +1,282 @@ +local S = minetest.get_translator("elevator") + + +local function string_endswith(str, ends) + local len = #ends + if str:sub(-len) == ends then + return str:sub(1, -len-1) + end +end + +local function string_startswith(str, start) + local len = #start + if str:sub(1, len) == start then + return str:sub(len+1) + end +end + +function elevator.find_nearest_elevator_network(pos, owner_name) + local nearest_network = false + local nearest_dist = false + local nearest_dist_x + local nearest_dist_z + for target_network_name, network in pairs(elevator.targets[owner_name]) do + local station_name = next(network, nil) + if station_name then + local station = network[station_name] + if station.nr and station.pos then + local dist_x = station.pos.x - pos.x + local dist_z = station.pos.z - pos.z + local dist = math.ceil(math.sqrt(dist_x * dist_x + dist_z * dist_z)) + -- find the nearest one; store network_name and (minimal) distance + if not nearest_dist or dist < nearest_dist then + nearest_dist = dist + nearest_dist_x = dist_x + nearest_dist_z = dist_z + nearest_network = target_network_name + end + end + end + end + return nearest_network, { + x = nearest_dist_x, + z = nearest_dist_z, + } +end + +function elevator.elevator_network(pos) + return tostring(pos.x) .. "," .. tostring(pos.z) +end + +function elevator.is_elevator(node_name) + return node_name == "elevator:elevator" +end + +function elevator.door_is_open(node, opposite_direction) + return string.sub(node.name, -5) == "_open" + -- handle doors that change their facedir + or ( + node.param2 ~= opposite_direction + and not ( + string_startswith(node.name, "elevator:elevator_door") + and string_endswith(node.name, "_closed") + ) + ) +end + +function elevator.door_is_closed(node, opposite_direction) + return string.sub(node.name, -7) == "_closed" + -- handle doors that change their facedir + or ( + node.param2 == opposite_direction + and not ( + string_startswith(node.name, "elevator:elevator_door") + and string_endswith(node.name, "_open") + ) + ) +end + +function elevator.param2_to_yaw(param2) + if param2 == 0 then + return 180 + elseif param2 == 1 then + return 90 + elseif param2 == 2 then + return 0 + elseif param2 == 3 then + return 270 + end +end + +function elevator.get_or_create_network(owner_name, network_name) + if not elevator.targets then + elevator.targets = {} + end + + -- first one by this player? + if not elevator.targets[owner_name] then + elevator.targets[owner_name] = {} + end + + local owners_targets = elevator.targets[owner_name] + + -- first station on this network? + if not owners_targets[network_name] then + owners_targets[network_name] = {} + end + + return owners_targets[network_name] +end + +function elevator.get_network(owner_name, network_name) + if not elevator.targets then return end + + local owners_targets = elevator.targets[owner_name] + if not owners_targets then return end + + return elevator.targets[owner_name][network_name] +end + +function elevator.get_station(owner_name, station_network, station_name) + + local network = elevator.get_network(owner_name, station_network) + if not network then return end + + return network[station_name] +end + +-- punching the elevator updates its formspec and shows it to the player; +-- however, that would be very annoying when actually trying to dig the thing. +-- Thus, check if the player is wielding a tool that can dig nodes of the +-- group cracky +function elevator.check_if_trying_to_dig(puncher) + -- if in doubt: show formspec + if not puncher or not puncher:get_wielded_item() then + return false + end + -- show menu when in creative mode + if creative and creative.is_enabled_for(puncher:get_player_name()) then + return false + end + local tool_capabilities = puncher:get_wielded_item():get_tool_capabilities() + if not tool_capabilities or not tool_capabilities["groupcaps"] or not tool_capabilities["groupcaps"]["cracky"] then + return false + end + -- tools which can dig cracky items can start digging immediately + return true +end + + +-- allow doors to open +function elevator.open_close_door(pos, player, mode) + local this_node = minetest.get_node_or_nil(pos) + -- give up if the area is *still* not loaded + if not this_node then + return + end + + local opposite_direction = (this_node.param2 + 2) % 4 + local door_pos = vector.add(pos, minetest.facedir_to_dir(opposite_direction)) + + local door_node = minetest.get_node_or_nil(door_pos) + + if not door_node or door_node.name == "ignore" or door_node.name == "air" + or not minetest.registered_nodes[door_node.name] then + return + end + + local right_click_action = minetest.registered_nodes[door_node.name].on_rightclick + if not right_click_action then return end + + -- Map to old API in case anyone is using it externally + if mode == 0 then mode = "toggle" + elseif mode == 1 then mode = "close" + elseif mode == 2 then mode = "open" + end + + -- at least for homedecor, same facedir would mean "door closed" + -- do not close the elevator door if it is already closed + if mode == "close" and elevator.door_is_closed(door_node, opposite_direction) then + return + end + + -- do not open the doors if they are already open (works only on elevator-doors; not on doors in general) + if mode == "open" and elevator.door_is_open(door_node, opposite_direction) then + return + end + + if mode == "open" then + local playername = player:get_player_name() + minetest.after(1, function() + -- Get the player again in case it doesn't exist anymore (logged out) + local pplayer = minetest.get_player_by_name(playername) + if pplayer then + right_click_action(door_pos, door_node, pplayer) + end + end) + else + right_click_action(door_pos, door_node, player) + end +end + + +elevator.rotate_player = function(target_pos, player, tries) + -- try later when the box is loaded + local target_node = minetest.get_node_or_nil(target_pos) + if target_node == nil then + if tries < 30 then + minetest.after(0, elevator.rotate_player, target_pos, player, tries+1) + end + return + end + + -- play sound at the target position as well + if elevator.elevator_sound_enabled then + local sound = "elevator_travel" + if elevator.is_elevator(target_node.name) then + sound = "elevator_bell" + end + + minetest.sound_play(sound, { + pos = target_pos, + gain = 0.75, + max_hear_distance = 10 + }) + end + + -- do this only on servers where the function exists + if player.set_look_horizontal then + -- rotate the player so that they can walk straight out of the box + local yaw = elevator.param2_to_yaw(target_node.param2) or 0 + + player:set_look_horizontal(math.rad(yaw)) + player:set_look_vertical(math.rad(0)) + end + + elevator.open_close_door(target_pos, player, "open") +end + + +elevator.remove_box = function(_, _, oldmetadata, digger) + if not oldmetadata or oldmetadata == "nil" or not oldmetadata.fields then + minetest.chat_send_player(digger:get_player_name(), S("Error") .. ": " .. + S("Could not find information about the station that is to be removed.")) + return + end + + local owner_name = oldmetadata.fields["owner"] + local station_name = oldmetadata.fields["station_name"] + local station_network = oldmetadata.fields["station_network"] + + -- station is not known? then just remove it + if not (owner_name and station_network and station_name) + or not elevator.get_station(owner_name, station_network, station_name) + then + minetest.chat_send_player(digger:get_player_name(), S("Error") .. ": " .. + S("Could not find the station that is to be removed.")) + return + end + + elevator.targets[owner_name][station_network][station_name] = nil + + -- inform the owner + minetest.chat_send_player(owner_name, + S("Station '@1'" .. " " .. + "has been REMOVED from the network '@2'.", station_name, station_network)) + + if digger and owner_name ~= digger:get_player_name() then + minetest.chat_send_player(digger:get_player_name(), + S("Station '@1'" .. " " .. + "has been REMOVED from the network '@2'.", station_name, station_network)) + end + + -- save the updated network data in a savefile over server restart + elevator.save_data() +end + + + +elevator.can_dig = function() + -- forbid digging of the elevator + return false +end diff --git a/mods/elevator/init.lua b/mods/elevator/init.lua new file mode 100644 index 0000000..d6ae417 --- /dev/null +++ b/mods/elevator/init.lua @@ -0,0 +1,129 @@ +--[[ + Teleporter networks that allow players to choose a destination out of a list + Copyright (C) 2013 Sokomine + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +--]] + +-- integration test +if minetest.settings:get_bool("elevator:.enable_elevator:_integration_test") then + dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/integration_test.lua") +end + +-- Required to save the elevator: data properly in all cases +if not minetest.safe_file_write then + error("[Mod elevator:] Your Minetest version is no longer supported. (version < 0.4.17)") +end + +elevator = {} + +elevator.targets = {} +elevator.path = minetest.get_modpath(minetest.get_current_modname()) + +local function mod_dofile(filename) + dofile(elevator.path .. "/"..filename..".lua") +end + +-- privs +mod_dofile("privs") + +-- read the configuration +mod_dofile("config") + +-- saving / reading +mod_dofile("persistence") + +-- common functions +mod_dofile("functions") + +-- formspec stuff +mod_dofile("formspecs") + +-- elevator: / elevator update +mod_dofile("update_formspec") + +-- add button +mod_dofile("add_target") + +-- receive fields handler +mod_dofile("on_receive_fields") + +-- invisible node to place inside top of elevator: box and elevator +minetest.register_node("elevator:hidden_top", { + drawtype = "nodebox", + paramtype = "light", + sunlight_propagates = true, + pointable = false, + diggable = false, + drop = "", + groups = { not_in_creative_inventory=1 }, + tiles = { "elevator_blank.png" }, + use_texture_alpha = "clip", + node_box = { + type = "fixed", + fixed = { -0.5, 0.45, -0.5, 0.5, 0.5, 0.5 }, + }, + collision_box = { + type = "fixed", + fixed = { -0.5, 0.45, -0.5, 0.5, 0.5, 0.5 }, + }, +}) + + +if elevator.elevator_effect_enabled then + minetest.register_entity("elevator:effect", { + hp_max = 1, + physical = false, + weight = 5, + collisionbox = { -0.4, -0.5, -0.4, 0.4, 1.5, 0.4 }, + visual = "upright_sprite", + visual_size = { x=1, y=2 }, + textures = { "elevator_flash.png" }, -- number of required textures depends on visual + spritediv = { x=1, y=1 }, + initial_sprite_basepos = { x=0, y=0 }, + is_visible = true, + makes_footstep_sound = false, + automatic_rotate = true, + + anz_rotations = 0, + + on_step = function(self) + -- this is supposed to be more flickering than smooth animation + self.object:set_yaw(self.object:get_yaw()+1) + self.anz_rotations = self.anz_rotations+1 + -- eventually self-destruct + if self.anz_rotations > 15 then + self.object:remove() + end + end + }) +end + + +if elevator.elevator_enabled then + mod_dofile("elevator") -- allows up/down transfers only +end +if elevator.doors_enabled then + -- doors that open and close automaticly when the elevator: or elevator is used + mod_dofile("doors") +end + +if elevator.enable_abm then + -- restore elevator: data when players pass by broken networks + mod_dofile("restore_network_via_abm") +end + +-- upon server start, read the savefile +elevator.restore_data() diff --git a/mods/elevator/integration_test.lua b/mods/elevator/integration_test.lua new file mode 100644 index 0000000..3f5c97f --- /dev/null +++ b/mods/elevator/integration_test.lua @@ -0,0 +1,25 @@ + +minetest.log("warning", "[TEST] integration-test enabled!") + +minetest.register_on_mods_loaded(function() + minetest.after(1, function() + + local data = minetest.write_json({ success=true }, true) + local file = io.open(minetest.get_worldpath() .. "/integration_test.json", "w") + if file then + file:write(data) + file:close() + end + + file = io.open(minetest.get_worldpath() .. "/registered_nodes.txt", "w") + if file then + for name in pairs(minetest.registered_nodes) do + file:write(name .. "\n") + end + file:close() + end + + minetest.log("warning", "[TEST] integration tests done!") + minetest.request_shutdown("success") + end) +end) diff --git a/mods/elevator/mod.conf b/mods/elevator/mod.conf new file mode 100644 index 0000000..8374cea --- /dev/null +++ b/mods/elevator/mod.conf @@ -0,0 +1,6 @@ +name = elevator +optional_depends = mesecons, dye +description = Network of teleporter-boxes that allows easy travelling to other boxes on the same network. +release = 8497 +author = mt-mods +title = Elevator diff --git a/mods/elevator/models/elevator_elevator.obj b/mods/elevator/models/elevator_elevator.obj new file mode 100644 index 0000000..cc006e2 --- /dev/null +++ b/mods/elevator/models/elevator_elevator.obj @@ -0,0 +1,64 @@ +# Blender v2.73 (sub 0) OBJ File: 'travelnet_elevator.blend' +# www.blender.org +o Cylinder +v -0.499016 -0.499034 0.499022 +v -0.499016 -0.499034 -0.498989 +v 0.499035 -0.499034 -0.498989 +v 0.499035 -0.499034 0.499022 +v -0.499016 1.498990 0.499022 +v -0.499016 1.498990 -0.498989 +v 0.499035 1.498990 -0.498989 +v 0.499035 1.498990 0.499022 +v 0.437500 -0.437500 0.437500 +v -0.499016 1.437500 -0.498989 +v 0.499035 1.437500 -0.498989 +v -0.437500 -0.437500 0.437500 +v 0.437500 1.437500 0.437500 +v -0.499016 -0.437500 -0.498989 +v 0.499035 -0.437500 -0.498989 +v -0.437500 1.437500 0.437500 +v -0.437500 -0.437500 -0.498989 +v 0.437500 -0.437500 -0.498989 +v -0.437500 1.437500 -0.498989 +v 0.437500 1.437500 -0.498989 +vt 0.000000 0.968750 +vt 1.000000 0.968750 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.062500 0.031250 +vt 0.062500 0.968750 +vt 0.000000 0.031250 +vt 0.937500 0.031250 +vt 1.000000 0.031250 +vt 0.937500 0.968750 +vt 1.000000 -0.000000 +vt 0.000000 -0.000000 +vt 0.062500 -0.000000 +vt 0.937500 -0.000000 +vt 0.937500 0.937500 +vt 0.062500 0.937500 +vt 0.062500 1.000000 +vt 0.062500 0.062500 +vt 0.937500 0.062500 +vt 0.937500 1.000000 +g Cylinder_Cylinder_front +s off +f 11/1 10/2 6/3 7/4 +f 18/5 20/6 11/1 15/7 +f 17/8 14/9 10/2 19/10 +f 13/6 9/5 12/8 16/10 +f 2/11 14/9 15/7 3/12 +f 17/7 19/1 16/10 12/8 +g Cylinder_Cylinder_controls +f 18/7 9/8 13/10 20/1 +g Cylinder_Cylinder_outside +f 8/3 4/11 3/12 7/4 +f 6/4 2/12 1/11 5/3 +f 8/4 5/3 1/11 4/12 +g Cylinder_Cylinder_ceiling +f 19/13 20/14 13/15 16/16 +g Cylinder_Cylinder_floor +f 17/17 12/18 9/19 18/20 +g Cylinder_Cylinder_top-bottom +f 5/12 8/11 7/3 6/4 +f 2/12 3/11 4/3 1/4 diff --git a/mods/elevator/on_receive_fields.lua b/mods/elevator/on_receive_fields.lua new file mode 100644 index 0000000..bf06490 --- /dev/null +++ b/mods/elevator/on_receive_fields.lua @@ -0,0 +1,218 @@ +local S = minetest.get_translator("elevator") + + +function elevator.on_receive_fields(pos, _, fields, player) + if not pos then + return + end + + local meta = minetest.get_meta(pos) + local name = player:get_player_name() + + -- the player wants to quit/exit the formspec; do not save/update anything + if fields and fields.station_exit and fields.station_exit ~= "" then + return + end + + local owner_name = meta:get_string("owner") + local station_network = meta:get_string("station_network") + local station_name = meta:get_string("station_name") + + -- if there is something wrong with the data + if not owner_name or not station_network or not station_name then + minetest.chat_send_player(name, S("Error") .. ": " .. + S("There is something wrong with the configuration of this station.") .. + " DEBUG DATA: owner: " .. (owner_name or "?") .. + " station_name: " .. (station_name or "?") .. + " station_network: " .. (station_network or "?") .. "." + ) + print( + "ERROR: The elevator at " .. minetest.pos_to_string(pos) .. " has a problem: " .. + " DATA: owner: " .. (owner_name or "?") .. + " station_name: " .. (station_name or "?") .. + " station_network: " .. (station_network or "?") .. "." + ) + return + end + + local node = minetest.get_node(pos) + + -- the player wants to remove the station + if fields.station_dig then + local description + + if node and minetest.get_item_group(node.name, "elevator") == 1 then + description = "elevator box" + elseif node and minetest.get_item_group(node.name, "elevator") == 1 then + description = "elevator" + elseif node and node.name == "locked_elevator:elevator" then + description = "locked elevator" + elseif node and node.name == "locked_elevator:elevator" then + description = "locked elevator" + else + minetest.chat_send_player(name, "Error: Unknown node.") + return + end + + -- players with elevator_remove priv can dig the station + if not minetest.check_player_privs(name, { elevator_remove=true }) + -- the function elevator.allow_dig(..) may allow additional digging + and not elevator.allow_dig(name, owner_name, station_network, pos) + -- the owner can remove the station + and owner_name ~= name + -- stations without owner can be removed by anybody + and owner_name ~= "" + then + minetest.chat_send_player(name, + S("This %s belongs to %s. You can't remove it."):format( + description, + tostring(owner_name) + ) + ) + return + end + + -- abort if protected by another mod + if minetest.is_protected(pos, name) + and not minetest.check_player_privs(name, { protection_bypass=true }) + then + minetest.record_protection_violation(pos, name) + return + end + + local player_inventory = player:get_inventory() + if not player_inventory:room_for_item("main", node.name) then + minetest.chat_send_player(name, S("You do not have enough room in your inventory.")) + return + end + + -- give the player the box + player_inventory:add_item("main", node.name) + -- remove the box from the data structure + elevator.remove_box(pos, nil, meta:to_table(), player) + -- remove the node as such + minetest.remove_node(pos) + return + end + + + -- if the box has not been configured yet + if station_network == "" then + elevator.add_target(fields.station_name, fields.station_network, pos, name, meta, fields.owner) + return + end + + if fields.open_door then + elevator.open_close_door(pos, player, "toggle") + return + end + + -- the owner or players with the elevator_attach priv can move stations up or down in the list + if fields.move_up or fields.move_down then + elevator.update_formspec(pos, name, fields) + return + end + + if not fields.target then + minetest.chat_send_player(name, S("Please click on the target you want to travel to.")) + return + end + + local network = elevator.get_network(owner_name, station_network) + + if not network then + elevator.add_target(station_name, station_network, pos, owner_name, meta, owner_name) + end + + if node ~= nil and elevator.is_elevator(node.name) then + for k,_ in pairs(network) do + if network[k].nr == fields.target then + fields.target = k + -- break ?? + end + end + end + + local target_station = network[fields.target] + + -- if the target station is gone + if not target_station then + minetest.chat_send_player(name, + S("Station '@1' does not exist (anymore?)" .. + " " .. "on this network.", fields.target or "?") + ) + elevator.update_formspec(pos, name, nil) + return + end + + + if not elevator.allow_travel(name, owner_name, station_network, station_name, fields.target) then + return + end + minetest.chat_send_player(name, S("Initiating transfer to station '@1'.", fields.target or "?")) + + if elevator.elevator_sound_enabled then + if node.name == "elevator:elevator" then + minetest.sound_play("elevator_bell", { + pos = pos, + gain = 0.75, + max_hear_distance = 10 + }) + else + minetest.sound_play("elevator_travel", { + pos = pos, + gain = 0.75, + max_hear_distance = 10 + }) + end + end + + if elevator.elevator_effect_enabled then + minetest.add_entity(vector.add(pos, { x=0, y=0.5, z=0 }), "elevator:effect") -- it self-destructs after 20 turns + end + + -- close the doors at the sending station + elevator.open_close_door(pos, player, "close") + + -- transport the player to the target location + + -- may be 0.0 for some versions of MT 5 player model + local player_model_bottom = tonumber(minetest.settings:get("player_model_bottom")) or -.5 + local player_model_vec = vector.new(0, player_model_bottom, 0) + local target_pos = target_station.pos + + local top_pos = vector.add(pos, { x=0, y=2, z=0 }) + local top_node = minetest.get_node(top_pos) + if top_node.name ~= "elevator:hidden_top" then + local def = minetest.registered_nodes[top_node.name] + if def and def.buildable_to then + minetest.set_node(top_pos, { name="elevator:hidden_top" }) + end + end + + player:move_to(vector.add(target_pos, player_model_vec), false) + + -- check if the box has at the other end has been removed. + local target_node = minetest.get_node_or_nil(target_pos) + if target_node ~= nil then + local target_node_def = minetest.registered_nodes[target_node.name] + local has_elevator_group = target_node_def.groups.elevator or target_node_def.groups.elevator + + if not has_elevator_group then + -- provide information necessary to identify the removed box + local oldmetadata = { + fields = { + owner = owner_name, + station_name = fields.target, + station_network = station_network + } + } + + elevator.remove_box(target_pos, nil, oldmetadata, player) + -- send the player back as there's no receiving elevator + player:move_to(pos, false) + else + elevator.rotate_player(target_pos, player, 0) + end + end +end diff --git a/mods/elevator/persistence.lua b/mods/elevator/persistence.lua new file mode 100644 index 0000000..300034f --- /dev/null +++ b/mods/elevator/persistence.lua @@ -0,0 +1,35 @@ +local S = minetest.get_translator("elevator") + +local mod_data_path = minetest.get_worldpath() .. "/mod_elevator.data" + +-- called whenever a station is added or removed +function elevator.save_data() + local data = minetest.serialize(elevator.targets) + + local success = minetest.safe_file_write(mod_data_path, data) + if not success then + print(S("[Mod elevator] Error: Savefile '@1' could not be written.", mod_data_path)) + end +end + + +function elevator.restore_data() + local file = io.open(mod_data_path, "r") + if not file then + print(S("[Mod elevator] Error: Savefile '@1' not found.", mod_data_path)) + return + end + + local data = file:read("*all") + elevator.targets = minetest.deserialize(data) + + if not elevator.targets then + local backup_file = mod_data_path .. ".bak" + print(S("[Mod elevator] Error: Savefile '@1' is damaged." .. " " .. + "Saved the backup as '@2'.", mod_data_path, backup_file)) + + minetest.safe_file_write(backup_file, data) + elevator.targets = {} + end + file:close() +end diff --git a/mods/elevator/privs.lua b/mods/elevator/privs.lua new file mode 100644 index 0000000..40256bd --- /dev/null +++ b/mods/elevator/privs.lua @@ -0,0 +1,11 @@ +local S = minetest.get_translator("travelnet") + +minetest.register_privilege("travelnet_attach", { + description = S("allows to attach travelnet boxes to travelnets of other players"), + give_to_singleplayer = false +}) + +minetest.register_privilege("travelnet_remove", { + description = S("allows to dig travelnet boxes which belog to nets of other players"), + give_to_singleplayer = false +}) diff --git a/mods/elevator/restore_network_via_abm.lua b/mods/elevator/restore_network_via_abm.lua new file mode 100644 index 0000000..239329a --- /dev/null +++ b/mods/elevator/restore_network_via_abm.lua @@ -0,0 +1,19 @@ + +minetest.register_abm({ + nodenames = { "travelnet:travelnet" }, + interval = 20, + chance = 1, + action = function(pos) + local meta = minetest.get_meta(pos) + local owner_name = meta:get_string("owner") + local station_name = meta:get_string("station_name") + local station_network = meta:get_string("station_network") + + if owner_name and station_name and station_network + and not travelnet.get_station(owner_name, station_network, station_name) then + travelnet.add_target(station_name, station_network, pos, owner_name, meta, owner_name) + print("TRAVELNET: re-adding " .. tostring(station_name) .. " to " .. + tostring(station_network) .. " owned by " .. tostring(owner_name)) + end + end +}) diff --git a/mods/elevator/screenshot.png b/mods/elevator/screenshot.png new file mode 100644 index 0000000..fd3e4f3 Binary files /dev/null and b/mods/elevator/screenshot.png differ diff --git a/mods/elevator/screenshot_day.png b/mods/elevator/screenshot_day.png new file mode 100644 index 0000000..55cb4b8 Binary files /dev/null and b/mods/elevator/screenshot_day.png differ diff --git a/mods/elevator/screenshot_night.png b/mods/elevator/screenshot_night.png new file mode 100644 index 0000000..a9940c2 Binary files /dev/null and b/mods/elevator/screenshot_night.png differ diff --git a/mods/elevator/sounds/travelnet_bell.ogg b/mods/elevator/sounds/travelnet_bell.ogg new file mode 100644 index 0000000..994f649 Binary files /dev/null and b/mods/elevator/sounds/travelnet_bell.ogg differ diff --git a/mods/elevator/sounds/travelnet_travel.ogg b/mods/elevator/sounds/travelnet_travel.ogg new file mode 100644 index 0000000..b39be8f Binary files /dev/null and b/mods/elevator/sounds/travelnet_travel.ogg differ diff --git a/mods/elevator/textures/elevator_ceiling.png b/mods/elevator/textures/elevator_ceiling.png new file mode 100644 index 0000000..7b2fe2d Binary files /dev/null and b/mods/elevator/textures/elevator_ceiling.png differ diff --git a/mods/elevator/textures/elevator_door.png b/mods/elevator/textures/elevator_door.png new file mode 100644 index 0000000..bdb7bd5 Binary files /dev/null and b/mods/elevator/textures/elevator_door.png differ diff --git a/mods/elevator/textures/elevator_door1.png b/mods/elevator/textures/elevator_door1.png new file mode 100644 index 0000000..06b6251 Binary files /dev/null and b/mods/elevator/textures/elevator_door1.png differ diff --git a/mods/elevator/textures/elevator_floor.png b/mods/elevator/textures/elevator_floor.png new file mode 100644 index 0000000..1fced6f Binary files /dev/null and b/mods/elevator/textures/elevator_floor.png differ diff --git a/mods/elevator/textures/elevator_front.png b/mods/elevator/textures/elevator_front.png new file mode 100644 index 0000000..f4b2e03 Binary files /dev/null and b/mods/elevator/textures/elevator_front.png differ diff --git a/mods/elevator/textures/elevator_panel.png b/mods/elevator/textures/elevator_panel.png new file mode 100644 index 0000000..8de4c15 Binary files /dev/null and b/mods/elevator/textures/elevator_panel.png differ diff --git a/mods/elevator/textures/travelnet_blank.png b/mods/elevator/textures/travelnet_blank.png new file mode 100644 index 0000000..1eb8499 Binary files /dev/null and b/mods/elevator/textures/travelnet_blank.png differ diff --git a/mods/elevator/textures/travelnet_bottom.png b/mods/elevator/textures/travelnet_bottom.png new file mode 100644 index 0000000..027252c Binary files /dev/null and b/mods/elevator/textures/travelnet_bottom.png differ diff --git a/mods/elevator/textures/travelnet_elevator_door_glass.png b/mods/elevator/textures/travelnet_elevator_door_glass.png new file mode 100644 index 0000000..53470be Binary files /dev/null and b/mods/elevator/textures/travelnet_elevator_door_glass.png differ diff --git a/mods/elevator/textures/travelnet_elevator_front.png b/mods/elevator/textures/travelnet_elevator_front.png new file mode 100644 index 0000000..294bc66 Binary files /dev/null and b/mods/elevator/textures/travelnet_elevator_front.png differ diff --git a/mods/elevator/textures/travelnet_elevator_inv.png b/mods/elevator/textures/travelnet_elevator_inv.png new file mode 100644 index 0000000..28f4ea3 Binary files /dev/null and b/mods/elevator/textures/travelnet_elevator_inv.png differ diff --git a/mods/elevator/textures/travelnet_elevator_sides_outside.png b/mods/elevator/textures/travelnet_elevator_sides_outside.png new file mode 100644 index 0000000..1248bbf Binary files /dev/null and b/mods/elevator/textures/travelnet_elevator_sides_outside.png differ diff --git a/mods/elevator/textures/travelnet_flash.png b/mods/elevator/textures/travelnet_flash.png new file mode 100644 index 0000000..b93e99c Binary files /dev/null and b/mods/elevator/textures/travelnet_flash.png differ diff --git a/mods/elevator/textures/travelnet_inv_base.png b/mods/elevator/textures/travelnet_inv_base.png new file mode 100644 index 0000000..c2f8ef4 Binary files /dev/null and b/mods/elevator/textures/travelnet_inv_base.png differ diff --git a/mods/elevator/textures/travelnet_inv_colorable.png b/mods/elevator/textures/travelnet_inv_colorable.png new file mode 100644 index 0000000..12ce570 Binary files /dev/null and b/mods/elevator/textures/travelnet_inv_colorable.png differ diff --git a/mods/elevator/textures/travelnet_top.png b/mods/elevator/textures/travelnet_top.png new file mode 100644 index 0000000..9fd2d19 Binary files /dev/null and b/mods/elevator/textures/travelnet_top.png differ diff --git a/mods/elevator/textures/travelnet_travelnet_back.png b/mods/elevator/textures/travelnet_travelnet_back.png new file mode 100644 index 0000000..4f5cf86 Binary files /dev/null and b/mods/elevator/textures/travelnet_travelnet_back.png differ diff --git a/mods/elevator/textures/travelnet_travelnet_back_color.png b/mods/elevator/textures/travelnet_travelnet_back_color.png new file mode 100644 index 0000000..dee3783 Binary files /dev/null and b/mods/elevator/textures/travelnet_travelnet_back_color.png differ diff --git a/mods/elevator/textures/travelnet_travelnet_front_color.png b/mods/elevator/textures/travelnet_travelnet_front_color.png new file mode 100644 index 0000000..9953c06 Binary files /dev/null and b/mods/elevator/textures/travelnet_travelnet_front_color.png differ diff --git a/mods/elevator/textures/travelnet_travelnet_side.png b/mods/elevator/textures/travelnet_travelnet_side.png new file mode 100644 index 0000000..fb60bc7 Binary files /dev/null and b/mods/elevator/textures/travelnet_travelnet_side.png differ diff --git a/mods/elevator/textures/travelnet_travelnet_side_color.png b/mods/elevator/textures/travelnet_travelnet_side_color.png new file mode 100644 index 0000000..e3e1b3b Binary files /dev/null and b/mods/elevator/textures/travelnet_travelnet_side_color.png differ diff --git a/mods/elevator/update_formspec.lua b/mods/elevator/update_formspec.lua new file mode 100644 index 0000000..f44a4af --- /dev/null +++ b/mods/elevator/update_formspec.lua @@ -0,0 +1,242 @@ +local S = minetest.get_translator("elevator") + +local function is_falsey_string(str) + return not str or str == "" +end + +-- called "on_punch" of elevator and elevator +function elevator.update_formspec(pos, puncher_name, fields) + local meta = minetest.get_meta(pos) + + local this_node = minetest.get_node(pos) + local is_elevator = this_node ~= nil and this_node.name == "elevator:elevator" + + if not meta then + return + end + + local owner_name = meta:get_string("owner") + local station_name = meta:get_string("station_name") + local station_network = meta:get_string("station_network") + + if not owner_name + or not station_name + or is_falsey_string(station_network) + then + if is_elevator then + elevator.add_target(nil, nil, pos, puncher_name, meta, owner_name) + return + end + + elevator.reset_formspec(meta) + elevator.show_message(pos, puncher_name, "Error", S("Update failed! Resetting this box on the elevator.")) + return + end + + -- if the station got lost from the network for some reason (savefile corrupted?) then add it again + if not elevator.get_station(owner_name, station_network, station_name) then + + local network = elevator.get_or_create_network(owner_name, station_network) + + local zeit = meta:get_int("timestamp") + if not zeit or type(zeit) ~= "number" or zeit < 100000 then + zeit = os.time() + end + + -- add this station + network[station_name] = { + pos = pos, + timestamp = zeit + } + + minetest.chat_send_player(owner_name, + S("Station '@1'" .. " " .. + "has been reattached to the network '@2'.", station_name, station_network)) + elevator.save_data() + end + + + -- add name of station + network + owner + update-button + + local formspec = ([[ + size[12,10] + label[3.3,0.0;%s:] + label[6.3,0.0;%s] + label[0.3,0.4;%s] + label[6.3,0.4;%s] + label[0.3,0.8;%s] + label[6.3,0.8;%s] + label[0.3,1.2;%s] + label[6.3,1.2;%s] + label[3.3,1.6;%s] + ]]):format( + S("elevator-Box"), + S("Punch box to update target list."), + S("Name of this station:"), + minetest.formspec_escape(station_name or "?"), + S("Assigned to Network:"), + minetest.formspec_escape(station_network or "?"), + S("Owned by:"), + minetest.formspec_escape(owner_name or "?"), + S("Click on target to travel there:") + ) + + local x = 0 + local y = 0 + local i = 0 + + -- collect all station names in a table + local stations = {} + local network = elevator.targets[owner_name][station_network] + + for k in pairs(network) do + table.insert(stations, k) + end + + local ground_level = 1 + if is_elevator then + table.sort(stations, function(a, b) + return network[a].pos.y > network[b].pos.y + end) + + -- find ground level + local vgl_timestamp = 999999999999 + for index,k in ipairs(stations) do + local station = network[k] + if not station.timestamp then + station.timestamp = os.time() + end + if station.timestamp < vgl_timestamp then + vgl_timestamp = station.timestamp + ground_level = index + end + end + + for index,k in ipairs(stations) do + local station = network[k] + if index == ground_level then + station.nr = "1" + else + station.nr = tostring(ground_level + 1 - index) + end + end + else + -- sort the table according to the timestamp (=time the station was configured) + table.sort(stations, function(a, b) + return network[a].timestamp < network[b].timestamp + end) + end + + -- does the player want to move this station one position up in the list? + -- only the owner and players with the elevator_attach priv can change the order of the list + -- Note: With elevators, only the "G"(round) marking is actually moved + if fields and (fields.move_up or fields.move_down) + and not is_falsey_string(owner_name) + and ( + (owner_name == puncher_name) + or (minetest.check_player_privs(puncher_name, { elevator_attach=true })) + ) + then + + local current_pos = -1 + for index, k in ipairs(stations) do + if k == station_name then + current_pos = index + -- break?? + end + end + + local swap_with_pos + if fields.move_up then + swap_with_pos = current_pos-1 + else + swap_with_pos = current_pos+1 + end + + -- handle errors + if swap_with_pos < 1 then + elevator.show_message(pos, puncher_name, "Info", S("This station is already the first one on the list.")) + return + elseif swap_with_pos > #stations then + elevator.show_message(pos, puncher_name, "Info", S("This station is already the last one on the list.")) + return + else + local current_station = stations[current_pos] + local swap_with_station = stations[swap_with_pos] + + -- swap the actual data by which the stations are sorted + local old_timestamp = network[swap_with_station].timestamp + network[swap_with_station].timestamp = network[current_station].timestamp + network[current_station].timestamp = old_timestamp + + -- for elevators, only the "G"(round) marking is moved; no point in swapping stations + if not is_elevator then + -- actually swap the stations + stations[swap_with_pos] = current_station + stations[current_pos] = swap_with_station + end + + -- store the changed order + elevator.save_data() + end + end + + -- if there are only 8 stations (plus this one), center them in the formspec + if #stations < 10 then + x = 4 + end + + for _,k in ipairs(stations) do + + i = i+1 + + -- new column + if y == 8 then + x = x + 4 + y = 0 + end + + -- check if there is an elevator door in front that needs to be opened + if k == station_name then + formspec = formspec .. + ("button_exit[%f,%f;1,0.5;open_door;<>]label[%f,%f;%s]") + :format(x, y + 2.5, x + 0.9, y + 2.35, k) + elseif is_elevator then + formspec = formspec .. + ("button_exit[%f,%f;1,0.5;target;%s]label[%f,%f;%s]") + :format(x, y + 2.5, tostring(network[k].nr), x + 0.9, y + 2.35, k) + else + formspec = formspec .. + ("button_exit[%f,%f;4,0.5;target;%s]") + :format(x, y + 2.5, k) + end + + y = y+1 + end + + formspec = formspec .. ([[ + label[8.0,1.6;%s] + button_exit[11.3,0.0;1.0,0.5;station_exit;%s] + button_exit[10.0,0.5;2.2,0.7;station_dig;%s] + button[9.6,1.6;1.4,0.5;move_up;%s] + button[10.9,1.6;1.4,0.5;move_down;%s] + ]]):format( + S("Position in list:"), + S("Exit"), + S("Remove station"), + S("move up"), + S("move down") + ) + + + meta:set_string("formspec", formspec) + + meta:set_string("infotext", + S("Station '@1'" .. " " .. + "on elevator '@2' (owned by @3)" .. " " .. + "ready for usage. Right-click to travel, punch to update.", + tostring(station_name), tostring(station_network), tostring(owner_name))) + + -- show the player the updated formspec + elevator.show_current_formspec(pos, meta, puncher_name) +end diff --git a/mods/env_sounds/README.txt b/mods/env_sounds/README.txt new file mode 100644 index 0000000..3b3d275 --- /dev/null +++ b/mods/env_sounds/README.txt @@ -0,0 +1,17 @@ +Minetest Game mod: env_sounds +============================= +See license.txt for license information. + +Authors of source code +---------------------- +paramat (MIT) + +Authors of media (sounds) +------------------------- +Yuval (CC0 1.0) +https://freesound.org/people/Yuval/sounds/197023/ + env_sounds_water.*.ogg + +Halion (CC0 1.0) +https://freesound.org/people/Halion/sounds/17785/ + env_sounds_lava.*.ogg diff --git a/mods/env_sounds/init.lua b/mods/env_sounds/init.lua new file mode 100644 index 0000000..31cc483 --- /dev/null +++ b/mods/env_sounds/init.lua @@ -0,0 +1,112 @@ +-- Parameters + +-- Node search radius around player +local radius = 8 + +local allsounds = { + ["env_sounds_water"] = { + trigger = {"default:water_flowing", "default:river_water_flowing"}, + base_volume = 0.04, + max_volume = 0.4, + per_node = 0.004, + }, + ["env_sounds_lava"] = { + trigger = {"default:lava_source", "default:lava_flowing"}, + base_volume = 0, + max_volume = 0.6, + per_node = { + ["default:lava_source"] = 0.008, + ["default:lava_flowing"] = 0.002, + }, + }, +} + +if minetest.settings:get_bool("river_source_sounds") then + table.insert(allsounds["env_sounds_water"].trigger, + "default:river_water_source") +end + + +-- Cache the union of all trigger nodes + +local cache_triggers = {} + +for sound, def in pairs(allsounds) do + for _, name in ipairs(def.trigger) do + table.insert(cache_triggers, name) + end +end + + +-- Update sound for player + +local function update_sound(player) + local player_name = player:get_player_name() + local ppos = player:get_pos() + ppos = vector.add(ppos, player:get_properties().eye_height) + local areamin = vector.subtract(ppos, radius) + local areamax = vector.add(ppos, radius) + + local pos = minetest.find_nodes_in_area(areamin, areamax, cache_triggers, true) + if next(pos) == nil then -- If table empty + return + end + for sound, def in pairs(allsounds) do + -- Find average position + local posav = {0, 0, 0} + local count = 0 + for _, name in ipairs(def.trigger) do + if pos[name] then + for _, p in ipairs(pos[name]) do + posav[1] = posav[1] + p.x + posav[2] = posav[2] + p.y + posav[3] = posav[3] + p.z + end + count = count + #pos[name] + end + end + + if count > 0 then + posav = vector.new(posav[1] / count, posav[2] / count, + posav[3] / count) + + -- Calculate gain + local gain = def.base_volume + if type(def.per_node) == 'table' then + for name, multiplier in pairs(def.per_node) do + if pos[name] then + gain = gain + #pos[name] * multiplier + end + end + else + gain = gain + count * def.per_node + end + gain = math.min(gain, def.max_volume) + + minetest.sound_play(sound, { + pos = posav, + to_player = player_name, + gain = gain, + }, true) + end + end +end + + +-- Update sound when player joins + +minetest.register_on_joinplayer(function(player) + update_sound(player) +end) + + +-- Cyclic sound update + +local function cyclic_update() + for _, player in pairs(minetest.get_connected_players()) do + update_sound(player) + end + minetest.after(3.5, cyclic_update) +end + +minetest.after(0, cyclic_update) diff --git a/mods/env_sounds/license.txt b/mods/env_sounds/license.txt new file mode 100644 index 0000000..ff8867d --- /dev/null +++ b/mods/env_sounds/license.txt @@ -0,0 +1,57 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2019 paramat + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media (sounds) +-------------------------- + +CC0 1.0 Universal (CC0 1.0) Public Domain Dedication +Yuval + +No Copyright + +The person who associated a work with this deed has dedicated the work to the +public domain by waiving all of his or her rights to the work worldwide under +copyright law, including all related and neighboring rights, to the extent +allowed by law. + +You can copy, modify, distribute and perform the work, even for commercial +purposes, all without asking permission. See Other Information below. + +Other Information: + +In no way are the patent or trademark rights of any person affected by CC0, nor +are the rights that other persons may have in the work or in how the work is +used, such as publicity or privacy rights. + +Unless expressly stated otherwise, the person who associated a work with this +deed makes no warranties about the work, and disclaims liability for all uses +of the work, to the fullest extent permitted by applicable law. + +When using or citing the work, you should not imply endorsement by the author +or the affirmer. + +For more details: +https://creativecommons.org/publicdomain/zero/1.0/ diff --git a/mods/env_sounds/mod.conf b/mods/env_sounds/mod.conf new file mode 100644 index 0000000..ad6feb3 --- /dev/null +++ b/mods/env_sounds/mod.conf @@ -0,0 +1,3 @@ +name = env_sounds +description = Minetest Game mod: env_sounds +depends = default diff --git a/mods/env_sounds/sounds/env_sounds_lava.1.ogg b/mods/env_sounds/sounds/env_sounds_lava.1.ogg new file mode 100644 index 0000000..3eafce2 Binary files /dev/null and b/mods/env_sounds/sounds/env_sounds_lava.1.ogg differ diff --git a/mods/env_sounds/sounds/env_sounds_lava.2.ogg b/mods/env_sounds/sounds/env_sounds_lava.2.ogg new file mode 100644 index 0000000..8648f17 Binary files /dev/null and b/mods/env_sounds/sounds/env_sounds_lava.2.ogg differ diff --git a/mods/env_sounds/sounds/env_sounds_water.1.ogg b/mods/env_sounds/sounds/env_sounds_water.1.ogg new file mode 100644 index 0000000..aa80882 Binary files /dev/null and b/mods/env_sounds/sounds/env_sounds_water.1.ogg differ diff --git a/mods/env_sounds/sounds/env_sounds_water.2.ogg b/mods/env_sounds/sounds/env_sounds_water.2.ogg new file mode 100644 index 0000000..b3ff114 Binary files /dev/null and b/mods/env_sounds/sounds/env_sounds_water.2.ogg differ diff --git a/mods/env_sounds/sounds/env_sounds_water.3.ogg b/mods/env_sounds/sounds/env_sounds_water.3.ogg new file mode 100644 index 0000000..431a6ed Binary files /dev/null and b/mods/env_sounds/sounds/env_sounds_water.3.ogg differ diff --git a/mods/env_sounds/sounds/env_sounds_water.4.ogg b/mods/env_sounds/sounds/env_sounds_water.4.ogg new file mode 100644 index 0000000..56c2ee2 Binary files /dev/null and b/mods/env_sounds/sounds/env_sounds_water.4.ogg differ diff --git a/mods/explosives/README.txt b/mods/explosives/README.txt new file mode 100644 index 0000000..df244fe --- /dev/null +++ b/mods/explosives/README.txt @@ -0,0 +1,74 @@ +Minetest Game mod: tnt +====================== +See license.txt for license information. + +Authors of source code +---------------------- +PilzAdam (MIT) +ShadowNinja (MIT) +sofar (sofar@foo-projects.org) (MIT) +Various Minetest developers and contributors (MIT) + +Authors of media +---------------- +BlockMen (CC BY-SA 3.0): +All textures not mentioned below. + +ShadowNinja (CC BY-SA 3.0): +tnt_smoke.png + +Wuzzy (CC BY-SA 3.0): +All gunpowder textures except tnt_gunpowder_inventory.png. + +sofar (sofar@foo-projects.org) (CC BY-SA 3.0): +tnt_blast.png + +paramat (CC BY-SA 3.0) +tnt_tnt_stick.png - Derived from a texture by benrob0329. + +TumeniNodes (CC0 1.0) +tnt_explode.ogg +renamed, edited, and converted to .ogg from Explosion2.wav +by steveygos93 (CC0 1.0) + + +tnt_ignite.ogg +renamed, edited, and converted to .ogg from sparkler_fuse_nm.wav +by theneedle.tv (CC0 1.0) + + +tnt_gunpowder_burning.ogg +renamed, edited, and converted to .ogg from road flare ignite burns.wav +by frankelmedico (CC0 1.0) + + + +Introduction +------------ +This mod adds TNT to Minetest. TNT is a tool to help the player +in mining. + +How to use the mod: + +Craft gunpowder by placing coal and gravel in the crafting area. +The gunpowder can be used to craft TNT sticks or as a fuse trail for TNT. + +To craft 2 TNT sticks: +G_G +GPG +G_G +G = gunpowder +P = paper +The sticks are not usable as an explosive. + +Craft TNT from 9 TNT sticks. + +There are different ways to ignite TNT: + 1. Hit it with a torch. + 2. Hit a gunpowder fuse trail that leads to TNT with a torch or + flint-and-steel. + 3. Activate it with mesecons (fastest way). + +For 1 TNT: +Node destruction radius is 3 nodes. +Player and object damage radius is 6 nodes. diff --git a/mods/explosives/init.lua b/mods/explosives/init.lua new file mode 100644 index 0000000..818c987 --- /dev/null +++ b/mods/explosives/init.lua @@ -0,0 +1,660 @@ + +explosives = {} + +minetest.register_alias("tnt:tnt", "explosives:propane_tank") + + +local enable_tnt = true + +-- loss probabilities array (one in X will be lost) +local loss_prob = {} + + +local explosion_radius = tonumber(minetest.settings:get("explosion_radius") or 3) + +-- Fill a list with data for content IDs, after all nodes are registered +local cid_data = {} +minetest.register_on_mods_loaded(function() + for name, def in pairs(minetest.registered_nodes) do + cid_data[minetest.get_content_id(name)] = { + name = name, + drops = def.drops, + flammable = def.groups.flammable, + on_blast = def.on_blast, + } + end +end) + +local function rand_pos(center, pos, radius) + local def + local reg_nodes = minetest.registered_nodes + local i = 0 + repeat + -- Give up and use the center if this takes too long + if i > 4 then + pos.x, pos.z = center.x, center.z + break + end + pos.x = center.x + math.random(-radius, radius) + pos.z = center.z + math.random(-radius, radius) + def = reg_nodes[minetest.get_node(pos).name] + i = i + 1 + until def and not def.walkable +end + +local function eject_drops(drops, pos, radius) + local drop_pos = vector.new(pos) + for _, item in pairs(drops) do + local count = math.min(item:get_count(), item:get_stack_max()) + while count > 0 do + local take = math.max(1,math.min(radius * radius, + count, + item:get_stack_max())) + rand_pos(pos, drop_pos, radius) + local dropitem = ItemStack(item) + dropitem:set_count(take) + local obj = minetest.add_item(drop_pos, dropitem) + if obj then + obj:get_luaentity().collect = true + obj:set_acceleration({x = 0, y = -10, z = 0}) + obj:set_velocity({x = math.random(-3, 3), + y = math.random(0, 10), + z = math.random(-3, 3)}) + end + count = count - take + end + end +end + +local function add_drop(drops, item) + item = ItemStack(item) + local name = item:get_name() + if loss_prob[name] ~= nil and math.random(1, loss_prob[name]) == 1 then + return + end + + local drop = drops[name] + if drop == nil then + drops[name] = item + else + drop:set_count(drop:get_count() + item:get_count()) + end +end + +local basic_flame_on_construct -- cached value +local function destroy(drops, npos, cid, c_air, c_fire, + on_blast_queue, on_construct_queue, + ignore_protection, ignore_on_blast, owner) + if not ignore_protection and minetest.is_protected(npos, owner) then + return cid + end + + local def = cid_data[cid] + + if not def then + return c_air + elseif not ignore_on_blast and def.on_blast then + on_blast_queue[#on_blast_queue + 1] = { + pos = vector.new(npos), + on_blast = def.on_blast + } + return cid + elseif def.flammable then + on_construct_queue[#on_construct_queue + 1] = { + fn = basic_flame_on_construct, + pos = vector.new(npos) + } + return c_fire + else + local node_drops = minetest.get_node_drops(def.name, "") + for _, item in pairs(node_drops) do + add_drop(drops, item) + end + return c_air + end +end + +local function calc_velocity(pos1, pos2, old_vel, power) + -- Avoid errors caused by a vector of zero length + if vector.equals(pos1, pos2) then + return old_vel + end + + local vel = vector.direction(pos1, pos2) + vel = vector.normalize(vel) + vel = vector.multiply(vel, power) + + -- Divide by distance + local dist = vector.distance(pos1, pos2) + dist = math.max(dist, 1) + vel = vector.divide(vel, dist) + + -- Add old velocity + vel = vector.add(vel, old_vel) + + -- randomize it a bit + vel = vector.add(vel, { + x = math.random() - 0.5, + y = math.random() - 0.5, + z = math.random() - 0.5, + }) + + -- Limit to terminal velocity + dist = vector.length(vel) + if dist > 250 then + vel = vector.divide(vel, dist / 250) + end + return vel +end + +local function entity_physics(pos, radius, drops) + local objs = minetest.get_objects_inside_radius(pos, radius) + for _, obj in pairs(objs) do + local obj_pos = obj:get_pos() + local dist = math.max(1, vector.distance(pos, obj_pos)) + + local damage = (4 / dist) * radius + if obj:is_player() then + local dir = vector.normalize(vector.subtract(obj_pos, pos)) + local moveoff = vector.multiply(dir, 2 / dist * radius) + obj:add_velocity(moveoff) + + obj:set_hp(obj:get_hp() - damage) + else + local luaobj = obj:get_luaentity() + + -- object might have disappeared somehow + if luaobj then + local do_damage = true + local do_knockback = true + local entity_drops = {} + local objdef = minetest.registered_entities[luaobj.name] + + if objdef and objdef.on_blast then + do_damage, do_knockback, entity_drops = objdef.on_blast(luaobj, damage) + end + + if do_knockback then + local obj_vel = obj:get_velocity() + obj:set_velocity(calc_velocity(pos, obj_pos, + obj_vel, radius * 10)) + end + if do_damage then + if not obj:get_armor_groups().immortal then + obj:punch(obj, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = damage}, + }, nil) + end + end + for _, item in pairs(entity_drops) do + add_drop(drops, item) + end + end + end + end +end + +local function add_effects(pos, radius, drops) + minetest.add_particle({ + pos = pos, + velocity = vector.new(), + acceleration = vector.new(), + expirationtime = 0.4, + size = radius * 10, + collisiondetection = false, + vertical = false, + texture = "tnt_boom.png", + glow = 15, + }) + minetest.add_particlespawner({ + amount = 64, + time = 0.5, + minpos = vector.subtract(pos, radius / 2), + maxpos = vector.add(pos, radius / 2), + minvel = {x = -10, y = -10, z = -10}, + maxvel = {x = 10, y = 10, z = 10}, + minacc = vector.new(), + maxacc = vector.new(), + minexptime = 1, + maxexptime = 2.5, + minsize = radius * 3, + maxsize = radius * 5, + texture = "tnt_smoke.png", + }) + + -- we just dropped some items. Look at the items entities and pick + -- one of them to use as texture + local texture = "tnt_blast.png" --fallback texture + local node + local most = 0 + for name, stack in pairs(drops) do + local count = stack:get_count() + if count > most then + most = count + local def = minetest.registered_nodes[name] + if def then + node = { name = name } + if def.tiles and type(def.tiles[1]) == "string" then + texture = def.tiles[1] + end + end + end + end + + minetest.add_particlespawner({ + amount = 64, + time = 0.1, + minpos = vector.subtract(pos, radius / 2), + maxpos = vector.add(pos, radius / 2), + minvel = {x = -3, y = 0, z = -3}, + maxvel = {x = 3, y = 5, z = 3}, + minacc = {x = 0, y = -10, z = 0}, + maxacc = {x = 0, y = -10, z = 0}, + minexptime = 0.8, + maxexptime = 2.0, + minsize = radius * 0.33, + maxsize = radius, + texture = texture, + -- ^ only as fallback for clients without support for `node` parameter + node = node, + collisiondetection = true, + }) +end + +function explosives.burn(pos, nodename) + local name = nodename or minetest.get_node(pos).name + local def = minetest.registered_nodes[name] + if not def then + return + elseif def.on_ignite then + def.on_ignite(pos) + elseif minetest.get_item_group(name, "explosives") > 0 then + minetest.swap_node(pos, {name = name .. "_burning"}) + minetest.sound_play("tnt_ignite", {pos = pos, gain = 1.0}, true) + minetest.get_node_timer(pos):start(1) + end +end + +local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast, owner, explode_center) + pos = vector.round(pos) + -- scan for adjacent explosives nodes first, and enlarge the explosion + local vm1 = VoxelManip() + local p1 = vector.subtract(pos, 2) + local p2 = vector.add(pos, 2) + local minp, maxp = vm1:read_from_map(p1, p2) + local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) + local data = vm1:get_data() + local count = 0 + + + + local c_air = minetest.CONTENT_AIR + local c_ignore = minetest.CONTENT_IGNORE + + + + -- make sure we still have explosion even when centre node isnt explosives related + if explode_center then + count = 1 + end + + + for z = pos.z - 2, pos.z + 2 do + for y = pos.y - 2, pos.y + 2 do + local vi = a:index(pos.x - 2, y, z) + for x = pos.x - 2, pos.x + 2 do + local cid = data[vi] + if cid == minetest.get_content_id("explosives:propane_tank") then + count = count + 1 -- Apparently the +=, -=, *=, etc. operators do not exist in lua <:-/ + data[vi] = c_air + end + vi = vi + 1 + end + end + end + + vm1:set_data(data) + vm1:write_to_map() + + -- recalculate new radius + radius = math.ceil(radius * math.pow(count, 2)) + + -- perform the explosion + local vm = VoxelManip() + local pr = PseudoRandom(os.time()) + p1 = vector.subtract(pos, radius) + p2 = vector.add(pos, radius) + minp, maxp = vm:read_from_map(p1, p2) + a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) + data = vm:get_data() + + local drops = {} + local on_blast_queue = {} + local on_construct_queue = {} + basic_flame_on_construct = minetest.registered_nodes["fire:basic_flame"].on_construct + + local c_fire = minetest.get_content_id("fire:basic_flame") + for z = -radius, radius do + for y = -radius, radius do + local vi = a:index(pos.x + (-radius), pos.y + y, pos.z + z) + for x = -radius, radius do + local r = vector.length(vector.new(x, y, z)) + if (radius * radius) / (r * r) >= (pr:next(80, 125) / 100) then + local cid = data[vi] + local p = {x = pos.x + x, y = pos.y + y, z = pos.z + z} + + -- What I'm trying to do is to make the explosions only affect nodes that are in a specific group + + if cid ~= c_air and cid ~= c_ignore and minetest.get_item_group(minetest.get_name_from_content_id(cid), "cracky") < 2 then + data[vi] = destroy(drops, p, cid, c_air, c_fire, on_blast_queue, on_construct_queue, ignore_protection, ignore_on_blast, owner) + destruction_counter.nodesDestroyed = destruction_counter.nodesDestroyed + 1 + destruction_counter.updateCounter(owner) + end + end + vi = vi + 1 + end + end + end + + vm:set_data(data) + vm:write_to_map() + vm:update_map() + vm:update_liquids() + + -- call check_single_for_falling for everything within 1.5x blast radius + for y = -radius * 1.5, radius * 1.5 do + for z = -radius * 1.5, radius * 1.5 do + for x = -radius * 1.5, radius * 1.5 do + local rad = {x = x, y = y, z = z} + local s = vector.add(pos, rad) + local r = vector.length(rad) + if r / radius < 1.4 then + minetest.check_single_for_falling(s) + end + end + end + end + + for _, queued_data in pairs(on_blast_queue) do + local dist = math.max(1, vector.distance(queued_data.pos, pos)) + local intensity = (radius * radius) / (dist * dist) + local node_drops = queued_data.on_blast(queued_data.pos, intensity) + if node_drops then + for _, item in pairs(node_drops) do + add_drop(drops, item) + end + end + end + + for _, queued_data in pairs(on_construct_queue) do + queued_data.fn(queued_data.pos) + end + + + + return drops, radius +end + +function explosives.boom(pos, def) + def = def or {} + def.radius = def.radius or 1 + def.damage_radius = def.damage_radius or def.radius * 2 + local owner = def.owner + + local sound = def.sound or "tnt_explode" + minetest.sound_play(sound, {pos = pos, gain = 2.5, + max_hear_distance = math.min(def.radius * 30, 128)}, true) + local drops, radius = tnt_explode(pos, def.radius, true, def.ignore_on_blast, owner, true) + -- append entity drops + local damage_radius = (radius / math.max(1, def.radius)) * def.damage_radius + entity_physics(pos, damage_radius, drops) + + --eject_drops(drops, pos, radius) + + add_effects(pos, radius, drops) + +end + + +minetest.register_node("explosives:gunpowder", { + description = "Gun Powder", + drawtype = "raillike", + paramtype = "light", + is_ground_content = false, + sunlight_propagates = true, + walkable = false, + tiles = { + "tnt_gunpowder_straight.png", + "tnt_gunpowder_curved.png", + "tnt_gunpowder_t_junction.png", + "tnt_gunpowder_crossing.png" + }, + inventory_image = "tnt_gunpowder_inventory.png", + wield_image = "tnt_gunpowder_inventory.png", + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2}, + }, + groups = {dig_immediate = 2, attached_node = 1, flammable = 5, + connect_to_raillike = minetest.raillike_group("gunpowder")}, + --sounds = default.node_sound_leaves_defaults(), + + on_punch = function(pos, node, puncher) + if puncher:get_wielded_item():get_name() == "main:torch" then + minetest.set_node(pos, {name = "explosives:gunpowder_burning"}) + end + end, + on_blast = function(pos, intensity) + minetest.set_node(pos, {name = "explosives:gunpowder_burning"}) + end, + on_burn = function(pos) + minetest.set_node(pos, {name = "explosives:gunpowder_burning"}) + end, + on_ignite = function(pos, igniter) + minetest.set_node(pos, {name = "explosives:gunpowder_burning"}) + end, +}) + +minetest.register_node("explosives:gunpowder_burning", { + drawtype = "raillike", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + light_source = 5, + tiles = {{ + name = "tnt_gunpowder_burning_straight_animated.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1, + } + }, + { + name = "tnt_gunpowder_burning_curved_animated.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1, + } + }, + { + name = "tnt_gunpowder_burning_t_junction_animated.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1, + } + }, + { + name = "tnt_gunpowder_burning_crossing_animated.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1, + } + }}, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2}, + }, + drop = "", + groups = { + dig_immediate = 2, + attached_node = 1, + connect_to_raillike = minetest.raillike_group("gunpowder"), + not_in_creative_inventory = 1 + }, + --sounds = default.node_sound_leaves_defaults(), + on_timer = function(pos, elapsed) + for dx = -1, 1 do + for dz = -1, 1 do + if math.abs(dx) + math.abs(dz) == 1 then + for dy = -1, 1 do + explosives.burn({ + x = pos.x + dx, + y = pos.y + dy, + z = pos.z + dz, + }) + end + end + end + end + minetest.remove_node(pos) + end, + -- unaffected by explosions + on_blast = function() end, + on_construct = function(pos) + minetest.sound_play("tnt_gunpowder_burning", {pos = pos, + gain = 1.0}, true) + minetest.get_node_timer(pos):start(1) + end, +}) + + + +minetest.register_craftitem("explosives:dynamite_stick", { + description = "Dynamite Stick", + inventory_image = "tnt_tnt_stick.png", + groups = {flammable = 5}, +}) + + + +function explosives.register_tnt(def) + local name + if not def.name:find(':') then + name = "explosives:" .. def.name + else + name = def.name + def.name = def.name:match(":([%w_]+)") + end + if not def.tiles then def.tiles = {} end + if not def.damage_radius then def.damage_radius = def.radius * 2 end + + if enable_tnt then + minetest.register_node(":" .. name, { + description = def.description, + tiles = {"tnt_side.png"}, + drawtype = "nodebox", + paramtype = "light", + node_box = + { + type = "fixed", + fixed = + { + {-0.375, -0.5, -0.375, 0.375, 0.0625, 0.375}, + {-0.3125, 0.0625, -0.3125, 0.3125, 0.25, 0.3125}, + {-0.25, 0.25, -0.25, -0.125, 0.5, 0.3125}, + {-0.125, 0.25, -0.25, 0.25, 0.5, -0.125}, + {-0.125, 0.25, 0.1875, 0.25, 0.5, 0.3125}, + {0.125, 0.25, -0.125, 0.25, 0.3125, 0.1875}, + {-0.0625, 0.25, -0.0625, 0.0625, 0.4375, 0.125}, + } + }, + is_ground_content = false, + groups = {dig_immediate = 2, mesecon = 2, explosives = 1, flammable = 5}, + --sounds = default.node_sound_wood_defaults(), + after_place_node = function(pos, placer) + if placer:is_player() then + local meta = minetest.get_meta(pos) + meta:set_string("owner", placer:get_player_name()) + end + end, + on_punch = function(pos, node, puncher) + if puncher:get_wielded_item():get_name() == "main:torch" then + minetest.swap_node(pos, {name = name .. "_burning"}) + minetest.registered_nodes[name .. "_burning"].on_construct(pos) + --default.log_player_action(puncher, "ignites", node.name, "at", pos) + end + end, + on_blast = function(pos, intensity) + minetest.after(0.1, function() + explosives.boom(pos, def) + end) + end, + mesecons = {effector = + {action_on = + function(pos) + explosives.boom(pos, def) + end + } + }, + on_burn = function(pos) + minetest.swap_node(pos, {name = name .. "_burning"}) + minetest.registered_nodes[name .. "_burning"].on_construct(pos) + end, + on_ignite = function(pos, igniter) + minetest.swap_node(pos, {name = name .. "_burning"}) + minetest.registered_nodes[name .. "_burning"].on_construct(pos) + end, + }) + end + + minetest.register_node(":" .. name .. "_burning", { + tiles = { + "tnt_side" + }, + + drawtype = "nodebox", + paramtype = "light", + node_box = + { + type = "fixed", + fixed = + { + {-0.375, -0.5, -0.375, 0.375, 0.0625, 0.375}, + {-0.3125, 0.0625, -0.3125, 0.3125, 0.25, 0.3125}, + {-0.25, 0.25, -0.25, -0.125, 0.5, 0.3125}, + {-0.125, 0.25, -0.25, 0.25, 0.5, -0.125}, + {-0.125, 0.25, 0.1875, 0.25, 0.5, 0.3125}, + {0.125, 0.25, -0.125, 0.25, 0.3125, 0.1875}, + {-0.0625, 0.25, -0.0625, 0.0625, 0.4375, 0.125}, + } + }, + light_source = 5, + drop = "", + --sounds = default.node_sound_wood_defaults(), + groups = {falling_node = 1, not_in_creative_inventory = 1}, + on_timer = function(pos, elapsed) + explosives.boom(pos, def) + end, + -- unaffected by explosions + on_blast = function() end, + on_construct = function(pos) + minetest.sound_play("tnt_ignite", {pos = pos}, true) + minetest.get_node_timer(pos):start(4) + minetest.check_for_falling(pos) + end, + }) +end + +explosives.register_tnt({ + name = "explosives:propane_tank", + description = "Propane Tank", + radius = explosion_radius, +}) diff --git a/mods/explosives/license.txt b/mods/explosives/license.txt new file mode 100644 index 0000000..e59ec6e --- /dev/null +++ b/mods/explosives/license.txt @@ -0,0 +1,100 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2014-2016 PilzAdam +Copyright (C) 2014-2016 ShadowNinja +Copyright (C) 2016 sofar (sofar@foo-projects.org) +Copyright (C) 2014-2016 Various Minetest developers and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + +=================================== + +Licenses of media +----------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2014-2016 BlockMen +Copyright (C) 2014-2016 ShadowNinja +Copyright (C) 2015-2016 Wuzzy +Copyright (C) 2016 sofar (sofar@foo-projects.org) +Copyright (C) 2018 paramat + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ + +==================================================== + +CC0 1.0 Universal (CC0 1.0) Public Domain Dedication +for audio files (found in sounds folder) +TumeniNodes +steveygos93 +theneedle.tv +frankelmedico + +No Copyright + +The person who associated a work with this deed has dedicated the work to the public domain +by waiving all of his or her rights to the work worldwide under copyright law, including all +related and neighboring rights, to the extent allowed by law. + +You can copy, modify, distribute and perform the work, even for commercial purposes, all +without asking permission. See Other Information below. + +In no way are the patent or trademark rights of any person affected by CC0, nor are the +rights that other persons may have in the work or in how the work is used, such as publicity +or privacy rights. + +Unless expressly stated otherwise, the person who associated a work with this deed makes no +warranties about the work, and disclaims liability for all uses of the work, to the fullest +extent permitted by applicable law. + +When using or citing the work, you should not imply endorsement by the author or the affirmer. + +This license is acceptable for Free Cultural Works. +For more Information: +https://creativecommons.org/publicdomain/zero/1.0/ + diff --git a/mods/explosives/mod.conf b/mods/explosives/mod.conf new file mode 100644 index 0000000..eac7dd0 --- /dev/null +++ b/mods/explosives/mod.conf @@ -0,0 +1,3 @@ +name = explosives +description = Explosives mod for Insane Protestor; derivative work of the TNT (tnt) mod from Minetest Game +depends = fire, destruction_counter diff --git a/mods/explosives/sounds/explosives_explode.ogg b/mods/explosives/sounds/explosives_explode.ogg new file mode 100644 index 0000000..e00a16c Binary files /dev/null and b/mods/explosives/sounds/explosives_explode.ogg differ diff --git a/mods/explosives/sounds/explosives_gunpowder_burning.ogg b/mods/explosives/sounds/explosives_gunpowder_burning.ogg new file mode 100644 index 0000000..8581c2d Binary files /dev/null and b/mods/explosives/sounds/explosives_gunpowder_burning.ogg differ diff --git a/mods/explosives/sounds/explosives_ignite.ogg b/mods/explosives/sounds/explosives_ignite.ogg new file mode 100644 index 0000000..1a7062e Binary files /dev/null and b/mods/explosives/sounds/explosives_ignite.ogg differ diff --git a/mods/explosives/textures/tnt_blast.png b/mods/explosives/textures/tnt_blast.png new file mode 100644 index 0000000..92be28b Binary files /dev/null and b/mods/explosives/textures/tnt_blast.png differ diff --git a/mods/explosives/textures/tnt_boom.png b/mods/explosives/textures/tnt_boom.png new file mode 100644 index 0000000..c848bfc Binary files /dev/null and b/mods/explosives/textures/tnt_boom.png differ diff --git a/mods/explosives/textures/tnt_gunpowder_burning_crossing_animated.png b/mods/explosives/textures/tnt_gunpowder_burning_crossing_animated.png new file mode 100644 index 0000000..efab2a9 Binary files /dev/null and b/mods/explosives/textures/tnt_gunpowder_burning_crossing_animated.png differ diff --git a/mods/explosives/textures/tnt_gunpowder_burning_curved_animated.png b/mods/explosives/textures/tnt_gunpowder_burning_curved_animated.png new file mode 100644 index 0000000..bd1437f Binary files /dev/null and b/mods/explosives/textures/tnt_gunpowder_burning_curved_animated.png differ diff --git a/mods/explosives/textures/tnt_gunpowder_burning_straight_animated.png b/mods/explosives/textures/tnt_gunpowder_burning_straight_animated.png new file mode 100644 index 0000000..654e539 Binary files /dev/null and b/mods/explosives/textures/tnt_gunpowder_burning_straight_animated.png differ diff --git a/mods/explosives/textures/tnt_gunpowder_burning_t_junction_animated.png b/mods/explosives/textures/tnt_gunpowder_burning_t_junction_animated.png new file mode 100644 index 0000000..5b567e3 Binary files /dev/null and b/mods/explosives/textures/tnt_gunpowder_burning_t_junction_animated.png differ diff --git a/mods/explosives/textures/tnt_gunpowder_crossing.png b/mods/explosives/textures/tnt_gunpowder_crossing.png new file mode 100644 index 0000000..c0487a0 Binary files /dev/null and b/mods/explosives/textures/tnt_gunpowder_crossing.png differ diff --git a/mods/explosives/textures/tnt_gunpowder_curved.png b/mods/explosives/textures/tnt_gunpowder_curved.png new file mode 100644 index 0000000..8ed01db Binary files /dev/null and b/mods/explosives/textures/tnt_gunpowder_curved.png differ diff --git a/mods/explosives/textures/tnt_gunpowder_inventory.png b/mods/explosives/textures/tnt_gunpowder_inventory.png new file mode 100644 index 0000000..105a2d2 Binary files /dev/null and b/mods/explosives/textures/tnt_gunpowder_inventory.png differ diff --git a/mods/explosives/textures/tnt_gunpowder_straight.png b/mods/explosives/textures/tnt_gunpowder_straight.png new file mode 100644 index 0000000..427feb9 Binary files /dev/null and b/mods/explosives/textures/tnt_gunpowder_straight.png differ diff --git a/mods/explosives/textures/tnt_gunpowder_t_junction.png b/mods/explosives/textures/tnt_gunpowder_t_junction.png new file mode 100644 index 0000000..b30c2b4 Binary files /dev/null and b/mods/explosives/textures/tnt_gunpowder_t_junction.png differ diff --git a/mods/explosives/textures/tnt_side.png b/mods/explosives/textures/tnt_side.png new file mode 100644 index 0000000..c6d519b Binary files /dev/null and b/mods/explosives/textures/tnt_side.png differ diff --git a/mods/explosives/textures/tnt_smoke.png b/mods/explosives/textures/tnt_smoke.png new file mode 100644 index 0000000..cb11644 Binary files /dev/null and b/mods/explosives/textures/tnt_smoke.png differ diff --git a/mods/explosives/textures/tnt_tnt_stick.png b/mods/explosives/textures/tnt_tnt_stick.png new file mode 100644 index 0000000..bc47a29 Binary files /dev/null and b/mods/explosives/textures/tnt_tnt_stick.png differ diff --git a/mods/extinguisher/LICENSE.txt b/mods/extinguisher/LICENSE.txt new file mode 100644 index 0000000..959d9a9 --- /dev/null +++ b/mods/extinguisher/LICENSE.txt @@ -0,0 +1,5 @@ +explosion sounds (CC0) from https://freesound.org/people/tommccann/sounds/235968/ +touch sounds (CC0) from http://freesound.org/people/talesjc/sounds/152572/ +extinguish sounds (CC0) from http://freesound.org/people/Planet-Leader/sounds/155516/ +textures (CC0) made with the GNU image manipulation program +code (CC0) partially copied from my version of the nuke mod diff --git a/mods/extinguisher/README.md b/mods/extinguisher/README.md new file mode 100644 index 0000000..6814fce --- /dev/null +++ b/mods/extinguisher/README.md @@ -0,0 +1,6 @@ +For a description of this Minetest mod, see +https://forum.minetest.net/viewtopic.php?f=9&t=10263. + +TODO: +* Add a fire extinguisher node which automatically shoots at fire nodes +* Add an alternative recipe if poisonify is not available diff --git a/mods/extinguisher/init.lua b/mods/extinguisher/init.lua new file mode 100644 index 0000000..0c561d7 --- /dev/null +++ b/mods/extinguisher/init.lua @@ -0,0 +1,347 @@ +local range = 100 +local v = 1 +local a = 100 +local speed = 0.1 --0 or less for default maximum speed + +local function spray_foam(pos) + if minetest.get_node(pos).name == "extinguisher:foam" then + -- Do not spray foam onto foam + return + end + for z = -1,1 do + for y = -1,1 do + for x = -1,1 do + local p = {x=pos.x+x, y=pos.y+y, z=pos.z+z} + local nn = minetest.get_node(p).name + if nn == "fire:basic_flame" or nn == "fire:permanent_flame" then + minetest.set_node(p, {name="air"}) + minetest.sound_play("fire_extinguish_flame", + {pos = p, max_hear_distance = 16, gain = 0.15}) + minetest.check_for_falling(p) + elseif math.random(0,3) >= 1 then + if nn == "air" then + minetest.set_node(p, {name="air"}) + minetest.check_for_falling(p) + + end + end + end + end + end +end + +local function extinguish(player) + --local t1 = os.clock() + + local playerpos = player:get_pos() + local dir = player:get_look_dir() + + local startpos = vector.new(playerpos) + startpos.y = startpos.y+1.625 + local bl, pos = minetest.line_of_sight(startpos, + vector.add(vector.multiply(dir, range), startpos), 1) + local snd = minetest.sound_play("extinguisher", + {pos = playerpos, gain = 0.5, max_hear_distance = range}) + local flight_time = 1 + if pos then + local s = math.max(vector.distance(startpos, pos)-0.5, 0) + flight_time = (math.sqrt(v * v + 2 * a * s) - v) / a + end + if not bl then + minetest.after(flight_time, function() + -- Extinguish the node + minetest.sound_stop(snd) + spray_foam(vector.round(pos)) + end) + end + minetest.add_particle({ + pos = startpos, + velocity = vector.multiply(dir, v), + acceleration = vector.multiply(dir, a), + expirationtime = flight_time, + size = 1, + texture = "extinguisher_shot.png^[transform" .. math.random(0,7), + }) + + --print("[extinguisher] my shot was calculated after "..tostring(os.clock()-t1).."s") +end + + +--[[ +local function table_empty(t) + for _,_ in pairs(t) do + return false + end + return true +end + +local function get_tab(pos) + local tab_tmp = {pos} + local tab_avoid = {[pos.x.." "..pos.y.." "..pos.z] = true} + local tab_done,num = {pos},2 + while not table_empty(tab_tmp) do + for n,p in pairs(tab_tmp) do + tab_tmp[n] = nil + for z = -2,2 do + for y = -2,2 do + for x = -2,2 do + local p2 = {x=pos.x+x, y=pos.y+y, z=pos.z+z} + local pstr = p2.x.." "..p2.y.." "..p2.z + if not tab_avoid[pstr] + and minetest.get_node(p2).name == "fire:basic_flame" then + tab_avoid[pstr] = true + tab_done[num] = p2 + num = num+1 + table.insert(tab_tmp, p2) + end + end + end + end + end + end + return tab_done +end]] + +local function stop_all_fire_sounds() + local players = minetest.get_connected_players() + for i = 1, #players do + fire.update_player_sound(players[i]) + end +end + +local c_fire, c_foam, c_lava, c_lavaf, c_obsidian, c_cobble +local function extinguish_fire(pos) + local t1 = os.clock() + c_fire = c_fire or minetest.get_content_id("fire:basic_flame") + c_fire1 = c_fire1 or minetest.get_content_id("fire:permanent_flame") + c_foam = c_foam or minetest.get_content_id("extinguisher:foam") + + local tab = vector.explosion_table(40) + + local manip = minetest.get_voxel_manip() + local emerged_pos1, emerged_pos2 = manip:read_from_map(vector.add(pos, -40), + vector.add(pos, 40)) + local area = VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2}) + local nodes = manip:get_data() + + for _,i in pairs(tab) do + local ran = i[2] + if not ran + or math.random(2) == 1 then + local p = area:indexp(vector.add(pos, i[1])) + local d_p = nodes[p] + if d_p == c_fire then + nodes[p] = air; + elseif d_p == c_fire1 then + nodes[p] = air; + end + end + end + + manip:set_data(nodes) + manip:write_to_map() + stop_all_fire_sounds() + print(string.format("[extinguisher] exploded at %s after ca. %.2fs", + minetest.pos_to_string(pos), os.clock() - t1)) + --[[t1 = os.clock() + manip:update_map() + print(string.format("[extinguisher] map updated after ca. %.2fs", os.clock() - t1))]] +end + +local function eexpl(pos) + if minetest.get_node(pos).name ~= "extinguisher:automatic" then + return + end + minetest.sound_play("extinguisher_explosion", {pos=pos}) + minetest.set_node(pos, {name="extinguisher:destroyed"}) + local startpos = minetest.find_node_near(pos, 2, {"fire:basic_flame"}) + if not startpos then + return + end + extinguish_fire(startpos) +end + + +minetest.register_node("extinguisher:foam", { + drawtype = "nodebox", + paramtype = "light", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + } + }, + use_texture_alpha = "blend", + tiles = {"extinguisher_foam.png"}, + drop = "", + groups = {dig_immediate=3, puts_out_fire=1, not_in_creative_inventory=1, falling_node=1}, +}) + +local adtime = 0 +local time = minetest.get_us_time() +local count = 0 +minetest.register_abm({ + nodenames = {"extinguisher:foam"}, + interval = 5, + chance = 5, + catch_up = false, + action = function(pos) + count = count+1 + local ct = minetest.get_us_time() + if count > 10 + and ct-time < 1000000 then + return + end + time = ct + count = 0 + minetest.remove_node(pos) + if adtime < 0.1 then + minetest.check_for_falling(pos) + end + end, +}) + +minetest.register_node("extinguisher:automatic", { + description = "Extinguisher", + tiles = {"extinguisher_top.png", "extinguisher_bottom.png", + "extinguisher.png", "extinguisher.png^[transformFX", + "extinguisher_front.png", "extinguisher_back.png"}, + use_texture_alpha = "opaque", + inventory_image = "extinguisher.png", + wield_image = "extinguisher_pipe.png", + paramtype = "light", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + -- Main bottle + {-2/16, -0.5, -5/16, 3/16, 0, 0}, + {-1/16, 0, -5/16, 2/16, 3/16, 0}, + {-2/16, 0, -4/16, 3/16, 3/16, -1/16}, + {-1/16, 3/16, -4/16, 2/16, 5/16, -1/16}, + {0, 5/16, -3/16, 1/16, 6/16, -2/16}, + + -- Outlet + {0, 3/16, -1/16, 1/16, 4/16, 2/16}, + {-1/16, 3/16, 2/16, 0, 4/16, 4/16}, + {1/16, 3/16, 2/16, 2/16, 4/16, 4/16}, + {0, 4/16, 2/16, 1/16, 5/16, 6/16}, + {0, 2/16, 2/16, 1/16, 3/16, 6/16}, + + -- Handle + {0, 6/16, -6/16, 1/16, 7/16, -1/16}, + {-1/16, 6/16, -3/16, 2/16, 7/16, -2/16}, + {0, 5/16, -7/16, 1/16, 6/16, -5/16}, + {0, 4/16, -7/16, 1/16, 5/16, -6/16}, + }, + }, + groups = {dig_immediate=2}, + sounds = {dig=""}, + on_punch = function(pos, _, player) + minetest.sound_play("extinguisher_touch", {pos=pos, gain=0.25, max_hear_distance=8}) + if player:get_wielded_item():get_name() == "main:torch" then + minetest.after(math.random()*5, eexpl, pos) + end + end, + on_use = function() -- do not dig or punch nodes + end, +}) + +minetest.register_node("extinguisher:destroyed", { + description = "Destroyed Extinguisher", + tiles = {"extinguisher_top.png", "extinguisher_bottom.png", + "extinguisher.png", "extinguisher.png^[transformFX", + "extinguisher_front.png", "extinguisher_destroyed.png"}, + use_texture_alpha = "opaque", + inventory_image = "extinguisher.png", + wield_image = "extinguisher_pipe.png", + paramtype = "light", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + -- Main bottle + {-2/16, -0.5, -3/16, 3/16, 0, 0}, + {-1/16, 0, -5/16, 1/16, 3/16, 0}, + {-1/16, 0, -4/16, 3/16, 3/16, -1/16}, + {-1/16, -3/16, -4/16, 2/16, 4/16, -1/16}, + }, + }, + groups = {dig_immediate=2}, + sounds = {dig=""}, + on_punch = function(pos, _, player) + minetest.sound_play("extinguisher_touch", {pos=pos, gain=0.25, max_hear_distance=8}) + if player:get_wielded_item():get_name() == "main:torch" then + minetest.after(math.random()*5, eexpl, pos) + end + end, + on_use = function() -- do not dig or punch nodes + end, +}) + +local timer = 0 +minetest.register_globalstep(function(dtime) + adtime = dtime + timer = timer+dtime + if timer < speed then + return + end + timer = 0 + for _,player in pairs(minetest.get_connected_players()) do + if player:get_wielded_item():get_name() == "extinguisher:automatic" + and player:get_player_control().LMB then + extinguish(player) + end + end +end) + +minetest.register_craftitem("extinguisher:foam_ingredient_1", { + description = "Foam Ingredient", + inventory_image = "extinguisher_essence_1.png", +}) + +minetest.register_craftitem("extinguisher:foam_ingredient_2", { + description = "Foam Ingredient", + inventory_image = "extinguisher_essence_2.png", +}) + +minetest.register_craftitem("extinguisher:foam_bucket", { + description = "Foam", + inventory_image = "extinguisher_foam_bucket.png", +}) + +if minetest.registered_items["poisonivy:climbing"] then + minetest.register_craft({ + output = "extinguisher:foam_ingredient_1 2", + recipe = { + {"default:stone"}, + {"poisonivy:climbing"}, + {"default:stone"}, + }, + replacements = {{"default:stone", "default:stone"}, {"default:stone", "default:stone"}}, + }) + + minetest.register_craft({ + output = "extinguisher:foam_ingredient_2", + recipe = { + {"default:stone"}, + {"poisonivy:seedling"}, + {"default:stone"}, + }, + replacements = {{"default:stone", "default:stone"}, {"default:stone", "default:stone"}}, + }) + + minetest.register_craft({ + output = "extinguisher:foam_ingredient_2 3", + recipe = { + {"default:stone"}, + {"poisonivy:sproutling"}, + {"default:stone"}, + }, + replacements = {{"default:stone", "default:stone"}, {"default:stone", "default:stone"}}, + }) +end + + + + diff --git a/mods/extinguisher/sounds/extinguisher.1.ogg b/mods/extinguisher/sounds/extinguisher.1.ogg new file mode 100644 index 0000000..a78fc35 Binary files /dev/null and b/mods/extinguisher/sounds/extinguisher.1.ogg differ diff --git a/mods/extinguisher/sounds/extinguisher.2.ogg b/mods/extinguisher/sounds/extinguisher.2.ogg new file mode 100644 index 0000000..3f4ab03 Binary files /dev/null and b/mods/extinguisher/sounds/extinguisher.2.ogg differ diff --git a/mods/extinguisher/sounds/extinguisher.3.ogg b/mods/extinguisher/sounds/extinguisher.3.ogg new file mode 100644 index 0000000..98ef4b7 Binary files /dev/null and b/mods/extinguisher/sounds/extinguisher.3.ogg differ diff --git a/mods/extinguisher/sounds/extinguisher_explosion.1.ogg b/mods/extinguisher/sounds/extinguisher_explosion.1.ogg new file mode 100644 index 0000000..f7bf6c4 Binary files /dev/null and b/mods/extinguisher/sounds/extinguisher_explosion.1.ogg differ diff --git a/mods/extinguisher/sounds/extinguisher_explosion.2.ogg b/mods/extinguisher/sounds/extinguisher_explosion.2.ogg new file mode 100644 index 0000000..10932b4 Binary files /dev/null and b/mods/extinguisher/sounds/extinguisher_explosion.2.ogg differ diff --git a/mods/extinguisher/sounds/extinguisher_touch.1.ogg b/mods/extinguisher/sounds/extinguisher_touch.1.ogg new file mode 100644 index 0000000..26d63b8 Binary files /dev/null and b/mods/extinguisher/sounds/extinguisher_touch.1.ogg differ diff --git a/mods/extinguisher/sounds/extinguisher_touch.2.ogg b/mods/extinguisher/sounds/extinguisher_touch.2.ogg new file mode 100644 index 0000000..b73f838 Binary files /dev/null and b/mods/extinguisher/sounds/extinguisher_touch.2.ogg differ diff --git a/mods/extinguisher/textures/extinguisher.png b/mods/extinguisher/textures/extinguisher.png new file mode 100644 index 0000000..929456b Binary files /dev/null and b/mods/extinguisher/textures/extinguisher.png differ diff --git a/mods/extinguisher/textures/extinguisher_back.png b/mods/extinguisher/textures/extinguisher_back.png new file mode 100644 index 0000000..6a60471 Binary files /dev/null and b/mods/extinguisher/textures/extinguisher_back.png differ diff --git a/mods/extinguisher/textures/extinguisher_bottom.png b/mods/extinguisher/textures/extinguisher_bottom.png new file mode 100644 index 0000000..8ca7282 Binary files /dev/null and b/mods/extinguisher/textures/extinguisher_bottom.png differ diff --git a/mods/extinguisher/textures/extinguisher_destroyed.png b/mods/extinguisher/textures/extinguisher_destroyed.png new file mode 100644 index 0000000..a02223f Binary files /dev/null and b/mods/extinguisher/textures/extinguisher_destroyed.png differ diff --git a/mods/extinguisher/textures/extinguisher_essence_1.png b/mods/extinguisher/textures/extinguisher_essence_1.png new file mode 100644 index 0000000..6ae36f9 Binary files /dev/null and b/mods/extinguisher/textures/extinguisher_essence_1.png differ diff --git a/mods/extinguisher/textures/extinguisher_essence_2.png b/mods/extinguisher/textures/extinguisher_essence_2.png new file mode 100644 index 0000000..3065e9d Binary files /dev/null and b/mods/extinguisher/textures/extinguisher_essence_2.png differ diff --git a/mods/extinguisher/textures/extinguisher_foam.png b/mods/extinguisher/textures/extinguisher_foam.png new file mode 100644 index 0000000..950c269 Binary files /dev/null and b/mods/extinguisher/textures/extinguisher_foam.png differ diff --git a/mods/extinguisher/textures/extinguisher_foam_bucket.png b/mods/extinguisher/textures/extinguisher_foam_bucket.png new file mode 100644 index 0000000..3f321b9 Binary files /dev/null and b/mods/extinguisher/textures/extinguisher_foam_bucket.png differ diff --git a/mods/extinguisher/textures/extinguisher_foam_normal.png b/mods/extinguisher/textures/extinguisher_foam_normal.png new file mode 100644 index 0000000..2808e63 Binary files /dev/null and b/mods/extinguisher/textures/extinguisher_foam_normal.png differ diff --git a/mods/extinguisher/textures/extinguisher_front.png b/mods/extinguisher/textures/extinguisher_front.png new file mode 100644 index 0000000..5b8e482 Binary files /dev/null and b/mods/extinguisher/textures/extinguisher_front.png differ diff --git a/mods/extinguisher/textures/extinguisher_pipe.png b/mods/extinguisher/textures/extinguisher_pipe.png new file mode 100644 index 0000000..2677ba0 Binary files /dev/null and b/mods/extinguisher/textures/extinguisher_pipe.png differ diff --git a/mods/extinguisher/textures/extinguisher_shot.png b/mods/extinguisher/textures/extinguisher_shot.png new file mode 100644 index 0000000..c1d03f3 Binary files /dev/null and b/mods/extinguisher/textures/extinguisher_shot.png differ diff --git a/mods/extinguisher/textures/extinguisher_top.png b/mods/extinguisher/textures/extinguisher_top.png new file mode 100644 index 0000000..5d453b1 Binary files /dev/null and b/mods/extinguisher/textures/extinguisher_top.png differ diff --git a/mods/fire/README.txt b/mods/fire/README.txt new file mode 100644 index 0000000..25ba26e --- /dev/null +++ b/mods/fire/README.txt @@ -0,0 +1,35 @@ +Minetest Game mod: fire +======================= +See license.txt for license information. + +Authors of source code +---------------------- +Originally by Perttu Ahola (celeron55) (LGPLv2.1+) +Various Minetest developers and contributors (LGPLv2.1+) + +Authors of media (textures and sounds) +-------------------------------------- +Everything not listed in here: +Copyright (C) 2012 Perttu Ahola (celeron55) (CC BY-SA 3.0) + +Muadtralk (CC BY-SA 3.0) + fire_basic_flame_animated.png + +Gambit (CC BY-SA 3.0) + fire_flint_steel.png + +dobroide (CC BY 3.0) +http://www.freesound.org/people/dobroide/sounds/4211/ + fire_small.ogg + +Dynamicell (CC BY 3.0) +http://www.freesound.org/people/Dynamicell/sounds/17548/ + fire_large.ogg + fire_fire.*.ogg + +fire_small.ogg and fire_large.ogg are unused but kept temporarily to not break +other mods that may use them. + +Benboncan (CC BY 3.0) +https://www.freesound.org/people/Benboncan/sounds/66457/ + fire_flint_and_steel.ogg diff --git a/mods/fire/init.lua b/mods/fire/init.lua new file mode 100644 index 0000000..6d9f3da --- /dev/null +++ b/mods/fire/init.lua @@ -0,0 +1,286 @@ +-- fire/init.lua + +-- Global namespace for functions +fire = {} + +-- Load support for MT game translation. +local S = minetest.get_translator("fire") + +-- 'Enable fire' setting +local fire_enabled = minetest.settings:get_bool("enable_fire") +if fire_enabled == nil then + -- enable_fire setting not specified, check for disable_fire + local fire_disabled = minetest.settings:get_bool("disable_fire") + if fire_disabled == nil then + -- Neither setting specified, check whether singleplayer + fire_enabled = minetest.is_singleplayer() + else + fire_enabled = not fire_disabled + end +end + +-- +-- Items +-- + +-- Flood flame function +local function flood_flame(pos, _, newnode) + -- Play flame extinguish sound if liquid is not an 'igniter' + if minetest.get_item_group(newnode.name, "igniter") == 0 then + minetest.sound_play("fire_extinguish_flame", + {pos = pos, max_hear_distance = 16, gain = 0.15}, true) + end + -- Remove the flame + return false +end + +-- Flame nodes +local fire_node = { + drawtype = "firelike", + tiles = {{ + name = "fire_basic_flame_animated.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1 + }} + }, + inventory_image = "fire_basic_flame.png", + paramtype = "light", + light_source = 13, + walkable = false, + buildable_to = true, + sunlight_propagates = true, + floodable = true, + damage_per_second = 4, + groups = {igniter = 2, dig_immediate = 3, fire = 1}, + drop = "", + on_flood = flood_flame +} + +-- Basic flame node +local flame_fire_node = table.copy(fire_node) +flame_fire_node.description = S("Fire") +flame_fire_node.groups.not_in_creative_inventory = 1 +flame_fire_node.on_timer = function(pos) + if not minetest.find_node_near(pos, 1, {"group:flammable"}) then + minetest.remove_node(pos) + return + end + -- Restart timer + return true +end +flame_fire_node.on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(30, 60)) +end + +minetest.register_node("fire:basic_flame", flame_fire_node) + +-- Permanent flame node +local permanent_fire_node = table.copy(fire_node) +permanent_fire_node.description = S("Permanent Fire") + +minetest.register_node("fire:permanent_flame", permanent_fire_node) + +-- Flint and Steel +minetest.register_tool("fire:flint_and_steel", { + description = S("Flint and Steel"), + inventory_image = "fire_flint_steel.png", + --sound = {breaks = "default_tool_breaks"}, + + on_use = function(itemstack, user, pointed_thing) + local sound_pos = pointed_thing.above or user:get_pos() + minetest.sound_play("fire_flint_and_steel", + {pos = sound_pos, gain = 0.2, max_hear_distance = 8}, true) + local player_name = user:get_player_name() + if pointed_thing.type == "node" then + local node_under = minetest.get_node(pointed_thing.under).name + local nodedef = minetest.registered_nodes[node_under] + if not nodedef then + return + end + if minetest.is_protected(pointed_thing.under, player_name) then + minetest.chat_send_player(player_name, "This area is protected") + return + end + if nodedef.on_ignite then + nodedef.on_ignite(pointed_thing.under, user) + elseif minetest.get_item_group(node_under, "flammable") >= 1 + and minetest.get_node(pointed_thing.above).name == "air" then + minetest.set_node(pointed_thing.above, {name = "fire:basic_flame"}) + end + end + if not minetest.is_creative_enabled(player_name) then + -- Wear tool + local wdef = itemstack:get_definition() + itemstack:add_wear_by_uses(66) + + -- Tool break sound + if itemstack:get_count() == 0 and wdef.sound and wdef.sound.breaks then + minetest.sound_play(wdef.sound.breaks, + {pos = sound_pos, gain = 0.5}, true) + end + return itemstack + end + end +}) + + + + + +-- +-- Sound +-- + +-- Enable if no setting present +local flame_sound = minetest.settings:get_bool("flame_sound", true) + +if flame_sound then + local handles = {} + local timer = 0 + + -- Parameters + local radius = 8 -- Flame node search radius around player + local cycle = 3 -- Cycle time for sound updates + + -- Update sound for player + function fire.update_player_sound(player) + local player_name = player:get_player_name() + -- Search for flame nodes in radius around player + local ppos = player:get_pos() + local areamin = vector.subtract(ppos, radius) + local areamax = vector.add(ppos, radius) + local fpos, num = minetest.find_nodes_in_area( + areamin, + areamax, + {"fire:basic_flame", "fire:permanent_flame"} + ) + -- Total number of flames in radius + local flames = (num["fire:basic_flame"] or 0) + + (num["fire:permanent_flame"] or 0) + -- Stop previous sound + if handles[player_name] then + minetest.sound_stop(handles[player_name]) + handles[player_name] = nil + end + -- If flames + if flames > 0 then + -- Find centre of flame positions + local fposmid = fpos[1] + -- If more than 1 flame + if #fpos > 1 then + local fposmin = areamax + local fposmax = areamin + for i = 1, #fpos do + local fposi = fpos[i] + if fposi.x > fposmax.x then + fposmax.x = fposi.x + end + if fposi.y > fposmax.y then + fposmax.y = fposi.y + end + if fposi.z > fposmax.z then + fposmax.z = fposi.z + end + if fposi.x < fposmin.x then + fposmin.x = fposi.x + end + if fposi.y < fposmin.y then + fposmin.y = fposi.y + end + if fposi.z < fposmin.z then + fposmin.z = fposi.z + end + end + fposmid = vector.divide(vector.add(fposmin, fposmax), 2) + end + -- Play sound + local handle = minetest.sound_play("fire_fire", { + pos = fposmid, + to_player = player_name, + gain = math.min(0.06 * (1 + flames * 0.125), 0.18), + max_hear_distance = 32, + loop = true -- In case of lag + }) + -- Store sound handle for this player + if handle then + handles[player_name] = handle + end + end + end + + -- Cycle for updating players sounds + minetest.register_globalstep(function(dtime) + timer = timer + dtime + if timer < cycle then + return + end + + timer = 0 + local players = minetest.get_connected_players() + for n = 1, #players do + fire.update_player_sound(players[n]) + end + end) + + -- Stop sound and clear handle on player leave + minetest.register_on_leaveplayer(function(player) + local player_name = player:get_player_name() + if handles[player_name] then + minetest.sound_stop(handles[player_name]) + handles[player_name] = nil + end + end) +end + + +-- Deprecated function kept temporarily to avoid crashes if mod fire nodes call it +function fire.update_sounds_around() end + +-- +-- ABMs +-- + +if fire_enabled then + -- Ignite neighboring nodes, add basic flames + minetest.register_abm({ + label = "Ignite flame", + nodenames = {"group:flammable"}, + neighbors = {"group:igniter"}, + interval = 7, + chance = 12, + catch_up = false, + action = function(pos) + local p = minetest.find_node_near(pos, 1, {"air"}) + if p then + minetest.set_node(p, {name = "fire:basic_flame"}) + end + end + }) + + -- Remove flammable nodes around basic flame + minetest.register_abm({ + label = "Remove flammable nodes", + nodenames = {"fire:basic_flame"}, + neighbors = "group:flammable", + interval = 5, + chance = 18, + catch_up = false, + action = function(pos) + local p = minetest.find_node_near(pos, 1, {"group:flammable"}) + if not p then + return + end + local flammable_node = minetest.get_node(p) + local def = minetest.registered_nodes[flammable_node.name] + if def.on_burn then + def.on_burn(p) + else + minetest.remove_node(p) + minetest.check_for_falling(p) + end + end + }) +end diff --git a/mods/fire/license.txt b/mods/fire/license.txt new file mode 100644 index 0000000..43f9cd7 --- /dev/null +++ b/mods/fire/license.txt @@ -0,0 +1,84 @@ +License of source code +---------------------- + +GNU Lesser General Public License, version 2.1 +Copyright (C) 2012-2016 celeron55, Perttu Ahola +Copyright (C) 2012-2016 Various Minetest developers and contributors + +This program is free software; you can redistribute it and/or modify it under the terms +of the GNU Lesser General Public License as published by the Free Software Foundation; +either version 2.1 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU Lesser General Public License for more details: +https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html + + +Licenses of media (textures and sounds) +--------------------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2012-2016 Perttu Ahola (celeron55) +Copyright (C) 2012-2016 Muadtralk +Copyright (C) 2013-2016 Gambit + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ + +----------------------- + +Attribution 3.0 Unported (CC BY 3.0) +Copyright (C) 2005 dobroide +Copyright (C) 2006 Dynamicell +Copyright (C) 2009 Benboncan + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by/3.0/ diff --git a/mods/fire/locale/fire.de.tr b/mods/fire/locale/fire.de.tr new file mode 100644 index 0000000..dad7c34 --- /dev/null +++ b/mods/fire/locale/fire.de.tr @@ -0,0 +1,4 @@ +# textdomain: fire +Fire=Feuer +Permanent Fire=Permanentes Feuer +Flint and Steel=Feuerstein und Stahl diff --git a/mods/fire/locale/fire.eo.tr b/mods/fire/locale/fire.eo.tr new file mode 100644 index 0000000..2fc0679 --- /dev/null +++ b/mods/fire/locale/fire.eo.tr @@ -0,0 +1,4 @@ +# textdomain: fire +Fire=Fajro +Permanent Fire=Ĉiama Fajro +Flint and Steel=Siliko kaj Ŝtalo diff --git a/mods/fire/locale/fire.es.tr b/mods/fire/locale/fire.es.tr new file mode 100644 index 0000000..4ce3f32 --- /dev/null +++ b/mods/fire/locale/fire.es.tr @@ -0,0 +1,4 @@ +# textdomain: fire +Fire=Fuego +Permanent Fire=Fuego permanente +Flint and Steel=Yesca y pedernal diff --git a/mods/fire/locale/fire.fr.tr b/mods/fire/locale/fire.fr.tr new file mode 100644 index 0000000..4d5d08a --- /dev/null +++ b/mods/fire/locale/fire.fr.tr @@ -0,0 +1,10 @@ +# textdomain: fire +Fire=Feu +Permanent Fire=Feu qui brûle en permanence +Flint and Steel=Briquet à silex en acier + + +##### not used anymore ##### + +# textdomain: fire +Permanent Flame=Flamme permanente diff --git a/mods/fire/locale/fire.id.tr b/mods/fire/locale/fire.id.tr new file mode 100644 index 0000000..a6d2da5 --- /dev/null +++ b/mods/fire/locale/fire.id.tr @@ -0,0 +1,4 @@ +# textdomain: fire +Fire=Api +Permanent Fire=Api Abadi +Flint and Steel=Pemantik Api diff --git a/mods/fire/locale/fire.it.tr b/mods/fire/locale/fire.it.tr new file mode 100644 index 0000000..61eae45 --- /dev/null +++ b/mods/fire/locale/fire.it.tr @@ -0,0 +1,10 @@ +# textdomain: fire +Fire= +Permanent Fire= +Flint and Steel=Acciarino + + +##### not used anymore ##### + +# textdomain: fire +Permanent Flame=Fiamma permanente diff --git a/mods/fire/locale/fire.ja.tr b/mods/fire/locale/fire.ja.tr new file mode 100644 index 0000000..bf5fec4 --- /dev/null +++ b/mods/fire/locale/fire.ja.tr @@ -0,0 +1,4 @@ +# textdomain: fire +Fire=炎 +Permanent Fire=燃え続ける炎 +Flint and Steel=火打ち石と打ち金 diff --git a/mods/fire/locale/fire.jbo.tr b/mods/fire/locale/fire.jbo.tr new file mode 100644 index 0000000..b081236 --- /dev/null +++ b/mods/fire/locale/fire.jbo.tr @@ -0,0 +1,4 @@ +# textdomain: fire +Fire=lo fagri +Permanent Fire=lo vitno fagri +Flint and Steel=lo fakro'i jo'u gasta diff --git a/mods/fire/locale/fire.ms.tr b/mods/fire/locale/fire.ms.tr new file mode 100644 index 0000000..fdd20a5 --- /dev/null +++ b/mods/fire/locale/fire.ms.tr @@ -0,0 +1,10 @@ +# textdomain: fire +Fire= +Permanent Fire= +Flint and Steel=Pemetik Api + + +##### not used anymore ##### + +# textdomain: fire +Permanent Flame=Api Abadi diff --git a/mods/fire/locale/fire.pl.tr b/mods/fire/locale/fire.pl.tr new file mode 100644 index 0000000..a19e6af --- /dev/null +++ b/mods/fire/locale/fire.pl.tr @@ -0,0 +1,4 @@ +# textdomain: fire +Fire=Ogień +Permanent Fire=Stały ogień +Flint and Steel=Zapalniczka diff --git a/mods/fire/locale/fire.pt_BR.tr b/mods/fire/locale/fire.pt_BR.tr new file mode 100644 index 0000000..8a37359 --- /dev/null +++ b/mods/fire/locale/fire.pt_BR.tr @@ -0,0 +1,4 @@ +# textdomain: fire +Fire=Fogo +Permanent Fire=Fogo Permanente +Flint and Steel=Sílex e Fogo diff --git a/mods/fire/locale/fire.ru.tr b/mods/fire/locale/fire.ru.tr new file mode 100644 index 0000000..496e81c --- /dev/null +++ b/mods/fire/locale/fire.ru.tr @@ -0,0 +1,10 @@ +# textdomain: fire +Fire=Огонь +Permanent Fire=Вечный Огонь +Flint and Steel=Огниво + + +##### not used anymore ##### + +# textdomain: fire +Permanent Flame=Вечный Огонь diff --git a/mods/fire/locale/fire.sk.tr b/mods/fire/locale/fire.sk.tr new file mode 100644 index 0000000..125c860 --- /dev/null +++ b/mods/fire/locale/fire.sk.tr @@ -0,0 +1,4 @@ +# textdomain: fire +Fire=Oheň +Permanent Fire=Stály oheň +Flint and Steel=Pazúrik a ocieľka diff --git a/mods/fire/locale/fire.sv.tr b/mods/fire/locale/fire.sv.tr new file mode 100644 index 0000000..28e9a4a --- /dev/null +++ b/mods/fire/locale/fire.sv.tr @@ -0,0 +1,4 @@ +# textdomain: fire +Fire=Eld +Permanent Fire=Permanent eld +Flint and Steel=Flinta och stål diff --git a/mods/fire/locale/fire.uk.tr b/mods/fire/locale/fire.uk.tr new file mode 100644 index 0000000..9da0beb --- /dev/null +++ b/mods/fire/locale/fire.uk.tr @@ -0,0 +1,4 @@ +# textdomain: fire +Fire=Вогонь +Permanent Fire=Вічний Вогонь +Flint and Steel=Кремінь і Сталь diff --git a/mods/fire/locale/fire.zh_CN.tr b/mods/fire/locale/fire.zh_CN.tr new file mode 100644 index 0000000..7b0a472 --- /dev/null +++ b/mods/fire/locale/fire.zh_CN.tr @@ -0,0 +1,4 @@ +# textdomain: fire +Fire=火焰 +Permanent Fire=永久火焰 +Flint and Steel=火石和划片 diff --git a/mods/fire/locale/fire.zh_TW.tr b/mods/fire/locale/fire.zh_TW.tr new file mode 100644 index 0000000..9e3d766 --- /dev/null +++ b/mods/fire/locale/fire.zh_TW.tr @@ -0,0 +1,4 @@ +# textdomain: fire +Fire=火焰 +Permanent Fire=永久火焰 +Flint and Steel=火石和鋼 diff --git a/mods/fire/locale/template.txt b/mods/fire/locale/template.txt new file mode 100644 index 0000000..e4e44e7 --- /dev/null +++ b/mods/fire/locale/template.txt @@ -0,0 +1,4 @@ +# textdomain: fire +Fire= +Permanent Fire= +Flint and Steel= diff --git a/mods/fire/mod.conf b/mods/fire/mod.conf new file mode 100644 index 0000000..1fc7ee9 --- /dev/null +++ b/mods/fire/mod.conf @@ -0,0 +1,2 @@ +name = fire +description = Fire mod, modified for Adsurv diff --git a/mods/fire/sounds/fire_extinguish_flame.1.ogg b/mods/fire/sounds/fire_extinguish_flame.1.ogg new file mode 100644 index 0000000..42506dd Binary files /dev/null and b/mods/fire/sounds/fire_extinguish_flame.1.ogg differ diff --git a/mods/fire/sounds/fire_extinguish_flame.2.ogg b/mods/fire/sounds/fire_extinguish_flame.2.ogg new file mode 100644 index 0000000..2747ab8 Binary files /dev/null and b/mods/fire/sounds/fire_extinguish_flame.2.ogg differ diff --git a/mods/fire/sounds/fire_extinguish_flame.3.ogg b/mods/fire/sounds/fire_extinguish_flame.3.ogg new file mode 100644 index 0000000..8baeac3 Binary files /dev/null and b/mods/fire/sounds/fire_extinguish_flame.3.ogg differ diff --git a/mods/fire/sounds/fire_fire.1.ogg b/mods/fire/sounds/fire_fire.1.ogg new file mode 100644 index 0000000..cbfee4c Binary files /dev/null and b/mods/fire/sounds/fire_fire.1.ogg differ diff --git a/mods/fire/sounds/fire_fire.2.ogg b/mods/fire/sounds/fire_fire.2.ogg new file mode 100644 index 0000000..e8d0eb1 Binary files /dev/null and b/mods/fire/sounds/fire_fire.2.ogg differ diff --git a/mods/fire/sounds/fire_fire.3.ogg b/mods/fire/sounds/fire_fire.3.ogg new file mode 100644 index 0000000..5cad3d9 Binary files /dev/null and b/mods/fire/sounds/fire_fire.3.ogg differ diff --git a/mods/fire/sounds/fire_flint_and_steel.ogg b/mods/fire/sounds/fire_flint_and_steel.ogg new file mode 100644 index 0000000..6996e16 Binary files /dev/null and b/mods/fire/sounds/fire_flint_and_steel.ogg differ diff --git a/mods/fire/sounds/fire_large.ogg b/mods/fire/sounds/fire_large.ogg new file mode 100644 index 0000000..fe78e62 Binary files /dev/null and b/mods/fire/sounds/fire_large.ogg differ diff --git a/mods/fire/sounds/fire_small.ogg b/mods/fire/sounds/fire_small.ogg new file mode 100644 index 0000000..5aac595 Binary files /dev/null and b/mods/fire/sounds/fire_small.ogg differ diff --git a/mods/fire/textures/fire_basic_flame.png b/mods/fire/textures/fire_basic_flame.png new file mode 100644 index 0000000..484bcb1 Binary files /dev/null and b/mods/fire/textures/fire_basic_flame.png differ diff --git a/mods/fire/textures/fire_basic_flame_animated.png b/mods/fire/textures/fire_basic_flame_animated.png new file mode 100644 index 0000000..53e680d Binary files /dev/null and b/mods/fire/textures/fire_basic_flame_animated.png differ diff --git a/mods/fire/textures/fire_flint_steel.png b/mods/fire/textures/fire_flint_steel.png new file mode 100644 index 0000000..9d32d85 Binary files /dev/null and b/mods/fire/textures/fire_flint_steel.png differ diff --git a/mods/give_initial_stuff/README.txt b/mods/give_initial_stuff/README.txt new file mode 100644 index 0000000..cbd240f --- /dev/null +++ b/mods/give_initial_stuff/README.txt @@ -0,0 +1,8 @@ +Minetest Game mod: give_initial_stuff +===================================== +See license.txt for license information. + +Authors of source code +---------------------- +Perttu Ahola (celeron55) (MIT) +Various Minetest developers and contributors (MIT) diff --git a/mods/give_initial_stuff/init.lua b/mods/give_initial_stuff/init.lua new file mode 100644 index 0000000..74421dc --- /dev/null +++ b/mods/give_initial_stuff/init.lua @@ -0,0 +1,46 @@ +-- gave_initial_stuff/init.lua + +local stuff_string = minetest.settings:get("initial_stuff") or + "default:pick_steel,default:axe_steel,default:shovel_steel," .. + "default:torch 99,default:cobble 99" + +give_initial_stuff = { + items = {} +} + +function give_initial_stuff.give(player) + minetest.log("action", + "Giving initial stuff to player " .. player:get_player_name()) + local inv = player:get_inventory() + for _, stack in ipairs(give_initial_stuff.items) do + inv:add_item("main", stack) + end +end + +function give_initial_stuff.add(stack) + give_initial_stuff.items[#give_initial_stuff.items + 1] = ItemStack(stack) +end + +function give_initial_stuff.clear() + give_initial_stuff.items = {} +end + +function give_initial_stuff.add_from_csv(str) + local items = str:split(",") + for _, itemname in ipairs(items) do + give_initial_stuff.add(itemname) + end +end + +function give_initial_stuff.set_list(list) + give_initial_stuff.items = list +end + +function give_initial_stuff.get_list() + return give_initial_stuff.items +end + +give_initial_stuff.add_from_csv(stuff_string) +if minetest.settings:get_bool("give_initial_stuff") then + minetest.register_on_newplayer(give_initial_stuff.give) +end diff --git a/mods/give_initial_stuff/license.txt b/mods/give_initial_stuff/license.txt new file mode 100644 index 0000000..8134c92 --- /dev/null +++ b/mods/give_initial_stuff/license.txt @@ -0,0 +1,25 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 Perttu Ahola (celeron55) +Copyright (C) 2012-2016 Various Minetest developers and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT diff --git a/mods/give_initial_stuff/mod.conf b/mods/give_initial_stuff/mod.conf new file mode 100644 index 0000000..51d31ae --- /dev/null +++ b/mods/give_initial_stuff/mod.conf @@ -0,0 +1,3 @@ +name = give_initial_stuff +description = Minetest Game mod: give_initial_stuff +depends = default diff --git a/mods/literal_trash/init.lua b/mods/literal_trash/init.lua new file mode 100644 index 0000000..9da244b --- /dev/null +++ b/mods/literal_trash/init.lua @@ -0,0 +1,132 @@ +minetest.register_node("literal_trash:disc",{ + description = "Optical Disc", + drawtype = "signlike", + tiles = {"literal_trash_disc.png"}, + inventory_image = "literal_trash_disc.png", + wield_image = "literal_trash_disc.png", + light_propagates = true, + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "wallmounted", + + walkable = false, + + + groups = {choppy = 2}, + selection_box = { + type = "wallmounted", + }, +}) + +minetest.register_node("literal_trash:vhs",{ + description = "VHS Tape", + drawtype = "signlike", + tiles = {"literal_trash_vhs.png"}, + inventory_image = "literal_trash_vhs.png", + wield_image = "literal_trash_vhs.png", + light_propagates = true, + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "wallmounted", + + walkable = false, + + + groups = {choppy = 2}, + selection_box = { + type = "wallmounted", + }, +}) + +minetest.register_node("literal_trash:bloodstain",{ + description = "Blood Stain", + drawtype = "signlike", + tiles = {"literal_trash_bloodstain.png"}, + inventory_image = "literal_trash_bloodstain.png", + wield_image = "literal_trash_bloodstain.png", + light_propagates = true, + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "wallmounted", + + walkable = false, + + + groups = {choppy = 2}, + selection_box = { + type = "wallmounted", + }, +}) + +minetest.register_node("literal_trash:vodka", { + description = "Vodka Bottle", + drawtype = "plantlike", + tiles = {"literal_trash_vodka.png"}, + inventory_image = "literal_trash_vodka.png", + wield_image = "literal_trash_vodka.png", + paramtype = "light", + is_ground_content = false, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} + }, + groups = {vessel = 1, dig_immediate = 3, attached_node = 1}, + sounds = default.node_sound_glass_defaults(), +}) + +minetest.register_node("literal_trash:beer_bottle", { + description = "Beer Bottle", + drawtype = "plantlike", + tiles = {"literal_trash_beer_bottle.png"}, + inventory_image = "literal_trash_beer_bottle.png", + wield_image = "literal_trash_beer_bottle.png", + paramtype = "light", + is_ground_content = false, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} + }, + groups = {vessel = 1, dig_immediate = 3, attached_node = 1}, + sounds = default.node_sound_glass_defaults(), +}) + +minetest.register_node("literal_trash:beer_bottle_empty", { + description = "Empty Beer Bottle", + drawtype = "plantlike", + tiles = {"literal_trash_beer_bottle_empty.png"}, + inventory_image = "literal_trash_beer_bottle_empty.png", + wield_image = "literal_trash_beer_bottle_empty.png", + paramtype = "light", + is_ground_content = false, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} + }, + groups = {vessel = 1, dig_immediate = 3, attached_node = 1}, + sounds = default.node_sound_glass_defaults(), +}) + + + + +minetest.register_node("literal_trash:empty_beer_bottles", { + description = "Empty Beer Bottles", + drawtype = "plantlike", + tiles = {"literal_trash_empty_beer_bottles.png"}, + inventory_image = "literal_trash_empty_beer_bottles.png", + wield_image = "literal_trash_empty_beer_bottles.png", + paramtype = "light", + is_ground_content = false, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} + }, + groups = {vessel = 1, dig_immediate = 3, attached_node = 1}, + sounds = default.node_sound_defaults(), +}) + + diff --git a/mods/literal_trash/textures/literal_trash_beer_bottle.png b/mods/literal_trash/textures/literal_trash_beer_bottle.png new file mode 100644 index 0000000..e2da6eb Binary files /dev/null and b/mods/literal_trash/textures/literal_trash_beer_bottle.png differ diff --git a/mods/literal_trash/textures/literal_trash_beer_bottle_empty.png b/mods/literal_trash/textures/literal_trash_beer_bottle_empty.png new file mode 100644 index 0000000..b111b56 Binary files /dev/null and b/mods/literal_trash/textures/literal_trash_beer_bottle_empty.png differ diff --git a/mods/literal_trash/textures/literal_trash_bloodstain.png b/mods/literal_trash/textures/literal_trash_bloodstain.png new file mode 100644 index 0000000..39b2eae Binary files /dev/null and b/mods/literal_trash/textures/literal_trash_bloodstain.png differ diff --git a/mods/literal_trash/textures/literal_trash_disc.png b/mods/literal_trash/textures/literal_trash_disc.png new file mode 100644 index 0000000..665cbbc Binary files /dev/null and b/mods/literal_trash/textures/literal_trash_disc.png differ diff --git a/mods/literal_trash/textures/literal_trash_empty_beer_bottles.png b/mods/literal_trash/textures/literal_trash_empty_beer_bottles.png new file mode 100644 index 0000000..dc3d35d Binary files /dev/null and b/mods/literal_trash/textures/literal_trash_empty_beer_bottles.png differ diff --git a/mods/literal_trash/textures/literal_trash_pipe.png b/mods/literal_trash/textures/literal_trash_pipe.png new file mode 100644 index 0000000..e7b5ec0 Binary files /dev/null and b/mods/literal_trash/textures/literal_trash_pipe.png differ diff --git a/mods/literal_trash/textures/literal_trash_rag.png b/mods/literal_trash/textures/literal_trash_rag.png new file mode 100644 index 0000000..0beb949 Binary files /dev/null and b/mods/literal_trash/textures/literal_trash_rag.png differ diff --git a/mods/literal_trash/textures/literal_trash_vhs.png b/mods/literal_trash/textures/literal_trash_vhs.png new file mode 100644 index 0000000..b25af78 Binary files /dev/null and b/mods/literal_trash/textures/literal_trash_vhs.png differ diff --git a/mods/literal_trash/textures/literal_trash_vodka.png b/mods/literal_trash/textures/literal_trash_vodka.png new file mode 100644 index 0000000..3546168 Binary files /dev/null and b/mods/literal_trash/textures/literal_trash_vodka.png differ diff --git a/mods/literal_trash/textures/vessels_drinking_glass.png b/mods/literal_trash/textures/vessels_drinking_glass.png new file mode 100644 index 0000000..aef7329 Binary files /dev/null and b/mods/literal_trash/textures/vessels_drinking_glass.png differ diff --git a/mods/literal_trash/textures/vessels_drinking_glass_inv.png b/mods/literal_trash/textures/vessels_drinking_glass_inv.png new file mode 100644 index 0000000..e50c8c7 Binary files /dev/null and b/mods/literal_trash/textures/vessels_drinking_glass_inv.png differ diff --git a/mods/literal_trash/textures/vessels_glass_fragments.png b/mods/literal_trash/textures/vessels_glass_fragments.png new file mode 100644 index 0000000..acf2d38 Binary files /dev/null and b/mods/literal_trash/textures/vessels_glass_fragments.png differ diff --git a/mods/literal_trash/textures/vessels_shelf.png b/mods/literal_trash/textures/vessels_shelf.png new file mode 100644 index 0000000..9dd41a1 Binary files /dev/null and b/mods/literal_trash/textures/vessels_shelf.png differ diff --git a/mods/literal_trash/textures/vessels_shelf_slot.png b/mods/literal_trash/textures/vessels_shelf_slot.png new file mode 100644 index 0000000..93a729e Binary files /dev/null and b/mods/literal_trash/textures/vessels_shelf_slot.png differ diff --git a/mods/literal_trash/textures/vessels_steel_bottle.png b/mods/literal_trash/textures/vessels_steel_bottle.png new file mode 100644 index 0000000..169930a Binary files /dev/null and b/mods/literal_trash/textures/vessels_steel_bottle.png differ diff --git a/mods/main/craftitems.lua b/mods/main/craftitems.lua new file mode 100644 index 0000000..e14ced5 --- /dev/null +++ b/mods/main/craftitems.lua @@ -0,0 +1,78 @@ +--------------- +--------------- +--Craft Items-- +--------------- +--------------- + +--Stick +minetest.register_craftitem("main:stick", +{ + description = "Stick", + inventory_image = "main_stick.png", +}) + +--Twig +minetest.register_craftitem("main:twig_item", +{ + description = "Twig", + inventory_image = "main_twig.png", +}) + + +---------- +--Minerals +---------- + +--Salt Crystals +minetest.register_craftitem("main:salt_crystals", { + description = "Salt Crystals", + inventory_image = "main_salt_crystals.png", +}) + +--Sulfur Lump +minetest.register_craftitem("main:lump_sulfur", { + description = "Sulfur Lump", + inventory_image = "main_lump_sulfur.png", +}) + +--Coal +minetest.register_craftitem("main:coal", { + description = "Coal", + inventory_image = "main_lump_coal.png", +}) + +--Iron Lump +minetest.register_craftitem("main:lump_iron", { + description = "Iron Lump", + inventory_image = "main_lump_iron.png", +}) + +--Copper Lump +minetest.register_craftitem("main:lump_copper", { + description = "Copper Lump", + inventory_image = "main_lump_copper.png", +}) + +--Raw Diamond +minetest.register_craftitem("main:diamond_raw", { + description = "Raw Diamond", + inventory_image = "main_dirt.png", -- Dummy/placeholder texture, will be changed in the future + --inventory_image = "main_diamond_raw.png", +}) + +--Polished Diamond +minetest.register_craftitem("main:diamond_polished", { + description = "Polished Diamond", + inventory_image = "main_dirt.png", -- Dummy/placeholder, will be changed in the future + --inventory_image = "main_diamond_polished.png", +}) +--------- +--Edibles +--------- + +--Strawberry +minetest.register_craftitem("main:berry_straw", { + description = "Strawberry", + tiles = {"main_berry_straw.png"}, + on_use = minetest.item_eat(1), +}) diff --git a/mods/main/init.lua b/mods/main/init.lua new file mode 100644 index 0000000..3ebe22a --- /dev/null +++ b/mods/main/init.lua @@ -0,0 +1,38 @@ +local modpath = minetest.get_modpath("main") +local formspec = +{ + "formspec_version[4]", + "size[12,9]", + "bgcolor[#1155FF]", + "position[0.5,0.5]", + "label[0.375,0.5;Welcome to Adsurv v0.6! Here's how to start: find a rock and a stick on the ground, pick them ", + "up and open your inventory to craft a primitive knife, then use the knife to chop down a tree!!!", + "", + "Be sure to check out my Web site!!!", + "", + "", + "", + "Thanks for playing Adsurv!!! ", + "Join the official server @ mcl.cubesoftware.xyz!!!", + "Have a nice day!]", + "", + "", + "button_exit[0.1,6.7;11.85,2;continue;CLICK HERE TO CONTINUE!!!]" +} + + +dofile(modpath.."/nodes.lua") +dofile(modpath.."/craftitems.lua") +dofile(modpath.."/recipes.lua") +dofile(modpath.."/mapgen.lua") +dofile(modpath.."/tools.lua") + + +minetest.register_on_joinplayer(function(player) + player:hud_set_hotbar_image("gui_hotbar.png") + player:hud_set_hotbar_selected_image("gui_hotbar_selected.png") + player:set_lighting({ + shadows = {intensity = 0.5} + }) + --minetest.show_formspec(player:get_player_name(), "formspec", table.concat(formspec, "\n")) +end) diff --git a/mods/main/license.txt b/mods/main/license.txt new file mode 100644 index 0000000..a848956 --- /dev/null +++ b/mods/main/license.txt @@ -0,0 +1,7 @@ +Copyright 2019-2021 MCL + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/mods/main/mapgen.lua b/mods/main/mapgen.lua new file mode 100644 index 0000000..ca50a3d --- /dev/null +++ b/mods/main/mapgen.lua @@ -0,0 +1,406 @@ +minetest.register_alias("mapgen_stone", "main:stone") +minetest.register_alias("mapgen_dirt", "main:dirt") +minetest.register_alias("mapgen_dirt_with_grass", "main:dirt_with_grass") +minetest.register_alias("mapgen_sand", "main:sand") +minetest.register_alias("mapgen_water_source", "main:water_source") +minetest.register_alias("mapgen_river_water_source", "main:muddywater_source") +minetest.register_alias("mapgen_lava_source", "main:lava_source") + +-------- +--Biomes +-------- + +--Grasslands +minetest.register_biome( + { + name = "Grasslands", + + node_top = "main:dirt_with_grass", + node_filler = "main:dirt", + + depth_top = 1, + depth_filler = 1, + + y_min = 4, + y_max = 14, + + heat_point = 60, + humidity_point = 30, +}) + +--Beach +minetest.register_biome( + { + name = "Beach", + + node_top = "main:sand", + node_filler = "main:stone", + + depth_top = 1, + depth_filler = 3, + + y_min = 1, + y_max = 4, + + heat_point = 70, + humidity_point = 55, +}) + +--Swamp +minetest.register_biome( + { + name = "Swamp", + + node_top = "main:dirt_with_swamp_grass", + node_filler = "main:dirt", + + depth_top = 1, + depth_filler = 3, + + y_min = 1, + y_max = 4, + + heat_point = 60, + humidity_point = 30, +}) + +--Sulfur Deposit +minetest.register_biome( + { + name = "Sulfur Deposit", + + node_top = "main:stone", + node_filler = "main:gravel", + + depth_top = 1, + depth_filler = 7, + + y_min = 7, + y_max = 15, + + heat_point = 80, + humidity_point = 90, +}) + +--Desert +minetest.register_biome( + { + name = "Desert", + + node_top = "main:sand", + node_filler = "main:sand", + + depth_top = 4, + depth_filler = 3, + + y_min = 3, + y_max = 50, + + heat_point = 100, + humidity_point = 8, +}) + +--Mountains +minetest.register_biome( + { + name = "Mountains", + + node_top = "main:cobble", + node_filler = "main:stone", + + depth_top = 1, + depth_filler = 1, + + y_min = 15, + y_max = 150, + + heat_point = 60, + humidity_point = 30, +}) + +--Mountain Peak (with snow) +minetest.register_biome( + { + name = "Mountain Peak", + + node_top = "main:snow", + node_filler = "main:snow", + + depth_top = 1, + depth_filler = 1, + + y_min = 150, + y_max = upper_limit, + + heat_point = 10, + humidity_point = 20, +}) + +--Wasteland +minetest.register_biome( + { + name = "Wasteland", + + node_top = "main:dirt", + depth_top = 2, + + node_water = "main:toxicwater_source", + + y_min = 1, + y_max = 170, + + heat_point = 80, + humidity_point = 10, +}) + +--Wasteland Ocean +minetest.register_biome( + { + name = "Wasteland Ocean", + + node_top = "main:dirt", + depth_top = 3, + + node_water = "main:toxicwater_source", + + y_min = -31000, + y_max = 0, + + heat_point = 80, + humidity_point = 30, +}) + +--Snow Plains +minetest.register_biome( + { + name = "Snow Plains", + + node_top = "main:snow", + depth_top = 6, + + node_filler = "main:dirt_frozen", + depth_filler = 8, + + node_water = "main:ice_thick", + node_river_water = "main:ice_thin", + + y_min = 1, + y_max = 50, + + heat_point = 0, + humidity_point = 10, +}) + +-------------- +--Scatter ores +-------------- + +minetest.register_ore({ + ore_type = "scatter", + ore = "main:sulfur_ore", + wherein = "main:stone", "main:cobble", + biomes = {"Sulfur Deposit"}, + clust_scarcity = 16 * 16 * 16, + clust_num_ores = 5, + clust_size = 3, + y_min = 7, + y_max = 15, +}) + +minetest.register_ore({ + ore_type = "scatter", + ore = "main:iron_ore", + wherein = "main:stone", "main:cobble", + clust_scarcity = 8 * 8 * 8, + clust_num_ores = 6, + clust_size = 4, + y_min = -30000, + y_max = -90, +}) + +minetest.register_ore({ + ore_type = "scatter", + ore = "main:iron_ore", + wherein = "main:stone", "main:cobble", + clust_scarcity = 15 * 15 * 15, + clust_num_ores = 2, + clust_size = 2, + y_min = 40, + y_max = upper_limit, +}) + +minetest.register_ore({ + ore_type = "scatter", + ore = "main:coal_ore", + wherein = "main:stone", "main:cobble", + clust_scarcity = 7 * 7 * 7, + clust_num_ores = 5, + clust_size = 3, + y_min = -30000, + y_max = 0, +}) + +minetest.register_ore({ + ore_type = "scatter", + ore = "main:coal_ore", + wherein = "main:stone", "main:cobble", + clust_scarcity = 20 * 20 * 20, + clust_num_ores = 4, + clust_size = 3, + y_min = -250, + y_max = upper_limit, +}) +--Cinnabar +minetest.register_ore({ + ore_type = "scatter", + ore = "main:cinnabar_ore", + wherein = "main:stone", "main:cobble", + clust_scarcity = 18 * 18 * 18, + clust_num_ores = 6, + clust_size = 4, + y_min = -30000, + y_max = -100, +}) + +--Salt +minetest.register_ore({ + ore_type = "scatter", + ore = "main:salt_ore", + wherein = "main:stone", "main:cobble", + clust_scarcity = 10 * 10 * 10, + clust_num_ores = 2, + clust_size = 2, + y_min = -30000, + y_max = 30, +}) + +--Low Density Diamond +minetest.register_ore({ + ore_type = "scatter", + ore = "main:diamond_ore_lowdens", + wherein = "main:stone", + clust_scarcity = 10 * 10 * 10, + clust_num_ores = 4, + clust_size = 6, + y_min = -30000, + y_max = -1000, +}) + +--Low Density Diamond +minetest.register_ore({ + ore_type = "scatter", + ore = "main:diamond_ore_hidens", + wherein = "main:stone", + clust_scarcity = 16 * 16 * 16, + clust_num_ores = 8, + clust_size = 6, + y_min = -30000, + y_max = -1200, +}) + +------------- +--Decorations +------------- + +-- Rock +minetest.register_decoration({ + deco_type = "simple", + place_on = {"main:stone", "main:dirt_with_grass", "main:dirt_with_swamp_grass", "main:dirt", "main:sand", "main:snow"}, + sidelen = 16, + fill_ratio = 0.004, + --biomes = {"grassy_plains"}, + y_max = 200, + y_min = 1, + decoration = "main:rock", +}) + +-- Twig +minetest.register_decoration({ + deco_type = "simple", + place_on = {"main:stone", "main:dirt_with_grass", "main:dirt_with_swamp_grass", "main:dirt", "main:sand", "main:snow"}, + sidelen = 16, + fill_ratio = 0.004, + --biomes = {"grassy_plains"}, + y_max = 200, + y_min = 1, + decoration = "main:twig", +}) + +--Small Boulder +minetest.register_decoration({ + deco_type = "schematic", + place_on = {"main:dirt_with_grass", "main:dirt", "main:sand", "main:dirt_with_swamp_grass"}, + rotation = "random", + sidelen = 16, + fill_ratio = 0.004, + biomes = {"Grasslands", "Swamp", "Desert", "Wasteland"}, + flags = "place_center_x, place_center_z", + schematic = minetest.get_modpath("main") .. "/schematics/main_rock_cobble_small.mts", + y_min = -32000, + y_max = 32000, +}) + +--Oak Tree +minetest.register_decoration({ + deco_type = "schematic", + place_on = {"main:dirt_with_grass"}, + rotation = "random", + sidelen = 16, + fill_ratio = 0.004, + biomes = {"Grasslands"}, + flags = "place_center_x, place_center_z", + schematic = minetest.get_modpath("main") .. "/schematics/main_tree_oak.mts", + y_min = -32000, + y_max = 32000, +}) + +--Tall Oak Tree +minetest.register_decoration({ + deco_type = "schematic", + place_on = {"main:dirt_with_grass"}, + rotation = "random", + sidelen = 16, + fill_ratio = 0.004, + biomes = {"Grasslands", "Swamp"}, + flags = "place_center_x, place_center_z", + schematic = minetest.get_modpath("main") .. "/schematics/main_tree_oak_tall.mts", + y_min = -32000, + y_max = 32000, +}) + +--Dead Tall Oak Tree +minetest.register_decoration({ + deco_type = "schematic", + place_on = {"main:dirt", "main:stone", "main:sand"}, + rotation = "random", + sidelen = 16, + biomes = {"Wasteland", "Sulfur Deposit", "Desert"}, + flags = "place_center_x, place_center_z", + schematic = minetest.get_modpath("main") .. "/schematics/main_tree_oak_tall_dead.mts", + y_min = -32000, + y_max = 32000, + + noise_params = + { + offset = -0.0003, + scale = 0.0009, + spread = {x = 200, y = 200, z = 200}, + seed = 230, + octaves = 3, + persist = 0.6 + }, +}) + +--Apple Tree +minetest.register_decoration({ + deco_type = "schematic", + place_on = {"main:dirt_with_grass"}, + rotation = "random", + sidelen = 16, + fill_ratio = 0.004, + biomes = {"Grasslands"}, + flags = "place_center_x, place_center_z", + schematic = minetest.get_modpath("main") .. "/schematics/main_tree_apple.mts", + y_min = -32000, + y_max = 32000, +}) diff --git a/mods/main/nodes.lua b/mods/main/nodes.lua new file mode 100644 index 0000000..198dc5e --- /dev/null +++ b/mods/main/nodes.lua @@ -0,0 +1,431 @@ +--Naturally generating nodes +minetest.register_node("main:stone", +{ + description = "Stone", + tiles = {"main_stone.png"}, + groups = {cracky = 1, stone = 1}, + drop = 'main:cobble', + legacy_mineral = true, +}) + +minetest.register_node("main:cobble", +{ + description = "Cobble", + tiles = {"main_cobble.png"}, + groups = {cracky = 2, stone = 1}, + drop = 'main:cobble', + legacy_mineral = true, +}) + +minetest.register_node("main:rock", +{ + description = "Rock", + tiles = {"main_cobble.png"}, + groups = {cracky = 3, stone = 1, oddly_breakable_by_hand = 3}, + drawtype = "nodebox", + paramtype = "light", + node_box = + { + type = "fixed", + fixed = + { + {-0.25, -0.5, -0.25, 0.25, 0, 0.25}, + } + } +}) + +minetest.register_node("main:dirt", +{ + description = "Dirt", + tiles = {"main_dirt.png"}, + groups = {crumbly = 3, soil = 1}, +}) + +minetest.register_node("main:dirt_frozen", { + description = "Frozen Dirt", + tiles = {"main_dirt_frozen.png"}, + groups = {cracky = 1}, +}) + +minetest.register_node("main:snow", { + description = "Snow", + tiles = {"main_snow.png"}, + groups = {crumbly = 3}, +}) + +minetest.register_node("main:ice_thin", { + drawtype = "allfaces", + paramtype = "light", + light_propagates = true, + sunlight_propagates = true, + alpha = 6, + description = "Thin Ice", + tiles = {"main_ice_thin.png"}, + groups = {cracky = 3, slippery = 3}, +}) + +minetest.register_node("main:ice_thick", { + description = "Thick Ice", + tiles = {"main_ice_thick.png"}, + groups = {cracky = 1}, +}) + +minetest.register_node("main:dirt_with_grass", +{ + description = "Dirt with Grass", + tiles = {"main_grass.png", "main_dirt.png", + {name = "main_dirt.png^main_grass_side.png", + tileable_vertical = false}}, + groups = {crumbly = 3, soil = 1, spreading_dirt_type = 1}, + drop = 'main:dirt', +}) + +minetest.register_node("main:dirt_with_swamp_grass", +{ + description = "Dirt with Swamp Grass", + tiles = {"main_swamp_grass.png", "main_dirt.png", + {name = "main_dirt.png^main_swamp_grass_side.png", + tileable_vertical = false}}, + groups = {crumbly = 3, soil = 1, spreading_dirt_type = 1}, + drop = 'main:dirt', +}) + +minetest.register_node("main:sand", +{ + description = "Sand", + tiles = {"main_sand.png"}, + groups = {crumbly = 3, falling_node = 1, sand = 1}, +}) + +minetest.register_node("main:twig", +{ + description = "Twig", + tiles = {"main_log_maple.png"}, + groups = {choppy = 3, stone = 1, oddly_breakable_by_hand = 3}, + drawtype = "nodebox", + paramtype = "light", + drop = "main:stick", + node_box = + { + type = "fixed", + fixed = + { + {-0.125, -0.5, 0, 0.125, -0.3125, 0.1875}, -- NodeBox1 + {-0.4375, -0.5, 0.0625, -0.125, -0.3125, 0.25}, -- NodeBox3 + {0.125, -0.5, -0.0625, 0.5, -0.3125, 0.125}, -- NodeBox4 + } + } +}) + +--Player made nodes +minetest.register_node("main:torch", +{ + description = "Torch", + tiles = {"main_lump_coal.png"}, + light_source = 14, + groups = {choppy = 3, oddly_breakable_by_hand = 3}, +}) + +minetest.register_node("main:bricks_red", +{ + description = "Red Bricks", + tiles = {"main_bricks_red.png"}, + groups = {cracky = 2}, +}) + +minetest.register_node("main:bricks_stone", +{ + description = "Stone Bricks", + tiles = {"main_bricks_stone.png"}, + groups = {cracky = 2}, +}) + +minetest.register_node("main:bricks_cobble", +{ + description = "Cobble Bricks", + tiles = {"main_bricks_cobble.png"}, + groups = {cracky = 2}, +}) + +minetest.register_node("main:glass", +{ + description = "Glass", + drawtype = "glasslike_framed_optional", + tiles = {"main_glass_frame.png", "main_glass.png"}, + inventory_image = minetest.inventorycube("main_glass_frame.png"), + paramtype = "light", + sunlight_propagates = true, + is_ground_content = false, + groups = {cracky = 1, oddly_breakable_by_hand = 1}, +}) + +--Ores +minetest.register_node("main:coal_ore", +{ + description = "Coal Ore", + tiles = {"main_stone.png^main_coal_ore.png"}, + groups = {cracky = 1}, +}) + +minetest.register_node("main:iron_ore", +{ + description = "Iron Ore", + tiles = {"main_stone.png^main_iron_ore.png"}, + groups = {cracky = 3}, +}) + +minetest.register_node("main:sulfur_ore", +{ + description = "Sulfur Ore", + tiles = {"main_stone.png^main_sulfur_ore.png"}, + groups = {cracky = 2}, +}) + +minetest.register_node("main:salt_ore", +{ + description = "Salt Ore", + tiles = {"main_stone.png^main_salt_ore.png"}, + groups = {cracky = 3}, + drop = 'main:salt_crystals', +}) + +minetest.register_node("main:cinnabar_ore", +{ + description = "Cinnabar", + tiles = {"main_stone.png^main_cinnabar_ore.png"}, + groups = {cracky = 3}, +}) + +--Diamond Ores +minetest.register_node("main:diamond_ore_lowdens", { + description = "Low Density Diamond ore", + tiles = {"main_stone.png^main_diamond_ore_lowdensity.png"}, + groups = {cracky = 3}, +}) + +minetest.register_node("main:diamond_ore_hidens", { + description = "High Density Diamond Ore", + tiles = {"main_stone.png^main_diamond_ore.png"}, + groups = {cracky = 3}, +}) + +--Iron Block +minetest.register_node("main:block_iron", { + description = "Block Of Iron", + tiles = {"main_block_iron.png"}, + groups = {cracky = 3}, + drop = 'main:block_iron', +}) + +--Copper Block +minetest.register_node("main:block_copper", { + description = "Block Of Copper", + tiles = {"main_block_copper.png"}, + groups = {cracky = 3}, +}) + +--Brass Block +minetest.register_node("main:block_brass", { + description = "Block Of Brass", + tiles = {"main_block_brass.png"}, + groups = {cracky = 3}, +}) + +--Gold Block +minetest.register_node("main:block_gold", { + description = "Block Of Gold", + tiles = {"main_block_gold.png"}, + groups = {cracky = 3}, +}) + +--Planks +minetest.register_node("main:planks_oak", { + description = "Planks", + tiles = {"main_planks_oak.png"}, + groups = {choppy = 3}, +}) + + +-- +-- Plants and Other Living Organisms +-- + +--Red Apple +minetest.register_node("main:apple_red", { + description = "Red Apple", + tiles = {"main_apple_red.png"}, + groups = {fleshy = 3, oddly_breakable_by_hand = 3}, + on_use = minetest.item_eat(5), +}) + +--Orange +minetest.register_node("main:orange", { + description = "Orange", + tiles = {"main_orange.png"}, + groups = {fleshy = 3, oddly_breakable_by_hand = 3}, + on_use = minetest.item_eat(4), +}) + + + +--Oak Log +minetest.register_node("main:log_oak", { + description = "Oak Log", + tiles = {"main_log_oak.png"}, + groups = {choppy = 2, logs = 1}, +}) + +--Oak Leaves +minetest.register_node("main:leaves_oak", { + paramtype = "light", + light_propagates = true, + sunlight_propagates = true, + walkable = false, + climbable = true, + is_ground_content = false, + description = "Oak Leaves", + tiles = {"main_leaves_oak.png"}, + groups = {snappy = 3}, + waving = 1, +}) + +--Apple Tree Log +minetest.register_node("main:log_apple", { + description = "Apple Tree Log", + tiles = {"main_log_apple.png"}, + groups = {choppy = 3, logs = 1}, + waving = 1, +}) + +--Apple Tree Leaves +minetest.register_node("main:leaves_apple", { + paramtype = "light", + light_propagates = true, + sunlight_propagates = true, + walkable = false, + climbable = true, + is_ground_content = false, + description = "Apple Tree Leaves", + tiles = {"main_leaves_apple.png"}, + groups = {snappy = 3}, + waving = 1, +}) + +-- +-- Liquids +-- + +--Fresh water +minetest.register_node("main:water_source", { + description = "Fresh Water Source", + drawtype = "liquid", + paramtype = "light", + + tiles = { + { + name = "main_water_source_animated.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 2.0, + }, + }, + }, + alpha = 180, + post_effect_color = {a = 50, r = 0, g = 50, b = 200}, + + --Behavior + walkable = false, + pointable = false, + buildable_to = true, + diggable = false, + is_ground_content = false, + + --Properties + liquid_range = 14, + liquid_viscosity = 0.1, + drowning = 1, + waving = 1, + liquidtype = "source", + liquid_alternative_flowing = "main:water_flowing", + liquid_alternative_source = "main:water_source", + groups = {liquid = 3, water = 1}, +}) + +minetest.register_node("main:water_flowing", { + description = "Flowing Water", + drawtype = "flowingliquid", + paramtype = "light", + + tiles = { + { + name = "main_water_flowing_animated.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 2.0, + }, + }, + }, + + special_tiles = { + { + name = "main_water_flowing_animated.png", + animation = {type = "vertical_frames", aspect_w = 16, + aspect_h = 16, length = 2.0}, + backface_culling = true, + }, + + { + name = "main_water_flowing_animated.png", + animation = {type = "vertical_frames", aspect_w = 16, + aspect_h = 16, length = 2.0}, + backface_culling = false, + } + }, + + alpha = 180, + post_effect_color = {a = 50, r = 0, g = 50, b = 200}, + + --Behavior + walkable = false, + pointable = false, + buildable_to = true, + diggable = false, + is_ground_content = false, + + --Properties + liquid_range = 14, + liquid_viscosity = 0.1, + drowning = 1, + waving = 1, + liquidtype = "flowing", + liquid_alternative_flowing = "main:water_flowing", + liquid_alternative_source = "main:water_source", + groups = {liquid = 3, water = 1}, +}) + + +stairs.register_stair_and_slab( + "planks_oak", + "main:planks_oak", + {choppy = 2}, + {"main_planks_oak.png"}, + "Oak Plank Stair", + "Oak Plank Slab", + default.node_sound_wood_defaults(), + true +) + +stairs.register_stair_and_slab( + "log_oak", + "main:log_oak", + {choppy = 2}, + {"main_log_oak.png"}, + "Oak Log Stair", + "Oak Log Slab", + default.node_sound_wood_defaults(), + true +) \ No newline at end of file diff --git a/mods/main/recipes.lua b/mods/main/recipes.lua new file mode 100644 index 0000000..81f86cd --- /dev/null +++ b/mods/main/recipes.lua @@ -0,0 +1,133 @@ +----------------------- +----------------------- +---- RECIPES ---- +----------------------- +----------------------- + + + +-------------------------- +-- Sticks, Planks, etc. -- +-------------------------- + +minetest.register_craft({ + output = "main:planks_oak 4", + recipe = + { + {"", "", ""}, + {"", "group:logs", ""}, + {"", "", ""} + } +}) + +minetest.register_craft({ + output = "main:stick 12", + recipe = { + {"", "", ""}, + {"", "main:planks_oak", ""}, + {"", "", ""} + } +}) + +------------ +-- Bricks -- +------------ +minetest.register_craft({ + output = "main:bricks_stone 4", + recipe = + { + {"", "", ""}, + {"", "main:stone", "main:stone"}, + {"", "main:stone", "main:stone"} + } +}) + +minetest.register_craft({ + output = "main:bricks_cobble 4", + recipe = + { + {"", "", ""}, + {"", "main:cobble", "main:cobble"}, + {"", "main:cobble", "main:cobble"} + } +}) + + +------------------------ +-- Simple Stone Tools -- +------------------------ +minetest.register_craft({ + output = "main:pickaxe_stone_simple", + recipe = { + {"main:rock", "main:rock", "main:rock"}, + {"main:rock", "main:stick", "main:rock"}, + {"", "main:stick", ""} + } +}) + +minetest.register_craft({ + output = "main:axe_stone_simple", + recipe = { + {"main:rock", "main:rock", "main:rock"}, + {"main:rock", "main:stick", ""}, + {"", "main:stick", ""} + } +}) + +minetest.register_craft({ + output = "main:knife_stone_simple", + recipe = { + {"", "", ""}, + {"", "main:rock", ""}, + {"", "main:stick", ""} + } +}) + + +------------------------- +-- Refined Stone Tools -- +------------------------- + +minetest.register_craft({ + output = "main:pickaxe_stone_refined", + recipe = { + {"", "", ""}, + {"", "main:pickaxe_stone_refined", ""}, + {"", "main:rope", ""} + } +}) + + + +----------------- +-- Steel Tools -- +----------------- + +minetest.register_craft({ + output = "main:pickaxe_steel", + recipe = { + {"main:steel_ingot", "main:steel_ingot", "main:steel_ingot"}, + {"main:steel_ingot", "main:stick", "main:steel_ingot"}, + {"", "main:stick", ""} + } +}) + +minetest.register_craft({ + output = "main:axe_steel", + recipe = { + {"main:steel_ingot", "main:steel_ingot", "main:steel_ingot"}, + {"main:steel_ingot", "main:stick", ""}, + {"", "main:stick", ""} + } +}) + +minetest.register_craft({ + output = "main:knife_steel", + recipe = { + {"", "", ""}, + {"", "main:steel_ingot", ""}, + {"", "main:stick", ""} + } +}) + +--TO DO: Add Tier 2 / High Tier tools such as chainsaws, pneumatic drills, etc. \ No newline at end of file diff --git a/mods/main/schematics/main_rock_cobble_small.mts b/mods/main/schematics/main_rock_cobble_small.mts new file mode 100644 index 0000000..0044421 Binary files /dev/null and b/mods/main/schematics/main_rock_cobble_small.mts differ diff --git a/mods/main/schematics/main_rock_small.mts b/mods/main/schematics/main_rock_small.mts new file mode 100644 index 0000000..0044421 Binary files /dev/null and b/mods/main/schematics/main_rock_small.mts differ diff --git a/mods/main/schematics/main_tree_apple.mts b/mods/main/schematics/main_tree_apple.mts new file mode 100644 index 0000000..5f96503 Binary files /dev/null and b/mods/main/schematics/main_tree_apple.mts differ diff --git a/mods/main/schematics/main_tree_oak.mts b/mods/main/schematics/main_tree_oak.mts new file mode 100644 index 0000000..66c213f Binary files /dev/null and b/mods/main/schematics/main_tree_oak.mts differ diff --git a/mods/main/schematics/main_tree_oak_tall.mts b/mods/main/schematics/main_tree_oak_tall.mts new file mode 100644 index 0000000..4146aa4 Binary files /dev/null and b/mods/main/schematics/main_tree_oak_tall.mts differ diff --git a/mods/main/schematics/main_tree_oak_tall_dead.mts b/mods/main/schematics/main_tree_oak_tall_dead.mts new file mode 100644 index 0000000..168b292 Binary files /dev/null and b/mods/main/schematics/main_tree_oak_tall_dead.mts differ diff --git a/mods/main/textures/bubble.png b/mods/main/textures/bubble.png new file mode 100644 index 0000000..f45f3f7 Binary files /dev/null and b/mods/main/textures/bubble.png differ diff --git a/mods/main/textures/character.png b/mods/main/textures/character.png new file mode 100644 index 0000000..f853d49 Binary files /dev/null and b/mods/main/textures/character.png differ diff --git a/mods/main/textures/character_female.png b/mods/main/textures/character_female.png new file mode 100644 index 0000000..941c92f Binary files /dev/null and b/mods/main/textures/character_female.png differ diff --git a/mods/main/textures/crack_anylength.png b/mods/main/textures/crack_anylength.png new file mode 100644 index 0000000..ab8d5b3 Binary files /dev/null and b/mods/main/textures/crack_anylength.png differ diff --git a/mods/main/textures/gui_hotbar.png b/mods/main/textures/gui_hotbar.png new file mode 100644 index 0000000..eb95bcd Binary files /dev/null and b/mods/main/textures/gui_hotbar.png differ diff --git a/mods/main/textures/gui_hotbar_selected.png b/mods/main/textures/gui_hotbar_selected.png new file mode 100644 index 0000000..3461dbe Binary files /dev/null and b/mods/main/textures/gui_hotbar_selected.png differ diff --git a/mods/main/textures/hand.png b/mods/main/textures/hand.png new file mode 100644 index 0000000..e40bc73 Binary files /dev/null and b/mods/main/textures/hand.png differ diff --git a/mods/main/textures/heart.png b/mods/main/textures/heart.png new file mode 100644 index 0000000..6d4e228 Binary files /dev/null and b/mods/main/textures/heart.png differ diff --git a/mods/main/textures/leaves_grey.png b/mods/main/textures/leaves_grey.png new file mode 100644 index 0000000..5055ca5 Binary files /dev/null and b/mods/main/textures/leaves_grey.png differ diff --git a/mods/main/textures/main_apple_red.png b/mods/main/textures/main_apple_red.png new file mode 100644 index 0000000..7c13886 Binary files /dev/null and b/mods/main/textures/main_apple_red.png differ diff --git a/mods/main/textures/main_berry_straw.png b/mods/main/textures/main_berry_straw.png new file mode 100644 index 0000000..de31c97 Binary files /dev/null and b/mods/main/textures/main_berry_straw.png differ diff --git a/mods/main/textures/main_block_brass.png b/mods/main/textures/main_block_brass.png new file mode 100644 index 0000000..f1812d1 Binary files /dev/null and b/mods/main/textures/main_block_brass.png differ diff --git a/mods/main/textures/main_block_copper.png b/mods/main/textures/main_block_copper.png new file mode 100644 index 0000000..ed6e99b Binary files /dev/null and b/mods/main/textures/main_block_copper.png differ diff --git a/mods/main/textures/main_block_gold.png b/mods/main/textures/main_block_gold.png new file mode 100644 index 0000000..ca5853b Binary files /dev/null and b/mods/main/textures/main_block_gold.png differ diff --git a/mods/main/textures/main_block_iron.png b/mods/main/textures/main_block_iron.png new file mode 100644 index 0000000..e3e6e84 Binary files /dev/null and b/mods/main/textures/main_block_iron.png differ diff --git a/mods/main/textures/main_bricks_cobble.png b/mods/main/textures/main_bricks_cobble.png new file mode 100644 index 0000000..96c4371 Binary files /dev/null and b/mods/main/textures/main_bricks_cobble.png differ diff --git a/mods/main/textures/main_bricks_red.png b/mods/main/textures/main_bricks_red.png new file mode 100644 index 0000000..2e92737 Binary files /dev/null and b/mods/main/textures/main_bricks_red.png differ diff --git a/mods/main/textures/main_bricks_stone.png b/mods/main/textures/main_bricks_stone.png new file mode 100644 index 0000000..1016eae Binary files /dev/null and b/mods/main/textures/main_bricks_stone.png differ diff --git a/mods/main/textures/main_cinnabar_ore.png b/mods/main/textures/main_cinnabar_ore.png new file mode 100644 index 0000000..40ab283 Binary files /dev/null and b/mods/main/textures/main_cinnabar_ore.png differ diff --git a/mods/main/textures/main_coal_ore.png b/mods/main/textures/main_coal_ore.png new file mode 100644 index 0000000..f421841 Binary files /dev/null and b/mods/main/textures/main_coal_ore.png differ diff --git a/mods/main/textures/main_cobble.png b/mods/main/textures/main_cobble.png new file mode 100644 index 0000000..0faee33 Binary files /dev/null and b/mods/main/textures/main_cobble.png differ diff --git a/mods/main/textures/main_copper_ore.png b/mods/main/textures/main_copper_ore.png new file mode 100644 index 0000000..2bcaee9 Binary files /dev/null and b/mods/main/textures/main_copper_ore.png differ diff --git a/mods/main/textures/main_diamond_ore.png b/mods/main/textures/main_diamond_ore.png new file mode 100644 index 0000000..5dba111 Binary files /dev/null and b/mods/main/textures/main_diamond_ore.png differ diff --git a/mods/main/textures/main_diamond_ore_lowdensity.png b/mods/main/textures/main_diamond_ore_lowdensity.png new file mode 100644 index 0000000..e7b8b27 Binary files /dev/null and b/mods/main/textures/main_diamond_ore_lowdensity.png differ diff --git a/mods/main/textures/main_dirt.png b/mods/main/textures/main_dirt.png new file mode 100644 index 0000000..205551e Binary files /dev/null and b/mods/main/textures/main_dirt.png differ diff --git a/mods/main/textures/main_dirt_frozen.png b/mods/main/textures/main_dirt_frozen.png new file mode 100644 index 0000000..e5401c3 Binary files /dev/null and b/mods/main/textures/main_dirt_frozen.png differ diff --git a/mods/main/textures/main_glass.png b/mods/main/textures/main_glass.png new file mode 100644 index 0000000..deeaec4 Binary files /dev/null and b/mods/main/textures/main_glass.png differ diff --git a/mods/main/textures/main_glass_frame.png b/mods/main/textures/main_glass_frame.png new file mode 100644 index 0000000..c7d0a96 Binary files /dev/null and b/mods/main/textures/main_glass_frame.png differ diff --git a/mods/main/textures/main_grass.png b/mods/main/textures/main_grass.png new file mode 100644 index 0000000..460973a Binary files /dev/null and b/mods/main/textures/main_grass.png differ diff --git a/mods/main/textures/main_grass_side.png b/mods/main/textures/main_grass_side.png new file mode 100644 index 0000000..453c64d Binary files /dev/null and b/mods/main/textures/main_grass_side.png differ diff --git a/mods/main/textures/main_ice_thick.png b/mods/main/textures/main_ice_thick.png new file mode 100644 index 0000000..f2db28c Binary files /dev/null and b/mods/main/textures/main_ice_thick.png differ diff --git a/mods/main/textures/main_ice_thin.png b/mods/main/textures/main_ice_thin.png new file mode 100644 index 0000000..e6b9fec Binary files /dev/null and b/mods/main/textures/main_ice_thin.png differ diff --git a/mods/main/textures/main_iron_ore.png b/mods/main/textures/main_iron_ore.png new file mode 100644 index 0000000..7679ced Binary files /dev/null and b/mods/main/textures/main_iron_ore.png differ diff --git a/mods/main/textures/main_knife_stone_simple.png b/mods/main/textures/main_knife_stone_simple.png new file mode 100644 index 0000000..d485d4d Binary files /dev/null and b/mods/main/textures/main_knife_stone_simple.png differ diff --git a/mods/main/textures/main_leaves_apple.png b/mods/main/textures/main_leaves_apple.png new file mode 100644 index 0000000..24452ea Binary files /dev/null and b/mods/main/textures/main_leaves_apple.png differ diff --git a/mods/main/textures/main_leaves_oak.png b/mods/main/textures/main_leaves_oak.png new file mode 100644 index 0000000..fbc24ca Binary files /dev/null and b/mods/main/textures/main_leaves_oak.png differ diff --git a/mods/main/textures/main_log_apple.png b/mods/main/textures/main_log_apple.png new file mode 100644 index 0000000..750557e Binary files /dev/null and b/mods/main/textures/main_log_apple.png differ diff --git a/mods/main/textures/main_log_birch.png b/mods/main/textures/main_log_birch.png new file mode 100644 index 0000000..db3f20a Binary files /dev/null and b/mods/main/textures/main_log_birch.png differ diff --git a/mods/main/textures/main_log_maple.png b/mods/main/textures/main_log_maple.png new file mode 100644 index 0000000..f6c6f9d Binary files /dev/null and b/mods/main/textures/main_log_maple.png differ diff --git a/mods/main/textures/main_log_oak.png b/mods/main/textures/main_log_oak.png new file mode 100644 index 0000000..3202fcc Binary files /dev/null and b/mods/main/textures/main_log_oak.png differ diff --git a/mods/main/textures/main_lump_coal.png b/mods/main/textures/main_lump_coal.png new file mode 100644 index 0000000..edeb8cf Binary files /dev/null and b/mods/main/textures/main_lump_coal.png differ diff --git a/mods/main/textures/main_lump_copper.png b/mods/main/textures/main_lump_copper.png new file mode 100644 index 0000000..33804e0 Binary files /dev/null and b/mods/main/textures/main_lump_copper.png differ diff --git a/mods/main/textures/main_lump_iron.png b/mods/main/textures/main_lump_iron.png new file mode 100644 index 0000000..3852784 Binary files /dev/null and b/mods/main/textures/main_lump_iron.png differ diff --git a/mods/main/textures/main_lump_sulfur.png b/mods/main/textures/main_lump_sulfur.png new file mode 100644 index 0000000..b9de75d Binary files /dev/null and b/mods/main/textures/main_lump_sulfur.png differ diff --git a/mods/main/textures/main_muddywater.png b/mods/main/textures/main_muddywater.png new file mode 100644 index 0000000..c741a0d Binary files /dev/null and b/mods/main/textures/main_muddywater.png differ diff --git a/mods/main/textures/main_orange.png b/mods/main/textures/main_orange.png new file mode 100644 index 0000000..466269e Binary files /dev/null and b/mods/main/textures/main_orange.png differ diff --git a/mods/main/textures/main_pickaxe_steel.png b/mods/main/textures/main_pickaxe_steel.png new file mode 100644 index 0000000..adf8fae Binary files /dev/null and b/mods/main/textures/main_pickaxe_steel.png differ diff --git a/mods/main/textures/main_pickaxe_stone.png b/mods/main/textures/main_pickaxe_stone.png new file mode 100644 index 0000000..5f0f925 Binary files /dev/null and b/mods/main/textures/main_pickaxe_stone.png differ diff --git a/mods/main/textures/main_planks_oak.png b/mods/main/textures/main_planks_oak.png new file mode 100644 index 0000000..dfb3ade Binary files /dev/null and b/mods/main/textures/main_planks_oak.png differ diff --git a/mods/main/textures/main_rope.png b/mods/main/textures/main_rope.png new file mode 100644 index 0000000..93395f4 Binary files /dev/null and b/mods/main/textures/main_rope.png differ diff --git a/mods/main/textures/main_salt_crystals.png b/mods/main/textures/main_salt_crystals.png new file mode 100644 index 0000000..8988cd2 Binary files /dev/null and b/mods/main/textures/main_salt_crystals.png differ diff --git a/mods/main/textures/main_salt_ore.png b/mods/main/textures/main_salt_ore.png new file mode 100644 index 0000000..6396a03 Binary files /dev/null and b/mods/main/textures/main_salt_ore.png differ diff --git a/mods/main/textures/main_sand.png b/mods/main/textures/main_sand.png new file mode 100644 index 0000000..5afda34 Binary files /dev/null and b/mods/main/textures/main_sand.png differ diff --git a/mods/main/textures/main_sandstone.png b/mods/main/textures/main_sandstone.png new file mode 100644 index 0000000..02064ed Binary files /dev/null and b/mods/main/textures/main_sandstone.png differ diff --git a/mods/main/textures/main_shelf_empty.png b/mods/main/textures/main_shelf_empty.png new file mode 100644 index 0000000..2d5d41e Binary files /dev/null and b/mods/main/textures/main_shelf_empty.png differ diff --git a/mods/main/textures/main_snow.png b/mods/main/textures/main_snow.png new file mode 100644 index 0000000..8a0602a Binary files /dev/null and b/mods/main/textures/main_snow.png differ diff --git a/mods/main/textures/main_stick.png b/mods/main/textures/main_stick.png new file mode 100644 index 0000000..218166f Binary files /dev/null and b/mods/main/textures/main_stick.png differ diff --git a/mods/main/textures/main_stone.png b/mods/main/textures/main_stone.png new file mode 100644 index 0000000..87d8eab Binary files /dev/null and b/mods/main/textures/main_stone.png differ diff --git a/mods/main/textures/main_sulfur_ore.png b/mods/main/textures/main_sulfur_ore.png new file mode 100644 index 0000000..b316a89 Binary files /dev/null and b/mods/main/textures/main_sulfur_ore.png differ diff --git a/mods/main/textures/main_swamp_grass.png b/mods/main/textures/main_swamp_grass.png new file mode 100644 index 0000000..c72e9e6 Binary files /dev/null and b/mods/main/textures/main_swamp_grass.png differ diff --git a/mods/main/textures/main_swamp_grass_side.png b/mods/main/textures/main_swamp_grass_side.png new file mode 100644 index 0000000..369913d Binary files /dev/null and b/mods/main/textures/main_swamp_grass_side.png differ diff --git a/mods/main/textures/main_toxicwater.png b/mods/main/textures/main_toxicwater.png new file mode 100644 index 0000000..883ab87 Binary files /dev/null and b/mods/main/textures/main_toxicwater.png differ diff --git a/mods/main/textures/main_toxicwater_animated.png b/mods/main/textures/main_toxicwater_animated.png new file mode 100644 index 0000000..f755ddf Binary files /dev/null and b/mods/main/textures/main_toxicwater_animated.png differ diff --git a/mods/main/textures/main_twig.png b/mods/main/textures/main_twig.png new file mode 100644 index 0000000..a9575a1 Binary files /dev/null and b/mods/main/textures/main_twig.png differ diff --git a/mods/main/textures/main_water.png b/mods/main/textures/main_water.png new file mode 100644 index 0000000..300b8a2 Binary files /dev/null and b/mods/main/textures/main_water.png differ diff --git a/mods/main/textures/main_water_flowing_animated.png b/mods/main/textures/main_water_flowing_animated.png new file mode 100644 index 0000000..f1c52f5 Binary files /dev/null and b/mods/main/textures/main_water_flowing_animated.png differ diff --git a/mods/main/textures/main_water_source_animated.png b/mods/main/textures/main_water_source_animated.png new file mode 100644 index 0000000..f1c52f5 Binary files /dev/null and b/mods/main/textures/main_water_source_animated.png differ diff --git a/mods/main/textures/player.png b/mods/main/textures/player.png new file mode 100644 index 0000000..6b0fac5 Binary files /dev/null and b/mods/main/textures/player.png differ diff --git a/mods/main/textures/player_back.png b/mods/main/textures/player_back.png new file mode 100644 index 0000000..1267458 Binary files /dev/null and b/mods/main/textures/player_back.png differ diff --git a/mods/main/tools.lua b/mods/main/tools.lua new file mode 100644 index 0000000..384db70 --- /dev/null +++ b/mods/main/tools.lua @@ -0,0 +1,69 @@ +minetest.register_item(":", { + type = "none", + wield_image = "hand.png", + wield_scale = {x=1.5,y=2,z=4.5}, + tool_capabilities = { + max_drop_level = 0, + full_punch_interval = 0.4, + + groupcaps = + { + oddly_breakable_by_hand = {times={[1]=3.50,[2]=2.00,[3]=0.70}, uses=0}, + snappy = {times={[3]=1.00}, uses=0, maxlevel=1}, + crumbly = {times={[2]=4.50, [3]=1.80}, uses=0, maxlevel=1}, + }, + damage_groups = {fleshy = 3, snappy = 2}, + } +}) + +minetest.register_item("main:pickaxe_steel", { + type = "none", + wield_image = "main_pickaxe_steel.png", + inventory_image = "main_pickaxe_steel.png", + tool_capabilities = { + max_drop_level = 1, + full_punch_interval = 0.8, + + groupcaps = + { + choppy = {times={[1]=0, [2]=0,[3]=0}, uses=0, maxlevel=8}, + cracky = {times={[1]=0, [2]=0,[3]=0}, uses=0, maxlevel=8}, + crumbly = {times={[1]=0, [2]=0, [3]=0}, uses=0, maxlevel=8}, + }, + } +}) + +minetest.register_item("main:pickaxe_stone", { + type = "none", + wield_image = "main_pickaxe_stone.png", + inventory_image = "main_pickaxe_stone.png", + tool_capabilities = { + max_drop_level = 1, + full_punch_interval = 0.8, + + groupcaps = + { + cracky = {times={[1]=3.80, [2]=2.00,[3]=1.50}, uses=0, maxlevel=1}, + crumbly = {times={[2]=3.50, [3]=1.80}, uses=0, maxlevel=1}, + }, + damage_groups = {fleshy = 4, cracky = 5}, + } +}) + +minetest.register_item("main:knife_stone_simple", { + type = "none", + wield_image = "main_knife_stone_simple.png", + inventory_image = "main_knife_stone_simple.png", + tool_capabilities = + { + max_drop_level = 1, + full_punch_interval = 0.8, + + groupcaps = + { + choppy = {times={[2]=2.00,[3]=1.50}, uses=0, maxlevel=1}, + crumbly = {times={[2]=3.50, [3]=1.80}, uses=0, maxlevel=1}, + }, + damage_groups = {fleshy = 7, choppy = 5}, + } +}) diff --git a/mods/mobs_redo/.luacheckrc b/mods/mobs_redo/.luacheckrc new file mode 100644 index 0000000..22f803f --- /dev/null +++ b/mods/mobs_redo/.luacheckrc @@ -0,0 +1,26 @@ +unused_args = false + +read_globals = { + "minetest", + "lucky_block", + "intllib", + "vector", + "table", + "invisibility", + "cmi", + "toolranks", + "pathfinder", + "tnt", + "ItemStack" +} + +globals = { + "mobs", + "player_api", + "default" +} + +ignore = { + "431", -- Shadowing an upvalue + "432", -- Shadowing an upvalue argument +} diff --git a/mods/mobs_redo/api.lua b/mods/mobs_redo/api.lua new file mode 100644 index 0000000..6ff43be --- /dev/null +++ b/mods/mobs_redo/api.lua @@ -0,0 +1,4883 @@ +-- Check for translation method +local S +if minetest.get_translator ~= nil then + S = minetest.get_translator("mobs") -- 5.x translation function +else + if minetest.get_modpath("intllib") then + dofile(minetest.get_modpath("intllib") .. "/init.lua") + if intllib.make_gettext_pair then + S = intllib.make_gettext_pair() -- new gettext method + else + S = intllib.Getter() -- old text file method + end + else -- boilerplate function + S = function(str, ...) + local args = {...} + return str:gsub("@%d+", function(match) + return args[tonumber(match:sub(2))] + end) + end + end +end + +-- CMI support check +local use_cmi = minetest.global_exists("cmi") + +mobs = { + mod = "redo", + version = "20221115", + intllib = S, + invis = minetest.global_exists("invisibility") and invisibility or {} +} + +-- localize common functions +local pi = math.pi +local square = math.sqrt +local sin = math.sin +local cos = math.cos +local abs = math.abs +local min = math.min +local max = math.max +local random = math.random +local floor = math.floor +local ceil = math.ceil +local rad = math.rad +local deg = math.deg +local atann = math.atan +local atan = function(x) + if not x or x ~= x then + return 0 -- NaN + else + return atann(x) + end +end +local table_copy = table.copy +local table_remove = table.remove +local vdirection = vector.direction +local vmultiply = vector.multiply +local vsubtract = vector.subtract +local settings = minetest.settings + +-- creative check +local creative_cache = minetest.settings:get_bool("creative_mode") +function mobs.is_creative(name) + return creative_cache or minetest.check_player_privs(name, + {creative = true}) +end + +-- Load settings +local damage_enabled = settings:get_bool("enable_damage") +local mobs_spawn = settings:get_bool("mobs_spawn") ~= false +local peaceful_only = settings:get_bool("only_peaceful_mobs") +local disable_blood = settings:get_bool("mobs_disable_blood") +local mobs_drop_items = settings:get_bool("mobs_drop_items") ~= false +local mobs_griefing = settings:get_bool("mobs_griefing") ~= false +local spawn_protected = settings:get_bool("mobs_spawn_protected") ~= false +local spawn_monster_protected = settings:get_bool("mobs_spawn_monster_protected") ~= false +local remove_far = settings:get_bool("remove_far_mobs") ~= false +local mob_area_spawn = settings:get_bool("mob_area_spawn") +local difficulty = tonumber(settings:get("mob_difficulty")) or 1.0 +local max_per_block = tonumber(settings:get("max_objects_per_block") or 99) +local mob_nospawn_range = tonumber(settings:get("mob_nospawn_range") or 12) +local active_limit = tonumber(settings:get("mob_active_limit") or 0) +local mob_chance_multiplier = tonumber(settings:get("mob_chance_multiplier") or 1) +local peaceful_player_enabled = settings:get_bool("enable_peaceful_player") +local mob_smooth_rotate = settings:get_bool("mob_smooth_rotate") ~= false +local active_mobs = 0 + +-- Peaceful mode message so players will know there are no monsters +if peaceful_only then + minetest.register_on_joinplayer(function(player) + minetest.chat_send_player(player:get_player_name(), + S("** Peaceful Mode Active - No Monsters Will Spawn")) + end) +end + +-- calculate aoc range for mob count +local aoc_range = tonumber(settings:get("active_block_range")) * 16 + +-- pathfinding settings +local enable_pathfinding = true +local stuck_timeout = 3 -- how long before stuck mod starts searching +local stuck_path_timeout = 5 -- how long will mob follow path before giving up + +-- default nodes +--local node_fire = "fire:basic_flame" +--local node_permanent_flame = "fire:permanent_flame" +local node_ice = "default:ice" +local node_snowblock = "default:snowblock" +local node_snow = "default:snow" + +mobs.fallback_node = minetest.registered_aliases["mapgen_dirt"] or "default:dirt" + +mobs.mob_class = { + stepheight = 1.1, + fly_in = "air", + owner = "", + order = "", + jump_height = 4, + lifetimer = 180, -- 3 minutes + physical = true, + collisionbox = {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25}, + visual_size = {x = 1, y = 1}, + texture_mods = "", + makes_footstep_sound = false, + view_range = 5, + walk_velocity = 1, + run_velocity = 2, + light_damage = 0, + light_damage_min = 14, + light_damage_max = 15, + water_damage = 0, + lava_damage = 4, + fire_damage = 4, + air_damage = 0, + suffocation = 2, + fall_damage = 1, + fall_speed = -10, -- must be lower than -2 (default: -10) + drops = {}, + armor = 100, + sounds = {}, + jump = true, + knock_back = true, + walk_chance = 50, + stand_chance = 30, + attack_chance = 5, + passive = false, + blood_amount = 10, + blood_texture = {"mobs_blood1.png", "mobs_blood.png"}, + shoot_offset = 0, + floats = 1, -- floats in water by default + replace_offset = 0, + timer = 0, + env_damage_timer = 0, -- only used when state = "attack" + tamed = false, + pause_timer = 0, + horny = false, + hornytimer = 0, + child = false, + gotten = false, + health = 0, + reach = 3, + htimer = 0, + docile_by_day = false, + time_of_day = 0.5, + fear_height = 0, + runaway_timer = 0, + immune_to = {}, + explosion_timer = 3, + allow_fuse_reset = true, + stop_to_explode = true, + dogshoot_count = 0, + dogshoot_count_max = 5, + dogshoot_count2_max = 5, + group_attack = false, + attack_monsters = false, + attack_animals = false, + attack_players = true, + attack_npcs = true, + facing_fence = false, + _breed_countdown = nil, + _cmi_is_mob = true +} + +local mob_class = mobs.mob_class -- Compatibility +local mob_class_meta = {__index = mob_class} + + +-- play sound +function mob_class:mob_sound(sound) + + if sound then + + -- higher pitch for a child + local pitch = self.child and 1.5 or 1.0 + + -- a little random pitch to be different + pitch = pitch + random(-10, 10) * 0.005 + + minetest.sound_play(sound, { + object = self.object, + gain = 1.0, + max_hear_distance = self.sounds.distance, + pitch = pitch + }, true) + end +end + + +-- attack player/mob +function mob_class:do_attack(player) + + if self.state == "attack" then + return + end + + self.attack = player + self.state = "attack" + + if random(100) < 90 then + self:mob_sound(self.sounds.war_cry) + end +end + + +-- calculate distance +local get_distance = function(a, b) + + if not a or not b then return 50 end -- nil check + + local x, y, z = a.x - b.x, a.y - b.y, a.z - b.z + + return square(x * x + y * y + z * z) +end + + +-- collision function based on jordan4ibanez' open_ai mod +function mob_class:collision() + + local pos = self.object:get_pos() + local x, z = 0, 0 + local width = -self.collisionbox[1] + self.collisionbox[4] + 0.5 + + for _,object in ipairs(minetest.get_objects_inside_radius(pos, width)) do + + if object:is_player() then + + local pos2 = object:get_pos() + local vec = {x = pos.x - pos2.x, z = pos.z - pos2.z} + + x = x + vec.x + z = z + vec.z + end + end + + return({x, z}) +end + + +-- check if string exists in another string or table +local check_for = function(look_for, look_inside) + + if type(look_inside) == "string" and look_inside == look_for then + + return true + + elseif type(look_inside) == "table" then + + for _, str in pairs(look_inside) do + + if str == look_for then + return true + end + + if str and str:find("group:") then + + local group = str:split(":")[2] or "" + + if minetest.get_item_group(look_for, group) ~= 0 then + return true + end + end + end + end + + return false +end + + +-- move mob in facing direction +function mob_class:set_velocity(v) + + -- halt mob if it has been ordered to stay + if self.order == "stand" then + + local vel = self.object:get_velocity() or {y = 0} + + self.object:set_velocity({x = 0, y = vel.y, z = 0}) + + return + end + + local c_x, c_y = 0, 0 + + -- can mob be pushed, if so calculate direction + if self.pushable then + c_x, c_y = unpack(self:collision()) + end + + local yaw = (self.object:get_yaw() or 0) + (self.rotate or 0) + + -- nil check for velocity + v = v or 0.01 + + -- check if standing in liquid with max viscosity of 7 + local visc = min(minetest.registered_nodes[self.standing_in].liquid_viscosity, 7) + + -- only slow mob trying to move while inside a viscous fluid that + -- they aren't meant to be in (fish in water, spiders in cobweb etc) + if v > 0 and visc and visc > 0 + and not check_for(self.standing_in, self.fly_in) then + v = v / (visc + 1) + end + + -- set velocity + local vel = self.object:get_velocity() or 0 + + local new_vel = { + x = (sin(yaw) * -v) + c_x, + y = vel.y, + z = (cos(yaw) * v) + c_y} + + self.object:set_velocity(new_vel) +end + +-- global version of above function +function mobs:set_velocity(entity, v) + mob_class.set_velocity(entity, v) +end + + +-- calculate mob velocity +function mob_class:get_velocity() + + local v = self.object:get_velocity() + + if not v then return 0 end + + return (v.x * v.x + v.z * v.z) ^ 0.5 +end + + +-- set and return valid yaw +function mob_class:set_yaw(yaw, delay) + + if not yaw or yaw ~= yaw then + yaw = 0 + end + + -- clamp our yaw to a 360 range + if deg(self.object:get_yaw()) > 360 then + + yaw = rad(10) ; delay = 0 + + elseif deg(self.object:get_yaw()) < 0 then + + yaw = rad(350) ; delay = 0 + end + + delay = mob_smooth_rotate and (delay or 0) or 0 + + if delay == 0 then + + self.object:set_yaw(yaw) + + return yaw + end + + self.target_yaw = yaw + self.delay = delay + + return self.target_yaw +end + +-- global function to set mob yaw +function mobs:yaw(entity, yaw, delay) + mob_class.set_yaw(entity, yaw, delay) +end + + +-- set defined animation +function mob_class:set_animation(anim, force) + + if not self.animation or not anim then return end + + self.animation.current = self.animation.current or "" + + -- only use different animation for attacks when using same set + if force ~= true and anim ~= "punch" and anim ~= "shoot" + and string.find(self.animation.current, anim) then + return + end + + local num = 0 + + -- check for more than one animation (max 4) + for n = 1, 4 do + + if self.animation[anim .. n .. "_start"] + and self.animation[anim .. n .. "_end"] then + num = n + end + end + + -- choose random animation from set + if num > 0 then + num = random(0, num) + anim = anim .. (num ~= 0 and num or "") + end + + if anim == self.animation.current + or not self.animation[anim .. "_start"] + or not self.animation[anim .. "_end"] then + return + end + + self.animation.current = anim + + self.object:set_animation({ + x = self.animation[anim .. "_start"], + y = self.animation[anim .. "_end"]}, + self.animation[anim .. "_speed"] or self.animation.speed_normal or 15, + 0, self.animation[anim .. "_loop"] ~= false) +end + +function mobs:set_animation(entity, anim) + entity.set_animation(entity, anim) +end + + +-- check line of sight (BrunoMine) +local line_of_sight = function(self, pos1, pos2, stepsize) + + stepsize = stepsize or 1 + + local s = minetest.line_of_sight(pos1, pos2, stepsize) + + -- normal walking and flying mobs can see you through air + if s == true then + return true + end + + -- New pos1 to be analyzed + local npos1 = {x = pos1.x, y = pos1.y, z = pos1.z} + + local r, pos = minetest.line_of_sight(npos1, pos2, stepsize) + + -- Checks the return + if r == true then return true end + + -- Nodename found + local nn = minetest.get_node(pos).name + + -- Target Distance (td) to travel + local td = get_distance(pos1, pos2) + + -- Actual Distance (ad) traveled + local ad = 0 + + -- It continues to advance in the line of sight in search of a real + -- obstruction which counts as 'walkable' nodebox. + while minetest.registered_nodes[nn] + and minetest.registered_nodes[nn].walkable == false do + + -- Check if you can still move forward + if td < ad + stepsize then + return true -- Reached the target + end + + -- Moves the analyzed pos + local d = get_distance(pos1, pos2) + + npos1.x = ((pos2.x - pos1.x) / d * stepsize) + pos1.x + npos1.y = ((pos2.y - pos1.y) / d * stepsize) + pos1.y + npos1.z = ((pos2.z - pos1.z) / d * stepsize) + pos1.z + + -- NaN checks + if d == 0 + or npos1.x ~= npos1.x + or npos1.y ~= npos1.y + or npos1.z ~= npos1.z then + return false + end + + ad = ad + stepsize + + -- scan again + r, pos = minetest.line_of_sight(npos1, pos2, stepsize) + + if r == true then return true end + + -- New Nodename found + nn = minetest.get_node(pos).name + end + + return false +end + + +-- check line of sight using raycasting (thanks Astrobe) +local ray_line_of_sight = function(self, pos1, pos2) + + local ray = minetest.raycast(pos1, pos2, true, false) + local thing = ray:next() + + while thing do -- thing.type, thing.ref + + if thing.type == "node" then + + local name = minetest.get_node(thing.under).name + + if minetest.registered_items[name] + and minetest.registered_items[name].walkable then + return false + end + end + + thing = ray:next() + end + + return true +end + + +function mob_class:line_of_sight(pos1, pos2, stepsize) + + if minetest.raycast then -- only use if minetest 5.0 is detected + return ray_line_of_sight(self, pos1, pos2) + end + + return line_of_sight(self, pos1, pos2, stepsize) +end + +-- global function +function mobs:line_of_sight(entity, pos1, pos2, stepsize) + return entity:line_of_sight(pos1, pos2, stepsize) +end + + +function mob_class:attempt_flight_correction(override) + + if self:flight_check() and override ~= true then return true end + + -- We are not flying in what we are supposed to. + -- See if we can find intended flight medium and return to it + local pos = self.object:get_pos() ; if not pos then return true end + local searchnodes = self.fly_in + + if type(searchnodes) == "string" then + searchnodes = {self.fly_in} + end + + local flyable_nodes = minetest.find_nodes_in_area( + {x = pos.x - 1, y = pos.y - 1, z = pos.z - 1}, + {x = pos.x + 1, y = pos.y + 0, z = pos.z + 1}, searchnodes) + -- pos.y + 0 hopefully fixes floating swimmers + + if #flyable_nodes < 1 then + return false + end + + local escape_target = flyable_nodes[random(#flyable_nodes)] + local escape_direction = vdirection(pos, escape_target) + + self.object:set_velocity(vmultiply(escape_direction, 1)) + + return true +end + + +-- are we flying in what we are suppose to? (taikedz) +function mob_class:flight_check() + + local def = minetest.registered_nodes[self.standing_in] + + if not def then return false end + + -- are we standing inside what we should be to fly/swim ? + if check_for(self.standing_in, self.fly_in) then + return true + end + + -- stops mobs getting stuck inside stairs and plantlike nodes + if def.drawtype ~= "airlike" + and def.drawtype ~= "liquid" + and def.drawtype ~= "flowingliquid" then + return true + end + + return false +end + + +-- turn mob to face position +local yaw_to_pos = function(self, target, rot) + + rot = rot or 0 + + local pos = self.object:get_pos() + local vec = {x = target.x - pos.x, z = target.z - pos.z} + local yaw = (atan(vec.z / vec.x) + rot + pi / 2) - self.rotate + + if target.x > pos.x then + yaw = yaw + pi + end + + yaw = self:set_yaw(yaw, rot) + + return yaw +end + +function mobs:yaw_to_pos(self, target, rot) + return yaw_to_pos(self, target, rot) +end + + +-- if stay near set then periodically check for nodes and turn towards them +function mob_class:do_stay_near() + + if not self.stay_near then return false end + + local pos = self.object:get_pos() + local searchnodes = self.stay_near[1] + local chance = self.stay_near[2] or 10 + + if not pos or random(chance) > 1 then + return false + end + + if type(searchnodes) == "string" then + searchnodes = {self.stay_near[1]} + end + + local r = self.view_range + local nearby_nodes = minetest.find_nodes_in_area( + {x = pos.x - r, y = pos.y - 1, z = pos.z - r}, + {x = pos.x + r, y = pos.y + 1, z = pos.z + r}, searchnodes) + + if #nearby_nodes < 1 then + return false + end + + yaw_to_pos(self, nearby_nodes[random(#nearby_nodes)]) + + self:set_animation("walk") + + self:set_velocity(self.walk_velocity) + + return true +end + + +-- custom particle effects +local effect = function(pos, amount, texture, min_size, max_size, + radius, gravity, glow, fall) + + radius = radius or 2 + min_size = min_size or 0.5 + max_size = max_size or 1 + gravity = gravity or -10 + glow = glow or 0 + + if fall == true then + fall = 0 + elseif fall == false then + fall = radius + else + fall = -radius + end + + minetest.add_particlespawner({ + amount = amount, + time = 0.25, + minpos = pos, + maxpos = pos, + minvel = {x = -radius, y = fall, z = -radius}, + maxvel = {x = radius, y = radius, z = radius}, + minacc = {x = 0, y = gravity, z = 0}, + maxacc = {x = 0, y = gravity, z = 0}, + minexptime = 0.1, + maxexptime = 1, + minsize = min_size, + maxsize = max_size, + texture = texture, + glow = glow + }) +end + +function mobs:effect(pos, amount, texture, min_size, max_size, + radius, gravity, glow, fall) + + effect(pos, amount, texture, min_size, max_size, radius, gravity, glow, fall) +end + + +-- Thanks Wuzzy for the following editable settings + +local HORNY_TIME = 30 +local HORNY_AGAIN_TIME = 60 * 5 -- 5 minutes +local CHILD_GROW_TIME = 60 * 20 -- 20 minutes + + +-- update nametag and infotext +function mob_class:update_tag() + + local col = "#00FF00" + local qua = self.hp_max / 4 + + if self.health <= floor(qua * 3) then + col = "#FFFF00" + end + + if self.health <= floor(qua * 2) then + col = "#FF6600" + end + + if self.health <= floor(qua) then + col = "#FF0000" + end + + local text = "" + + if self.horny == true then + + text = "\nLoving: " .. (self.hornytimer - (HORNY_TIME + HORNY_AGAIN_TIME)) + + elseif self.child == true then + + text = "\nGrowing: " .. (self.hornytimer - CHILD_GROW_TIME) + + elseif self._breed_countdown then + + text = "\nBreeding: " .. self._breed_countdown + + end + + if self.protected then + if self.protected == 2 then + text = text .. "\nProtection: Level 2" + else + text = text .. "\nProtection: Level 1" + end + end + + self.infotext = "Health: " .. self.health .. " / " .. self.hp_max + .. (self.owner == "" and "" or "\nOwner: " .. self.owner) + .. text + + -- set changes + self.object:set_properties({ + nametag = self.nametag, + nametag_color = col, + infotext = self.infotext + }) +end + + +-- drop items +function mob_class:item_drop() + + -- no drops if disabled by setting or mob is child + if not mobs_drop_items or self.child then return end + + local pos = self.object:get_pos() + + -- check for drops function + self.drops = type(self.drops) == "function" and self.drops(pos) or self.drops + + -- check for nil or no drops + if not self.drops or #self.drops == 0 then + return + end + + -- was mob killed by player? + local death_by_player = self.cause_of_death + and self.cause_of_death.puncher + and self.cause_of_death.puncher:is_player() + + -- check for tool 'looting_level' under tool_capabilities as default, or use + -- meta string 'looting_level' if found (max looting level is 3). + local looting = 0 + + if death_by_player then + + local wield_stack = self.cause_of_death.puncher:get_wielded_item() + local wield_name = wield_stack:get_name() + local wield_stack_meta = wield_stack:get_meta() + local item_def = minetest.registered_items[wield_name] + local item_looting = item_def and item_def.tool_capabilities and + item_def.tool_capabilities.looting_level or 0 + + looting = tonumber(wield_stack_meta:get_string("looting_level")) or item_looting + looting = min(looting, 3) + end + +--print("--- looting level", looting) + + local obj, item, num + + for n = 1, #self.drops do + + if random(self.drops[n].chance) == 1 then + + num = random(self.drops[n].min or 0, self.drops[n].max or 1) + item = self.drops[n].name + + -- cook items on a hot death + if self.cause_of_death.hot then + + local output = minetest.get_craft_result({ + method = "cooking", width = 1, items = {item}}) + + if output and output.item and not output.item:is_empty() then + item = output.item:get_name() + end + end + + -- only drop rare items (drops.min = 0) if killed by player + if death_by_player or self.drops[n].min ~= 0 then + obj = minetest.add_item(pos, ItemStack(item .. " " .. (num + looting))) + end + + if obj and obj:get_luaentity() then + + obj:set_velocity({ + x = random(-10, 10) / 9, + y = 6, + z = random(-10, 10) / 9 + }) + + elseif obj then + obj:remove() -- item does not exist + end + end + end + + self.drops = {} +end + + +-- remove mob and descrease counter +local remove_mob = function(self, decrease) + + self.object:remove() + + if decrease and active_limit > 0 then + + active_mobs = active_mobs - 1 + + if active_mobs < 0 then + active_mobs = 0 + end + end +--print("-- active mobs: " .. active_mobs .. " / " .. active_limit) +end + +-- global function for removing mobs +function mobs:remove(self, decrease) + remove_mob(self, decrease) +end + + +-- check if mob is dead or only hurt +function mob_class:check_for_death(cmi_cause) + + -- We dead already + if self.state == "die" then + return true + end + + -- has health actually changed? + if self.health == self.old_health and self.health > 0 then + return false + end + + local damaged = self.health < self.old_health + + self.old_health = self.health + + -- still got some health? play hurt sound + if self.health > 0 then + + -- only play hurt sound if damaged + if damaged then + self:mob_sound(self.sounds.damage) + end + + -- make sure health isn't higher than max + if self.health > self.hp_max then + self.health = self.hp_max + end + + self:update_tag() + + return false + end + + self.cause_of_death = cmi_cause + + -- drop items + self:item_drop() + + self:mob_sound(self.sounds.death) + + local pos = self.object:get_pos() + + -- execute custom death function + if pos and self.on_die then + + self:on_die(pos) + + if use_cmi then + cmi.notify_die(self.object, cmi_cause) + end + + remove_mob(self, true) + + return true + end + + -- check for custom death function and die animation + if self.animation + and self.animation.die_start + and self.animation.die_end then + + local frames = self.animation.die_end - self.animation.die_start + local speed = self.animation.die_speed or 15 + local length = max((frames / speed), 0) + local rot = self.animation.die_rotate and 5 + + self.attack = nil + self.following = nil + self.v_start = false + self.timer = 0 + self.blinktimer = 0 + self.passive = true + self.state = "die" + self.object:set_properties({ + pointable = false, collide_with_objects = false, + automatic_rotate = rot, static_save = false + }) + self:set_velocity(0) + self:set_animation("die") + + minetest.after(length, function(self) + + if self.object:get_luaentity() then + + if use_cmi then + cmi.notify_die(self.object, cmi_cause) + end + + remove_mob(self, true) + end + end, self) + + return true + + elseif pos then -- otherwise remove mod and show particle effect + + if use_cmi then + cmi.notify_die(self.object, cmi_cause) + end + + remove_mob(self, true) + + effect(pos, 20, "tnt_smoke.png") + end + + return true +end + + +-- get node but use fallback for nil or unknown +local node_ok = function(pos, fallback) + + local node = minetest.get_node_or_nil(pos) + + if node and minetest.registered_nodes[node.name] then + return node + end + + return minetest.registered_nodes[(fallback or mobs.fallback_node)] +end + + +-- Returns true is node can deal damage to self +function mobs:is_node_dangerous(mob_object, nodename) + + if mob_object.water_damage > 0 + and minetest.get_item_group(nodename, "water") ~= 0 then + return true + end + + if mob_object.lava_damage > 0 + and minetest.get_item_group(nodename, "lava") ~= 0 then + return true + end + + if mob_object.fire_damage > 0 + and minetest.get_item_group(nodename, "fire") ~= 0 then + return true + end + + if minetest.registered_nodes[nodename].damage_per_second > 0 then + return true + end + + return false +end + +local function is_node_dangerous(mob_object, nodename) + return mobs:is_node_dangerous(mob_object, nodename) +end + + +-- is mob facing a cliff +function mob_class:is_at_cliff() + + if self.driver or self.fear_height == 0 then -- 0 for no falling protection! + return false + end + + -- get yaw but if nil returned object no longer exists + local yaw = self.object:get_yaw() + + if not yaw then return false end + + local dir_x = -sin(yaw) * (self.collisionbox[4] + 0.5) + local dir_z = cos(yaw) * (self.collisionbox[4] + 0.5) + local pos = self.object:get_pos() + local ypos = pos.y + self.collisionbox[2] -- just above floor + + local free_fall, blocker = minetest.line_of_sight( + {x = pos.x + dir_x, y = ypos, z = pos.z + dir_z}, + {x = pos.x + dir_x, y = ypos - self.fear_height, z = pos.z + dir_z}) + + -- check for straight drop + if free_fall then + return true + end + + local bnode = node_ok(blocker, "air") + + -- will we drop onto dangerous node? + if is_node_dangerous(self, bnode.name) then + return true + end + + local def = minetest.registered_nodes[bnode.name] + + return (not def and def.walkable) +end + + +-- environmental damage (water, lava, fire, light etc.) +function mob_class:do_env_damage() + + self:update_tag() + + local pos = self.object:get_pos() ; if not pos then return end + + self.time_of_day = minetest.get_timeofday() + + -- halt mob if standing inside ignore node + if self.standing_in == "ignore" then + + self.object:set_velocity({x = 0, y = 0, z = 0}) + + return true + end + + -- particle appears at random mob height + local py = { + x = pos.x, + y = pos.y + random(self.collisionbox[2], self.collisionbox[5]), + z = pos.z + } + + local nodef = minetest.registered_nodes[self.standing_in] + + -- water + if self.water_damage ~= 0 and nodef.groups.water then + + self.health = self.health - self.water_damage + + effect(py, 5, "bubble.png", nil, nil, 1, nil) + + if self:check_for_death({type = "environment", + pos = pos, node = self.standing_in}) then + return true + end + + -- lava damage + elseif self.lava_damage ~= 0 and nodef.groups.lava then + + self.health = self.health - self.lava_damage + + effect(py, 15, "fire_basic_flame.png", 1, 5, 1, 0.2, 15, true) + + if self:check_for_death({type = "environment", pos = pos, + node = self.standing_in, hot = true}) then + return true + end + + -- fire damage + elseif self.fire_damage ~= 0 and nodef.groups.fire then + + self.health = self.health - self.fire_damage + + effect(py, 15, "fire_basic_flame.png", 1, 5, 1, 0.2, 15, true) + + if self:check_for_death({type = "environment", pos = pos, + node = self.standing_in, hot = true}) then + return true + end + + -- damage_per_second node check (not fire and lava) + elseif nodef.damage_per_second ~= 0 + and nodef.groups.lava == nil and nodef.groups.fire == nil then + + self.health = self.health - nodef.damage_per_second + + effect(py, 5, "tnt_smoke.png") + + if self:check_for_death({type = "environment", + pos = pos, node = self.standing_in}) then + return true + end + end + + -- air damage + if self.air_damage ~= 0 and self.standing_in == "air" then + + self.health = self.health - self.air_damage + + effect(py, 3, "bubble.png", 1, 1, 1, 0.2) + + if self:check_for_death({type = "environment", + pos = pos, node = self.standing_in}) then + return true + end + end + + -- is mob light sensative, or scared of the dark :P + if self.light_damage ~= 0 then + + local light = minetest.get_node_light(pos) or 0 + + if light >= self.light_damage_min + and light <= self.light_damage_max then + + self.health = self.health - self.light_damage + + effect(py, 5, "tnt_smoke.png") + + if self:check_for_death({type = "light"}) then + return true + end + end + end + + --- suffocation inside solid node + if (self.suffocation and self.suffocation ~= 0) + and (nodef.walkable == nil or nodef.walkable == true) + and (nodef.collision_box == nil or nodef.collision_box.type == "regular") + and (nodef.node_box == nil or nodef.node_box.type == "regular") + and (nodef.groups.disable_suffocation ~= 1) then + + local damage + + if self.suffocation == true then + damage = 2 + else + damage = (self.suffocation or 2) + end + + self.health = self.health - damage + + if self:check_for_death({type = "suffocation", + pos = pos, node = self.standing_in}) then + return true + end + end + + return self:check_for_death({type = "unknown"}) +end + + +-- jump if facing a solid node (not fences or gates) +function mob_class:do_jump() + + if not self.jump + or self.jump_height == 0 + or self.fly + or self.child + or self.order == "stand" then + return false + end + + self.facing_fence = false + + -- something stopping us while moving? + if self.state ~= "stand" + and self:get_velocity() > 0.5 + and self.object:get_velocity().y ~= 0 then + return false + end + + local pos = self.object:get_pos() + local yaw = self.object:get_yaw() + + -- sanity check + if not yaw then return false end + + -- we can only jump if standing on solid node + if minetest.registered_nodes[self.standing_on].walkable == false then + return false + end + + -- where is front + local dir_x = -sin(yaw) * (self.collisionbox[4] + 0.5) + local dir_z = cos(yaw) * (self.collisionbox[4] + 0.5) + + -- set y_pos to base of mob + pos.y = pos.y + self.collisionbox[2] + + -- what is in front of mob and above? + local nod = node_ok({x = pos.x + dir_x, y = pos.y + 0.5, z = pos.z + dir_z}) + local nodt = node_ok({x = pos.x + dir_x, y = pos.y + 1.5, z = pos.z + dir_z}) + local blocked = minetest.registered_nodes[nodt.name].walkable + + -- are we facing a fence or wall + if nod.name:find("fence") or nod.name:find("gate") or nod.name:find("wall") then + self.facing_fence = true + end + +--[[ +print("on: " .. self.standing_on + .. ", front: " .. nod.name + .. ", front above: " .. nodt.name + .. ", blocked: " .. (blocked and "yes" or "no") + .. ", fence: " .. (self.facing_fence and "yes" or "no") +) +]] + + -- if mob can leap then remove blockages and let them try + if self.can_leap == true then + blocked = false + self.facing_fence = false + end + + -- jump if standing on solid node (not snow) and not blocked + if (self.walk_chance == 0 or minetest.registered_items[nod.name].walkable) + and not blocked and not self.facing_fence and nod.name ~= node_snow then + + local v = self.object:get_velocity() + + v.y = self.jump_height + + self:set_animation("jump") -- only when defined + + self.object:set_velocity(v) + + -- when in air move forward + minetest.after(0.3, function(self, v) + + if self.object:get_luaentity() then + + self.object:set_acceleration({ + x = v.x * 2, + y = 0, + z = v.z * 2 + }) + end + end, self, v) + + if self:get_velocity() > 0 then + self:mob_sound(self.sounds.jump) + end + + self.jump_count = 0 + + return true + end + + -- if blocked for 3 counts then turn + if not self.following and (self.facing_fence or blocked) then + + self.jump_count = (self.jump_count or 0) + 1 + + if self.jump_count > 2 then + + local yaw = self.object:get_yaw() or 0 + local turn = random(0, 2) + 1.35 + + self:set_yaw(yaw + turn, 12) + + self.jump_count = 0 + end + end + + return false +end + + +-- blast damage to entities nearby (modified from TNT mod) +local entity_physics = function(pos, radius) + + radius = radius * 2 + + local objs = minetest.get_objects_inside_radius(pos, radius) + local obj_pos, dist + + for n = 1, #objs do + + obj_pos = objs[n]:get_pos() + + dist = get_distance(pos, obj_pos) + + if dist < 1 then dist = 1 end + + local damage = floor((4 / dist) * radius) + + -- punches work on entities AND players + objs[n]:punch(objs[n], 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = damage} + }, pos) + end +end + + +-- can mob see player +local is_invisible = function(self, player_name) + + if mobs.invis[player_name] and not self.ignore_invisibility then + return true + end +end + + +-- should mob follow what I'm holding ? +function mob_class:follow_holding(clicker) + + if is_invisible(self, clicker:get_player_name()) then + return false + end + + local item = clicker:get_wielded_item() + + -- are we holding an item mob can follow ? + if check_for(item:get_name(), self.follow) then + return true + end + + return false +end + + +-- find two animals of same type and breed if nearby and horny +function mob_class:breed() + + -- child takes a long time before growing into adult + if self.child == true then + + self.hornytimer = self.hornytimer + 1 + + if self.hornytimer > CHILD_GROW_TIME then + + self.child = false + self.hornytimer = 0 + + self.object:set_properties({ + textures = self.base_texture, + mesh = self.base_mesh, + visual_size = self.base_size, + collisionbox = self.base_colbox, + selectionbox = self.base_selbox + }) + + -- custom function when child grows up + if self.on_grown then + self.on_grown(self) + else + local pos = self.object:get_pos() ; if not pos then return end + local ent = self.object:get_luaentity() + + pos.y = pos.y + (ent.collisionbox[2] * -1) - 0.4 + + self.object:set_pos(pos) + + -- jump slightly when fully grown so as not to fall into ground + self.object:set_velocity({x = 0, y = 2, z = 0 }) + end + end + + return + end + + -- horny animal can mate for HORNY_TIME seconds, + -- afterwards horny animal cannot mate again for HORNY_AGAIN_TIME seconds + if self.horny == true + and self.hornytimer < HORNY_TIME + HORNY_AGAIN_TIME then + + self.hornytimer = self.hornytimer + 1 + + if self.hornytimer >= HORNY_TIME + HORNY_AGAIN_TIME then + self.hornytimer = 0 + self.horny = false + end + + self:update_tag() + end + + -- find another same animal who is also horny and mate if nearby + if self.horny == true + and self.hornytimer <= HORNY_TIME then + + local pos = self.object:get_pos() + + effect({x = pos.x, y = pos.y + 1, z = pos.z}, 8, "heart.png", 3, 4, 1, 0.1) + + local objs = minetest.get_objects_inside_radius(pos, 3) + local ent + + for n = 1, #objs do + + ent = objs[n]:get_luaentity() + + -- check for same animal with different colour + local canmate = false + + if ent then + + if ent.name == self.name then + canmate = true + else + local entname = ent.name:split(":") + local selfname = self.name:split(":") + + if entname[1] == selfname[1] then + + entname = entname[2]:split("_") + selfname = selfname[2]:split("_") + + if entname[1] == selfname[1] then + canmate = true + end + end + end + end + + -- found another similar horny animal that isn't self? + if ent and ent.object ~= self.object + and canmate == true + and ent.horny == true + and ent.hornytimer <= HORNY_TIME then + + local pos2 = ent.object:get_pos() + + -- Have mobs face one another + yaw_to_pos(self, pos2) + yaw_to_pos(ent, self.object:get_pos()) + + self.hornytimer = HORNY_TIME + 1 + ent.hornytimer = HORNY_TIME + 1 + + self:update_tag() + + -- have we reached active mob limit + if active_limit > 0 and active_mobs >= active_limit then + minetest.chat_send_player(self.owner, + S("Active Mob Limit Reached!") + .. " (" .. active_mobs + .. " / " .. active_limit .. ")") + return + end + + -- spawn baby + minetest.after(5, function(self, ent) + + if not self.object:get_luaentity() then + return + end + + -- custom breed function + if self.on_breed then + + -- when false skip going any further + if self:on_breed(ent) == false then + return + end + else + effect(pos, 15, "tnt_smoke.png", 1, 2, 2, 15, 5) + end + + pos.y = pos.y + 0.5 -- spawn child a little higher + + local mob = minetest.add_entity(pos, self.name) + local ent2 = mob:get_luaentity() + local textures = self.base_texture + + -- using specific child texture (if found) + if self.child_texture then + textures = self.child_texture[1] + end + + -- and resize to half height + mob:set_properties({ + textures = textures, + visual_size = { + x = self.base_size.x * .5, + y = self.base_size.y * .5 + }, + collisionbox = { + self.base_colbox[1] * .5, + self.base_colbox[2] * .5, + self.base_colbox[3] * .5, + self.base_colbox[4] * .5, + self.base_colbox[5] * .5, + self.base_colbox[6] * .5 + }, + selectionbox = { + self.base_selbox[1] * .5, + self.base_selbox[2] * .5, + self.base_selbox[3] * .5, + self.base_selbox[4] * .5, + self.base_selbox[5] * .5, + self.base_selbox[6] * .5 + } + }) + -- tamed and owned by parents' owner + ent2.child = true + ent2.tamed = true + ent2.owner = self.owner + end, self, ent) + + break + end + end + end +end + + +-- find and replace what mob is looking for (grass, wheat etc.) +function mob_class:replace(pos) + + local vel = self.object:get_velocity() + if not vel then return end + + if not mobs_griefing + or not self.replace_rate + or not self.replace_what + or self.child == true + or vel.y ~= 0 + or random(self.replace_rate) > 1 then + return + end + + local what, with, y_offset + + if type(self.replace_what[1]) == "table" then + + local num = random(#self.replace_what) + + what = self.replace_what[num][1] or "" + with = self.replace_what[num][2] or "" + y_offset = self.replace_what[num][3] or 0 + else + what = self.replace_what + with = self.replace_with or "" + y_offset = self.replace_offset or 0 + end + + pos.y = pos.y + y_offset + + if #minetest.find_nodes_in_area(pos, pos, what) > 0 then + +-- print("replace node = ".. minetest.get_node(pos).name, pos.y) + + if self.on_replace then + + local oldnode = what or "" + local newnode = with + + -- pass actual node name when using table or groups + if type(oldnode) == "table" + or oldnode:find("group:") then + oldnode = minetest.get_node(pos).name + end + + if self:on_replace(pos, oldnode, newnode) == false then + return + end + end + + minetest.set_node(pos, {name = with}) + end +end + + +-- check if daytime and also if mob is docile during daylight hours +function mob_class:day_docile() + + if self.docile_by_day == false then + return false + elseif self.docile_by_day == true + and self.time_of_day > 0.2 + and self.time_of_day < 0.8 then + return true + end +end + + +local los_switcher = false +local height_switcher = false +local can_dig_drop = function(pos) + + if minetest.is_protected(pos, "") then + return false + end + + local node = node_ok(pos, "air").name + local ndef = minetest.registered_nodes[node] + + if node ~= "ignore" + and ndef + and ndef.drawtype ~= "airlike" + and not ndef.groups.level + and not ndef.groups.unbreakable + and not ndef.groups.liquid then + + local drops = minetest.get_node_drops(node) + + for _, item in ipairs(drops) do + + minetest.add_item({ + x = pos.x - 0.5 + random(), + y = pos.y - 0.5 + random(), + z = pos.z - 0.5 + random() + }, item) + end + + minetest.remove_node(pos) + + return true + end + + return false +end + + +local pathfinder_mod = minetest.get_modpath("pathfinder") + +-- path finding and smart mob routine by rnd, +-- line_of_sight and other edits by Elkien3 +function mob_class:smart_mobs(s, p, dist, dtime) + + local s1 = self.path.lastpos + local target_pos = p + + + -- is it becoming stuck? + if abs(s1.x - s.x) + abs(s1.z - s.z) < .5 then + self.path.stuck_timer = self.path.stuck_timer + dtime + else + self.path.stuck_timer = 0 + end + + self.path.lastpos = {x = s.x, y = s.y, z = s.z} + + local use_pathfind = false + local has_lineofsight = minetest.line_of_sight( + {x = s.x, y = (s.y) + .5, z = s.z}, + {x = target_pos.x, y = (target_pos.y) + 1.5, z = target_pos.z}, .2) + + -- im stuck, search for path + if not has_lineofsight then + + if los_switcher == true then + use_pathfind = true + los_switcher = false + end -- cannot see target! + else + if los_switcher == false then + + los_switcher = true + use_pathfind = false + + minetest.after(1, function(self) + + if self.object:get_luaentity() then + + if has_lineofsight then + self.path.following = false + end + end + end, self) + end -- can see target! + end + + if self.path.stuck_timer > stuck_timeout and not self.path.following then + + use_pathfind = true + self.path.stuck_timer = 0 + + minetest.after(1, function(self) + + if self.object:get_luaentity() then + + if has_lineofsight then + self.path.following = false + end + end + end, self) + end + + if self.path.stuck_timer > stuck_path_timeout and self.path.following then + + use_pathfind = true + self.path.stuck_timer = 0 + + minetest.after(1, function(self) + + if self.object:get_luaentity() then + + if has_lineofsight then + self.path.following = false + end + end + end, self) + end + + if abs(vsubtract(s, target_pos).y) > self.stepheight then + + if height_switcher then + use_pathfind = true + height_switcher = false + end + else + if not height_switcher then + use_pathfind = false + height_switcher = true + end + end + + -- lets try find a path, first take care of positions + -- since pathfinder is very sensitive + if use_pathfind then + + -- round position to center of node to avoid stuck in walls + -- also adjust height for player models! + s.x = floor(s.x + 0.5) + s.z = floor(s.z + 0.5) + + local ssight, sground = minetest.line_of_sight(s, { + x = s.x, y = s.y - 4, z = s.z}, 1) + + -- determine node above ground + if not ssight then + s.y = sground.y + 1 + end + + local p1 = self.attack:get_pos() + + p1.x = floor(p1.x + 0.5) + p1.y = floor(p1.y + 0.5) + p1.z = floor(p1.z + 0.5) + + local dropheight = 6 + + if self.fear_height ~= 0 then dropheight = self.fear_height end + + local jumpheight = 0 + + if self.jump and self.jump_height >= 4 then + jumpheight = min(ceil(self.jump_height / 4), 4) + + elseif self.stepheight > 0.5 then + jumpheight = 1 + end + + if pathfinder_mod then + self.path.way = pathfinder.find_path(s, p1, self, dtime) + else + self.path.way = minetest.find_path(s, p1, 16, jumpheight, + dropheight, "Dijkstra") + end +--[[ + -- show path using particles + if self.path.way and #self.path.way > 0 then + + print("-- path length:" .. tonumber(#self.path.way)) + + for _,pos in pairs(self.path.way) do + + minetest.add_particle({ + pos = pos, + velocity = {x=0, y=0, z=0}, + acceleration = {x=0, y=0, z=0}, + expirationtime = 1, + size = 4, + collisiondetection = false, + vertical = false, + texture = "heart.png", + }) + end + end +]] + + self.state = "" + + if self.attack then + self:do_attack(self.attack) + end + + -- no path found, try something else + if not self.path.way then + + self.path.following = false + + -- lets make way by digging/building if not accessible + if self.pathfinding == 2 and mobs_griefing then + + -- is player more than 1 block higher than mob? + if p1.y > (s.y + 1) then + + -- build upwards + if not minetest.is_protected(s, "") then + + local ndef1 = minetest.registered_nodes[self.standing_in] + + if ndef1 and (ndef1.buildable_to or ndef1.groups.liquid) then + minetest.set_node(s, {name = mobs.fallback_node}) + end + end + + local sheight = ceil(self.collisionbox[5]) + 1 + + -- assume mob is 2 blocks high so it digs above its head + s.y = s.y + sheight + + -- remove one block above to make room to jump + can_dig_drop(s) + + s.y = s.y - sheight + self.object:set_pos({x = s.x, y = s.y + 2, z = s.z}) + + -- is player more than 1 block lower than mob + elseif p1.y < (s.y - 1) then + + -- dig down + s.y = s.y - self.collisionbox[4] - 0.2 + + can_dig_drop(s) + + else -- dig 2 blocks to make door toward player direction + + local yaw1 = self.object:get_yaw() + pi / 2 + local p1 = { + x = s.x + cos(yaw1), + y = s.y, + z = s.z + sin(yaw1) + } + + -- dig bottom node first incase of door + can_dig_drop(p1) + + p1.y = p1.y + 1 + + can_dig_drop(p1) + end + end + + -- will try again in 2 second + self.path.stuck_timer = stuck_timeout - 2 + + elseif s.y < p1.y and (not self.fly) then + self:do_jump() --add jump to pathfinding + self.path.following = true + else + -- yay i found path + if self.attack then + self:mob_sound(self.sounds.war_cry) + else + self:mob_sound(self.sounds.random) + end + + self:set_velocity(self.walk_velocity) + + -- follow path now that it has it + self.path.following = true + end + end +end + + +-- peaceful player privilege support +local function is_peaceful_player(player) + + -- main setting enabled + if peaceful_player_enabled then + return true + end + + local player_name = player:get_player_name() + + -- player priv enabled + if player_name + and minetest.check_player_privs(player_name, "peaceful_player") then + return true + end + + return false +end + + +-- general attack function for all mobs +function mob_class:general_attack() + + -- return if already attacking, passive or docile during day + if self.passive + or self.state == "runaway" + or self.state == "attack" + or self:day_docile() then + return + end + + local s = self.object:get_pos() ; if not s then return end + local objs = minetest.get_objects_inside_radius(s, self.view_range) + + -- remove entities we aren't interested in + for n = 1, #objs do + + local ent = objs[n]:get_luaentity() + + -- are we a player? + if objs[n]:is_player() then + + -- if player invisible or mob cannot attack then remove from list + if not damage_enabled + or self.attack_players == false + or (self.owner and self.type ~= "monster") + or is_invisible(self, objs[n]:get_player_name()) + or (self.specific_attack + and not check_for("player", self.specific_attack)) then + objs[n] = nil +--print("- pla", n) + end + + -- or are we a mob? + elseif ent and ent._cmi_is_mob then + + -- remove mobs not to attack + if self.name == ent.name + or (not self.attack_animals and ent.type == "animal") + or (not self.attack_monsters and ent.type == "monster") + or (not self.attack_npcs and ent.type == "npc") + or (self.specific_attack + and not check_for(ent.name, self.specific_attack)) then + objs[n] = nil +--print("- mob", n, self.name, ent.name) + end + + -- remove all other entities + else +--print(" -obj", n) + objs[n] = nil + end + end + + local p, sp, dist, min_player + local min_dist = self.view_range + 1 + + -- go through remaining entities and select closest + for _,player in pairs(objs) do + + p = player:get_pos() + sp = s + + dist = get_distance(p, s) + + -- aim higher to make looking up hills more realistic + p.y = p.y + 1 + sp.y = sp.y + 1 + + -- choose closest player to attack that isnt self + if dist ~= 0 + and dist < min_dist + and self:line_of_sight(sp, p, 2) == true + and not is_peaceful_player(player) then + min_dist = dist + min_player = player + end + end + + -- attack closest player or mob + if min_player and random(100) > self.attack_chance then + self:do_attack(min_player) + end +end + + +-- find someone to runaway from +function mob_class:do_runaway_from() + + if not self.runaway_from then + return + end + + local s = self.object:get_pos() ; if not s then return end + local p, sp, dist, pname + local player, obj, min_player, name + local min_dist = self.view_range + 1 + local objs = minetest.get_objects_inside_radius(s, self.view_range) + + for n = 1, #objs do + + if objs[n]:is_player() then + + pname = objs[n]:get_player_name() + + if is_invisible(self, pname) + or self.owner == pname then + + name = "" + else + player = objs[n] + name = "player" + end + else + obj = objs[n]:get_luaentity() + + if obj then + player = obj.object + name = obj.name or "" + end + end + + -- find specific mob to runaway from + if name ~= "" and name ~= self.name + and (self.runaway_from and check_for(name, self.runaway_from)) then + + sp = s + p = player and player:get_pos() or s + + -- aim higher to make looking up hills more realistic + p.y = p.y + 1 + sp.y = sp.y + 1 + + dist = get_distance(p, s) + + -- choose closest player/mob to runaway from + if dist < min_dist + and self:line_of_sight(sp, p, 2) == true then + min_dist = dist + min_player = player + end + end + end + + if min_player then + + yaw_to_pos(self, min_player:get_pos(), 3) + + self.state = "runaway" + self.runaway_timer = 3 + self.following = nil + end +end + + +-- follow player if owner or holding item, if fish outta water then flop +function mob_class:follow_flop() + + -- find player to follow + if (self.follow ~= "" or self.order == "follow") + and not self.following + and self.state ~= "attack" + and self.state ~= "runaway" then + + local s = self.object:get_pos() ; if not s then return end + local players = minetest.get_connected_players() + + for n = 1, #players do + + if players[n] + and not is_invisible(self, players[n]:get_player_name()) + and get_distance(players[n]:get_pos(), s) < self.view_range then + + self.following = players[n] + + break + end + end + end + + if self.type == "npc" + and self.order == "follow" + and self.state ~= "attack" + and self.owner ~= "" then + + -- npc stop following player if not owner + if self.following + and self.owner + and self.owner ~= self.following:get_player_name() then + self.following = nil + end + else + -- stop following player if not holding specific item or mob is horny + if self.following + and self.following:is_player() + and (self:follow_holding(self.following) == false + or self.horny) then + self.following = nil + end + + end + + -- follow that thing + if self.following then + + local s = self.object:get_pos() + local p + + if self.following:is_player() then + + p = self.following:get_pos() + + elseif self.following.object then + + p = self.following.object:get_pos() + end + + if p then + + local dist = get_distance(p, s) + + -- dont follow if out of range + if dist > self.view_range then + self.following = nil + else + yaw_to_pos(self, p) + + -- anyone but standing npc's can move along + if dist >= self.reach + and self.order ~= "stand" then + + self:set_velocity(self.walk_velocity) + self.follow_stop = nil + + if self.walk_chance ~= 0 then + self:set_animation("walk") + end + else + self:set_velocity(0) + self:set_animation("stand") + self.follow_stop = true + end + + return + end + end + end + + -- swimmers flop when out of their element, and swim again when back in + if self.fly then + + if not self:attempt_flight_correction() then + + self.state = "flop" + + -- do we have a custom on_flop function? + if self.on_flop then + + if self:on_flop(self) then + return + end + end + + self.object:set_velocity({x = 0, y = -5, z = 0}) + + self:set_animation("stand") + + return + + elseif self.state == "flop" then + self.state = "stand" + end + end +end + + +-- dogshoot attack switch and counter function +function mob_class:dogswitch(dtime) + + -- switch mode not activated + if not self.dogshoot_switch + or not dtime then + return 0 + end + + self.dogshoot_count = self.dogshoot_count + dtime + + if (self.dogshoot_switch == 1 + and self.dogshoot_count > self.dogshoot_count_max) + or (self.dogshoot_switch == 2 + and self.dogshoot_count > self.dogshoot_count2_max) then + + self.dogshoot_count = 0 + + if self.dogshoot_switch == 1 then + self.dogshoot_switch = 2 + else + self.dogshoot_switch = 1 + end + end + + return self.dogshoot_switch +end + + +-- execute current state (stand, walk, run, attacks) +function mob_class:do_states(dtime) + + local yaw = self.object:get_yaw() ; if not yaw then return end + + if self.state == "stand" and not self.follow_stop then + + if self.randomly_turn and random(4) == 1 then + + local lp + local s = self.object:get_pos() + local objs = minetest.get_objects_inside_radius(s, 3) + + for n = 1, #objs do + + if objs[n]:is_player() then + lp = objs[n]:get_pos() + break + end + end + + -- look at any players nearby, otherwise turn randomly + if lp then + yaw = yaw_to_pos(self, lp) + else + yaw = yaw + random(-0.5, 0.5) + end + + self:set_yaw(yaw, 8) + end + + self:set_velocity(0) + self:set_animation("stand") + + -- mobs ordered to stand stay standing + if self.order ~= "stand" + and self.walk_chance ~= 0 + and self.facing_fence ~= true + and random(100) <= self.walk_chance + and self.at_cliff == false then + + self:set_velocity(self.walk_velocity) + self.state = "walk" + self:set_animation("walk") + end + + elseif self.state == "walk" then + + local s = self.object:get_pos() + local lp + + -- is there something I need to avoid? + if self.water_damage > 0 + and self.lava_damage > 0 then + + lp = minetest.find_node_near(s, 1, {"group:water", "group:igniter"}) + + elseif self.water_damage > 0 then + + lp = minetest.find_node_near(s, 1, {"group:water"}) + + elseif self.lava_damage > 0 then + + lp = minetest.find_node_near(s, 1, {"group:igniter"}) + end + + if lp then + + -- if mob in dangerous node then look for land + if not is_node_dangerous(self, self.standing_in) then + + lp = minetest.find_nodes_in_area_under_air( + {s.x - 5, s.y - 1, s.z - 5}, + {s.x + 5, s.y + 2, s.z + 5}, + {"group:soil", "group:stone", "group:sand", + node_ice, node_snowblock}) + + -- select position of random block to climb onto + lp = #lp > 0 and lp[random(#lp)] + + -- did we find land? + if lp then + + yaw = yaw_to_pos(self, lp) + + self:do_jump() + self:set_velocity(self.walk_velocity) + else + yaw = yaw + random(-0.5, 0.5) + end + end + + self:set_yaw(yaw, 8) + + -- otherwise randomly turn + elseif self.randomly_turn and random(100) <= 30 then + + yaw = yaw + random(-0.5, 0.5) + + self:set_yaw(yaw, 8) + + -- for flying/swimming mobs randomly move up and down also + if self.fly_in + and not self.following then + self:attempt_flight_correction(true) + end + end + + -- stand for great fall in front + if self.facing_fence == true + or self.at_cliff + or random(100) <= self.stand_chance then + + -- don't stand if mob flies and keep_flying set + if (self.fly and not self.keep_flying) + or not self.fly then + + self:set_velocity(0) + self.state = "stand" + self:set_animation("stand", true) + end + else + self:set_velocity(self.walk_velocity) + + -- figure out which animation to use while in motion + if self:flight_check() + and self.animation + and self.animation.fly_start + and self.animation.fly_end then + + local on_ground = minetest.registered_nodes[self.standing_on].walkable + local in_water = minetest.registered_nodes[self.standing_in].groups.water + + if on_ground and in_water then + self:set_animation("fly") + elseif on_ground then + self:set_animation("walk") + else + self:set_animation("fly") + end + else + self:set_animation("walk") + end + end + + -- runaway when punched + elseif self.state == "runaway" then + + self.runaway_timer = self.runaway_timer + 1 + + -- stop after 5 seconds or when at cliff + if self.runaway_timer > 5 + or self.at_cliff + or self.order == "stand" then + self.runaway_timer = 0 + self:set_velocity(0) + self.state = "stand" + self:set_animation("stand") + else + self:set_velocity(self.run_velocity) + self:set_animation("walk") + end + + -- attack routines (explode, dogfight, shoot, dogshoot) + elseif self.state == "attack" then + + -- get mob and enemy positions and distance between + local s = self.object:get_pos() + local p = self.attack and self.attack:get_pos() + local dist = p and get_distance(p, s) or 500 + + -- stop attacking if player out of range or invisible + if dist > self.view_range + or not self.attack + or not self.attack:get_pos() + or self.attack:get_hp() <= 0 + or (self.attack:is_player() + and is_invisible(self, self.attack:get_player_name())) then + +--print(" ** stop attacking **", dist, self.view_range) + + self.state = "stand" + self:set_velocity(0) + self:set_animation("stand") + self.attack = nil + self.v_start = false + self.timer = 0 + self.blinktimer = 0 + self.path.way = nil + + return + end + + if self.attack_type == "explode" then + + yaw_to_pos(self, p) + + local node_break_radius = self.explosion_radius or 1 + local entity_damage_radius = self.explosion_damage_radius + or (node_break_radius * 2) + + -- look a little higher to fix raycast + s.y = s.y + 0.5 ; p.y = p.y + 0.5 + + -- start timer when in reach and line of sight + if not self.v_start + and dist <= self.reach + and self:line_of_sight(s, p, 2) then + + self.v_start = true + self.timer = 0 + self.blinktimer = 0 + self:mob_sound(self.sounds.fuse) + +--print("=== explosion timer started", self.explosion_timer) + + -- stop timer if out of reach or direct line of sight + elseif self.allow_fuse_reset + and self.v_start + and (dist > self.reach or not self:line_of_sight(s, p, 2)) then + +--print("=== explosion timer stopped") + + self.v_start = false + self.timer = 0 + self.blinktimer = 0 + self.blinkstatus = false + self.object:set_texture_mod("") + end + + -- walk right up to player unless the timer is active + if self.v_start and (self.stop_to_explode or dist < 1.5) then + self:set_velocity(0) + else + self:set_velocity(self.run_velocity) + end + + if self.animation and self.animation.run_start then + self:set_animation("run") + else + self:set_animation("walk") + end + + if self.v_start then + + self.timer = self.timer + dtime + self.blinktimer = (self.blinktimer or 0) + dtime + + if self.blinktimer > 0.2 then + + self.blinktimer = 0 + + if self.blinkstatus then + + self.object:set_texture_mod(self.texture_mods) + else + + self.object:set_texture_mod(self.texture_mods .. "^[brighten") + end + + self.blinkstatus = not self.blinkstatus + end + +--print("=== explosion timer", self.timer) + + if self.timer > self.explosion_timer then + + local pos = self.object:get_pos() + + -- dont damage anything if area protected or next to water + if minetest.find_node_near(pos, 1, {"group:water"}) + or minetest.is_protected(pos, "") then + + node_break_radius = 1 + end + + remove_mob(self, true) + + mobs:boom(self, pos, entity_damage_radius, node_break_radius) + + return true + end + end + + elseif self.attack_type == "dogfight" + or (self.attack_type == "dogshoot" and self:dogswitch(dtime) == 2) + or (self.attack_type == "dogshoot" and dist <= self.reach + and self:dogswitch() == 0) then + + if self.fly + and dist > self.reach then + + local p1 = s + local me_y = floor(p1.y) + local p2 = p + local p_y = floor(p2.y + 1) + local v = self.object:get_velocity() + + if self:flight_check() then + + if me_y < p_y then + + self.object:set_velocity({ + x = v.x, + y = 1 * self.walk_velocity, + z = v.z + }) + + elseif me_y > p_y then + + self.object:set_velocity({ + x = v.x, + y = -1 * self.walk_velocity, + z = v.z + }) + end + else + if me_y < p_y then + + self.object:set_velocity({ + x = v.x, + y = 0.01, + z = v.z + }) + + elseif me_y > p_y then + + self.object:set_velocity({ + x = v.x, + y = -0.01, + z = v.z + }) + end + end + end + + -- rnd: new movement direction + if self.path.following + and self.path.way + and self.attack_type ~= "dogshoot" then + + -- no paths longer than 50 + if #self.path.way > 50 + or dist < self.reach then + self.path.following = false + return + end + + local p1 = self.path.way[1] + + if not p1 then + self.path.following = false + return + end + + if abs(p1.x - s.x) + abs(p1.z - s.z) < 0.6 then + -- reached waypoint, remove it from queue + table_remove(self.path.way, 1) + end + + -- set new temporary target + p = {x = p1.x, y = p1.y, z = p1.z} + end + + yaw_to_pos(self, p) + + -- move towards enemy if beyond mob reach + if dist > (self.reach + (self.reach_ext or 0)) then + + -- path finding by rnd + if self.pathfinding -- only if mob has pathfinding enabled + and enable_pathfinding then + + self:smart_mobs(s, p, dist, dtime) + end + + -- distance padding to stop spinning mob + local pad = abs(p.x - s.x) + abs(p.z - s.z) + + self.reach_ext = 0 -- extended ready off by default + + if self.at_cliff or pad < 0.2 then + + -- when on top of player extend reach slightly so player can + -- still be attacked. + self.reach_ext = 0.8 + self:set_velocity(0) + self:set_animation("stand") + else + + if self.path.stuck then + self:set_velocity(self.walk_velocity) + else + self:set_velocity(self.run_velocity) + end + + if self.animation and self.animation.run_start then + self:set_animation("run") + else + self:set_animation("walk") + end + end + else -- rnd: if inside reach range + + self.path.stuck = false + self.path.stuck_timer = 0 + self.path.following = false -- not stuck anymore + + self:set_velocity(0) + + if self.timer > 1 then + + -- no custom attack or custom attack returns true to continue + if not self.custom_attack + or self:custom_attack(self, p) == true then + + self.timer = 0 + self:set_animation("punch") + + local p2 = p + local s2 = s + + p2.y = p2.y + .5 + s2.y = s2.y + .5 + + if self:line_of_sight(p2, s2) == true then + + -- play attack sound + self:mob_sound(self.sounds.attack) + + -- punch player (or what player is attached to) + local attached = self.attack:get_attach() + + if attached then + self.attack = attached + end + + local dgroup = self.damage_group or "fleshy" + + self.attack:punch(self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = {[dgroup] = self.damage} + }, nil) + end + end + end + end + + elseif self.attack_type == "shoot" + or (self.attack_type == "dogshoot" and self:dogswitch(dtime) == 1) + or (self.attack_type == "dogshoot" and dist > self.reach and + self:dogswitch() == 0) then + + p.y = p.y - .5 + s.y = s.y + .5 + + local vec = {x = p.x - s.x, y = p.y - s.y, z = p.z - s.z} + + yaw_to_pos(self, p) + + self:set_velocity(0) + + if self.shoot_interval + and self.timer > self.shoot_interval + and random(100) <= 60 then + + self.timer = 0 + self:set_animation("shoot") + + -- play shoot attack sound + self:mob_sound(self.sounds.shoot_attack) + + local p = self.object:get_pos() + + p.y = p.y + (self.collisionbox[2] + self.collisionbox[5]) / 2 + + if minetest.registered_entities[self.arrow] then + + local obj = minetest.add_entity(p, self.arrow) + local ent = obj:get_luaentity() + local amount = (vec.x * vec.x + vec.y * vec.y + vec.z * vec.z) ^ 0.5 + + -- check for custom override for arrow + if self.arrow_override then + self.arrow_override(ent) + end + + local v = ent.velocity or 1 -- or set to default + + ent.switch = 1 + ent.owner_id = tostring(self.object) -- add unique owner id to arrow + + -- offset makes shoot aim accurate + vec.y = vec.y + self.shoot_offset + vec.x = vec.x * (v / amount) + vec.y = vec.y * (v / amount) + vec.z = vec.z * (v / amount) + + obj:set_velocity(vec) + end + end + end + end +end + + +-- falling and fall damage +function mob_class:falling(pos) + + if self.fly or self.disable_falling then + return + end + + -- floating in water (or falling) + local v = self.object:get_velocity() + + -- sanity check + if not v then return end + + local fall_speed = self.fall_speed + + -- in water then use liquid viscosity for float/sink speed + if self.floats == 1 and self.standing_in + and minetest.registered_nodes[self.standing_in].groups.liquid then + + local visc = min( + minetest.registered_nodes[self.standing_in].liquid_viscosity, 7) + 1 + + self.object:set_velocity({x = v.x, y = 0.6, z = v.z}) + fall_speed = -1.2 / visc + else + + -- fall damage onto solid ground + if self.fall_damage == 1 + and self.object:get_velocity().y == 0 then + + local d = (self.old_y or 0) - self.object:get_pos().y + + if d > 5 then + + self.health = self.health - floor(d - 5) + + effect(pos, 5, "tnt_smoke.png", 1, 2, 2, nil) + + if self:check_for_death({type = "fall"}) then + return true + end + end + + self.old_y = self.object:get_pos().y + end + end + + -- fall at set speed + self.object:set_acceleration({x = 0, y = fall_speed, z = 0}) +end + + +-- is Took Ranks mod active? +local tr = minetest.get_modpath("toolranks") + +-- deal damage and effects when mob punched +function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage) + + -- mob health check + if self.health <= 0 then + return true + end + + -- custom punch function + if self.do_punch + and self:do_punch(hitter, tflp, tool_capabilities, dir) == false then + return true + end + + -- error checking when mod profiling is enabled + if not tool_capabilities then + + minetest.log("warning", "[mobs] Mod profiling enabled, damage not enabled") + + return true + end + + -- is mob protected + if self.protected then + + -- did player hit mob and if so is it in protected area + if hitter:is_player() then + + local player_name = hitter:get_player_name() + + if player_name ~= self.owner + and minetest.is_protected(self.object:get_pos(), player_name) then + + minetest.chat_send_player(hitter:get_player_name(), + S("Mob has been protected!")) + + return true + end + + -- if protection is on level 2 then dont let arrows harm mobs + elseif self.protected == 2 then + + local ent = hitter and hitter:get_luaentity() + + if ent and ent._is_arrow then + + return true -- arrow entity + + elseif not ent then + + return true -- non entity + end + end + end + + local weapon = hitter:get_wielded_item() + local weapon_def = weapon:get_definition() or {} + + -- calculate mob damage + local damage = 0 + local armor = self.object:get_armor_groups() or {} + local tmp + + -- quick error check incase it ends up 0 (serialize.h check test) + if tflp == 0 then + tflp = 0.2 + end + + if use_cmi then + damage = cmi.calculate_damage(self.object, hitter, tflp, tool_capabilities, dir) + else + + for group,_ in pairs( (tool_capabilities.damage_groups or {}) ) do + + tmp = tflp / (tool_capabilities.full_punch_interval or 1.4) + + if tmp < 0 then + tmp = 0.0 + elseif tmp > 1 then + tmp = 1.0 + end + + damage = damage + (tool_capabilities.damage_groups[group] or 0) + * tmp * ((armor[group] or 0) / 100.0) + end + end + + -- check for tool immunity or special damage + for n = 1, #self.immune_to do + + if self.immune_to[n][1] == weapon_def.name then + + damage = self.immune_to[n][2] or 0 + + break + + -- if "all" then no tools deal damage unless it's specified in list + elseif self.immune_to[n][1] == "all" then + damage = self.immune_to[n][2] or 0 + end + end + +--print("Mob Damage is", damage) + + -- healing + if damage <= -1 then + + self.health = self.health - floor(damage) + + return true + end + + if use_cmi + and cmi.notify_punch(self.object, hitter, tflp, tool_capabilities, dir, damage) then + return true + end + + -- add weapon wear + local punch_interval = tool_capabilities.full_punch_interval or 1.4 + + -- toolrank support + local wear = floor((punch_interval / 75) * 9000) + + if mobs.is_creative(hitter:get_player_name()) then + + if tr then + wear = 1 + else + wear = 0 + end + end + + if tr and weapon_def.original_description then + toolranks.new_afteruse(weapon, hitter, nil, {wear = wear}) + else + weapon:add_wear(wear) + end + + hitter:set_wielded_item(weapon) + + -- only play hit sound and show blood effects if damage is 1 or over + if damage >= 1 then + + -- select tool use sound if found, or fallback to default + local snd = weapon_def.sound and weapon_def.sound.use + or "default_punch" + + minetest.sound_play(snd, {object = self.object, max_hear_distance = 8}, true) + + -- blood_particles + if not disable_blood and self.blood_amount > 0 then + + local pos = self.object:get_pos() + local blood = self.blood_texture + local amount = self.blood_amount + + pos.y = pos.y + (-self.collisionbox[2] + self.collisionbox[5]) * .5 + + -- lots of damage = more blood :) + if damage > 4 then + amount = self.blood_amount * 2 + end + + -- do we have a single blood texture or multiple? + if type(self.blood_texture) == "table" then + blood = self.blood_texture[random(#self.blood_texture)] + end + + effect(pos, amount, blood, 1, 2, 1.75, nil, nil, true) + end + + -- do damage + self.health = self.health - floor(damage) + + -- exit here if dead, check for tools with fire damage + local hot = tool_capabilities and tool_capabilities.damage_groups + and tool_capabilities.damage_groups.fire + + if self:check_for_death({type = "punch", puncher = hitter, hot = hot}) then + return true + end + end + + -- knock back effect (only on full punch) + if self.knock_back and tflp >= punch_interval then + + local v = self.object:get_velocity() + + -- sanity check + if not v then return true end + + local kb = damage or 1 + local up = 2 + + -- if already in air then dont go up anymore when hit + if v.y > 0 + or self.fly then + up = 0 + end + + -- direction error check + dir = dir or {x = 0, y = 0, z = 0} + + -- use tool knockback value or default + kb = tool_capabilities.damage_groups["knockback"] or kb + + self.object:set_velocity({x = dir.x * kb, y = up, z = dir.z * kb}) + + self.pause_timer = 0.25 + end + + -- if skittish then run away + if self.runaway == true + and self.order ~= "stand" then + + local lp = hitter:get_pos() + yaw = yaw_to_pos(self, lp, 3) + + self.state = "runaway" + self.runaway_timer = 0 + self.following = nil + end + + local name = hitter:get_player_name() or "" + + -- attack puncher and call other mobs for help + if self.passive == false + and self.state ~= "flop" + and self.child == false + and self.attack_players == true + and hitter:get_player_name() ~= self.owner + and not is_invisible(self, name) + and self.object ~= hitter then + + -- attack whoever punched mob + self.state = "" + self:do_attack(hitter) + + -- alert others to the attack + local objs = minetest.get_objects_inside_radius( + hitter:get_pos(), self.view_range) + local obj + + for n = 1, #objs do + + obj = objs[n]:get_luaentity() + + if obj and obj._cmi_is_mob then + + -- only alert members of same mob and assigned helper + if obj.group_attack == true + and obj.state ~= "attack" + and obj.owner ~= name + and (obj.name == self.name + or obj.name == self.group_helper) then + + obj:do_attack(hitter) + end + + -- have owned mobs attack player threat + if obj.owner == name and obj.owner_loyal then + obj:do_attack(self.object) + end + end + end + end +end + + +-- get entity staticdata +function mob_class:mob_staticdata() + + -- this handles mob count for mobs activated, unloaded, reloaded + if active_limit > 0 and self.active_toggle then + active_mobs = active_mobs + self.active_toggle + self.active_toggle = -self.active_toggle +--print("-- staticdata", active_mobs, active_limit, self.active_toggle) + end + + -- remove mob when out of range unless tamed + if remove_far + and self.remove_ok + and self.type ~= "npc" + and self.state ~= "attack" + and not self.tamed + and self.lifetimer < 20000 then + +--print("REMOVED " .. self.name) + + remove_mob(self, true) + + return minetest.serialize({remove_ok = true, static_save = true}) + end + + self.remove_ok = true + self.attack = nil + self.following = nil + self.state = "stand" + + -- used to rotate older mobs + if self.drawtype and self.drawtype == "side" then + self.rotate = rad(90) + end + + if use_cmi then + self.serialized_cmi_components = cmi.serialize_components( + self._cmi_components) + end + + local tmp, t = {} + + for _,stat in pairs(self) do + + t = type(stat) + + if t ~= "function" + and t ~= "nil" + and t ~= "userdata" + and _ ~= "object" + and _ ~= "_cmi_components" then + tmp[_] = self[_] + end + end + + return minetest.serialize(tmp) +end + + +-- activate mob and reload settings +function mob_class:mob_activate(staticdata, def, dtime) + + -- if dtime == 0 then entity has just been created + -- anything higher means it is respawning (thanks SorceryKid) + if dtime == 0 and active_limit > 0 then + self.active_toggle = 1 + end + + -- remove mob if not tamed and mob total reached + if active_limit > 0 and active_mobs >= active_limit and not self.tamed then + + remove_mob(self) +--print("-- mob limit reached, removing " .. self.name) + return + end + + -- remove monsters in peaceful mode + if self.type == "monster" and peaceful_only then + + remove_mob(self, true) + + return + end + + -- load entity variables + local tmp = minetest.deserialize(staticdata) + + if tmp then + + local t + + for _,stat in pairs(tmp) do + + t = type(stat) + + if t ~= "function" + and t ~= "nil" + and t ~= "userdata" then + self[_] = stat + end + end + end + + -- force current model into mob + self.mesh = def.mesh + self.base_mesh = def.mesh + self.collisionbox = def.collisionbox + self.selectionbox = def.selectionbox + + -- select random texture, set model and size + if not self.base_texture then + + -- compatiblity with old simple mobs textures + if def.textures and type(def.textures[1]) == "string" then + def.textures = {def.textures} + end + + self.base_texture = def.textures and def.textures[random(#def.textures)] + self.base_mesh = def.mesh + self.base_size = self.visual_size + self.base_colbox = self.collisionbox + self.base_selbox = self.selectionbox + end + + -- for current mobs that dont have this set + if not self.base_selbox then + self.base_selbox = self.selectionbox or self.base_colbox + end + + -- set texture, model and size + local textures = self.base_texture + local mesh = self.base_mesh + local vis_size = self.base_size + local colbox = self.base_colbox + local selbox = self.base_selbox + + -- specific texture if gotten + if self.gotten == true and def.gotten_texture then + textures = def.gotten_texture + end + + -- specific mesh if gotten + if self.gotten == true and def.gotten_mesh then + mesh = def.gotten_mesh + end + + -- set child objects to half size + if self.child == true then + + vis_size = {x = self.base_size.x * .5, y = self.base_size.y * .5} + + if def.child_texture then + textures = def.child_texture[1] + end + + colbox = { + self.base_colbox[1] * .5, self.base_colbox[2] * .5, + self.base_colbox[3] * .5, self.base_colbox[4] * .5, + self.base_colbox[5] * .5, self.base_colbox[6] * .5} + + selbox = { + self.base_selbox[1] * .5, self.base_selbox[2] * .5, + self.base_selbox[3] * .5, self.base_selbox[4] * .5, + self.base_selbox[5] * .5, self.base_selbox[6] * .5} + end + + if self.health == 0 then + self.health = random(self.hp_min, self.hp_max) + end + + -- pathfinding init + self.path = {} + self.path.way = {} -- path to follow, table of positions + self.path.lastpos = {x = 0, y = 0, z = 0} + self.path.stuck = false + self.path.following = false -- currently following path? + self.path.stuck_timer = 0 -- if stuck for too long search for path + + -- Armor groups (immortal = 1 for custom damage handling) + local armor + if type(self.armor) == "table" then + armor = table_copy(self.armor) + else + armor = {fleshy = self.armor, immortal = 1} + end + self.object:set_armor_groups(armor) + + -- mob defaults + self.old_y = self.object:get_pos().y + self.old_health = self.health + self.sounds.distance = self.sounds.distance or 10 + self.textures = textures + self.mesh = mesh + self.collisionbox = colbox + self.selectionbox = selbox + self.visual_size = vis_size + self.standing_in = "air" + self.standing_on = "air" + + -- check existing nametag + if not self.nametag then + self.nametag = def.nametag + end + + -- set anything changed above + self.object:set_properties(self) + self:set_yaw((random(0, 360) - 180) / 180 * pi, 6) + self:update_tag() + self:set_animation("stand") + + -- apply any texture mods + self.object:set_texture_mod(self.texture_mods) + + -- set 5.x flag to remove monsters when map area unloaded + if remove_far and self.type == "monster" and not self.tamed then + self.static_save = false + end + + -- run on_spawn function if found + if self.on_spawn and not self.on_spawn_run then + if self.on_spawn(self) then + self.on_spawn_run = true -- if true, set flag to run once only + end + end + + -- run after_activate + if def.after_activate then + def.after_activate(self, staticdata, def, dtime) + end + + if use_cmi then + self._cmi_components = cmi.activate_components(self.serialized_cmi_components) + cmi.notify_activate(self.object, dtime) + end +end + + +-- handle mob lifetimer and expiration +function mob_class:mob_expire(pos, dtime) + + -- when lifetimer expires remove mob (except npc and tamed) + if self.type ~= "npc" + and not self.tamed + and self.state ~= "attack" + and remove_far ~= true + and self.lifetimer < 20000 then + + self.lifetimer = self.lifetimer - dtime + + if self.lifetimer <= 0 then + + -- only despawn away from player + local objs = minetest.get_objects_inside_radius(pos, 15) + + for n = 1, #objs do + + if objs[n]:is_player() then + + self.lifetimer = 20 + + return + end + end + +-- minetest.log("action", S("lifetimer expired, removed @1", self.name)) + + effect(pos, 15, "tnt_smoke.png", 2, 4, 2, 0) + + remove_mob(self, true) + + return + end + end +end + + +-- main mob function +function mob_class:on_step(dtime, moveresult) + + if self.state == "die" then return end + + if use_cmi then + cmi.notify_step(self.object, dtime) + end + + local pos = self.object:get_pos() + local yaw = self.object:get_yaw() + + -- early warning check, if no yaw then no entity, skip rest of function + if not yaw then return end + + self.node_timer = (self.node_timer or 0) + dtime + + -- get nodes above and below foot level every 1/4 second + if self.node_timer > 0.25 then + + self.node_timer = 0 + + local y_level = self.collisionbox[2] + + if self.child then + y_level = self.collisionbox[2] * 0.5 + end + + -- what is mob standing in? + self.standing_in = node_ok({ + x = pos.x, y = pos.y + y_level + 0.25, z = pos.z}, "air").name + + self.standing_on = node_ok({ + x = pos.x, y = pos.y + y_level - 0.25, z = pos.z}, "air").name + +--print("standing in " .. self.standing_in) + + -- if standing inside solid block then jump to escape + if minetest.registered_nodes[self.standing_in].walkable + and minetest.registered_nodes[self.standing_in].drawtype == "normal" then + + self.object:set_velocity({ + x = 0, + y = self.jump_height, + z = 0 + }) + end + + -- check and stop if standing at cliff and fear of heights + self.at_cliff = self:is_at_cliff() + + if self.at_cliff then + self:set_velocity(0) + end + + -- has mob expired (0.25 instead of dtime since were in a timer) + self:mob_expire(pos, 0.25) + end + + -- check if falling, flying, floating and return if player died + if self:falling(pos) then + return + end + + -- smooth rotation by ThomasMonroe314 + if self.delay and self.delay > 0 then + + if self.delay == 1 then + yaw = self.target_yaw + else + local dif = abs(yaw - self.target_yaw) + + if yaw > self.target_yaw then + + if dif > pi then + dif = 2 * pi - dif + yaw = yaw + dif / self.delay -- need to add + else + yaw = yaw - dif / self.delay -- need to subtract + end + + elseif yaw < self.target_yaw then + + if dif > pi then + dif = 2 * pi - dif + yaw = yaw - dif / self.delay -- need to subtract + else + yaw = yaw + dif / self.delay -- need to add + end + end + + if yaw > (pi * 2) then yaw = yaw - (pi * 2) end + if yaw < 0 then yaw = yaw + (pi * 2) end + end + + self.delay = self.delay - 1 + self.object:set_yaw(yaw) + end + + -- knockback timer + if self.pause_timer > 0 then + + self.pause_timer = self.pause_timer - dtime + + return + end + + -- run custom function (defined in mob lua file) + if self.do_custom then + + -- when false skip going any further + if self:do_custom(dtime) == false then + return + end + end + + -- attack timer + self.timer = self.timer + dtime + + if self.state ~= "attack" then + + if self.timer < 1 then + return + end + + self.timer = 0 + end + + -- never go over 100 + if self.timer > 100 then + self.timer = 1 + end + + -- mob plays random sound at times + if random(100) == 1 then + self:mob_sound(self.sounds.random) + end + + -- environmental damage timer (every 1 second) + self.env_damage_timer = self.env_damage_timer + dtime + + if (self.state == "attack" and self.env_damage_timer > 1) + or self.state ~= "attack" then + + self.env_damage_timer = 0 + + -- check for environmental damage (water, fire, lava etc.) + if self:do_env_damage() then return end + + -- node replace check (cow eats grass etc.) + self:replace(pos) + end + + self:general_attack() + + self:breed() + + self:follow_flop() + + if self:do_states(dtime) then return end + + self:do_jump() + + self:do_runaway_from(self) + + self:do_stay_near() +end + + +-- default function when mobs are blown up with TNT +function mob_class:on_blast(damage) + +--print("-- blast damage", damage) + + self.object:punch(self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = damage}, + }, nil) + + -- return no damage, no knockback, no item drops, mob api handles all + return false, false, {} +end + + +mobs.spawning_mobs = {} + +-- register mob entity +function mobs:register_mob(name, def) + + mobs.spawning_mobs[name] = {} + + local collisionbox = def.collisionbox or {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25} + + -- quick fix to stop mobs glitching through nodes if too small + if -collisionbox[2] + collisionbox[5] < 1.01 then + collisionbox[5] = collisionbox[2] + 0.99 + end + +minetest.register_entity(name, setmetatable({ + + stepheight = def.stepheight, + name = name, + type = def.type, + attack_type = def.attack_type, + fly = def.fly, + fly_in = def.fly_in, + keep_flying = def.keep_flying, + owner = def.owner, + order = def.order, + on_die = def.on_die, + on_flop = def.on_flop, + do_custom = def.do_custom, + jump_height = def.jump_height, + can_leap = def.can_leap, + drawtype = def.drawtype, -- DEPRECATED, use rotate instead + rotate = rad(def.rotate or 0), -- 0=front 90=side 180=back 270=side2 + glow = def.glow, + lifetimer = def.lifetimer, + hp_min = max(1, (def.hp_min or 5) * difficulty), + hp_max = max(1, (def.hp_max or 10) * difficulty), + collisionbox = collisionbox, --def.collisionbox, + selectionbox = def.selectionbox or collisionbox, --def.collisionbox, + visual = def.visual, + visual_size = def.visual_size, + mesh = def.mesh, + makes_footstep_sound = def.makes_footstep_sound, + view_range = def.view_range, + walk_velocity = def.walk_velocity, + run_velocity = def.run_velocity, + damage = max(0, (def.damage or 0) * difficulty), + damage_group = def.damage_group, + damage_texture_modifier = def.damage_texture_modifier, + light_damage = def.light_damage, + light_damage_min = def.light_damage_min, + light_damage_max = def.light_damage_max, + water_damage = def.water_damage, + lava_damage = def.lava_damage, + fire_damage = def.fire_damage, + air_damage = def.air_damage, + suffocation = def.suffocation, + fall_damage = def.fall_damage, + fall_speed = def.fall_speed, + drops = def.drops, + armor = def.armor, + on_rightclick = def.on_rightclick, + arrow = def.arrow, + arrow_override = def.arrow_override, + shoot_interval = def.shoot_interval, + sounds = def.sounds, + animation = def.animation, + follow = def.follow, + jump = def.jump, + walk_chance = def.walk_chance, + stand_chance = def.stand_chance, + attack_chance = def.attack_chance, + passive = def.passive, + knock_back = def.knock_back, + blood_amount = def.blood_amount, + blood_texture = def.blood_texture, + shoot_offset = def.shoot_offset, + floats = def.floats, + replace_rate = def.replace_rate, + replace_what = def.replace_what, + replace_with = def.replace_with, + replace_offset = def.replace_offset, + on_replace = def.on_replace, + reach = def.reach, + texture_list = def.textures, + texture_mods = def.texture_mods or "", + child_texture = def.child_texture, + docile_by_day = def.docile_by_day, + fear_height = def.fear_height, + runaway = def.runaway, + pathfinding = def.pathfinding, + immune_to = def.immune_to, + explosion_radius = def.explosion_radius, + explosion_damage_radius = def.explosion_damage_radius, + explosion_timer = def.explosion_timer, + allow_fuse_reset = def.allow_fuse_reset, + stop_to_explode = def.stop_to_explode, + custom_attack = def.custom_attack, + double_melee_attack = def.double_melee_attack, + dogshoot_switch = def.dogshoot_switch, + dogshoot_count_max = def.dogshoot_count_max, + dogshoot_count2_max = def.dogshoot_count2_max or def.dogshoot_count_max, + group_attack = def.group_attack, + group_helper = def.group_helper, + attack_monsters = def.attacks_monsters or def.attack_monsters, + attack_animals = def.attack_animals, + attack_players = def.attack_players, + attack_npcs = def.attack_npcs, + specific_attack = def.specific_attack, + runaway_from = def.runaway_from, + owner_loyal = def.owner_loyal, + pushable = def.pushable, + stay_near = def.stay_near, + randomly_turn = def.randomly_turn ~= false, + ignore_invisibility = def.ignore_invisibility, + messages = def.messages, + + on_spawn = def.on_spawn, + + on_blast = def.on_blast, -- class redifinition + + do_punch = def.do_punch, + + on_breed = def.on_breed, + + on_grown = def.on_grown, + + on_activate = function(self, staticdata, dtime) + return self:mob_activate(staticdata, def, dtime) + end, + + get_staticdata = function(self) + return self:mob_staticdata(self) + end + +}, mob_class_meta)) + +end -- END mobs:register_mob function + + +-- count how many mobs of one type are inside an area +-- will also return true for second value if player is inside area +local count_mobs = function(pos, type) + + local total = 0 + local objs = minetest.get_objects_inside_radius(pos, aoc_range * 2) + local ent + local players + + for n = 1, #objs do + + if not objs[n]:is_player() then + + ent = objs[n]:get_luaentity() + + -- count mob type and add to total also + if ent and ent.name and ent.name == type then + total = total + 1 + end + else + players = true + end + end + + return total, players +end + + +-- do we have enough space to spawn mob? (thanks wuzzy) +local can_spawn = function(pos, name) + + local ent = minetest.registered_entities[name] + local width_x = max(1, ceil(ent.collisionbox[4] - ent.collisionbox[1])) + local min_x, max_x + + if width_x % 2 == 0 then + max_x = floor(width_x / 2) + min_x = -(max_x - 1) + else + max_x = floor(width_x / 2) + min_x = -max_x + end + + local width_z = max(1, ceil(ent.collisionbox[6] - ent.collisionbox[3])) + local min_z, max_z + + if width_z % 2 == 0 then + max_z = floor(width_z / 2) + min_z = -(max_z - 1) + else + max_z = floor(width_z / 2) + min_z = -max_z + end + + local max_y = max(0, ceil(ent.collisionbox[5] - ent.collisionbox[2]) - 1) + local pos2 + + for y = 0, max_y do + for x = min_x, max_x do + for z = min_z, max_z do + + pos2 = {x = pos.x + x, y = pos.y + y, z = pos.z + z} + + if minetest.registered_nodes[node_ok(pos2).name].walkable == true then + return nil + end + end + end + end + + -- tweak X/Z spawn pos + if width_x % 2 == 0 then + pos.x = pos.x + 0.5 + end + + if width_z % 2 == 0 then + pos.z = pos.z + 0.5 + end + + return pos +end + +function mobs:can_spawn(pos, name) + return can_spawn(pos, name) +end + + +-- global functions + +function mobs:add_mob(pos, def) + + -- nil check + if not pos or not def then +--print("--- no position or definition given") + return + end + + -- is mob actually registered? + if not mobs.spawning_mobs[def.name] + or not minetest.registered_entities[def.name] then +--print("--- mob doesn't exist", def.name) + return + end + + -- are we over active mob limit + if active_limit > 0 and active_mobs >= active_limit then +--print("--- active mob limit reached", active_mobs, active_limit) + return + end + + -- get total number of this mob in area + local num_mob, is_pla = count_mobs(pos, def.name) + + if not is_pla then +--print("--- no players within active area, will not spawn " .. def.name) + return + end + + local aoc = mobs.spawning_mobs[def.name] + and mobs.spawning_mobs[def.name].aoc or 1 + + if def.ignore_count ~= true and num_mob >= aoc then +--print("--- too many " .. def.name .. " in area", num_mob .. "/" .. aoc) + return + end + + local mob = minetest.add_entity(pos, def.name) + +--print("[mobs] Spawned " .. def.name .. " at " .. minetest.pos_to_string(pos)) + + local ent = mob:get_luaentity() + + if not ent then +--print("[mobs] entity not found " .. def.name) + return false + end + + if def.child then + + local textures = ent.base_texture + + -- using specific child texture (if found) + if ent.child_texture then + textures = ent.child_texture[1] + end + + -- and resize to half height + mob:set_properties({ + textures = textures, + visual_size = { + x = ent.base_size.x * .5, + y = ent.base_size.y * .5 + }, + collisionbox = { + ent.base_colbox[1] * .5, + ent.base_colbox[2] * .5, + ent.base_colbox[3] * .5, + ent.base_colbox[4] * .5, + ent.base_colbox[5] * .5, + ent.base_colbox[6] * .5 + }, + selectionbox = { + ent.base_selbox[1] * .5, + ent.base_selbox[2] * .5, + ent.base_selbox[3] * .5, + ent.base_selbox[4] * .5, + ent.base_selbox[5] * .5, + ent.base_selbox[6] * .5 + } + }) + + ent.child = true + end + + if def.owner then + ent.tamed = true + ent.owner = def.owner + end + + if def.nametag then + + -- limit name entered to 64 characters long + if def.nametag:len() > 64 then + def.nametag = def.nametag:sub(1, 64) + end + + ent.nametag = def.nametag + + ent:update_tag() + end + + return ent +end + + +function mobs:spawn_abm_check(pos, node, name) + -- global function to add additional spawn checks + -- return true to stop spawning mob +end + + +function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval, + chance, aoc, min_height, max_height, day_toggle, on_spawn, map_load) + + -- Do mobs spawn at all? + if not mobs_spawn or not mobs.spawning_mobs[name] then +--print ("--- spawning not registered for " .. name) + return + end + + -- chance/spawn number override in minetest.conf for registered mob + local numbers = settings:get(name) + + if numbers then + + numbers = numbers:split(",") + chance = tonumber(numbers[1]) or chance + aoc = tonumber(numbers[2]) or aoc + + if chance == 0 then + + minetest.log("warning", + string.format("[mobs] %s has spawning disabled", name)) + return + end + + minetest.log("action", string.format( + "[mobs] Chance setting for %s changed to %s (total: %s)", + name, chance, aoc)) + end + + mobs.spawning_mobs[name].aoc = aoc + + local spawn_action = function(pos, node, active_object_count, + active_object_count_wider) + + -- use instead of abm's chance setting when using lbm + if map_load and random(max(1, (chance * mob_chance_multiplier))) > 1 then + return + end + + -- use instead of abm's neighbor setting when using lbm + if map_load and not minetest.find_node_near(pos, 1, neighbors) then +--print("--- lbm neighbors not found") + return + end + + -- is mob actually registered? + if not mobs.spawning_mobs[name] + or not minetest.registered_entities[name] then +--print("--- mob doesn't exist", name) + return + end + + -- are we over active mob limit + if active_limit > 0 and active_mobs >= active_limit then +--print("--- active mob limit reached", active_mobs, active_limit) + return + end + + -- additional custom checks for spawning mob + if mobs:spawn_abm_check(pos, node, name) == true then + return + end + + -- do not spawn if too many entities in area + if active_object_count_wider + and active_object_count_wider >= max_per_block then +--print("--- too many entities in area", active_object_count_wider) + return + end + + -- get total number of this mob in area + local num_mob, is_pla = count_mobs(pos, name) + + if not is_pla then +--print("--- no players within active area, will not spawn " .. name) + return + end + + if num_mob >= aoc then +--print("--- too many " .. name .. " in area", num_mob .. "/" .. aoc) + return + end + + -- if toggle set to nil then ignore day/night check + if day_toggle ~= nil then + + local tod = (minetest.get_timeofday() or 0) * 24000 + + if tod > 4500 and tod < 19500 then + -- daylight, but mob wants night + if day_toggle == false then +--print("--- mob needs night", name) + return + end + else + -- night time but mob wants day + if day_toggle == true then +--print("--- mob needs day", name) + return + end + end + end + + -- spawn above node + pos.y = pos.y + 1 + + -- are we spawning within height limits? + if pos.y > max_height + or pos.y < min_height then +--print("--- height limits not met", name, pos.y) + return + end + + -- are light levels ok? + local light = minetest.get_node_light(pos) + if not light + or light > max_light + or light < min_light then +--print("--- light limits not met", name, light) + return + end + + -- check if mob can spawn inside protected areas + if (spawn_protected == false + or (spawn_monster_protected == false + and minetest.registered_entities[name].type == "monster")) + and minetest.is_protected(pos, "") then +--print("--- inside protected area", name) + return + end + + -- only spawn a set distance away from player + local objs = minetest.get_objects_inside_radius(pos, mob_nospawn_range) + + for n = 1, #objs do + + if objs[n]:is_player() then +--print("--- player too close", name) + return + end + end + + local ent = minetest.registered_entities[name] + + -- should we check mob area for obstructions ? + if mob_area_spawn ~= true then + + -- do we have enough height clearance to spawn mob? + local height = max(0, ent.collisionbox[5] - ent.collisionbox[2]) + + for n = 0, floor(height) do + + local pos2 = {x = pos.x, y = pos.y + n, z = pos.z} + + if minetest.registered_nodes[node_ok(pos2).name].walkable == true then +--print ("--- inside block", name, node_ok(pos2).name) + return + end + end + else + -- returns position if we have enough space to spawn mob + pos = can_spawn(pos, name) + end + + if pos then + + -- adjust for mob collision box + pos.y = pos.y + (ent.collisionbox[2] * -1) - 0.4 + + local mob = minetest.add_entity(pos, name) + +-- print("[mobs] Spawned " .. name .. " at " +-- .. minetest.pos_to_string(pos) .. " on " +-- .. node.name .. " near " .. neighbors[1]) + + if on_spawn then + on_spawn(mob:get_luaentity(), pos) + end + else +--print("--- not enough space to spawn", name) + end + end + + + -- are we registering an abm or lbm? + if map_load == true then + + minetest.register_lbm({ + name = name .. "_spawning", + label = name .. " spawning", + nodenames = nodes, + run_at_every_load = false, + + action = function(pos, node) + spawn_action(pos, node) + end + }) + + else + + minetest.register_abm({ + label = name .. " spawning", + nodenames = nodes, + neighbors = neighbors, + interval = interval, + chance = max(1, (chance * mob_chance_multiplier)), + catch_up = false, + + action = function(pos, node, active_object_count, active_object_count_wider) + spawn_action(pos, node, active_object_count, active_object_count_wider) + end + }) + end +end + + +-- compatibility with older mob registration +function mobs:register_spawn(name, nodes, max_light, min_light, chance, + active_object_count, max_height, day_toggle) + + mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30, + chance, active_object_count, -31000, max_height, day_toggle) +end + + +-- MarkBu's spawn function (USE this one please) +function mobs:spawn(def) + + mobs:spawn_specific( + def.name, + def.nodes or {"group:soil", "group:stone"}, + def.neighbors or {"air"}, + def.min_light or 0, + def.max_light or 15, + def.interval or 30, + def.chance or 5000, + def.active_object_count or 1, + def.min_height or -31000, + def.max_height or 31000, + def.day_toggle, + def.on_spawn, + def.on_map_load) +end + + +-- register arrow for shoot attack +function mobs:register_arrow(name, def) + + if not name or not def then return end -- errorcheck + + minetest.register_entity(name, { + + physical = def.physical or false, + collide_with_objects = def.collide_with_objects or false, + static_save = false, + + visual = def.visual, + visual_size = def.visual_size, + textures = def.textures, + velocity = def.velocity, + hit_player = def.hit_player, + hit_node = def.hit_node, + hit_mob = def.hit_mob, + hit_object = def.hit_object, + drop = def.drop or false, -- drops arrow as registered item when true + collisionbox = def.collisionbox or {-.1, -.1, -.1, .1, .1, .1}, + timer = 0, + lifetime = def.lifetime or 4.5, + switch = 0, + owner_id = def.owner_id, + rotate = def.rotate, + automatic_face_movement_dir = def.rotate + and (def.rotate - (pi / 180)) or false, + + on_activate = def.on_activate, + + on_punch = def.on_punch or function( + self, hitter, tflp, tool_capabilities, dir) + end, + + on_step = def.on_step or function(self, dtime) + + self.timer = self.timer + dtime + + local pos = self.object:get_pos() + + if self.switch == 0 or self.timer > self.lifetime then + + self.object:remove() ; -- print("removed arrow") + + return + end + + -- does arrow have a tail (fireball) + if def.tail and def.tail == 1 and def.tail_texture then + + minetest.add_particle({ + pos = pos, + velocity = {x = 0, y = 0, z = 0}, + acceleration = {x = 0, y = 0, z = 0}, + expirationtime = def.expire or 0.25, + collisiondetection = false, + texture = def.tail_texture, + size = def.tail_size or 5, + glow = def.glow or 0 + }) + end + + if self.hit_node then + + local node = node_ok(pos).name + + if minetest.registered_nodes[node].walkable then + + self:hit_node(pos, node) + + if self.drop == true then + + pos.y = pos.y + 1 + + self.lastpos = (self.lastpos or pos) + + minetest.add_item(self.lastpos, + self.object:get_luaentity().name) + end + + self.object:remove() ; -- print("hit node") + + return + end + end + + if self.hit_player or self.hit_mob or self.hit_object then + + for _,player in pairs( + minetest.get_objects_inside_radius(pos, 1.0)) do + + if self.hit_player and player:is_player() then + + self:hit_player(player) + + self.object:remove() ; -- print("hit player") + + return + end + + local entity = player:get_luaentity() + + if entity + and self.hit_mob + and entity._cmi_is_mob == true + and tostring(player) ~= self.owner_id + and entity.name ~= self.object:get_luaentity().name then + + self:hit_mob(player) + + self.object:remove() ; --print("hit mob") + + return + end + + if entity + and self.hit_object + and (not entity._cmi_is_mob) + and tostring(player) ~= self.owner_id + and entity.name ~= self.object:get_luaentity().name then + + self:hit_object(player) + + self.object:remove() ; -- print("hit object") + + return + end + end + end + + self.lastpos = pos + end + }) +end + + +-- compatibility function (deprecated) +function mobs:explosion(pos, radius) + mobs:boom({sounds = {explode = "tnt_explode"}}, pos, radius, radius, "tnt_smoke.png") +end + + +-- no damage to nodes explosion +function mobs:safe_boom(self, pos, radius, texture) + + minetest.sound_play(self.sounds and self.sounds.explode or "tnt_explode", { + pos = pos, + gain = 1.0, + max_hear_distance = self.sounds and self.sounds.distance or 32 + }, true) + + entity_physics(pos, radius) + + effect(pos, 32, texture, radius * 3, radius * 5, radius, 1, 0) +end + + +-- make explosion with protection and tnt mod check +function mobs:boom(self, pos, radius, damage_radius, texture) + + if mobs_griefing + and minetest.get_modpath("tnt") and tnt and tnt.boom + and not minetest.is_protected(pos, "") then + + tnt.boom(pos, { + radius = radius, + damage_radius = damage_radius, + sound = self.sounds and self.sounds.explode, + explode_center = true, + tiles = {(texture or "tnt_smoke.png")} + }) + else + mobs:safe_boom(self, pos, radius, texture) + end +end + + +-- Register spawn eggs + +-- Note: This also introduces the “spawn_egg” group: +-- * spawn_egg=1: Spawn egg (generic mob, no metadata) +-- * spawn_egg=2: Spawn egg (captured/tamed mob, metadata) +function mobs:register_egg(mob, desc, background, addegg, no_creative) + + local grp = {spawn_egg = 1} + + -- do NOT add this egg to creative inventory (e.g. dungeon master) + if no_creative == true then + grp.not_in_creative_inventory = 1 + end + + local invimg = background + + if addegg == 1 then + invimg = "mobs_chicken_egg.png^(" .. invimg .. + "^[mask:mobs_chicken_egg_overlay.png)" + end + + -- register new spawn egg containing mob information + minetest.register_craftitem(mob .. "_set", { + + description = S("@1 (Tamed)", desc), + inventory_image = invimg, + groups = {spawn_egg = 2, not_in_creative_inventory = 1}, + stack_max = 1, + + on_place = function(itemstack, placer, pointed_thing) + + local pos = pointed_thing.above + + -- does existing on_rightclick function exist? + local under = minetest.get_node(pointed_thing.under) + local def = minetest.registered_nodes[under.name] + + if def and def.on_rightclick then + + return def.on_rightclick( + pointed_thing.under, under, placer, itemstack, pointed_thing) + end + + if pos + and not minetest.is_protected(pos, placer:get_player_name()) then + + if not minetest.registered_entities[mob] then + return + end + + pos.y = pos.y + 1 + + local data = itemstack:get_metadata() + local smob = minetest.add_entity(pos, mob, data) + local ent = smob and smob:get_luaentity() + + if not ent then return end -- sanity check + + -- set owner if not a monster + if ent.type ~= "monster" then + ent.owner = placer:get_player_name() + ent.tamed = true + end + + -- since mob is unique we remove egg once spawned + itemstack:take_item() + end + + return itemstack + end + }) + + + -- register old stackable mob egg + minetest.register_craftitem(mob, { + + description = desc, + inventory_image = invimg, + groups = grp, + + on_place = function(itemstack, placer, pointed_thing) + + local pos = pointed_thing.above + + -- does existing on_rightclick function exist? + local under = minetest.get_node(pointed_thing.under) + local def = minetest.registered_nodes[under.name] + + if def and def.on_rightclick then + + return def.on_rightclick( + pointed_thing.under, under, placer, itemstack, pointed_thing) + end + + if pos + and not minetest.is_protected(pos, placer:get_player_name()) then + + if not minetest.registered_entities[mob] then + return + end + + -- have we reached active mob limit + if active_limit > 0 and active_mobs >= active_limit then + minetest.chat_send_player(placer:get_player_name(), + S("Active Mob Limit Reached!") + .. " (" .. active_mobs + .. " / " .. active_limit .. ")") + return + end + + pos.y = pos.y + 1 + + local smob = minetest.add_entity(pos, mob) + local ent = smob and smob:get_luaentity() + + if not ent then return end -- sanity check + + -- don't set owner if monster or sneak pressed + if ent.type ~= "monster" + and not placer:get_player_control().sneak then + ent.owner = placer:get_player_name() + ent.tamed = true + end + + -- if not in creative then take item + if not mobs.is_creative(placer:get_player_name()) then + itemstack:take_item() + end + end + + return itemstack + end + }) +end + + +-- force capture a mob if space available in inventory, or drop as spawn egg +function mobs:force_capture(self, clicker) + + -- add special mob egg with all mob information + local new_stack = ItemStack(self.name .. "_set") + + local tmp, t = {} + + for _,stat in pairs(self) do + + t = type(stat) + + if t ~= "function" + and t ~= "nil" + and t ~= "userdata" then + tmp[_] = self[_] + end + end + + local data_str = minetest.serialize(tmp) + + new_stack:set_metadata(data_str) + + local inv = clicker:get_inventory() + + if inv:room_for_item("main", new_stack) then + inv:add_item("main", new_stack) + else + minetest.add_item(clicker:get_pos(), new_stack) + end + + self:mob_sound("default_place_node_hard") + + remove_mob(self, true) +end + + +-- capture critter (thanks to blert2112 for idea) +function mobs:capture_mob(self, clicker, chance_hand, chance_net, + chance_lasso, force_take, replacewith) + + if not self + or not clicker:is_player() + or not clicker:get_inventory() then + return false + end + + -- get name of clicked mob + local mobname = self.name + + -- if not nil change what will be added to inventory + if replacewith then + mobname = replacewith + end + + local name = clicker:get_player_name() + local tool = clicker:get_wielded_item() + + -- are we using hand, net or lasso to pick up mob? + if tool:get_name() ~= "" + and tool:get_name() ~= "mobs:net" + and tool:get_name() ~= "mobs:lasso" then + return false + end + + -- is mob tamed? + if self.tamed == false and force_take == false then + + minetest.chat_send_player(name, S("Not tamed!")) + + return false + end + + -- cannot pick up if not owner (unless player has protection_bypass priv) + if not minetest.check_player_privs(name, "protection_bypass") + and self.owner ~= name and force_take == false then + + minetest.chat_send_player(name, S("@1 is owner!", self.owner)) + + return false + end + + if clicker:get_inventory():room_for_item("main", mobname) then + + -- was mob clicked with hand, net, or lasso? + local chance = 0 + + if tool:get_name() == "" then + chance = chance_hand + + elseif tool:get_name() == "mobs:net" then + + chance = chance_net + + tool:add_wear(4000) -- 17 uses + + clicker:set_wielded_item(tool) + + elseif tool:get_name() == "mobs:lasso" then + + chance = chance_lasso + + tool:add_wear(650) -- 100 uses + + clicker:set_wielded_item(tool) + + end + + -- calculate chance.. add to inventory if successful? + if chance and chance > 0 and random(100) <= chance then + + -- default mob egg + local new_stack = ItemStack(mobname) + + -- add special mob egg with all mob information + -- unless 'replacewith' contains new item to use + if not replacewith then + + new_stack = ItemStack(mobname .. "_set") + + local tmp, t = {} + + for _,stat in pairs(self) do + + t = type(stat) + + if t ~= "function" + and t ~= "nil" + and t ~= "userdata" then + tmp[_] = self[_] + end + end + + local data_str = minetest.serialize(tmp) + + new_stack:set_metadata(data_str) + end + + local inv = clicker:get_inventory() + + if inv:room_for_item("main", new_stack) then + inv:add_item("main", new_stack) + else + minetest.add_item(clicker:get_pos(), new_stack) + end + + self:mob_sound("default_place_node_hard") + + remove_mob(self, true) + + return new_stack + + -- when chance above fails or set to 0, miss! + elseif chance and chance ~= 0 then + + minetest.chat_send_player(name, S("Missed!")) + + self:mob_sound("mobs_swing") + + return false + + -- when chance is nil always return a miss (used for npc walk/follow) + elseif not chance then + return false + end + end + + return true +end + + +-- protect tamed mob with rune item +function mobs:protect(self, clicker) + + local name = clicker:get_player_name() + local tool = clicker:get_wielded_item() + local tool_name = tool:get_name() + + if tool_name ~= "mobs:protector" + and tool_name ~= "mobs:protector2" then + return false + end + + if not self.tamed then + minetest.chat_send_player(name, S("Not tamed!")) + return true + end + + if (self.protected and tool_name == "mobs:protector") + or (self.protected == 2 and tool_name == "mobs:protector2") then + minetest.chat_send_player(name, S("Already protected!")) + return true + end + + if not mobs.is_creative(clicker:get_player_name()) then + tool:take_item() -- take 1 protection rune + clicker:set_wielded_item(tool) + end + + -- set protection level + if tool_name == "mobs:protector" then + self.protected = true + else + self.protected = 2 ; self.fire_damage = 0 + end + + local pos = self.object:get_pos() + + pos.y = pos.y + self.collisionbox[2] + 0.5 + + effect(self.object:get_pos(), 25, "mobs_protect_particle.png", 0.5, 4, 2, 15) + + self:mob_sound("mobs_spell") + + return true +end + + +local mob_obj = {} +local mob_sta = {} + +-- feeding, taming and breeding (thanks blert2112) +function mobs:feed_tame(self, clicker, feed_count, breed, tame) + + -- can eat/tame with item in hand + if self.follow + and self:follow_holding(clicker) then + + -- if not in creative then take item + if not mobs.is_creative(clicker:get_player_name()) then + + local item = clicker:get_wielded_item() + + item:take_item() + + clicker:set_wielded_item(item) + end + + -- increase health + self.health = self.health + 4 + + if self.health >= self.hp_max then + + self.health = self.hp_max + end + + self.object:set_hp(self.health) + + -- make children grow quicker + if self.child == true then + + -- deduct 10% of the time to adulthood + self.hornytimer = math.floor(self.hornytimer + ( + (CHILD_GROW_TIME - self.hornytimer) * 0.1)) +--print ("====", self.hornytimer) + return true + end + + -- feed and tame + self.food = (self.food or 0) + 1 + self._breed_countdown = feed_count - self.food + + if self.food >= feed_count then + + self.food = 0 + self._breed_countdown = nil + + if breed and self.hornytimer == 0 then + self.horny = true + end + + if tame then + + if self.tamed == false then + minetest.chat_send_player(clicker:get_player_name(), + S("@1 has been tamed!", + self.name:split(":")[2])) + end + + self.tamed = true + self.static_save = true + + if not self.owner or self.owner == "" then + self.owner = clicker:get_player_name() + end + end + + -- make sound when fed so many times + self:mob_sound(self.sounds.random) + end + + self:update_tag() + + return true + end + + local item = clicker:get_wielded_item() + local name = clicker:get_player_name() + + -- if mob has been tamed you can name it with a nametag + if item:get_name() == "mobs:nametag" + and (name == self.owner + or minetest.check_player_privs(name, "protection_bypass")) then + + -- store mob and nametag stack in external variables + mob_obj[name] = self + mob_sta[name] = item + + local tag = self.nametag or "" + local esc = minetest.formspec_escape + + minetest.show_formspec(name, "mobs_nametag", + "size[8,4]" .. + "field[0.5,1;7.5,0;name;" .. + esc(S("Enter name:")) .. + ";" .. tag .. "]" .. + "button_exit[2.5,3.5;3,1;mob_rename;" .. + esc(S("Rename")) .. "]") + + return true + end + + -- if mob follows items and user right clicks while holding sneak it shows info + if self.follow then + + if clicker:get_player_control().sneak then + + if type(self.follow) == "string" then + self.follow = {self.follow} + end + + minetest.chat_send_player(clicker:get_player_name(), + S("@1 follows:\n- @2", + self.name:split(":")[2], + table.concat(self.follow, "\n- "))) + end + end + + return false +end + + +-- inspired by blockmen's nametag mod +minetest.register_on_player_receive_fields(function(player, formname, fields) + + -- right-clicked with nametag and name entered? + if formname == "mobs_nametag" + and fields.name + and fields.name ~= "" then + + local name = player:get_player_name() + + if not mob_obj[name] + or not mob_obj[name].object then + return + end + + -- make sure nametag is being used to name mob + local item = player:get_wielded_item() + + if item:get_name() ~= "mobs:nametag" then + return + end + + -- limit name entered to 64 characters long + if fields.name:len() > 64 then + fields.name = fields.name:sub(1, 64) + end + + -- update nametag + mob_obj[name].nametag = fields.name + + mob_obj[name]:update_tag() + + -- if not in creative then take item + if not mobs.is_creative(name) then + + mob_sta[name]:take_item() + + player:set_wielded_item(mob_sta[name]) + end + + -- reset external variables + mob_obj[name] = nil + mob_sta[name] = nil + end +end) + + +-- compatibility function for old mobs entities to new mobs_redo modpack +function mobs:alias_mob(old_name, new_name) + + -- check old_name entity doesnt already exist + if minetest.registered_entities[old_name] then + return + end + + -- spawn egg + minetest.register_alias(old_name, new_name) + + -- entity + minetest.register_entity(":" .. old_name, { + + physical = false, static_save = false, + + on_activate = function(self, staticdata) + + if minetest.registered_entities[new_name] then + + minetest.add_entity(self.object:get_pos(), new_name, staticdata) + end + + remove_mob(self) + end, + + get_staticdata = function(self) + return self + end + }) +end + + +-- admin command to remove untamed mobs around players +minetest.register_chatcommand("clear_mobs", { + params = "", + description = "Remove untamed mobs from around players.", + privs = {server = true}, + + func = function (name, param) + + local count = 0 + + for _, player in pairs(minetest.get_connected_players()) do + + if player then + + local pos = player:get_pos() + + local objs = minetest.get_objects_inside_radius(pos, 28) + + for _, obj in pairs(objs) do + + if obj then + + local ent = obj:get_luaentity() + + -- only remove mobs redo mobs that are not tamed + if ent and ent._cmi_is_mob and ent.tamed ~= true then + + remove_mob(ent, true) + + count = count + 1 + end + end + end + end + end + + minetest.chat_send_player(name, S("@1 mobs removed.", count)) + end +}) diff --git a/mods/mobs_redo/api.txt b/mods/mobs_redo/api.txt new file mode 100644 index 0000000..76095ae --- /dev/null +++ b/mods/mobs_redo/api.txt @@ -0,0 +1,901 @@ + +Mobs Redo API +============= + +Welcome to the world of mobs in minetest and hopefully an easy guide to defining +your own mobs and having them appear in your worlds. + + +Quick Note +---------- + +Since the mobs redo api checks for nodes around the mob to function, it relies on a +default node incase anything goes wrong, so in the default game this is default:dirt +but for any custom game please make sure the following line is registered with your +preferred dirt node of choice: + +minetest.register_alias("mapgen_dirt", "mymod:my_dirt_node") + + +Registering Mobs +---------------- + +To register a mob and have it ready for use requires the following function: + + mobs:register_mob(name, definition) + +The 'name' of a mob usually starts with the mod name it's running from followed +by it's own name e.g. + + "mobs_monster:sand_monster" or "mymod:totally_awesome_beast" + +... and the 'definition' is a table which holds all of the settings and +functions needed for the mob to work properly which contains the following: + + 'nametag' contains the name which is shown above mob. + 'type' holds the type of mob that inhabits your world e.g. + "animal" usually docile and walking around. + "monster" attacks player or npc on sight. + "npc" walk around and will defend themselves if hit first, they + kill monsters. + 'hp_min' has the minimum health value the mob can spawn with. + 'hp_max' has the maximum health value the mob can spawn with. + 'armor' holds strength of mob, 100 is normal, lower is more powerful + and needs more hits and better weapons to kill. + 'passive' when false allows animals to defend themselves when hit, + otherwise they amble onwards. + 'walk_velocity' is the speed that your mob can walk around. + 'run_velocity' is the speed your mob can run with, usually when attacking. + 'stand_chance' has a 0-100 chance value your mob will stand from walking. + 'walk_chance' has a 0-100 chance value your mob will walk from standing, + set to 0 for jumping mobs only. + 'randomly_turn' if set to false then mob will not turn to face player or + randomly turn while walking or standing. + 'jump' when true allows your mob to jump updwards. + 'jump_height' holds the height your mob can jump, 0 to disable jumping. + 'can_leap' when true obstacles like fences or pits wont stop a mob + from trying to jump out. + 'stepheight' height of a block that your mob can easily walk up onto, + defaults to 1.1. + 'fly' when true allows your mob to fly around instead of walking. + 'fly_in' holds the node name that the mob flies (or swims) around + in e.g. "air" or "default:water_source". + 'keep_flying' when true mobs like birds no longer stop and stand. + 'stay_near' when set allows mobs the chance to stay around certain nodes. + 'nodes' string or table of nodes to stay nearby e.g. "farming:straw" + 'chance' chance of searching for above node(s), default is 10. + 'runaway' if true causes animals to turn and run away when hit. + 'pushable' when true mobs can be pushed by player or other mobs. + 'view_range' how many nodes in distance the mob can see a player. + 'damage' how many health points the mob does to a player or another + mob when melee attacking. + 'damage_group' group in which damage is dealt, dedaults to "fleshy". + 'damage_texture_modifier' applies texture modifier on hit e.g "^[brighten" + 'knock_back' when true has mobs falling backwards when hit, the greater + the damage the more they move back. + 'fear_height' is how high a cliff or edge has to be before the mob stops + walking, 0 to turn off height fear. + 'fall_speed' has the maximum speed the mob can fall at, default is -10. + 'fall_damage' when true causes falling to inflict damage. + 'water_damage' holds the damage per second infliced to mobs when standing in + water. + 'air_damage' holds damage per second inflicted to mob when standing in air. + 'lava_damage' holds the damage per second inflicted to mobs when standing + in lava. + 'fire_damage' holds the damage per second inflicted to mobs when standing + in fire. + + 'light_damage' holds the damage per second inflicted to mobs when light + level is between the min and max values below + 'light_damage_min' minimum light value when mob is affected (default: 14) + 'light_damage_max' maximum light value when mob is affected (default: 15) + 'suffocation' when > 0 mobs will suffocate inside solid blocks and will be + hurt by the value given every second (0 to disable). + 'floats' when set to 1 mob will float in water, 0 has them sink. + 'follow' mobs follow player when holding any of the items which appear + on this table, the same items can be fed to a mob to tame or + breed e.g. {"farming:wheat", "default:apple", "group:fish"} + + 'reach' is how far the mob can attack player when standing + nearby, default is 3 nodes. + 'docile_by_day' when true has mobs wandering around during daylight + hours and only attacking player at night or when + provoked. + 'attack_chance' 0 to 100 chance the mob will attack (default is 5). + 'attack_monsters' when true mob will attack monsters. + 'attack_animals' when true mob will attack animals. + 'attack_npcs' when true mob will attack npcs within range. + 'attack_players' when true mob will attack players nearby. + 'owner_loyal' when true non-docile tamed mobs attack anything player + punches when nearby. + 'group_attack' when true has same mob type grouping together to attack + offender. + 'group_helper' string containing mob name that attacks alongside + current mob when group attacking. + mob is attacking in groups. + 'attack_type' tells the api what a mob does when attacking the player + or another mob: + 'dogfight' is a melee attack when player is within mob reach. + 'shoot' has mob shoot pre-defined arrows at player when inside + view_range. + 'dogshoot' has melee attack when inside reach and shoot attack + when inside view_range. + 'explode' causes mob to stop and explode when inside reach. + 'explosion_radius' the radius of explosion node destruction, + defaults to 1 + 'explosion_damage_radius' the radius of explosion entity & player damage, + defaults to explosion_radius * 2 + 'explosion_timer' number of seconds before mob explodes while its target + is still inside reach or explosion_damage_radius, + defaults to 3. + 'allow_fuse_reset' Allow 'explode' attack_type to reset fuse and resume + chasing if target leaves the blast radius or line of + sight. Defaults to true. + 'stop_to_explode' When set to true (default), mob must stop and wait for + explosion_timer in order to explode. If false, mob will + continue chasing. + 'arrow' holds the pre-defined arrow object to shoot when + attacking. + 'arrow_override' function that allows tweaking of arrow entity from + inside mob definition (self) passed to function. + 'dogshoot_switch' allows switching between attack types by using timers + (1 for shoot, 2 for dogfight) + 'dogshoot_count_max' contains how many seconds before switching from + dogfight to shoot. + 'dogshoot_count2_max' contains how many seconds before switching from shoot + to dogfight. + 'shoot_interval' has the number of seconds between shots. + 'shoot_offset' holds the y position added as to where the + arrow/fireball appears on mob. + 'specific_attack' has a table of entity names that mob can also attack + e.g. {"player", "mobs_animal:chicken"}. + 'runaway_from' contains a table with mob names to run away from, add + "player" to list to runaway from player also. + 'ignore_invisibility' When true mob will still be able to see and attack + player even if invisible (invisibility mod only). + 'blood_amount' contains the number of blood droplets to appear when + mob is hit. + 'blood_texture' has the texture name to use for droplets e.g. + "mobs_blood.png", or table {"blood1.png", "blood2.png"} + 'pathfinding' set to 1 for mobs to use pathfinder feature to locate + player, set to 2 so they can build/break also (only + works with dogfight attack and when 'mobs_griefing' + in minetest.conf is not false). Adding {unbreakable=1} + to node groups stops them being broken by mobs. + 'immune_to' is a table that holds specific damage when being hit by + certain items e.g. + {"default:sword_wood", 0} -- causes no damage. + {"default:gold_lump", -10} -- heals by 10 health points. + {"default:coal_block", 20} -- 20 damage when hit on head with coal blocks. + {"all"} -- stops all weapons causing damage apart from those on list. + + 'makes_footstep_sound' when true you can hear mobs walking. + 'sounds' this is a table with sounds of the mob + 'distance' maximum distance sounds can be heard, default is 10. + 'random' random sound that plays during gameplay. + 'war_cry' what you hear when mob starts to attack player. + 'attack' what you hear when being attacked. + 'shoot_attack' sound played when mob shoots. + 'damage' sound heard when mob is hurt. + 'death' played when mob is killed. + 'jump' played when mob jumps. + 'fuse' sound played when mob explode timer starts. + 'explode' sound played when mob explodes. + + 'drops' table of items that are dropped when mob is killed, fields are: + 'name' name of item to drop. + 'chance' chance of drop, 1 for always, 2 for 1-in-2 chance etc. + 'min' minimum number of items dropped, set to 0 for rare drops. + 'max' maximum number of items dropped. + Note: If weapon has {fire=1} damage group set then cooked items will drop. + Note2: A function can now be passed which can also return drops table, e.g. + drops = function(pos) + -- do something + return { {name = "farming:bread"}, {name = "default:dirt", chance = 2} } + end + + 'visual' holds the look of the mob you wish to create: + 'cube' looks like a normal node + 'sprite' sprite which looks same from all angles. + 'upright_sprite' flat model standing upright. + 'wielditem' how it looks when player holds it in hand. + 'mesh' uses separate object file to define mob. + 'visual_size' has the size of the mob, defaults to {x = 1, y = 1} + 'collisionbox' has the box in which mob can be interacted with the + world e.g. {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5} + 'selectionbox' has the box in which player can interact with mob + 'textures' holds a table list of textures to be used for mob, or you + could use multiple lists inside another table for random + selection e.g. { {"texture1.png"}, {"texture2.png"} } + 'child_texture' holds the texture table for when baby mobs are used. + 'gotten_texture' holds the texture table for when self.gotten value is + true, used for milking cows or shearing sheep. + 'texture_mods' holds a string which overlays a texture on top of the + mob texture e.g. "^saddle.png" + 'mesh' holds the name of the external object used for mob model + e.g. "mobs_cow.b3d" + 'gotten_mesh" holds the name of the external object used for when + self.gotten is true for mobs. + 'rotate' custom model rotation, 0 = front, 90 = side, 180 = back, + 270 = other side. + 'glow' has mob glow without light source, 0 to 15 or nil to disable + 'double_melee_attack' when true has the api choose between 'punch' and + 'punch2' animations. [DEPRECATED] + + 'animation' holds a table containing animation names and settings for use with + mesh models: + 'stand_start' start frame for when mob stands still. + 'stand_end' end frame of stand animation. + 'stand_speed' speed of animation in frames per second. + 'walk_start' when mob is walking around. + 'walk_end' + 'walk_speed' + 'run_start' when a mob runs or attacks. + 'run_end' + 'run_speed' + 'fly_start' when a mob is flying. + 'fly_end' + 'fly_speed' + 'jump_start' when a mob is jumping + 'jump_end' + 'jump_speed' + 'punch_start' when a mob melee attacks. + 'punch_end' + 'punch_speed' + 'punch2_start' alternative melee attack animation. + 'punch2_end' + 'punch2_speed' + 'shoot_start' shooting animation. + 'shoot_end' + 'shoot_speed' + 'die_start' death animation + 'die_end' + 'die_speed' + 'die_loop' when set to false stops the animation looping. + 'die_rotate' if true mob spins during death animation. + + Using '_loop = false' setting will stop any of the above animations from + looping. + + 'speed_normal' is used for animation speed for compatibility with some + older mobs. + + Note: Up to 5 different animations can be used per action e.g. + stand_start, stand_end, stand1_start, stand1_end .. up to stand4_start + + +Node Replacement +---------------- + +Mobs can look around for specific nodes as they walk and replace them to mimic +eating. + + 'replace_what' group of items to replace e.g. + {"farming:wheat_8", "farming:carrot_8"} + or you can use the specific options of what, with and + y offset by using this instead: + { + {"group:grass", "air", 0}, + {"default:dirt_with_grass", "default:dirt", -1} + } + 'replace_with' replace with what e.g. "air" or in chickens case "mobs:egg" + 'replace_rate' how random should the replace rate be (typically 10) + 'replace_offset' +/- value to check specific node to replace + + 'on_replace(self, pos, oldnode, newnode)' is called when mob is about to + replace a node. + 'self' ObjectRef of mob + 'pos' Position of node to replace + 'oldnode' Current node + 'newnode' What the node will become after replacing + + If false is returned, the mob will not replace the node. + + By default, replacing sets self.gotten to true and resets the object + properties. (DEPRECATED, use on_replace to make changes). + + +Custom Definition Functions +--------------------------- + +Along with the above mob registry settings we can also use custom functions to +enhance mob functionality and have them do many interesting things: + + 'on_die' a function that is called when the mob is killed the + parameters are (self, pos) + 'on_rightclick' its same as in minetest.register_entity() + 'on_blast' is called when an explosion happens near mob when using TNT + functions, parameters are (object, damage) and returns + (do_damage, do_knockback, drops) + 'on_spawn' is a custom function that runs on mob spawn with 'self' as + variable, return true at end of function to run only once. + 'after_activate' is a custom function that runs once mob has been activated + with these paramaters (self, staticdata, def, dtime) + 'on_breed' called when two similar mobs breed, paramaters are + (parent1, parent2) objects, return false to stop child from + being resized and owner/tamed flags and child textures being + applied. Function itself must spawn new child mob. + 'on_grown' is called when a child mob has grown up, only paramater is + (self). + 'do_punch' called when mob is punched with paramaters (self, hitter, + time_from_last_punch, tool_capabilities, direction), return + false to stop punch damage and knockback from taking place. + 'custom_attack' when set this function is called instead of the normal mob + melee attack, parameters are (self, to_attack) and if true + is returned normal attack function continued. + 'on_die' a function that is called when mob is killed (self, pos), also + has access to self.cause_of_death table. + 'on_flop' function called when flying or swimmimng mob is no longer in + air/water, (self) paramater and return true to skip the built + in api flop feature. + 'do_custom' a custom function that is called every tick while mob is + active and which has access to all of the self.* variables + e.g. (self.health for health or self.standing_in for node + status), return with 'false' to skip remainder of mob API. + + +Internal Variables +------------------ + +The mob api also has some preset variables and functions that it will remember +for each mob. + + 'self.health' contains current health of mob (cannot exceed + self.hp_max) + 'self.texture_list' contains list of all mob textures + 'self.child_texture' contains mob child texture when growing up + 'self.base_texture' contains current skin texture which was randomly + selected from textures list + 'self.gotten' this is used for obtaining milk from cow and wool from + sheep + 'self.horny' when animal fed enough it is set to true and animal can + breed with same animal + 'self.hornytimer' background timer that controls breeding functions and + mob childhood timings + 'self.child' used for when breeding animals have child, will use + child_texture and be half size + 'self.owner' string used to set owner of npc mobs, typically used for + dogs + 'self.order' set to "follow" or "stand" so that npc will follow owner + or stand it's ground + 'self.nametag' contains the name of the mob which it can show above + 'self.state' Current mob state. + "stand": no movement (except turning around) + "walk": walk or move around aimlessly + "attack": chase and attack enemy + "runaway": flee from target + "flop": bounce around aimlessly + (for swimming mobs that have stranded) + "die": during death + + +Adding Mobs in World +-------------------- + + mobs:add_mob(pos, { + name = "mobs_animal:chicken", + child = true, + owner = "singleplayer", + nametag = "Bessy", + ignore_count = true -- ignores mob count per map area + }) + +Returns false if mob could not be added, returns mob object if spawned ok. + + +Removing Mob from World +----------------------- + + mobs:remove(self, decrease) + +Removes mob 'self' from the world and if 'decrease' is true then the mob counter +will also be decreased by one. + + +Spawning Mobs in World +---------------------- + + mobs:spawn({ + name = "mobs_monster:tree_monster", + nodes = {"group:leaves"}, + max_light = 7, + }) + +Spawn functions require the following settings, some of which already have a +default setting and can be omitted: + + 'name' is the name of the animal/monster + 'nodes' is a list of nodenames on that the animal/monster can + spawn on top of (defaults to {"group:dirt", "group:stone"} + 'neighbors' is a list of nodenames on that the animal/monster will + spawn beside (default is {"air"}) + 'interval' is same as in register_abm() (default is 30) + 'chance' is same as in register_abm() (default is 5000) + 'min_light' is the minimum light level (default is 0) + 'max_light' is the maximum light (default is 15) + 'min_height' is the minimum height a mob can spawn (default: -31000) + 'max_height' is the maximum height a mob can spawn (default is 31000) + 'active_object_count' number of this type of mob to spawn at one time inside + map area (default is 1) + 'day_toggle' true for day spawning, false for night or nil for + anytime + 'on_spawn' is a custom function which runs after mob has spawned + and gives self and pos values. + 'on_map_load' when true mobs will have a chance of spawning only + when new areas of map are loaded, interval will not be + used. + +The older spawn functions are still active and working but have no defaults like +the mobs:spawn, so it is recommended to use the above instead. + +mobs:register_spawn(name, nodes, max_light, min_light, chance, + active_object_count, max_height, day_toggle) + +mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval, + chance, active_object_count, min_height, max_height, day_toggle, on_spawn) + +A simpler way to handle mob spawns has been added with the mobs:spawn(def) +command which uses above names to make settings clearer: + + +For each mob that spawns with this function is a field in mobs.spawning_mobs. +It tells if the mob should spawn or not. Default is true. So other mods can +only use the API of this mod by disabling the spawning of the default mobs in +this mod. + + +mobs:spawn_abm_check(pos, node, name) + +This global function can be changed to contain additional checks for mobs to +spawn e.g. mobs that spawn only in specific areas and the like. By returning +true the mob will not spawn. + + 'pos' holds the position of the spawning mob + 'node' contains the node the mob is spawning on top of + 'name' is the name of the animal/monster + + +Particle Effects +---------------- + +mobs:effect(pos, amount, texture, min_size, max_size, radius, gravity, glow, fall) + +This function provides a quick way to spawn particles as an effect. + + 'pos' center position of particle effect. + 'amount' how many particles. + 'texture' texture filename to use for effect. + 'min_size' smallest particle size. + 'max_size' largest particle size. + 'radius' how far particles spread outward from center. + 'gravity' gravity applied to particles once they spawn. + 'glow' number between 1 and 15 for glowing particles. + 'fall' when true particles fall, false has them rising, nil has them scatter. + + +Making Arrows +------------- + +mobs:register_arrow(name, definition) + +This function registers a arrow for mobs with the attack type shoot. + + 'name' is the name of the arrow + 'definition' is a table with the following values: + 'visual' same is in minetest.register_entity() + 'visual_size' same is in minetest.register_entity() + 'textures' same is in minetest.register_entity() + 'physical' same is in minetest.register_entity() [default: false] + 'collide_with_objects' same as above + 'velocity' the velocity of the arrow + 'drop' if set to true any arrows hitting a node will drop as item + 'hit_player' a function that is called when the arrow hits a player; + this function should hurt the player, the parameters are + (self, player) + 'hit_mob' a function that is called when the arrow hits a mob; + this function should hurt the mob, the parameters are + (self, player) + 'hit_object' a function that is called when the arrow hits an object; + this function parameters are (self, player) + 'hit_node' a function that is called when the arrow hits a node, the + parameters are (self, pos, node) + 'tail' when set to 1 adds a trail or tail to mob arrows + 'tail_texture' texture string used for above effect + 'tail_size' has size for above texture (defaults to between 5 and 10) + 'expire' contains float value for how long tail appears for + (defaults to 0.25) + 'glow' has value for how brightly tail glows 1 to 10 (default is + 0 for no glow) + 'rotate' integer value in degrees to rotate arrow + 'on_step' is a custom function when arrow is active, nil for + default. + 'on_punch' is a custom function when arrow is punched, nil by default + 'collisionbox' is hitbox table for arrow, {-.1,-.1,-.1,.1,.1,.1} by default. + 'lifetime' contains float value for how many seconds arrow exists in + world before being removed (default is 4.5 seconds). + + +Spawn Eggs +---------- + +mobs:register_egg(name, description, background, addegg, no_creative) + +This function registers a spawn egg which can be used to properly spawn in a mob. +Animals are spawned as tamed unless sneak/shift is held while spawning. + + 'name' this is the name of your new mob to spawn e.g. "mob:sheep" + 'description' the name of the new egg you are creating e.g. "Spawn Sheep" + 'background' the texture displayed for the egg in inventory + 'addegg' would you like an egg image in front of your texture (1 = yes, + 0 = no) + 'no_creative' when set to true this stops spawn egg appearing in creative + mode for destructive mobs like Dungeon Masters. + + +Explosion Function +------------------ + +mobs:explosion(pos, radius) -- DEPRECATED!!! use mobs:boom() instead + +mobs:boom(self, pos, radius, damage_radius, texture) + 'self' mob entity + 'pos' centre position of explosion + 'radius' radius of explosion (typically set to 3) + 'damage_radius' radius of damage around explosion + 'texture' particle texture during explosion, defaults to "tnt_smoke.png" + +This function generates an explosion which removes nodes in a specific radius +and damages any entity caught inside the blast radius. Protection will limit +node destruction but not entity damage. + + +Capturing Mobs +-------------- + +mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, + force_take, replacewith) + +This function is generally called inside the on_rightclick section of the mob +api code, it provides a chance of capturing the mob by hand, using the net or +lasso items, and can also have the player take the mob by force if tamed and +replace with another item entirely. + + 'self' mob information + 'clicker' player information + 'chance_hand' chance of capturing mob by hand (1 to 100) 0 to disable + 'chance_net' chance of capturing mob using net (1 to 100) 0 to disable + 'chance_lasso' chance of capturing mob using magic lasso (1 to 100) 0 to + disable + 'force_take' take mob by force, even if tamed (true or false) + 'replacewith' once captured replace mob with this item instead (overrides + new mob eggs with saved information) + +mobs:force_capture(self, clicker) + +Same as above but does no checks, it simply captures any and all mobs and places +inside a spawn egg containing all of the mob information. + + +Feeding and Taming/Breeding +--------------------------- + +mobs:feed_tame(self, clicker, feed_count, breed, tame) + +This function allows the mob to be fed the item inside self.follow be it apple, +wheat or whatever a set number of times and be tamed or bred as a result. +Will return true when mob is fed with item it likes. + + 'self' mob information + 'clicker' player information + 'feed_count' number of times mob must be fed to tame or breed + 'breed' true or false stating if mob can be bred and a child created + afterwards + 'tame' true or false stating if mob can be tamed so player can pick + them up + + +Protecting Mobs +--------------- + +mobs:protect(self, clicker) + +This function can be used to right-click any tamed mob with mobs:protector item, +this will protect the mob from harm inside of a protected area from other +players. Will return true when mob right-clicked with mobs:protector item. + + 'self' mob information + 'clicker' player information + + +Riding Mobs +----------- + +Mobs can now be ridden by players and the following shows its functions and +usage: + + +mobs:attach(self, player) + +This function attaches a player to the mob so it can be ridden. + + 'self' mob information + 'player' player information + + +mobs:detach(player, offset) + +This function will detach the player currently riding a mob to an offset +position. + + 'player' player information + 'offset' position table containing offset values + + +mobs:drive(self, move_animation, stand_animation, can_fly, dtime) + +This function allows an attached player to move the mob around and animate it at +same time. + + 'self' mob information + 'move_animation' string containing movement animation e.g. "walk" + 'stand_animation' string containing standing animation e.g. "stand" + 'can_fly' if true then jump and sneak controls will allow mob to fly + up and down + 'dtime' tick time used inside drive function + + +mobs:fly(self, dtime, speed, can_shoot, arrow_entity, move_animation, stand_animation) + +This function allows an attached player to fly the mob around using directional +controls. + + 'self' mob information + 'dtime' tick time used inside fly function + 'speed' speed of flight + 'can_shoot' true if mob can fire arrow (sneak and left mouse button + fires) + 'arrow_entity' name of arrow entity used for firing + 'move_animation' string containing name of pre-defined animation e.g. "walk" + or "fly" etc. + 'stand_animation' string containing name of pre-defined animation e.g. + "stand" or "blink" etc. + +Note: animation names above are from the pre-defined animation lists inside mob +registry without extensions. + + +mobs:set_animation(self, name) + +This function sets the current animation for mob, defaulting to "stand" if not +found. + + 'self' mob information + 'name' name of animation + + +Certain variables need to be set before using the above functions: + + 'self.v2' toggle switch used to define below values for the + first time + 'self.max_speed_forward' max speed mob can move forward + 'self.max_speed_reverse' max speed mob can move backwards + 'self.accel' acceleration speed + 'self.terrain_type' integer containing terrain mob can walk on + (1 = water, 2 or 3 = land) + 'self.driver_attach_at' position offset for attaching player to mob + 'self.driver_eye_offset' position offset for attached player view + 'self.driver_scale' sets driver scale for mobs larger than {x=1, y=1} + + +mobs:line_of_sight(self, pos1, pos2, stepsize) [DEPRECATED] + +This function is for use within the mobs definition for special use cases and +returns true if a mob can see the player or victim. + +...'self' mob information + 'pos1' position of mob + 'pos2' position of vistim or player + 'stepsize' usually set to 1 + +Use this instead: + + mob_class:line_of_sight(pos1, pos2, stepsize) + + +mobs:can_spawn(pos, name) + +This function checks the surrounding area at [pos] to see if there is enough empty +space to spawn mob [name], if so then a new position is returned for use, +otherwise nil is returned. + + +mobs:is_node_dangerous(mob_object, nodename) + +This function returns true if the node name given is harmful to the mob (mob_object), +it is mainly used when a mob is near a node it has to avoid. + + +Looting Level +------------- + +If a tool is used with 'looting_level' defined under tool_capabilities then mobs can drop +extra items per level up to a maximum of 3 levels. 'looting_level' can also be read from +the tools own meta to override the default. + + +External Settings for "minetest.conf" +------------------------------------ + + 'enable_damage' if true monsters will attack players (default is true) + 'only_peaceful_mobs' if true only animals will spawn in game (default is + false) + 'mobs_disable_blood' if false blood effects appear when mob is hit (default + is false) + 'mobs_spawn_protected' if set to false then mobs will not spawn in protected + areas (default is true) + 'mobs_spawn_monster_protected' if set to false then monsters will not spawn in + protected areas (default is true) + 'remove_far_mobs' if true then untamed mobs that are outside players + visual range will be removed (default is true) + 'mobname' can change specific mob chance rate (0 to disable) and + spawn number e.g. mobs_animal:cow = 1000,5 + 'mob_difficulty' sets difficulty level (health and hit damage + multiplied by this number), defaults to 1.0. + 'mob_chance_multiplier' multiplies chance of all mobs spawning and can be set + to 0.5 to have mobs spawn more or 2.0 to spawn less. + e.g. 1 in 7000 * 0.5 = 1 in 3500 so better odds of + spawning. + 'mobs_spawn' if false then mobs no longer spawn without spawner or + spawn egg. + 'mobs_drop_items' when false mobs no longer drop items when they die. + 'mobs_griefing' when false mobs cannot break blocks when using either + pathfinding level 2, replace functions or mobs:boom + function. + 'mob_nospawn_range' Minimum range a mob can spawn near player (def: 12) + 'mob_active_limit' Number of active mobs in game, 0 for unlimited + 'mob_area_spawn' When true will check surrounding area the size of the + mob for obstructions before spawning, otherwise it + defaults to checking the height of the mob only. + 'mob_smooth_rotate' Enables smooth rotation when mobs turn by default. + +Players can override the spawn chance for each mob registered by adding a line +to their minetest.conf file with a new value, the lower the value the more each +mob will spawn e.g. + +mobs_animal:sheep 11000 +mobs_monster:sand_monster 100 + +...you can also change how many of a certain mob appear in an active mapblock by +adding a comma and then a new value e.g. + +mobs_animal:cow = 8000,4 <-- 4 cows per mapblock at 8000 spawn chance +mobs_monster:dirt_monster = ,20 <-- 20 dirt monsters per mapblock + + +Rideable Horse Example Mob +-------------------------- + +mobs:register_mob("mob_horse:horse", { + type = "animal", + visual = "mesh", + visual_size = {x = 1.20, y = 1.20}, + mesh = "mobs_horse.x", + collisionbox = {-0.4, -0.01, -0.4, 0.4, 1.25, 0.4}, + animation = { + speed_normal = 15, + speed_run = 30, + stand_start = 25, + stand_end = 75, + walk_start = 75, + walk_end = 100, + run_start = 75, + run_end = 100, + }, + textures = { + {"mobs_horse.png"}, + {"mobs_horsepeg.png"}, + {"mobs_horseara.png"} + }, + fear_height = 3, + runaway = true, + fly = false, + walk_chance = 60, + view_range = 5, + follow = {"farming:wheat"}, + passive = true, + hp_min = 12, + hp_max = 16, + armor = 200, + lava_damage = 5, + fall_damage = 5, + water_damage = 1, + makes_footstep_sound = true, + drops = { + {name = "mobs:meat_raw", chance = 1, min = 2, max = 3} + }, + sounds = { + random = "horse_neigh.ogg", + damage = "horse_whinney.ogg", + }, + + do_custom = function(self, dtime) + + -- set needed values if not already present + if not self.v2 then + self.v2 = 0 + self.max_speed_forward = 6 + self.max_speed_reverse = 2 + self.accel = 6 + self.terrain_type = 3 + self.driver_attach_at = {x = 0, y = 20, z = -2} + self.driver_eye_offset = {x = 0, y = 3, z = 0} + self.driver_scale = {x = 1, y = 1} + end + + -- if driver present allow control of horse + if self.driver then + + mobs.drive(self, "walk", "stand", false, dtime) + + return false -- skip rest of mob functions + end + + return true + end, + + on_die = function(self, pos) + + -- drop saddle when horse is killed while riding + -- also detach from horse properly + if self.driver then + minetest.add_item(pos, "mobs:saddle") + mobs.detach(self.driver, {x = 1, y = 0, z = 1}) + end + + end, + + on_rightclick = function(self, clicker) + + -- make sure player is clicking + if not clicker or not clicker:is_player() then + return + end + + -- feed, tame or heal horse + if mobs:feed_tame(self, clicker, 10, true, true) then + return + end + + -- make sure tamed horse is being clicked by owner only + if self.tamed and self.owner == clicker:get_player_name() then + + local inv = clicker:get_inventory() + + -- detatch player already riding horse + if self.driver and clicker == self.driver then + + mobs.detach(clicker, {x = 1, y = 0, z = 1}) + + -- add saddle back to inventory + if inv:room_for_item("main", "mobs:saddle") then + inv:add_item("main", "mobs:saddle") + else + minetest.add_item(clicker.get_pos(), "mobs:saddle") + end + + -- attach player to horse + elseif not self.driver + and clicker:get_wielded_item():get_name() == "mobs:saddle" then + + self.object:set_properties({stepheight = 1.1}) + mobs.attach(self, clicker) + + -- take saddle from inventory + inv:remove_item("main", "mobs:saddle") + end + end + + -- used to capture horse with magic lasso + mobs:capture_mob(self, clicker, 0, 0, 80, false, nil) + end +}) diff --git a/mods/mobs_redo/crafts.lua b/mods/mobs_redo/crafts.lua new file mode 100644 index 0000000..32dd745 --- /dev/null +++ b/mods/mobs_redo/crafts.lua @@ -0,0 +1,379 @@ + +local S = mobs.intllib + +-- name tag +minetest.register_craftitem("mobs:nametag", { + description = S("Name Tag"), + inventory_image = "mobs_nametag.png", + groups = {flammable = 2, nametag = 1} +}) + +if minetest.get_modpath("dye") and minetest.get_modpath("farming") then + minetest.register_craft({ + output = "mobs:nametag", + recipe = {{"default:paper", "dye:black", "farming:string"}} + }) +end + +-- leather +minetest.register_craftitem("mobs:leather", { + description = S("Leather"), + inventory_image = "mobs_leather.png", + groups = {flammable = 2, leather = 1} +}) + +-- raw meat +minetest.register_craftitem("mobs:meat_raw", { + description = S("Raw Meat"), + inventory_image = "mobs_meat_raw.png", + on_use = minetest.item_eat(3), + groups = {food_meat_raw = 1, flammable = 2} +}) + +-- cooked meat +minetest.register_craftitem("mobs:meat", { + description = S("Meat"), + inventory_image = "mobs_meat.png", + on_use = minetest.item_eat(8), + groups = {food_meat = 1, flammable = 2} +}) + +minetest.register_craft({ + type = "cooking", + output = "mobs:meat", + recipe = "mobs:meat_raw", + cooktime = 5 +}) + +-- lasso +minetest.register_tool("mobs:lasso", { + description = S("Lasso (right-click animal to put in inventory)"), + inventory_image = "mobs_magic_lasso.png", + groups = {flammable = 2} +}) + +if minetest.get_modpath("farming") then + + minetest.register_craft({ + output = "mobs:lasso", + recipe = { + {"farming:string", "", "farming:string"}, + {"", "default:diamond", ""}, + {"farming:string", "", "farming:string"} + } + }) +end + +minetest.register_alias("mobs:magic_lasso", "mobs:lasso") + +-- net +minetest.register_tool("mobs:net", { + description = S("Net (right-click animal to put in inventory)"), + inventory_image = "mobs_net.png", + groups = {flammable = 2} +}) + +if minetest.get_modpath("farming") then + + minetest.register_craft({ + output = "mobs:net", + recipe = { + {"group:stick", "", "group:stick"}, + {"group:stick", "", "group:stick"}, + {"farming:string", "group:stick", "farming:string"} + } + }) +end + +-- shears (right click to shear animal) +minetest.register_tool("mobs:shears", { + description = S("Steel Shears (right-click to shear)"), + inventory_image = "mobs_shears.png", + groups = {flammable = 2} +}) + +minetest.register_craft({ + output = "mobs:shears", + recipe = { + {"", "default:steel_ingot", ""}, + {"", "group:stick", "default:steel_ingot"} + } +}) + +-- protection rune +minetest.register_craftitem("mobs:protector", { + description = S("Mob Protection Rune"), + inventory_image = "mobs_protector.png", + groups = {flammable = 2} +}) + +minetest.register_craft({ + output = "mobs:protector", + recipe = { + {"default:stone", "default:stone", "default:stone"}, + {"default:stone", "default:goldblock", "default:stone"}, + {"default:stone", "default:stone", "default:stone"} + } +}) + +-- level 2 protection rune +minetest.register_craftitem("mobs:protector2", { + description = S("Mob Protection Rune (Level 2)"), + inventory_image = "mobs_protector2.png", + groups = {flammable = 2} +}) + +minetest.register_craft({ + output = "mobs:protector2", + recipe = { + {"mobs:protector", "default:mese_crystal", "mobs:protector"}, + {"default:mese_crystal", "default:diamondblock", "default:mese_crystal"}, + {"mobs:protector", "default:mese_crystal", "mobs:protector"} + } +}) + +-- saddle +minetest.register_craftitem("mobs:saddle", { + description = S("Saddle"), + inventory_image = "mobs_saddle.png", + groups = {flammable = 2, saddle = 1} +}) + +minetest.register_craft({ + output = "mobs:saddle", + recipe = { + {"mobs:leather", "mobs:leather", "mobs:leather"}, + {"mobs:leather", "default:steel_ingot", "mobs:leather"}, + {"mobs:leather", "default:steel_ingot", "mobs:leather"} + } +}) + + +-- make sure we can register fences +local mod_def = minetest.get_modpath("default") + +if mod_def and default.register_fence then + +-- mob fence (looks like normal fence but collision is 2 high) +default.register_fence("mobs:fence_wood", { + description = S("Mob Fence"), + texture = "default_wood.png", + material = "default:fence_wood", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + sounds = mod_def and default.node_sound_wood_defaults(), + collision_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 1.9, 0.5}, + } + } +}) +end + +-- mob fence top (has enlarged collisionbox to stop mobs getting over) +minetest.register_node("mobs:fence_top", { + description = S("Mob Fence Top"), + drawtype = "nodebox", + tiles = {"default_wood.png"}, + paramtype = "light", + is_ground_content = false, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + sounds = mod_def and default.node_sound_wood_defaults(), + node_box = { + type = "fixed", + fixed = {-0.2, -0.5, -0.2, 0.2, 0, 0.2} + }, + collision_box = { + type = "fixed", + fixed = {-0.4, -1.5, -0.4, 0.4, 0, 0.4} + }, + selection_box = { + type = "fixed", + fixed = {-0.4, -1.5, -0.4, 0.4, 0, 0.4} + } +}) + +minetest.register_craft({ + output = "mobs:fence_top 12", + recipe = { + {"group:wood", "group:wood", "group:wood"}, + {"", "default:fence_wood", ""} + } +}) + + +-- items that can be used as fuel +minetest.register_craft({ + type = "fuel", + recipe = "mobs:nametag", + burntime = 3 +}) + +minetest.register_craft({ + type = "fuel", + recipe = "mobs:lasso", + burntime = 7 +}) + +minetest.register_craft({ + type = "fuel", + recipe = "mobs:net", + burntime = 8 +}) + +minetest.register_craft({ + type = "fuel", + recipe = "mobs:leather", + burntime = 4 +}) + +minetest.register_craft({ + type = "fuel", + recipe = "mobs:saddle", + burntime = 7 +}) + +minetest.register_craft({ + type = "fuel", + recipe = "mobs:fence_wood", + burntime = 7 +}) + +minetest.register_craft({ + type = "fuel", + recipe = "mobs:fence_top", + burntime = 2 +}) + + +-- this tool spawns same mob and adds owner, protected, nametag info +-- then removes original entity, this is used for fixing any issues. +-- also holding sneak while punching mob lets you change texture name. + +local tex_obj + +minetest.register_tool(":mobs:mob_reset_stick", { + description = S("Mob Reset Stick"), + inventory_image = "default_stick.png^[colorize:#ff000050", + stack_max = 1, + groups = {not_in_creative_inventory = 1}, + + on_use = function(itemstack, user, pointed_thing) + + if pointed_thing.type ~= "object" then + return + end + + local obj = pointed_thing.ref + + local control = user:get_player_control() + local sneak = control and control.sneak + + -- spawn same mob with saved stats, with random texture + if obj and not sneak then + + local self = obj:get_luaentity() + local obj2 = minetest.add_entity(obj:get_pos(), self.name) + + if obj2 then + + local ent2 = obj2:get_luaentity() + + ent2.protected = self.protected + ent2.owner = self.owner + ent2.nametag = self.nametag + ent2.gotten = self.gotten + ent2.tamed = self.tamed + ent2.health = self.health + ent2.order = self.order + + if self.child then + obj2:set_velocity({x = 0, y = self.jump_height, z = 0}) + end + + obj2:set_properties({nametag = self.nametag}) + + obj:remove() + end + end + + -- display form to enter texture name ending in .png + if obj and sneak then + + tex_obj = obj + + -- get base texture + local bt = tex_obj:get_luaentity().base_texture[1] + + if type(bt) ~= "string" then + bt = "" + end + + local name = user:get_player_name() + + minetest.show_formspec(name, "mobs_texture", "size[8,4]" + .. "field[0.5,1;7.5,0;name;" + .. minetest.formspec_escape(S("Enter texture:")) .. ";" .. bt .. "]" + .. "button_exit[2.5,3.5;3,1;mob_texture_change;" + .. minetest.formspec_escape(S("Change")) .. "]") + end + end +}) + +minetest.register_on_player_receive_fields(function(player, formname, fields) + + -- right-clicked with nametag and name entered? + if formname == "mobs_texture" + and fields.name + and fields.name ~= "" then + + -- does mob still exist? + if not tex_obj + or not tex_obj:get_luaentity() then + return + end + + -- make sure nametag is being used to name mob + local item = player:get_wielded_item() + + if item:get_name() ~= "mobs:mob_reset_stick" then + return + end + + -- limit name entered to 64 characters long + if fields.name:len() > 64 then + fields.name = fields.name:sub(1, 64) + end + + -- update texture + local self = tex_obj:get_luaentity() + + self.base_texture = {fields.name} + + tex_obj:set_properties({textures = {fields.name}}) + + -- reset external variable + tex_obj = nil + end +end) + + +-- Meat Block (thanks to painterlypack.net for allowing me to use these textures) +minetest.register_node("mobs:meatblock", { + description = S("Meat Block"), + tiles = {"mobs_meat_top.png", "mobs_meat_bottom.png", "mobs_meat_side.png"}, + paramtype2 = "facedir", + groups = {choppy = 1, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = mod_def and default.node_sound_leaves_defaults(), + on_place = minetest.rotate_node, + on_use = minetest.item_eat(20) +}) + +minetest.register_craft({ + output = "mobs:meatblock", + recipe = { + {"group:food_meat", "group:food_meat", "group:food_meat"}, + {"group:food_meat", "group:food_meat", "group:food_meat"}, + {"group:food_meat", "group:food_meat", "group:food_meat"} + } +}) diff --git a/mods/mobs_redo/depends.txt b/mods/mobs_redo/depends.txt new file mode 100644 index 0000000..6297913 --- /dev/null +++ b/mods/mobs_redo/depends.txt @@ -0,0 +1,11 @@ +default? +tnt? +dye? +farming? +invisibility? +intllib? +lucky_block? +cmi? +toolranks? +pathfinder? +player_api? diff --git a/mods/mobs_redo/description.txt b/mods/mobs_redo/description.txt new file mode 100644 index 0000000..919852a --- /dev/null +++ b/mods/mobs_redo/description.txt @@ -0,0 +1 @@ +Adds a mob api for mods to add animals or monsters etc. \ No newline at end of file diff --git a/mods/mobs_redo/init.lua b/mods/mobs_redo/init.lua new file mode 100644 index 0000000..4632238 --- /dev/null +++ b/mods/mobs_redo/init.lua @@ -0,0 +1,25 @@ + +local path = minetest.get_modpath("mobs") + +-- Peaceful player privilege +minetest.register_privilege("peaceful_player", { + description = "Prevents Mobs Redo mobs from attacking player", + give_to_singleplayer = false +}) + +-- Mob API +dofile(path .. "/api.lua") + +-- Rideable Mobs +dofile(path .. "/mount.lua") + +-- Mob Items +dofile(path .. "/crafts.lua") + +-- Mob Spawner +dofile(path .. "/spawner.lua") + +-- Lucky Blocks +dofile(path .. "/lucky_block.lua") + +print("[MOD] Mobs Redo loaded") diff --git a/mods/mobs_redo/license.txt b/mods/mobs_redo/license.txt new file mode 100644 index 0000000..fec6f6a --- /dev/null +++ b/mods/mobs_redo/license.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 TenPlus1 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/mods/mobs_redo/locale/de_DE.po b/mods/mobs_redo/locale/de_DE.po new file mode 100644 index 0000000..ac406bf --- /dev/null +++ b/mods/mobs_redo/locale/de_DE.po @@ -0,0 +1,131 @@ +# Mobs Redo translation. +# Copyright (C) 2017 TenPlus1 +# This file is distributed under the same license as the mobs package. +# Wuzzy , 2017 +# +msgid "" +msgstr "" +"Project-Id-Version: mobs\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-07-02 16:48+0200\n" +"PO-Revision-Date: 2017-07-02 14:27+0200\n" +"Last-Translator: Wuzzy \n" +"Language-Team: \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: api.lua +msgid "** Peaceful Mode Active - No Monsters Will Spawn" +msgstr "" + +#: api.lua +msgid "Mob has been protected!" +msgstr "Kreatur wurde geschützt!" + +#: api.lua +msgid "@1 (Tamed)" +msgstr "@1 (Gezähmt)" + +#: api.lua +msgid "Not tamed!" +msgstr "Nicht gezähmt!" + +#: api.lua +msgid "@1 is owner!" +msgstr "@1 ist der Besitzer!" + +#: api.lua +msgid "Missed!" +msgstr "Daneben!" + +#: api.lua +msgid "Already protected!" +msgstr "Bereits geschützt!" + +#: api.lua +msgid "@1 at full health (@2)" +msgstr "@1 bei voller Gesundheit (@2)" + +#: api.lua +msgid "@1 has been tamed!" +msgstr "@1 wurde gezähmt!" + +#: api.lua +msgid "Enter name:" +msgstr "Namen eingeben:" + +#: api.lua +msgid "Rename" +msgstr "Umbenennen" + +#: crafts.lua +msgid "Name Tag" +msgstr "Namensschild" + +#: crafts.lua +msgid "Leather" +msgstr "Leder" + +#: crafts.lua +msgid "Raw Meat" +msgstr "Rohes Fleisch" + +#: crafts.lua +msgid "Meat" +msgstr "Fleisch" + +#: crafts.lua +msgid "Lasso (right-click animal to put in inventory)" +msgstr "Lasso (Rechtsklick auf Tier, um es zu nehmen)" + +#: crafts.lua +msgid "Net (right-click animal to put in inventory)" +msgstr "Netz (Rechtsklick auf Tier, um es zu nehmen)" + +#: crafts.lua +msgid "Steel Shears (right-click to shear)" +msgstr "Stahlschere (Rechtsklick zum Scheren)" + +#: crafts.lua +msgid "Mob Protection Rune" +msgstr "Kreaturschutzrune" + +#: crafts.lua +msgid "Saddle" +msgstr "Sattel" + +#: crafts.lua +msgid "Mob Fence" +msgstr "Kreaturen Zaun" + +#: spawner.lua +msgid "Mob Spawner" +msgstr "Kreaturenspawner" + +#: spawner.lua +msgid "Mob MinLight MaxLight Amount PlayerDist" +msgstr "Kreatur MinLicht MaxLicht Menge SpielerEntfng" + +#: spawner.lua +msgid "Spawner Not Active (enter settings)" +msgstr "Nicht aktiv (Einstellungen eingeben)" + +#: spawner.lua +msgid "Spawner Active (@1)" +msgstr "Spawner aktiv (@1)" + +#: spawner.lua +msgid "Mob Spawner settings failed!" +msgstr "Kreaturenspawner-Einstellungen gescheitert!" + +#: spawner.lua +msgid "" +"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] " +"distance[1-20] y_offset[-10 to 10]”" +msgstr "" +"Syntax: „name min_licht[0-14] max_licht[0-14] max_mobs_im_gebiet[0 zum " +"Deaktivieren] distanz[1-20] y_versatz[-10 bis 10]“" diff --git a/mods/mobs_redo/locale/es.po b/mods/mobs_redo/locale/es.po new file mode 100644 index 0000000..849db66 --- /dev/null +++ b/mods/mobs_redo/locale/es.po @@ -0,0 +1,128 @@ +# Mobs Redo translation. +# Copyright (C) 2017 TenPlus1 +# This file is distributed under the same license as the mobs package. +# Wuzzy , 2017 +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-07-16 16:48+0200\n" +"PO-Revision-Date: 2017-07-16 16:48+0200\n" +"Last-Translator: Aleks \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: api.lua +msgid "** Peaceful Mode Active - No Monsters Will Spawn" +msgstr "" + +#: api.lua +msgid "Mob has been protected!" +msgstr "El mob ha sido protegido!" + +#: api.lua +msgid "@1 (Tamed)" +msgstr "@1 (Domesticado)" + +#: api.lua +msgid "Not tamed!" +msgstr "No domesticado!" + +#: api.lua +msgid "@1 is owner!" +msgstr "@1 es el dueño!" + +#: api.lua +msgid "Missed!" +msgstr "Perdido!" + +#: api.lua +msgid "Already protected!" +msgstr "Ya está protegido!" + +#: api.lua +msgid "@1 at full health (@2)" +msgstr "@1 con salud llena (@2)" + +#: api.lua +msgid "@1 has been tamed!" +msgstr "@1 ha sido domesticado!" + +#: api.lua +msgid "Enter name:" +msgstr "Ingrese nombre:" + +#: api.lua +msgid "Rename" +msgstr "Renombrar" + +#: crafts.lua +msgid "Name Tag" +msgstr "Nombrar etiqueta" + +#: crafts.lua +msgid "Leather" +msgstr "Cuero" + +#: crafts.lua +msgid "Raw Meat" +msgstr "Carne cruda" + +#: crafts.lua +msgid "Meat" +msgstr "Carne" + +#: crafts.lua +msgid "Lasso (right-click animal to put in inventory)" +msgstr "Lazo (click derecho en animal para colocar en inventario)" + +#: crafts.lua +msgid "Net (right-click animal to put in inventory)" +msgstr "Red (click derecho en animal para colocar en inventario)" + +#: crafts.lua +msgid "Steel Shears (right-click to shear)" +msgstr "Tijera de acero (click derecho para esquilar)" + +#: crafts.lua +msgid "Mob Protection Rune" +msgstr "Runa de protección de Mob" + +#: crafts.lua +msgid "Saddle" +msgstr "Montura" + +#: crafts.lua +msgid "Mob Fence" +msgstr "" + +#: spawner.lua +msgid "Mob Spawner" +msgstr "Generador de Mob" + +#: spawner.lua +msgid "Mob MinLight MaxLight Amount PlayerDist" +msgstr "Mob LuzMin LuzMax Cantidad DistJugador" + +#: spawner.lua +msgid "Spawner Not Active (enter settings)" +msgstr "Generador no activo (ingrese config)" + +#: spawner.lua +msgid "Spawner Active (@1)" +msgstr "Generador activo (@1)" + +#: spawner.lua +msgid "Mob Spawner settings failed!" +msgstr "Configuracion de generador de Mob falló!" + +#: spawner.lua +msgid "" +"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] " +"distance[1-20] y_offset[-10 to 10]”" +msgstr "Sintaxis: “nombre luz_min[0-14] luz_max[0-14] max_mobs_en_area[0 para deshabilitar] " +"distancia[1-20] compensacion[-10 a 10]”" diff --git a/mods/mobs_redo/locale/fr.po b/mods/mobs_redo/locale/fr.po new file mode 100644 index 0000000..53b5f9f --- /dev/null +++ b/mods/mobs_redo/locale/fr.po @@ -0,0 +1,136 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-07-29 09:13+0200\n" +"PO-Revision-Date: 2020-08-13 21:20+0500\n" +"Last-Translator: Olivier Dragon \n" +"Language-Team: \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: api.lua +msgid "** Peaceful Mode Active - No Monsters Will Spawn" +msgstr "** Mode pacifique activé - Aucun monstre ne sera généré" + +#: api.lua +msgid "Mob has been protected!" +msgstr "L'animal a été protégé !" + +#: api.lua +msgid "@1 (Tamed)" +msgstr "@1 (apprivoisé)" + +#: api.lua +msgid "Not tamed!" +msgstr "Non-apprivoisé !" + +#: api.lua +msgid "@1 is owner!" +msgstr "Appartient à @1 !" + +#: api.lua +msgid "Missed!" +msgstr "Raté !" + +#: api.lua +msgid "Already protected!" +msgstr "Déjà protégé !" + +#: api.lua +msgid "@1 at full health (@2)" +msgstr "@1 est en pleine forme (@2) " + +#: api.lua +msgid "@1 has been tamed!" +msgstr "@1 a été apprivoisé ! " + +#: api.lua +msgid "Enter name:" +msgstr "Saisissez un nom :" + +#: api.lua +msgid "Rename" +msgstr "Renommer" + +#: crafts.lua +msgid "Name Tag" +msgstr "Étiquette de collier" + +#: crafts.lua +msgid "Leather" +msgstr "Cuir" + +#: crafts.lua +msgid "Raw Meat" +msgstr "Viande crue" + +#: crafts.lua +msgid "Meat" +msgstr "Viande" + +#: crafts.lua +msgid "Lasso (right-click animal to put in inventory)" +msgstr "Lasso (clic droit sur l'animal pour le mettre dans l'inventaire)" + +#: crafts.lua +msgid "Net (right-click animal to put in inventory)" +msgstr "Filet (clic droit sur l'animal pour le mettre dans l'inventaire)" + +#: crafts.lua +msgid "Steel Shears (right-click to shear)" +msgstr "Ciseaux à laine (clic droit pour tondre)" + +#: crafts.lua +msgid "Mob Protection Rune" +msgstr "Rune de protection des animaux" + +#: crafts.lua +msgid "Saddle" +msgstr "Selle" + +#: crafts.lua +msgid "Mob Fence" +msgstr "Clôture à animaux" + +#: crafts.lua +msgid "Mob Fence Top" +msgstr "Haut de clôture à animaux" + +#: spawner.lua +msgid "Mob Spawner" +msgstr "Générateur de mob" + +#: spawner.lua +msgid "(mob name) (min light) (max light) (amount) (player distance) (Y offset)" +msgstr "(Nom) (MinLumière) (MaxLumière) (Quantité) (Distance du Joueur) (Décalage en Y)" + +#: spawner.lua +msgid "Spawner Not Active (enter settings)" +msgstr "Générateur non actif (entrez les paramètres)" + +#: spawner.lua +msgid "Command:" +msgstr "Commande:" + +#: spawner.lua +msgid "Spawner Active (@1)" +msgstr "Générateur actif (@1)" + +#: spawner.lua +msgid "Mob Spawner settings failed!" +msgstr "Echec des paramètres du générateur" + +#: spawner.lua +msgid "" +"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] " +"distance[1-20] y_offset[-10 to 10]”" +msgstr "Syntaxe : “nom min_lumière[0-14] max_lumière[0-14] max_mobs_dans_zone[0 pour désactiver] distance[1-20] décalage_y[-10 à 10]“" diff --git a/mods/mobs_redo/locale/it.po b/mods/mobs_redo/locale/it.po new file mode 100644 index 0000000..a40c33f --- /dev/null +++ b/mods/mobs_redo/locale/it.po @@ -0,0 +1,131 @@ +# ITALIAN LOCALE FILE FOR THE MOBS REDO MODULE +# Copyright (c) 2014 Krupnov Pavel and 2016 TenPlus1 +# This file is distributed under the same license as the MOBS REDO package. +# Hamlet , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: Italian locale file for the Mobs Redo module\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-07-02 16:48+0200\n" +"PO-Revision-Date: 2020-05-11 13:33+0200\n" +"Last-Translator: Hamlet \n" +"Language-Team: \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 2.2.1\n" + +#: api.lua +msgid "** Peaceful Mode Active - No Monsters Will Spawn" +msgstr "** Modalità pacifica attiva - non comparirà nessun mostro" + +#: api.lua +msgid "Mob has been protected!" +msgstr "Il mob è stato protetto!" + +#: api.lua +msgid "@1 (Tamed)" +msgstr "@1 (Addomesticato)" + +#: api.lua +msgid "Not tamed!" +msgstr "Non addomesticato!" + +#: api.lua +msgid "@1 is owner!" +msgstr "Il padrone è @1!" + +#: api.lua +msgid "Missed!" +msgstr "Mancato!" + +#: api.lua +msgid "Already protected!" +msgstr "Già protetto!" + +#: api.lua +msgid "@1 at full health (@2)" +msgstr "@1 in piena salute (@2)" + +#: api.lua +msgid "@1 has been tamed!" +msgstr "@1 è stato addomesticato!" + +#: api.lua +msgid "Enter name:" +msgstr "Inserire il nome:" + +#: api.lua +msgid "Rename" +msgstr "Rinomina" + +#: crafts.lua +msgid "Name Tag" +msgstr "Targhetta" + +#: crafts.lua +msgid "Leather" +msgstr "Pelle" + +#: crafts.lua +msgid "Raw Meat" +msgstr "Carne cruda" + +#: crafts.lua +msgid "Meat" +msgstr "Carne" + +#: crafts.lua +msgid "Lasso (right-click animal to put in inventory)" +msgstr "Lazo (click di destro per mettere l'animale nell'inventario)" + +#: crafts.lua +msgid "Net (right-click animal to put in inventory)" +msgstr "Rete (click destro per mettere l'animale nell'inventario)" + +#: crafts.lua +msgid "Steel Shears (right-click to shear)" +msgstr "Cesoie d'acciaio (click destro per tosare)" + +#: crafts.lua +msgid "Mob Protection Rune" +msgstr "Runa di protezione per mob" + +#: crafts.lua +msgid "Saddle" +msgstr "Sella" + +#: crafts.lua +msgid "Mob Fence" +msgstr "Recinzione per mob" + +#: spawner.lua +msgid "Mob Spawner" +msgstr "Generatore di mob" + +#: spawner.lua +msgid "Mob MinLight MaxLight Amount PlayerDist" +msgstr "Mob LuceMin LuceMax Ammontare DistGiocat." + +#: spawner.lua +msgid "Spawner Not Active (enter settings)" +msgstr "Generatore inattivo (inserire le impostazioni)" + +#: spawner.lua +msgid "Spawner Active (@1)" +msgstr "Generatore attivo (@1)" + +#: spawner.lua +msgid "Mob Spawner settings failed!" +msgstr "Impostazioni del generatore di mob fallite!" + +#: spawner.lua +msgid "" +"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] " +"distance[1-20] y_offset[-10 to 10]”" +msgstr "" +"Sintassi: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 per " +"disabilitare] distance[1-20] y_offset[-10 fino a 10]”" diff --git a/mods/mobs_redo/locale/mobs.de.tr b/mods/mobs_redo/locale/mobs.de.tr new file mode 100644 index 0000000..f11b665 --- /dev/null +++ b/mods/mobs_redo/locale/mobs.de.tr @@ -0,0 +1,34 @@ +# textdomain:mobs +#** Peaceful Mode Active - No Monsters Will Spawn= +@1 (Tamed)=@1 (Gezähmt) +@1 at full health (@2)=@1 bei voller Gesundheit (@2) +@1 has been tamed!=@1 wurde gezähmt! +@1 is owner!=@1 ist der Besitzer! +#Active Mob Limit Reached!= +Already protected!=Bereits geschützt! +#Change= +#Command:= +Enter name:=Namen eingeben: +#Enter texture:= +Lasso (right-click animal to put in inventory)=Lasso (Rechtsklick auf Tier, um es zu nehmen) +Leather=Leder +Meat=Fleisch +Missed!=Daneben! +Mob Fence=Kreaturen Zaun +#Mob Fence Top= +Mob Protection Rune=Kreaturschutzrune +#Mob Reset Stick= +#Mob Spawner= +Mob Spawner settings failed!=Kreaturenspawner-Einstellungen gescheitert! +Mob has been protected!=Kreatur wurde geschützt! +Name Tag=Namensschild +Net (right-click animal to put in inventory)=Netz (Rechtsklick auf Tier, um es zu nehmen) +Not tamed!=Nicht gezähmt! +Raw Meat=Rohes Fleisch +Rename=Umbenennen +Saddle=Sattel +Spawner Active (@1)=Spawner aktiv (@1) +Spawner Not Active (enter settings)=Nicht aktiv (Einstellungen eingeben) +Steel Shears (right-click to shear)=Stahlschere (Rechtsklick zum Scheren) +#Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] player_distance[1-20] y_offset[-10 to 10]”= +#lifetimer expired, removed @1= diff --git a/mods/mobs_redo/locale/mobs.en.tr b/mods/mobs_redo/locale/mobs.en.tr new file mode 100644 index 0000000..fab62b7 --- /dev/null +++ b/mods/mobs_redo/locale/mobs.en.tr @@ -0,0 +1,34 @@ +# textdomain:mobs +#** Peaceful Mode Active - No Monsters Will Spawn= +#@1 (Tamed)= +#@1 at full health (@2)= +#@1 has been tamed!= +#@1 is owner!= +#Active Mob Limit Reached!= +#Already protected!= +#Change= +#Command:= +#Enter name:= +#Enter texture:= +#Lasso (right-click animal to put in inventory)= +#Leather= +#Meat= +#Missed!= +#Mob Fence= +#Mob Fence Top= +#Mob Protection Rune= +#Mob Reset Stick= +#Mob Spawner= +#Mob Spawner settings failed!= +#Mob has been protected!= +#Name Tag= +#Net (right-click animal to put in inventory)= +#Not tamed!= +#Raw Meat= +#Rename= +#Saddle= +#Spawner Active (@1)= +#Spawner Not Active (enter settings)= +#Steel Shears (right-click to shear)= +#Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] player_distance[1-20] y_offset[-10 to 10]”= +#lifetimer expired, removed @1= diff --git a/mods/mobs_redo/locale/mobs.es.tr b/mods/mobs_redo/locale/mobs.es.tr new file mode 100644 index 0000000..29ee934 --- /dev/null +++ b/mods/mobs_redo/locale/mobs.es.tr @@ -0,0 +1,34 @@ +# textdomain:mobs +#** Peaceful Mode Active - No Monsters Will Spawn= +@1 (Tamed)=@1 (Domesticado) +@1 at full health (@2)=@1 con salud llena (@2) +@1 has been tamed!=@1 ha sido domesticado! +@1 is owner!=@1 es el dueño! +#Active Mob Limit Reached!= +Already protected!=Ya está protegido! +#Change= +#Command:= +Enter name:=Ingrese nombre: +#Enter texture:= +Lasso (right-click animal to put in inventory)=Lazo (click derecho en animal para colocar en inventario) +Leather=Cuero +Meat=Carne +Missed!=Perdido! +#Mob Fence= +#Mob Fence Top= +Mob Protection Rune=Runa de protección de Mob +#Mob Reset Stick= +#Mob Spawner= +Mob Spawner settings failed!=Configuracion de generador de Mob falló! +Mob has been protected!=El mob ha sido protegido! +Name Tag=Nombrar etiqueta +Net (right-click animal to put in inventory)=Red (click derecho en animal para colocar en inventario) +Not tamed!=No domesticado! +Raw Meat=Carne cruda +Rename=Renombrar +Saddle=Montura +Spawner Active (@1)=Generador activo (@1) +Spawner Not Active (enter settings)=Generador no activo (ingrese config) +Steel Shears (right-click to shear)=Tijera de acero (click derecho para esquilar) +#Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] player_distance[1-20] y_offset[-10 to 10]”= +#lifetimer expired, removed @1= diff --git a/mods/mobs_redo/locale/mobs.fr.tr b/mods/mobs_redo/locale/mobs.fr.tr new file mode 100644 index 0000000..3e137fb --- /dev/null +++ b/mods/mobs_redo/locale/mobs.fr.tr @@ -0,0 +1,34 @@ +# textdomain:mobs +** Peaceful Mode Active - No Monsters Will Spawn=** Mode pacifique activé - aucun monstre ne sera généré +@1 (Tamed)=@1 (apprivoisé) +@1 at full health (@2)=@1 est en pleine forme (@2) +@1 has been tamed!=@1 a été apprivoisé ! +@1 is owner!=Appartient à @1 ! +Active Mob Limit Reached!=Limite atteinte du nombre des êtres vivants actifs ! +Already protected!=Déjà protégé ! +Change=Changer +Command:=Commande : +Enter name:=Saisissez un nom : +Enter texture:=Saisissez une texture : +Lasso (right-click animal to put in inventory)=Lasso (clic droit sur l'animal pour le mettre dans l'inventaire) +Leather=Cuir +Meat=Viande +Missed!=Raté ! +Mob Fence= Clôture à animaux +Mob Fence Top=Haut de clôture à animaux +Mob Protection Rune=Rune de protection des animaux +Mob Reset Stick=Baguette de réinitialisation des êtres vivants +Mob Spawner=Créateur d'êtres vivants +Mob Spawner settings failed!=Échec des paramètres du créateur d'être vivants ! +Mob has been protected!=L'animal a été protégé ! +Name Tag=Étiquette de collier +Net (right-click animal to put in inventory)=Filet (clic droit sur l'animal pour le mettre dans l'inventaire) +Not tamed!=Non-apprivoisé ! +Raw Meat=Viande crue +Rename=Renommer +Saddle=Selle +Spawner Active (@1)=Créateur actif (@1) +Spawner Not Active (enter settings)=Créateur non actif (entrez les paramètres) +Steel Shears (right-click to shear)=Ciseaux à laine (clic droit pour tondre) +Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] player_distance[1-20] y_offset[-10 to 10]”=Syntaxe : «name min_lumière[0-14] max_lumière[0-14] max_être_vivant_dans_région[0 pour désactiver] distance_joueur[1-20] décalage_y[-10 to 10]» +lifetimer expired, removed @1=Être immortel expiré ; @1 retiré diff --git a/mods/mobs_redo/locale/mobs.it.tr b/mods/mobs_redo/locale/mobs.it.tr new file mode 100644 index 0000000..6b5edd9 --- /dev/null +++ b/mods/mobs_redo/locale/mobs.it.tr @@ -0,0 +1,34 @@ +# textdomain:mobs +** Peaceful Mode Active - No Monsters Will Spawn=** Modalità pacifica attiva - non comparirà nessun mostro +@1 (Tamed)=@1 (Addomesticato) +@1 at full health (@2)=@1 in piena salute (@2) +@1 has been tamed!=@1 è stato addomesticato! +@1 is owner!=Il padrone è @1! +#Active Mob Limit Reached!= +Already protected!=Già protetto! +#Change= +#Command:= +Enter name:=Inserire il nome: +#Enter texture:= +Lasso (right-click animal to put in inventory)=Lazo (click di destro per mettere l'animale nell'inventario) +Leather=Pelle +Meat=Carne +Missed!=Mancato! +Mob Fence=Recinzione per mob +#Mob Fence Top= +Mob Protection Rune=Runa di protezione per mob +#Mob Reset Stick= +#Mob Spawner= +Mob Spawner settings failed!=Impostazioni del generatore di mob fallite! +Mob has been protected!=Il mob è stato protetto! +Name Tag=Targhetta +Net (right-click animal to put in inventory)=Rete (click destro per mettere l'animale nell'inventario) +Not tamed!=Non addomesticato! +Raw Meat=Carne cruda +Rename=Rinomina +Saddle=Sella +Spawner Active (@1)=Generatore attivo (@1) +Spawner Not Active (enter settings)=Generatore inattivo (inserire le impostazioni) +Steel Shears (right-click to shear)=Cesoie d'acciaio (click destro per tosare) +#Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] player_distance[1-20] y_offset[-10 to 10]”= +#lifetimer expired, removed @1= diff --git a/mods/mobs_redo/locale/mobs.ms.tr b/mods/mobs_redo/locale/mobs.ms.tr new file mode 100644 index 0000000..f79e2fb --- /dev/null +++ b/mods/mobs_redo/locale/mobs.ms.tr @@ -0,0 +1,34 @@ +# textdomain:mobs +** Peaceful Mode Active - No Monsters Will Spawn=** Mod Aman Diaktifkan - Tiada Raksasa Akan Muncul +@1 (Tamed)=@1 (Jinak) +@1 at full health (@2)=Mata kesihatan @1 telah penuh (@2) +@1 has been tamed!=@1 telah dijinakkan! +@1 is owner!=Ini hak milik @1! +#Active Mob Limit Reached!= +Already protected!=Telah dilindungi! +#Change= +#Command:= +Enter name:=Masukkan nama: +#Enter texture:= +Lasso (right-click animal to put in inventory)=Tanjul (klik-kanan haiwan untuk masukkan ke inventori) +Leather=Kulit +Meat=Daging Bakar +Missed!=Terlepas! +Mob Fence=Pagar Mob +#Mob Fence Top= +Mob Protection Rune=Rune Perlindungan Mob +#Mob Reset Stick= +#Mob Spawner= +Mob Spawner settings failed!=Penetapan Pewujud Mob gagal! +Mob has been protected!=Mob telah pun dilindungi! +Name Tag=Tanda Nama +Net (right-click animal to put in inventory)=Jaring (klik-kanan haiwan untuk masukkan ke inventori) +Not tamed!=Belum dijinakkan! +Raw Meat=Daging Mentah +Rename=Namakan semula +Saddle=Pelana +Spawner Active (@1)=Pewujud Mob Aktif (@1) +Spawner Not Active (enter settings)=Pewujud Mob Tidak Aktif (masukkan tetapan) +Steel Shears (right-click to shear)=Ketam Keluli (klik-kanan untuk mengetam bulu biri-biri) +#Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] player_distance[1-20] y_offset[-10 to 10]”= +#lifetimer expired, removed @1= diff --git a/mods/mobs_redo/locale/mobs.pt.tr b/mods/mobs_redo/locale/mobs.pt.tr new file mode 100644 index 0000000..b62e989 --- /dev/null +++ b/mods/mobs_redo/locale/mobs.pt.tr @@ -0,0 +1,34 @@ +# textdomain:mobs +#** Peaceful Mode Active - No Monsters Will Spawn= +#@1 (Tamed)= +@1 at full health (@2)=@1 em plena saude (@2) +@1 has been tamed!=@1 foi domesticado! +@1 is owner!=Dono @1! +#Active Mob Limit Reached!= +#Already protected!= +#Change= +#Command:= +Enter name:=Insira um nome: +#Enter texture:= +Lasso (right-click animal to put in inventory)=Laço (clique-direito no animal para por no inventario) +Leather=Couro +Meat=Carne +Missed!=Faltou! +#Mob Fence= +#Mob Fence Top= +#Mob Protection Rune= +#Mob Reset Stick= +#Mob Spawner= +Mob Spawner settings failed!=Configuraçao de Spawnador do Mob falhou! +#Mob has been protected!= +Name Tag=Etiqueta +Net (right-click animal to put in inventory)=Net (clique-direito no animal para por no inventario) +Not tamed!=Indomesticado! +Raw Meat=Carne crua +Rename=Renomear +#Saddle= +Spawner Active (@1)=Spawnador Ativo (@1) +Spawner Not Active (enter settings)=Spawnador Inativo (configurar) +Steel Shears (right-click to shear)=Tesoura de Aço (clique-direito para tosquiar) +#Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] player_distance[1-20] y_offset[-10 to 10]”= +#lifetimer expired, removed @1= diff --git a/mods/mobs_redo/locale/mobs.ru.tr b/mods/mobs_redo/locale/mobs.ru.tr new file mode 100644 index 0000000..f7c201a --- /dev/null +++ b/mods/mobs_redo/locale/mobs.ru.tr @@ -0,0 +1,34 @@ +# textdomain:mobs +** Peaceful Mode Active - No Monsters Will Spawn=** Мирный модус активирован - монстры не спаунятся +@1 (Tamed)=@1 (Прирученный) +@1 at full health (@2)=@1 при полном здоровье (@2) +@1 has been tamed!=@1 приручен +@1 is owner!=@1 владелец +#Active Mob Limit Reached!= +Already protected!=Уже защищен! +#Change= +#Command:= +Enter name:=Введите имя: +#Enter texture:= +Lasso (right-click animal to put in inventory)=Лассо (Правый клик - положить животное в инвентарь) +Leather=Кожа +Meat=Мясо +Missed!=Промазал! +Mob Fence=Забор от мобов +#Mob Fence Top= +Mob Protection Rune=Защитная руна мобов +#Mob Reset Stick= +#Mob Spawner= +Mob Spawner settings failed!=Настройки спаунера моба провалились +Mob has been protected!=Моб защищен! +Name Tag=Новый тэг +Net (right-click animal to put in inventory)=Сеть (Правый клик - положить животное в инвентарь) +Not tamed!=Не прирученный +Raw Meat=Сырое мясо +Rename=Переименовать +Saddle=Седло +Spawner Active (@1)=Активные спаунер (@1) +Spawner Not Active (enter settings)=Спаунер не активен (введите настройки) +Steel Shears (right-click to shear)=Ножницы (Правый клик - подстричь) +#Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] player_distance[1-20] y_offset[-10 to 10]”= +#lifetimer expired, removed @1= diff --git a/mods/mobs_redo/locale/mobs.tr.tr b/mods/mobs_redo/locale/mobs.tr.tr new file mode 100644 index 0000000..6e28706 --- /dev/null +++ b/mods/mobs_redo/locale/mobs.tr.tr @@ -0,0 +1,34 @@ +# textdomain:mobs +#** Peaceful Mode Active - No Monsters Will Spawn= +#@1 (Tamed)= +@1 at full health (@2)=@1 tam canında (@2) +@1 has been tamed!=@1 tamamen evcilleştirilmiştir! +@1 is owner!=Sahibi @1! +#Active Mob Limit Reached!= +#Already protected!= +#Change= +#Command:= +Enter name:=İsim gir: +#Enter texture:= +Lasso (right-click animal to put in inventory)=Kement (hayvana sağ tıklayarak envantere koy) +Leather=Deri +Meat=Et +Missed!=Kaçırdın! +Mob Fence=Canavar Yaratıcı +#Mob Fence Top= +#Mob Protection Rune= +#Mob Reset Stick= +#Mob Spawner= +Mob Spawner settings failed!=Yaratıcı ayarları uygulanamadı. +#Mob has been protected!= +Name Tag=İsim etiketi +Net (right-click animal to put in inventory)=Ağ (hayvana sağ tıklayarak envantere koy) +Not tamed!=Evcil değil! +Raw Meat=Çiğ et +Rename=Yeniden adlandır +#Saddle= +Spawner Active (@1)=Yaratıcı aktif (@1) +Spawner Not Active (enter settings)=Yaratıcı aktif değil (ayarlara gir) +Steel Shears (right-click to shear)=Çelik makas (sağ tıklayarak kes) +#Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] player_distance[1-20] y_offset[-10 to 10]”= +#lifetimer expired, removed @1= diff --git a/mods/mobs_redo/locale/mobs.zh_CN.tr b/mods/mobs_redo/locale/mobs.zh_CN.tr new file mode 100644 index 0000000..fe7556c --- /dev/null +++ b/mods/mobs_redo/locale/mobs.zh_CN.tr @@ -0,0 +1,34 @@ +# textdomain:mobs +** Peaceful Mode Active - No Monsters Will Spawn=** 和平模式已激活——没有怪物会产生 +@1 (Tamed)=@1(已驯服) +@1 at full health (@2)=@1已经满血(@2) +@1 has been tamed!=@1已经被驯服! +@1 is owner!=@1 是主人 +#Active Mob Limit Reached!= +Already protected!=已经被保护! +#Change= +#Command:= +Enter name:=输入名称: +#Enter texture:= +Lasso (right-click animal to put in inventory)=套索(右键单击动物以放入物品栏) +Leather=皮革 +Meat=肉 +Missed!=没抓住! +Mob Fence=Mob 栅栏 +#Mob Fence Top= +Mob Protection Rune=Mob 保护符文 +#Mob Reset Stick= +#Mob Spawner= +Mob Spawner settings failed!=Mob 孵化器设置失败! +Mob has been protected!=Mob 已经被保护了! +Name Tag=名称标签 +Net (right-click animal to put in inventory)=网(右键单击动物以放入物品栏) +Not tamed!=没有驯服! +Raw Meat=生肉 +Rename=重新命名 +Saddle=鞍 +Spawner Active (@1)=孵化器正在运转(@1) +Spawner Not Active (enter settings)=孵化器未使用(输入设置) +Steel Shears (right-click to shear)=钢剪(右键单击以剪切) +#Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] player_distance[1-20] y_offset[-10 to 10]”= +#lifetimer expired, removed @1= diff --git a/mods/mobs_redo/locale/mobs.zh_TW.tr b/mods/mobs_redo/locale/mobs.zh_TW.tr new file mode 100644 index 0000000..89bed26 --- /dev/null +++ b/mods/mobs_redo/locale/mobs.zh_TW.tr @@ -0,0 +1,34 @@ +# textdomain:mobs +** Peaceful Mode Active - No Monsters Will Spawn=** 和平模式已激活——沒有怪物會產生 +@1 (Tamed)=@1(已馴服) +@1 at full health (@2)=@1已經滿血(@2) +@1 has been tamed!=@1已經被馴服! +@1 is owner!=@1 是主人 +#Active Mob Limit Reached!= +Already protected!=已經被保護! +#Change= +#Command:= +Enter name:=輸入名稱: +#Enter texture:= +Lasso (right-click animal to put in inventory)=套索(右鍵單擊動物以放入物品欄) +Leather=皮革 +Meat=肉 +Missed!=沒抓住! +Mob Fence=Mob 柵欄 +#Mob Fence Top= +Mob Protection Rune=Mob 保護符文 +#Mob Reset Stick= +#Mob Spawner= +Mob Spawner settings failed!=Mob 孵化器設置失敗! +Mob has been protected!=Mob 已經被保護了! +Name Tag=名稱標籤 +Net (right-click animal to put in inventory)=網(右鍵單擊動物以放入物品欄) +Not tamed!=沒有馴服! +Raw Meat=生肉 +Rename=重新命名 +Saddle=鞍 +Spawner Active (@1)=孵化器正在運轉(@1) +Spawner Not Active (enter settings)=孵化器未使用(輸入設置) +Steel Shears (right-click to shear)=鋼剪(右鍵單擊以剪切) +#Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] player_distance[1-20] y_offset[-10 to 10]”= +#lifetimer expired, removed @1= diff --git a/mods/mobs_redo/locale/ms.po b/mods/mobs_redo/locale/ms.po new file mode 100644 index 0000000..a2a31f3 --- /dev/null +++ b/mods/mobs_redo/locale/ms.po @@ -0,0 +1,131 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-02-05 23:40+0800\n" +"PO-Revision-Date: 2018-02-05 23:51+0800\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.6\n" +"Last-Translator: MuhdNurHidayat (MNH48) \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"Language: ms\n" + +#: api.lua +msgid "** Peaceful Mode Active - No Monsters Will Spawn" +msgstr "** Mod Aman Diaktifkan - Tiada Raksasa Akan Muncul" + +#: api.lua +msgid "Mob has been protected!" +msgstr "Mob telah pun dilindungi!" + +#: api.lua +msgid "@1 (Tamed)" +msgstr "@1 (Jinak)" + +#: api.lua +msgid "Not tamed!" +msgstr "Belum dijinakkan!" + +#: api.lua +msgid "@1 is owner!" +msgstr "Ini hak milik @1!" + +#: api.lua +msgid "Missed!" +msgstr "Terlepas!" + +#: api.lua +msgid "Already protected!" +msgstr "Telah dilindungi!" + +#: api.lua +msgid "@1 at full health (@2)" +msgstr "Mata kesihatan @1 telah penuh (@2)" + +#: api.lua +msgid "@1 has been tamed!" +msgstr "@1 telah dijinakkan!" + +#: api.lua +msgid "Enter name:" +msgstr "Masukkan nama:" + +#: api.lua +msgid "Rename" +msgstr "Namakan semula" + +#: crafts.lua +msgid "Name Tag" +msgstr "Tanda Nama" + +#: crafts.lua +msgid "Leather" +msgstr "Kulit" + +#: crafts.lua +msgid "Raw Meat" +msgstr "Daging Mentah" + +#: crafts.lua +msgid "Meat" +msgstr "Daging Bakar" + +#: crafts.lua +msgid "Lasso (right-click animal to put in inventory)" +msgstr "Tanjul (klik-kanan haiwan untuk masukkan ke inventori)" + +#: crafts.lua +msgid "Net (right-click animal to put in inventory)" +msgstr "Jaring (klik-kanan haiwan untuk masukkan ke inventori)" + +#: crafts.lua +msgid "Steel Shears (right-click to shear)" +msgstr "Ketam Keluli (klik-kanan untuk mengetam bulu biri-biri)" + +#: crafts.lua +msgid "Mob Protection Rune" +msgstr "Rune Perlindungan Mob" + +#: crafts.lua +msgid "Saddle" +msgstr "Pelana" + +#: crafts.lua +msgid "Mob Fence" +msgstr "Pagar Mob" + +#: spawner.lua +msgid "Mob Spawner" +msgstr "Pewujud Mob" + +#: spawner.lua +msgid "Mob MinLight MaxLight Amount PlayerDist" +msgstr "Mob CahayaMin CahayaMax Amaun JarakPemain" + +#: spawner.lua +msgid "Spawner Not Active (enter settings)" +msgstr "Pewujud Mob Tidak Aktif (masukkan tetapan)" + +#: spawner.lua +msgid "Spawner Active (@1)" +msgstr "Pewujud Mob Aktif (@1)" + +#: spawner.lua +msgid "Mob Spawner settings failed!" +msgstr "Penetapan Pewujud Mob gagal!" + +#: spawner.lua +msgid "" +"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] " +"distance[1-20] y_offset[-10 to 10]”" +msgstr "" +"Sintaks: \"nama cahaya_minimum[0-14] cahaya_maksimum[0-14] " +"amaun_mob_maksimum[0 untuk lumpuhkan] jarak[1-20] ketinggian[-10 hingga 10]\"" diff --git a/mods/mobs_redo/locale/pt.po b/mods/mobs_redo/locale/pt.po new file mode 100644 index 0000000..b52afd6 --- /dev/null +++ b/mods/mobs_redo/locale/pt.po @@ -0,0 +1,133 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: mobs\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-07-02 16:48+0200\n" +"PO-Revision-Date: 2017-07-02 14:55+0200\n" +"Last-Translator: Wuzzy \n" +"Language-Team: \n" +"Language: pt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: api.lua +msgid "** Peaceful Mode Active - No Monsters Will Spawn" +msgstr "" + +#: api.lua +msgid "Mob has been protected!" +msgstr "" + +#: api.lua +msgid "@1 (Tamed)" +msgstr "" + +#: api.lua +msgid "Not tamed!" +msgstr "Indomesticado!" + +#: api.lua +msgid "@1 is owner!" +msgstr "Dono @1!" + +#: api.lua +msgid "Missed!" +msgstr "Faltou!" + +#: api.lua +msgid "Already protected!" +msgstr "" + +#: api.lua +msgid "@1 at full health (@2)" +msgstr "@1 em plena saude (@2)" + +#: api.lua +msgid "@1 has been tamed!" +msgstr "@1 foi domesticado!" + +#: api.lua +msgid "Enter name:" +msgstr "Insira um nome:" + +#: api.lua +msgid "Rename" +msgstr "Renomear" + +#: crafts.lua +msgid "Name Tag" +msgstr "Etiqueta" + +#: crafts.lua +msgid "Leather" +msgstr "Couro" + +#: crafts.lua +msgid "Raw Meat" +msgstr "Carne crua" + +#: crafts.lua +msgid "Meat" +msgstr "Carne" + +#: crafts.lua +#, fuzzy +msgid "Lasso (right-click animal to put in inventory)" +msgstr "Laço (clique-direito no animal para por no inventario)" + +#: crafts.lua +msgid "Net (right-click animal to put in inventory)" +msgstr "Net (clique-direito no animal para por no inventario)" + +#: crafts.lua +msgid "Steel Shears (right-click to shear)" +msgstr "Tesoura de Aço (clique-direito para tosquiar)" + +#: crafts.lua +msgid "Mob Protection Rune" +msgstr "" + +#: crafts.lua +msgid "Saddle" +msgstr "" + +#: crafts.lua +msgid "Mob Fence" +msgstr "" + +#: spawner.lua +msgid "Mob Spawner" +msgstr "Spawnador de Mob" + +#: spawner.lua +msgid "Mob MinLight MaxLight Amount PlayerDist" +msgstr "Mob LuzMinima LuzMaxima Valor DistJogador" + +#: spawner.lua +msgid "Spawner Not Active (enter settings)" +msgstr "Spawnador Inativo (configurar)" + +#: spawner.lua +msgid "Spawner Active (@1)" +msgstr "Spawnador Ativo (@1)" + +#: spawner.lua +msgid "Mob Spawner settings failed!" +msgstr "Configuraçao de Spawnador do Mob falhou!" + +#: spawner.lua +#, fuzzy +msgid "" +"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] " +"distance[1-20] y_offset[-10 to 10]”" +msgstr "" +"> nome luz_min[0-14] luz_max[0-14] max_mobs_na_area[0 para desabilitar] " +"distancia[1-20] y_offset[-10 a 10]" diff --git a/mods/mobs_redo/locale/ru.po b/mods/mobs_redo/locale/ru.po new file mode 100644 index 0000000..6cde7ef --- /dev/null +++ b/mods/mobs_redo/locale/ru.po @@ -0,0 +1,129 @@ +# Russian translation for the mobs_redo mod. +# Copyright (C) 2018 TenPlus1 +# This file is distributed under the same license as the mobs_redo package. +# Oleg720 , 2017. +# CodeXP , 2018. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-08-13 15:47+0200\n" +"PO-Revision-Date: 2018-03-23 22:22+0100\n" +"Last-Translator: CodeXP \n" +"Language-Team: \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: api.lua +msgid "** Peaceful Mode Active - No Monsters Will Spawn" +msgstr "** Мирный модус активирован - монстры не спаунятся" + +#: api.lua +msgid "Mob has been protected!" +msgstr "Моб защищен!" + +#: api.lua +msgid "@1 (Tamed)" +msgstr "@1 (Прирученный)" + +#: api.lua +msgid "Not tamed!" +msgstr "Не прирученный" + +#: api.lua +msgid "@1 is owner!" +msgstr "@1 владелец" + +#: api.lua +msgid "Missed!" +msgstr "Промазал!" + +#: api.lua +msgid "Already protected!" +msgstr "Уже защищен!" + +#: api.lua +msgid "@1 at full health (@2)" +msgstr "@1 при полном здоровье (@2)" + +#: api.lua +msgid "@1 has been tamed!" +msgstr "@1 приручен" + +#: api.lua +msgid "Enter name:" +msgstr "Введите имя:" + +#: api.lua +msgid "Rename" +msgstr "Переименовать" + +#: crafts.lua +msgid "Name Tag" +msgstr "Новый тэг" + +#: crafts.lua +msgid "Leather" +msgstr "Кожа" + +#: crafts.lua +msgid "Raw Meat" +msgstr "Сырое мясо" + +#: crafts.lua +msgid "Meat" +msgstr "Мясо" + +#: crafts.lua +msgid "Lasso (right-click animal to put in inventory)" +msgstr "Лассо (Правый клик - положить животное в инвентарь)" + +#: crafts.lua +msgid "Net (right-click animal to put in inventory)" +msgstr "Сеть (Правый клик - положить животное в инвентарь)" + +#: crafts.lua +msgid "Steel Shears (right-click to shear)" +msgstr "Ножницы (Правый клик - подстричь)" + +#: crafts.lua +msgid "Mob Protection Rune" +msgstr "Защитная руна мобов" + +#: crafts.lua +msgid "Saddle" +msgstr "Седло" + +#: crafts.lua +msgid "Mob Fence" +msgstr "Забор от мобов" + +#: spawner.lua +msgid "Mob Spawner" +msgstr "Спаунер моба" + +#: spawner.lua +msgid "Mob MinLight MaxLight Amount PlayerDist" +msgstr "" + +#: spawner.lua +msgid "Spawner Not Active (enter settings)" +msgstr "Спаунер не активен (введите настройки)" + +#: spawner.lua +msgid "Spawner Active (@1)" +msgstr "Активные спаунер (@1)" + +#: spawner.lua +msgid "Mob Spawner settings failed!" +msgstr "Настройки спаунера моба провалились" + +#: spawner.lua +msgid "" +"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] " +"distance[1-20] y_offset[-10 to 10]”" +msgstr "" diff --git a/mods/mobs_redo/locale/template.pot b/mods/mobs_redo/locale/template.pot new file mode 100644 index 0000000..a625ee3 --- /dev/null +++ b/mods/mobs_redo/locale/template.pot @@ -0,0 +1,136 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-07-02 16:48+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: api.lua +msgid "** Peaceful Mode Active - No Monsters Will Spawn" +msgstr "" + +#: api.lua +msgid "Mob has been protected!" +msgstr "" + +#: api.lua +msgid "@1 (Tamed)" +msgstr "" + +#: api.lua +msgid "Not tamed!" +msgstr "" + +#: api.lua +msgid "@1 is owner!" +msgstr "" + +#: api.lua +msgid "Missed!" +msgstr "" + +#: api.lua +msgid "Already protected!" +msgstr "" + +#: api.lua +msgid "@1 at full health (@2)" +msgstr "" + +#: api.lua +msgid "@1 has been tamed!" +msgstr "" + +#: api.lua +msgid "Enter name:" +msgstr "" + +#: api.lua +msgid "Rename" +msgstr "" + +#: crafts.lua +msgid "Name Tag" +msgstr "" + +#: crafts.lua +msgid "Leather" +msgstr "" + +#: crafts.lua +msgid "Raw Meat" +msgstr "" + +#: crafts.lua +msgid "Meat" +msgstr "" + +#: crafts.lua +msgid "Lasso (right-click animal to put in inventory)" +msgstr "" + +#: crafts.lua +msgid "Net (right-click animal to put in inventory)" +msgstr "" + +#: crafts.lua +msgid "Steel Shears (right-click to shear)" +msgstr "" + +#: crafts.lua +msgid "Mob Protection Rune" +msgstr "" + +#: crafts.lua +msgid "Saddle" +msgstr "" + +#: crafts.lua +msgid "Mob Fence" +msgstr "" + +#: crafts.lua +msgid "Mob Fence Top" +msgstr "" + +#: spawner.lua +msgid "Mob Spawner" +msgstr "" + +#: spawner.lua +msgid "(mob name) (min light) (max light) (amount) (player distance) (Y offset)" +msgstr "" + +#: spawner.lua +msgid "Spawner Not Active (enter settings)" +msgstr "" + +#@ spawner.lua +msgid "Command:" +msgstr "" + +#: spawner.lua +msgid "Spawner Active (@1)" +msgstr "" + +#: spawner.lua +msgid "Mob Spawner settings failed!" +msgstr "" + +#: spawner.lua +msgid "" +"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] " +"distance[1-20] y_offset[-10 to 10]”" +msgstr "" diff --git a/mods/mobs_redo/locale/tr.po b/mods/mobs_redo/locale/tr.po new file mode 100644 index 0000000..10688e2 --- /dev/null +++ b/mods/mobs_redo/locale/tr.po @@ -0,0 +1,133 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: mobs\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-07-02 16:48+0200\n" +"PO-Revision-Date: 2017-07-02 14:56+0200\n" +"Last-Translator: Wuzzy \n" +"Language-Team: \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: api.lua +msgid "** Peaceful Mode Active - No Monsters Will Spawn" +msgstr "" + +#: api.lua +msgid "Mob has been protected!" +msgstr "" + +#: api.lua +msgid "@1 (Tamed)" +msgstr "" + +#: api.lua +msgid "Not tamed!" +msgstr "Evcil değil!" + +#: api.lua +msgid "@1 is owner!" +msgstr "Sahibi @1!" + +#: api.lua +msgid "Missed!" +msgstr "Kaçırdın!" + +#: api.lua +msgid "Already protected!" +msgstr "" + +#: api.lua +msgid "@1 at full health (@2)" +msgstr "@1 tam canında (@2)" + +#: api.lua +msgid "@1 has been tamed!" +msgstr "@1 tamamen evcilleştirilmiştir!" + +#: api.lua +msgid "Enter name:" +msgstr "İsim gir:" + +#: api.lua +msgid "Rename" +msgstr "Yeniden adlandır" + +#: crafts.lua +msgid "Name Tag" +msgstr "İsim etiketi" + +#: crafts.lua +msgid "Leather" +msgstr "Deri" + +#: crafts.lua +msgid "Raw Meat" +msgstr "Çiğ et" + +#: crafts.lua +msgid "Meat" +msgstr "Et" + +#: crafts.lua +#, fuzzy +msgid "Lasso (right-click animal to put in inventory)" +msgstr "Kement (hayvana sağ tıklayarak envantere koy)" + +#: crafts.lua +msgid "Net (right-click animal to put in inventory)" +msgstr "Ağ (hayvana sağ tıklayarak envantere koy)" + +#: crafts.lua +msgid "Steel Shears (right-click to shear)" +msgstr "Çelik makas (sağ tıklayarak kes)" + +#: crafts.lua +msgid "Mob Protection Rune" +msgstr "" + +#: crafts.lua +msgid "Saddle" +msgstr "" + +#: crafts.lua +msgid "Mob Fence" +msgstr "Canavar Yaratıcı" + +#: spawner.lua +msgid "Mob Spawner" +msgstr "Canavar Yaratıcı" + +#: spawner.lua +msgid "Mob MinLight MaxLight Amount PlayerDist" +msgstr "Mob MinIşık MaxIşık Miktar OyuncuMesafesi" + +#: spawner.lua +msgid "Spawner Not Active (enter settings)" +msgstr "Yaratıcı aktif değil (ayarlara gir)" + +#: spawner.lua +msgid "Spawner Active (@1)" +msgstr "Yaratıcı aktif (@1)" + +#: spawner.lua +msgid "Mob Spawner settings failed!" +msgstr "Yaratıcı ayarları uygulanamadı." + +#: spawner.lua +#, fuzzy +msgid "" +"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] " +"distance[1-20] y_offset[-10 to 10]”" +msgstr "" +"> isim min_isik[0-14] max_isik[0-14] alandaki_max_canavar_sayisi[kapatmak " +"icin 0] mesafe[1-20] y_cikinti[-10 ve 10 arası]" diff --git a/mods/mobs_redo/locale/zh_CN.po b/mods/mobs_redo/locale/zh_CN.po new file mode 100644 index 0000000..bd8ffa0 --- /dev/null +++ b/mods/mobs_redo/locale/zh_CN.po @@ -0,0 +1,130 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# IFRFSX<1079092922@qq.com>, 2020. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-07-02 16:48+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: api.lua +msgid "** Peaceful Mode Active - No Monsters Will Spawn" +msgstr "** 和平模式已激活——没有怪物会产生" + +#: api.lua +msgid "Mob has been protected!" +msgstr "Mob 已经被保护了!" + +#: api.lua +msgid "@1 (Tamed)" +msgstr "@1(已驯服)" + +#: api.lua +msgid "Not tamed!" +msgstr "没有驯服!" + +#: api.lua +msgid "@1 is owner!" +msgstr "@1 是主人" + +#: api.lua +msgid "Missed!" +msgstr "没抓住!" + +#: api.lua +msgid "Already protected!" +msgstr "已经被保护!" + +#: api.lua +msgid "@1 at full health (@2)" +msgstr "@1已经满血(@2)" + +#: api.lua +msgid "@1 has been tamed!" +msgstr "@1已经被驯服!" + +#: api.lua +msgid "Enter name:" +msgstr "输入名称:" + +#: api.lua +msgid "Rename" +msgstr "重新命名" + +#: crafts.lua +msgid "Name Tag" +msgstr "名称标签" + +#: crafts.lua +msgid "Leather" +msgstr "皮革" + +#: crafts.lua +msgid "Raw Meat" +msgstr "生肉" + +#: crafts.lua +msgid "Meat" +msgstr "肉" + +#: crafts.lua +msgid "Lasso (right-click animal to put in inventory)" +msgstr "套索(右键单击动物以放入物品栏)" + +#: crafts.lua +msgid "Net (right-click animal to put in inventory)" +msgstr "网(右键单击动物以放入物品栏)" + +#: crafts.lua +msgid "Steel Shears (right-click to shear)" +msgstr "钢剪(右键单击以剪切)" + +#: crafts.lua +msgid "Mob Protection Rune" +msgstr "Mob 保护符文" + +#: crafts.lua +msgid "Saddle" +msgstr "鞍" + +#: crafts.lua +msgid "Mob Fence" +msgstr "Mob 栅栏" + +#: spawner.lua +msgid "Mob Spawner" +msgstr "Mob 孵化器" + +#: spawner.lua +msgid "Mob MinLight MaxLight Amount PlayerDist" +msgstr "Mob/最小光量/最大光量/玩家距离" + +#: spawner.lua +msgid "Spawner Not Active (enter settings)" +msgstr "孵化器未使用(输入设置)" + +#: spawner.lua +msgid "Spawner Active (@1)" +msgstr "孵化器正在运转(@1)" + +#: spawner.lua +msgid "Mob Spawner settings failed!" +msgstr "Mob 孵化器设置失败!" + +#: spawner.lua +msgid "" +"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] " +"distance[1-20] y_offset[-10 to 10]”" +msgstr "" +"语法: “物品名称 最小光亮[0-14] 最大光亮[0-14] 范围内的最大Mob数量[0 to disable] " +"距离[1-20] y_offset[-10 to 10]”" diff --git a/mods/mobs_redo/locale/zh_TW.po b/mods/mobs_redo/locale/zh_TW.po new file mode 100644 index 0000000..6350a63 --- /dev/null +++ b/mods/mobs_redo/locale/zh_TW.po @@ -0,0 +1,130 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# IFRFSX<1079092922@qq.com>, 2020. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-07-02 16:48+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: api.lua +msgid "** Peaceful Mode Active - No Monsters Will Spawn" +msgstr "** 和平模式已激活——沒有怪物會產生" + +#: api.lua +msgid "Mob has been protected!" +msgstr "Mob 已經被保護了!" + +#: api.lua +msgid "@1 (Tamed)" +msgstr "@1(已馴服)" + +#: api.lua +msgid "Not tamed!" +msgstr "沒有馴服!" + +#: api.lua +msgid "@1 is owner!" +msgstr "@1 是主人" + +#: api.lua +msgid "Missed!" +msgstr "沒抓住!" + +#: api.lua +msgid "Already protected!" +msgstr "已經被保護!" + +#: api.lua +msgid "@1 at full health (@2)" +msgstr "@1已經滿血(@2)" + +#: api.lua +msgid "@1 has been tamed!" +msgstr "@1已經被馴服!" + +#: api.lua +msgid "Enter name:" +msgstr "輸入名稱:" + +#: api.lua +msgid "Rename" +msgstr "重新命名" + +#: crafts.lua +msgid "Name Tag" +msgstr "名稱標籤" + +#: crafts.lua +msgid "Leather" +msgstr "皮革" + +#: crafts.lua +msgid "Raw Meat" +msgstr "生肉" + +#: crafts.lua +msgid "Meat" +msgstr "肉" + +#: crafts.lua +msgid "Lasso (right-click animal to put in inventory)" +msgstr "套索(右鍵單擊動物以放入物品欄)" + +#: crafts.lua +msgid "Net (right-click animal to put in inventory)" +msgstr "網(右鍵單擊動物以放入物品欄)" + +#: crafts.lua +msgid "Steel Shears (right-click to shear)" +msgstr "鋼剪(右鍵單擊以剪切)" + +#: crafts.lua +msgid "Mob Protection Rune" +msgstr "Mob 保護符文" + +#: crafts.lua +msgid "Saddle" +msgstr "鞍" + +#: crafts.lua +msgid "Mob Fence" +msgstr "Mob 柵欄" + +#: spawner.lua +msgid "Mob Spawner" +msgstr "Mob 孵化器" + +#: spawner.lua +msgid "Mob MinLight MaxLight Amount PlayerDist" +msgstr "Mob/最小光量/最大光量/玩家距離" + +#: spawner.lua +msgid "Spawner Not Active (enter settings)" +msgstr "孵化器未使用(輸入設置)" + +#: spawner.lua +msgid "Spawner Active (@1)" +msgstr "孵化器正在運轉(@1)" + +#: spawner.lua +msgid "Mob Spawner settings failed!" +msgstr "Mob 孵化器設置失敗!" + +#: spawner.lua +msgid "" +"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] " +"distance[1-20] y_offset[-10 to 10]”" +msgstr "" +"語法: “物品名稱 最小光亮[0-14] 最大光亮[0-14] 範圍內的最大Mob數量[0 to disable] " +"距離[1-20] y_offset[-10 to 10]”" diff --git a/mods/mobs_redo/lucky_block.lua b/mods/mobs_redo/lucky_block.lua new file mode 100644 index 0000000..b823e83 --- /dev/null +++ b/mods/mobs_redo/lucky_block.lua @@ -0,0 +1,18 @@ + +if minetest.get_modpath("lucky_block") then + + lucky_block:add_blocks({ + {"dro", {"mobs:meat_raw"}, 5}, + {"dro", {"mobs:meat"}, 5}, + {"dro", {"mobs:nametag"}, 1}, + {"dro", {"mobs:leather"}, 5}, + {"dro", {"default:stick"}, 10}, + {"dro", {"mobs:net"}, 1}, + {"dro", {"mobs:lasso"}, 1}, + {"dro", {"mobs:shears"}, 1}, + {"dro", {"mobs:protector"}, 1}, + {"dro", {"mobs:fence_wood"}, 10}, + {"dro", {"mobs:fence_top"}, 12}, + {"lig"} + }) +end diff --git a/mods/mobs_redo/mod.conf b/mods/mobs_redo/mod.conf new file mode 100644 index 0000000..d1f746c --- /dev/null +++ b/mods/mobs_redo/mod.conf @@ -0,0 +1,4 @@ +name = mobs +depends = +optional_depends = default, tnt, dye, farming, invisibility, intllib, lucky_block, cmi, toolranks, pathfinder, player_api +description = Adds a mob api for mods to add animals or monsters etc. diff --git a/mods/mobs_redo/mount.lua b/mods/mobs_redo/mount.lua new file mode 100644 index 0000000..88cbcd0 --- /dev/null +++ b/mods/mobs_redo/mount.lua @@ -0,0 +1,514 @@ +-- lib_mount by Blert2112 (edited by TenPlus1) + +local is_50 = minetest.get_modpath("player_api") -- 5.x compatibility + +local abs, cos, floor, sin, sqrt, pi = + math.abs, math.cos, math.floor, math.sin, math.sqrt, math.pi + +-- +-- Helper functions +-- + +local node_ok = function(pos, fallback) + + fallback = fallback or mobs.fallback_node + + local node = minetest.get_node_or_nil(pos) + + if node and minetest.registered_nodes[node.name] then + return node + end + + return {name = fallback} +end + + +local function node_is(pos) + + local node = node_ok(pos) + + if node.name == "air" then + return "air" + end + + if minetest.get_item_group(node.name, "lava") ~= 0 then + return "lava" + end + + if minetest.get_item_group(node.name, "liquid") ~= 0 then + return "liquid" + end + + if minetest.registered_nodes[node.name].walkable == true then + return "walkable" + end + + return "other" +end + + +local function get_sign(i) + + i = i or 0 + + if i == 0 then + return 0 + else + return i / abs(i) + end +end + + +local function get_velocity(v, yaw, y) + + local x = -sin(yaw) * v + local z = cos(yaw) * v + + return {x = x, y = y, z = z} +end + + +local function get_v(v) + return sqrt(v.x * v.x + v.z * v.z) +end + + +local function force_detach(player) + + if not player then return end + + local attached_to = player:get_attach() + + if not attached_to then + return + end + + local entity = attached_to:get_luaentity() + + if entity and entity.driver + and entity.driver == player then + entity.driver = nil + end + + player:set_detach() + + local name = player:get_player_name() + + if is_50 then + player_api.player_attached[name] = false + player_api.set_animation(player, "stand", 30) + else + default.player_attached[name] = false + default.player_set_animation(player, "stand", 30) + end + + player:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0}) + player:set_properties({visual_size = {x = 1, y = 1}}) +end + + +minetest.register_on_leaveplayer(function(player) + force_detach(player) +end) + + +minetest.register_on_shutdown(function() + + local players = minetest.get_connected_players() + + for i = 1, #players do + force_detach(players[i]) + end +end) + + +minetest.register_on_dieplayer(function(player) + force_detach(player) + return true +end) + + +-- Just for correct detaching +local function find_free_pos(pos) + + local check = { + {x = 1, y = 0, z = 0}, + {x = 1, y = 1, z = 0}, + {x = -1, y = 0, z = 0}, + {x = -1, y = 1, z = 0}, + {x = 0, y = 0, z = 1}, + {x = 0, y = 1, z = 1}, + {x = 0, y = 0, z = -1}, + {x = 0, y = 1, z = -1} + } + + for _, c in pairs(check) do + + local npos = {x = pos.x + c.x, y = pos.y + c.y, z = pos.z + c.z} + local node = minetest.get_node_or_nil(npos) + + if node and node.name then + + local def = minetest.registered_nodes[node.name] + + if def and not def.walkable and + def.liquidtype == "none" then + return npos + end + end + end + + return pos +end + + +function mobs.attach(entity, player) + + entity.player_rotation = entity.player_rotation or {x = 0, y = 0, z = 0} + entity.driver_attach_at = entity.driver_attach_at or {x = 0, y = 0, z = 0} + entity.driver_eye_offset = entity.driver_eye_offset or {x = 0, y = 0, z = 0} + entity.driver_scale = entity.driver_scale or {x = 1, y = 1} + + local rot_view = 0 + + if entity.player_rotation.y == 90 then + rot_view = pi / 2 + end + + local attach_at = entity.driver_attach_at + local eye_offset = entity.driver_eye_offset + + entity.driver = player + + force_detach(player) + + if is_50 then + player_api.player_attached[player:get_player_name()] = true + else + default.player_attached[player:get_player_name()] = true + end + + player:set_attach(entity.object, "", attach_at, entity.player_rotation) + player:set_eye_offset(eye_offset, {x = 0, y = 0, z = 0}) + + player:set_properties({ + visual_size = { + x = entity.driver_scale.x, + y = entity.driver_scale.y + } + }) + + minetest.after(0.2, function() + + if player and player:is_player() then + + if is_50 then + player_api.set_animation(player, "sit", 30) + else + default.player_set_animation(player, "sit", 30) + end + end + end) + + player:set_look_horizontal(entity.object:get_yaw() - rot_view) +end + + +function mobs.detach(player) + + force_detach(player) + + minetest.after(0.1, function() + + if player and player:is_player() then + + local pos = find_free_pos(player:get_pos()) + + pos.y = pos.y + 0.5 + + player:set_pos(pos) + end + end) +end + + +function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime) + + local yaw = entity.object:get_yaw() or 0 + local rot_view = 0 + + if entity.player_rotation.y == 90 then + rot_view = pi / 2 + end + + local acce_y = 0 + local velo = entity.object:get_velocity() ; if not velo then return end + + entity.v = get_v(velo) * get_sign(entity.v) + + -- process controls + if entity.driver then + + local ctrl = entity.driver:get_player_control() + + -- move forwards + if ctrl.up then + + entity.v = entity.v + entity.accel * dtime + + -- move backwards + elseif ctrl.down then + + if entity.max_speed_reverse == 0 and entity.v == 0 then + return + end + + entity.v = entity.v - entity.accel * dtime + end + + -- mob rotation + local horz + + if entity.alt_turn == true then + + horz = yaw + + if ctrl.left then + horz = horz + 0.05 + + elseif ctrl.right then + horz = horz - 0.05 + end + else + horz = entity.driver:get_look_horizontal() or 0 + end + + entity.object:set_yaw(horz - entity.rotate) + + if can_fly then + + -- fly up + if ctrl.jump then + + velo.y = velo.y + 1 + + if velo.y > entity.accel then velo.y = entity.accel end + + elseif velo.y > 0 then + + velo.y = velo.y - dtime + + if velo.y < 0 then velo.y = 0 end + end + + -- fly down + if ctrl.sneak then + + velo.y = velo.y - 1 + + if velo.y < -entity.accel then velo.y = -entity.accel end + + elseif velo.y < 0 then + + velo.y = velo.y + dtime + + if velo.y > 0 then velo.y = 0 end + end + else + -- jump + if ctrl.jump then + + if velo.y == 0 then + velo.y = velo.y + entity.jump_height + acce_y = acce_y + (acce_y * 3) + 1 + end + end + end + end + + -- if not moving then set animation and return + if entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then + + if stand_anim then + mobs:set_animation(entity, stand_anim) + end + + return + end + + -- set moving animation + if moving_anim then + mobs:set_animation(entity, moving_anim) + end + + -- Stop! + local s = get_sign(entity.v) + + entity.v = entity.v - 0.02 * s + + if s ~= get_sign(entity.v) then + + entity.object:set_velocity({x = 0, y = 0, z = 0}) + entity.v = 0 + + return + end + + -- enforce speed limit forward and reverse + if entity.v > entity.max_speed_forward then + entity.v = entity.max_speed_forward + elseif entity.v < -entity.max_speed_reverse then + entity.v = -entity.max_speed_reverse + end + + -- Set position, velocity and acceleration + local p = entity.object:get_pos() + + if not p then return end + + local new_acce = {x = 0, y = entity.fall_speed, z = 0} + + p.y = p.y - 0.5 + + local ni = node_is(p) + local v = entity.v + + if ni == "air" then + + if can_fly == true then + new_acce.y = 0 + end + + elseif ni == "liquid" or ni == "lava" then + + if ni == "lava" and entity.lava_damage ~= 0 then + + entity.lava_counter = (entity.lava_counter or 0) + dtime + + if entity.lava_counter > 1 then + + minetest.sound_play("default_punch", { + object = entity.object, + max_hear_distance = 5 + }, true) + + entity.object:punch(entity.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = entity.lava_damage} + }, nil) + + entity.lava_counter = 0 + end + end + + local terrain_type = entity.terrain_type + + if terrain_type == 2 or terrain_type == 3 then + + new_acce.y = 0 + p.y = p.y + 1 + + if node_is(p) == "liquid" then + + if velo.y >= 5 then + velo.y = 5 + elseif velo.y < 0 then + new_acce.y = 20 + else + new_acce.y = 5 + end + else + if abs(velo.y) < 1 then + + local pos = entity.object:get_pos() + + if not pos then return end + + pos.y = floor(pos.y) + 0.5 + entity.object:set_pos(pos) + velo.y = 0 + end + end + else + v = v * 0.25 + end + end + + local new_velo = get_velocity(v, yaw - rot_view, velo.y) + + new_acce.y = new_acce.y + acce_y + + entity.object:set_velocity(new_velo) + entity.object:set_acceleration(new_acce) + + entity.v2 = v +end + + +-- directional flying routine by D00Med (edited by TenPlus1) +function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim) + + local ctrl = entity.driver:get_player_control() ; if not ctrl then return end + local velo = entity.object:get_velocity() + local dir = entity.driver:get_look_dir() + local yaw = entity.driver:get_look_horizontal() + 1.57 + + if not ctrl or not velo then return end + + if ctrl.up then + + entity.object:set_velocity({ + x = dir.x * speed, + y = dir.y * speed + 2, + z = dir.z * speed + }) + + elseif ctrl.down then + + entity.object:set_velocity({ + x = -dir.x * speed, + y = dir.y * speed + 2, + z = -dir.z * speed + }) + + elseif not ctrl.down or ctrl.up or ctrl.jump then + entity.object:set_velocity({x = 0, y = -2, z = 0}) + end + + entity.object:set_yaw(yaw + pi + pi / 2 - entity.rotate) + + -- firing arrows + if ctrl.LMB and ctrl.sneak and shoots then + + local pos = entity.object:get_pos() + local obj = minetest.add_entity({ + x = pos.x + 0 + dir.x * 2.5, + y = pos.y + 1.5 + dir.y, + z = pos.z + 0 + dir.z * 2.5}, arrow) + + local ent = obj:get_luaentity() + + if ent then + + ent.switch = 1 -- for mob specific arrows + ent.owner_id = tostring(entity.object) -- so arrows dont hurt entity you are riding + + local vec = {x = dir.x * 6, y = dir.y * 6, z = dir.z * 6} + + yaw = entity.driver:get_look_horizontal() + + obj:set_yaw(yaw + pi / 2) + obj:set_velocity(vec) + else + obj:remove() + end + end + + -- change animation if stopped + if velo.x == 0 and velo.y == 0 and velo.z == 0 then + mobs:set_animation(entity, stand_anim) + else + -- moving animation + mobs:set_animation(entity, moving_anim) + end +end diff --git a/mods/mobs_redo/readme.MD b/mods/mobs_redo/readme.MD new file mode 100644 index 0000000..febcdb8 --- /dev/null +++ b/mods/mobs_redo/readme.MD @@ -0,0 +1,93 @@ + +MOBS REDO for MINETEST + +Built from PilzAdam's original Simple Mobs with additional mobs by KrupnoPavel, Zeg9, ExeterDad and AspireMint. + + +This mod contains the API only for adding your own mobs into the world, so please use the additional modpacks to add animals, monsters etc. + + +https://forum.minetest.net/viewtopic.php?f=11&t=9917 + + +Crafts: + + - Nametag (paper, black dye, string) can be used right-click on a tamed mob to give them a name. + - Nets can be used to right-click tamed mobs to pick them up and place inside inventory as a spawn egg. + - Magic Lasso is similar to nets but with a better chance of picking up larger mobs. + - Shears are used to right-click sheep and return 1-3 wool. + - Protection Rune lets you protect tamed mobs from harm by other players + - Mob Fence and Fence Top (to stop mobs escaping/glitching through fences) + +Lucky Blocks: 9 + + +Changelog: +- 1.56 - Added arrow_override function to mob definition to tweak arrow entity settings, tamed monsters no longer despawn when outside loaded map area, 'looting_level' can be read from tool definition or tool meta to add extra drops when mob killed. +- 1.55 - Add 'peaceful_player' privelage and setting so mobs don't attack specific players (thanks sfence), add support for MarkBu's pathfinder mod, remove need for default mod +- 1.54 - Simplified animal breeding function, added editable settings (thanks Wuzzy), Child mobs now take 20 mins to grow up, reverted to simple mob spawning with setting to use area checks, on_flop added, air_damage added. +- 1.53 - Added 'on_map_load' settings to mobs:spawn so that mobs will only spawn when new areas of map are loaded. +- 1.52 - Added 'mob_active_limit' in settings to set number of mobs in game, +(default is 0 for unlimited), removed {immortal} from mob armor, fluid viscocity slows mobs +- 1.51 - Added some node checks for dangerous nodes, jumping and falling tweaks, spawn area check (thx for idea wuzzy), re-enabled mob suffocation, add 'mob_nospawn_range' setting +- 1.50 - Added new line_of_sight function that uses raycasting if mt5.0 is found, (thanks Astrobe), dont spawn mobs if world anchor nearby (technic or simple_anchor mods), chinese local added +- 1.49- Added mobs:force_capture(self, player) function, api functions now use metatables thanks to bell07 +- 1.48- Add mobs:set_velocity(self, velocity) global function +- 1.47- Mob damage changes, min and max light level for damage added, ignition sources checked for lava damage +- 1.46- Mobs only drop rare items when killed by player (drops.min = 0 makes them rare), code tweak, pathfinding no longer sees through walkable nodes +- 1.45- Added Fence Top to add on top of any fence to stop mobs escaping, new line_of_sight tweaked by Astrobe +- 1.44- Added ToolRanks support for swords when attacking mobs +- 1.43- Better 0.4.16 compatibility, added general attack function and settings +- 1.42- Added "all" option to immune_to table, tidied floating mobs to be less intensive +- 1.41- Mob pathfinding has been updated thanks to Elkien3 +- 1.40- Updated to use newer functions, requires Minetest 0.4.16+ to work. +- 1.39- Added 'on_breed', 'on_grown' and 'do_punch' custom functions per mob +- 1.38- Better entity checking, nametag setting and on_spawn function added to mob registry, tweaked light damage +- 1.37- Added support for Raymoo's CMI (common mob interface) mod: https://forum.minetest.net/viewtopic.php?f=9&t=15448 +- 1.36- Death check added, if mob dies in fire/lava/with lava pick then drops are cooked +- 1.35- Added owner_loyal flag for owned mobs to attack player enemies, also fixed group_attack +- 1.34- Added function to fly mob using directional movement (thanks D00Med for flying code) +- 1.33- Added functions to mount ride mobs (mobs.attach, mobs.detach, mobs.drive) many thanks to Blert2112 +- 1.32- Added new spawn check to count specific mobs AND new minetest.conf setting to chance spawn chance and numbers, added ability to protect tamed mobs +- 1.31- Added 'attack_animals' and 'specific_attack' flags for custom monster attacks, also 'mob_difficulty' .conf setting to make mobs harder. +- 1.30- Added support for invisibility mod (mobs cant attack what they cant see), tweaked and tidied code +- 1.29- Split original Mobs Redo into a modpack to make it easier to disable mob sets (animal, monster, npc) or simply use the Api itself for your own mod +- 1.28- New damage system added with ability for mob to be immune to weapons or healed by them :) +- 1.27- Added new sheep, lava flan and spawn egg textures. New Lava Pick tool smelts what you dig. New atan checking function. +- 1.26- Pathfinding feature added thanks to rnd, when monsters attack they become scary smart in finding you :) also, beehive produces honey now :) +- 1.25- Mobs no longer spawn within 12 blocks of player or despawn within same range, spawners now have player detection, Code tidy and tweak. +- 1.24- Added feature where certain animals run away when punched (runaway = true in mob definition) +- 1.23- Added mob spawner block for admin to setup spawners in-game (place and right click to enter settings) +- 1.22- Added ability to name tamed animals and npc using nametags, also npc will attack anyone who punches them apart from owner +- 1.21- Added some more error checking to reduce serialize.h error and added height checks for falling off cliffs (thanks cmdskp) +- 1.20- Error checking added to remove bad mobs, out of map limit mobs and stop serialize.h error +- 1.19- Chickens now drop egg items instead of placing the egg, also throwing eggs result in 1/8 chance of spawning chick +- 1.18- Added docile_by_day flag so that monsters will not attack automatically during daylight hours unless hit first +- 1.17- Added 'dogshoot' attack type, shoots when out of reach, melee attack when in reach, also api tweaks and self.reach added +- 1.16- Mobs follow multiple items now, Npc's can breed +- 1.15- Added Feeding/Taming/Breeding function, right-click to pick up any sheep with X mark on them and replace with new one to fix compatibility. +- 1.14- All .self variables saved in staticdata, Fixed self.health bug +- 1.13- Added capture function (thanks blert2112) chance of picking up mob with hand; net; magic lasso, replaced some .x models with newer .b3d one's +- 1.12- Added animal ownership so that players cannot steal your tamed animals +- 1.11- Added flying mobs (and swimming), fly=true and fly_in="air" or "deafult:water_source" for fishy +- 1,10- Footstep removed (use replace), explosion routine added for exploding mobs. +- 1.09- reworked breeding routine, added mob rotation value, added footstep feature, added jumping mobs with sounds feature, added magic lasso for picking up animals +- 1.08- Mob throwing attack has been rehauled so that they can damage one another, also drops and on_die function added +- 1.07- Npc's can now be set to follow player or stand by using self.order and self.owner variables +- beta- Npc mob added, kills monsters, attacks player when punched, right click with food to heal or gold lump for drop +- 1.06- Changed recovery times after breeding, and time taken to grow up (can be sped up by feeding baby animal) +- 1.05- Added ExeterDad's bunny's which can be picked up and tamed with 4 carrots from farming redo or farming_plus, also shears added to get wool from sheep and lastly Jordach/BSD's kitten +- 1.04- Added mating for sheep, cows and hogs... feed animals to make horny and hope for a baby which is half size, will grow up quick though :) +- 1.03- Added mob drop/replace feature so that chickens can drop eggs, cow/sheep can eat grass/wheat etc. +- 1.02- Sheared sheep are remembered and spawn shaven, Warthogs will attack when threatened, Api additions +- 1.01- Mobs that suffer fall damage or die in water/lava/sunlight will now drop items +- 1.0 - more work on Api so that certain mobs can float in water while some sink like a brick :) +- 0.9 - Spawn eggs added for all mobs (admin only, cannot be placed in protected areas)... Api tweaked +- 0.8 - Added sounds to monster mobs (thanks Cyberpangolin for the sfx) and also chicken sound +- 0.7 - mobs.protected switch added to api.lua, when set to 1 mobs no longer spawn in protected areas, also bug fixes +- 0.6 - Api now supports multi-textured mobs, e.g oerkki, dungeon master, rats and chickens have random skins when spawning (sheep fix TODO), also new Honey block +- 0.5 - Mobs now float in water, die from falling, and some code improvements +- 0.4 - Dungeon Masters and Mese Monsters have much better aim due to shoot_offset, also they can both shoot through nodes that aren't walkable (flowers, grass etc) plus new sheep sound :) +- 0.3 - Added LOTT's Spider mob, made Cobwebs, added KPavel's Bee with Honey and Beehives (made texture), Warthogs now have sound and can be tamed, taming of shaved sheep or milked cow with 8 wheat so it will not despawn, many bug fixes :) +- 0.2 - Cooking bucket of milk into cheese now returns empty bucket +- 0.1 - Initial Release diff --git a/mods/mobs_redo/settingtypes.txt b/mods/mobs_redo/settingtypes.txt new file mode 100644 index 0000000..37bbce9 --- /dev/null +++ b/mods/mobs_redo/settingtypes.txt @@ -0,0 +1,44 @@ +# If false then mobs no longer spawn in world without spawner or spawn egg +mobs_spawn (Spawn Mobs) bool true + +# If enabled then monsters no longer spawn in world +only_peaceful_mobs (Only spawn peaceful Mobs) bool false + +# If enabled then punching mobs no longer shows blood effects +mobs_disable_blood (Disable Mob blood) bool false + +# If disabled then Mobs no longer destroy world blocks +mobs_griefing (Griefing Mobs) bool true + +# If false then Mobs no longer spawn inside player protected areas +mobs_spawn_protected (Spawn Mobs in protected areas) bool true + +# If false then Monsters no longer spawn inside player protected areas +mobs_spawn_monster_protected (Spawn Monsters in protected areas) bool true + +# If true Mobs will be removed once a map chunk is out of view +remove_far_mobs (Remove far Mobs) bool true + +# Sets Mob difficulty level by multiplying punch damage +mob_difficulty (Mob difficulty) float 1.0 + +# Contains a value used to multiply Mob spawn values +mob_chance_multiplier (Mob chance multiplier) float 1.0 + +# When false Mob no longer drop items when killed +mobs_drop_items (Mob drops) bool true + +# Sets minimum distance around player that mobs cannot spawn +mob_nospawn_range (Mob no-spawn range) float 12.0 + +# Sets maximum number of active mobs in game (0 for unlimited) +mob_active_limit (Mob Active Limit) float 0 + +# Enables area check when spawning mobs +mob_area_spawn (Mob Area Spawn) bool false + +# Enable peaceful player attack prevention +enable_peaceful_player (Mobs do not attack peaceful player without reason) bool false + +# Enable mobs smooth rotation +mob_smooth_rotate (Smooth rotation for mobs) bool true diff --git a/mods/mobs_redo/sounds/default_punch.ogg b/mods/mobs_redo/sounds/default_punch.ogg new file mode 100644 index 0000000..28a500b Binary files /dev/null and b/mods/mobs_redo/sounds/default_punch.ogg differ diff --git a/mods/mobs_redo/sounds/license.txt b/mods/mobs_redo/sounds/license.txt new file mode 100644 index 0000000..3b160fe --- /dev/null +++ b/mods/mobs_redo/sounds/license.txt @@ -0,0 +1,7 @@ +Creative Commons sounds from Freesound.org + +mobs_swing.ogg by qubodup + - http://freesound.org/people/qubodup/sounds/60012/ + +mobs_spell.ogg by littlerobotsoundfactory + - http://freesound.org/people/LittleRobotSoundFactory/sounds/270396/ diff --git a/mods/mobs_redo/sounds/mobs_spell.ogg b/mods/mobs_redo/sounds/mobs_spell.ogg new file mode 100644 index 0000000..455b54f Binary files /dev/null and b/mods/mobs_redo/sounds/mobs_spell.ogg differ diff --git a/mods/mobs_redo/sounds/mobs_swing.ogg b/mods/mobs_redo/sounds/mobs_swing.ogg new file mode 100644 index 0000000..ffe6a9c Binary files /dev/null and b/mods/mobs_redo/sounds/mobs_swing.ogg differ diff --git a/mods/mobs_redo/spawner.lua b/mods/mobs_redo/spawner.lua new file mode 100644 index 0000000..bfcdcba --- /dev/null +++ b/mods/mobs_redo/spawner.lua @@ -0,0 +1,192 @@ + +local S = mobs.intllib + +-- mob spawner + +local spawner_default = "mobs_animal:pumba 10 15 0 0 0" + +minetest.register_node("mobs:spawner", { + tiles = {"mob_spawner.png"}, + drawtype = "glasslike", + paramtype = "light", + walkable = true, + description = S("Mob Spawner"), + groups = {cracky = 1}, + + on_construct = function(pos) + + local meta = minetest.get_meta(pos) + + -- setup formspec + local head = S("(mob name) (min light) (max light) (amount)" + .. " (player distance) (Y offset)") + + -- text entry formspec + meta:set_string("formspec", + "size[10,3.5]" + .. "label[0.15,0.5;" .. minetest.formspec_escape(head) .. "]" + .. "field[1,2.5;8.5,0.8;text;" .. S("Command:") + .. ";${command}]") + + meta:set_string("infotext", S("Spawner Not Active (enter settings)")) + meta:set_string("command", spawner_default) + end, + + on_right_click = function(pos, placer) + + if minetest.is_protected(pos, placer:get_player_name()) then + return + end + end, + + on_receive_fields = function(pos, formname, fields, sender) + + if not fields.text or fields.text == "" then + return + end + + local meta = minetest.get_meta(pos) + local comm = fields.text:split(" ") + local name = sender:get_player_name() + + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return + end + + local mob = comm[1] -- mob to spawn + local mlig = tonumber(comm[2]) -- min light + local xlig = tonumber(comm[3]) -- max light + local num = tonumber(comm[4]) -- total mobs in area + local pla = tonumber(comm[5]) -- player distance (0 to disable) + local yof = tonumber(comm[6]) or 0 -- Y offset to spawn mob + + if mob and mob ~= "" and mobs.spawning_mobs[mob] + and num and num >= 0 and num <= 10 + and mlig and mlig >= 0 and mlig <= 15 + and xlig and xlig >= 0 and xlig <= 15 + and pla and pla >= 0 and pla <= 20 + and yof and yof > -10 and yof < 10 then + + meta:set_string("command", fields.text) + meta:set_string("infotext", S("Spawner Active (@1)", mob)) + + else + minetest.chat_send_player(name, S("Mob Spawner settings failed!")) + minetest.chat_send_player(name, + S("Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] player_distance[1-20] y_offset[-10 to 10]”")) + end + end +}) + + +local max_per_block = tonumber(minetest.settings:get("max_objects_per_block") or 99) + +-- spawner abm +minetest.register_abm({ + label = "Mob spawner node", + nodenames = {"mobs:spawner"}, + interval = 10, + chance = 4, + catch_up = false, + + action = function(pos, node, active_object_count, active_object_count_wider) + + -- return if too many entities already + if active_object_count_wider >= max_per_block then + return + end + + -- get meta and command + local meta = minetest.get_meta(pos) + local comm = meta:get_string("command"):split(" ") + + -- get settings from command + local mob = comm[1] + local mlig = tonumber(comm[2]) + local xlig = tonumber(comm[3]) + local num = tonumber(comm[4]) + local pla = tonumber(comm[5]) or 0 + local yof = tonumber(comm[6]) or 0 + + -- if amount is 0 then do nothing + if num == 0 then + return + end + + -- are we spawning a registered mob? + if not mobs.spawning_mobs[mob] then + --print ("--- mob doesn't exist", mob) + return + end + + -- check objects inside 9x9 area around spawner + local objs = minetest.get_objects_inside_radius(pos, 9) + local count = 0 + local ent + + -- count mob objects of same type in area + for _, obj in ipairs(objs) do + + ent = obj:get_luaentity() + + if ent and ent.name and ent.name == mob then + count = count + 1 + end + end + + -- is there too many of same type? + if count >= num then + return + end + + -- spawn mob if player detected and in range + if pla > 0 then + + local in_range = 0 + local objsp = minetest.get_objects_inside_radius(pos, pla) + + for _, oir in pairs(objsp) do + + if oir:is_player() then + + in_range = 1 + + break + end + end + + -- player not found + if in_range == 0 then + return + end + end + + -- set medium mob usually spawns in (defaults to air) + local reg = minetest.registered_entities[mob].fly_in + + if not reg or type(reg) == "string" then + reg = {(reg or "air")} + end + + -- find air blocks within 5 nodes of spawner + local air = minetest.find_nodes_in_area( + {x = pos.x - 5, y = pos.y + yof, z = pos.z - 5}, + {x = pos.x + 5, y = pos.y + yof, z = pos.z + 5}, reg) + + -- spawn in random air block + if air and #air > 0 then + + local pos2 = air[math.random(#air)] + local lig = minetest.get_node_light(pos2) or 0 + + pos2.y = pos2.y + 0.5 + + -- only if light levels are within range + if lig >= mlig and lig <= xlig + and minetest.registered_entities[mob] then + minetest.add_entity(pos2, mob) + end + end + end +}) diff --git a/mods/mobs_redo/textures/mob_spawner.png b/mods/mobs_redo/textures/mob_spawner.png new file mode 100644 index 0000000..8f0ac39 Binary files /dev/null and b/mods/mobs_redo/textures/mob_spawner.png differ diff --git a/mods/mobs_redo/textures/mobs_blood.png b/mods/mobs_redo/textures/mobs_blood.png new file mode 100644 index 0000000..4236a00 Binary files /dev/null and b/mods/mobs_redo/textures/mobs_blood.png differ diff --git a/mods/mobs_redo/textures/mobs_blood1.png b/mods/mobs_redo/textures/mobs_blood1.png new file mode 100644 index 0000000..23d2e34 Binary files /dev/null and b/mods/mobs_redo/textures/mobs_blood1.png differ diff --git a/mods/mobs_redo/textures/mobs_chicken_egg.png b/mods/mobs_redo/textures/mobs_chicken_egg.png new file mode 100644 index 0000000..be8a4e1 Binary files /dev/null and b/mods/mobs_redo/textures/mobs_chicken_egg.png differ diff --git a/mods/mobs_redo/textures/mobs_chicken_egg_overlay.png b/mods/mobs_redo/textures/mobs_chicken_egg_overlay.png new file mode 100644 index 0000000..e81716a Binary files /dev/null and b/mods/mobs_redo/textures/mobs_chicken_egg_overlay.png differ diff --git a/mods/mobs_redo/textures/mobs_leather.png b/mods/mobs_redo/textures/mobs_leather.png new file mode 100644 index 0000000..3205e5d Binary files /dev/null and b/mods/mobs_redo/textures/mobs_leather.png differ diff --git a/mods/mobs_redo/textures/mobs_magic_lasso.png b/mods/mobs_redo/textures/mobs_magic_lasso.png new file mode 100644 index 0000000..befdc11 Binary files /dev/null and b/mods/mobs_redo/textures/mobs_magic_lasso.png differ diff --git a/mods/mobs_redo/textures/mobs_meat.png b/mods/mobs_redo/textures/mobs_meat.png new file mode 100644 index 0000000..4c63fdd Binary files /dev/null and b/mods/mobs_redo/textures/mobs_meat.png differ diff --git a/mods/mobs_redo/textures/mobs_meat_bottom.png b/mods/mobs_redo/textures/mobs_meat_bottom.png new file mode 100644 index 0000000..351c16f Binary files /dev/null and b/mods/mobs_redo/textures/mobs_meat_bottom.png differ diff --git a/mods/mobs_redo/textures/mobs_meat_raw.png b/mods/mobs_redo/textures/mobs_meat_raw.png new file mode 100644 index 0000000..0dea4ec Binary files /dev/null and b/mods/mobs_redo/textures/mobs_meat_raw.png differ diff --git a/mods/mobs_redo/textures/mobs_meat_side.png b/mods/mobs_redo/textures/mobs_meat_side.png new file mode 100644 index 0000000..10dac08 Binary files /dev/null and b/mods/mobs_redo/textures/mobs_meat_side.png differ diff --git a/mods/mobs_redo/textures/mobs_meat_top.png b/mods/mobs_redo/textures/mobs_meat_top.png new file mode 100644 index 0000000..0058e6a Binary files /dev/null and b/mods/mobs_redo/textures/mobs_meat_top.png differ diff --git a/mods/mobs_redo/textures/mobs_nametag.png b/mods/mobs_redo/textures/mobs_nametag.png new file mode 100644 index 0000000..74005b3 Binary files /dev/null and b/mods/mobs_redo/textures/mobs_nametag.png differ diff --git a/mods/mobs_redo/textures/mobs_net.png b/mods/mobs_redo/textures/mobs_net.png new file mode 100644 index 0000000..df7c3a6 Binary files /dev/null and b/mods/mobs_redo/textures/mobs_net.png differ diff --git a/mods/mobs_redo/textures/mobs_noentry_particle.png b/mods/mobs_redo/textures/mobs_noentry_particle.png new file mode 100644 index 0000000..87938ff Binary files /dev/null and b/mods/mobs_redo/textures/mobs_noentry_particle.png differ diff --git a/mods/mobs_redo/textures/mobs_protect_particle.png b/mods/mobs_redo/textures/mobs_protect_particle.png new file mode 100644 index 0000000..debe20c Binary files /dev/null and b/mods/mobs_redo/textures/mobs_protect_particle.png differ diff --git a/mods/mobs_redo/textures/mobs_protector.png b/mods/mobs_redo/textures/mobs_protector.png new file mode 100644 index 0000000..f3937b7 Binary files /dev/null and b/mods/mobs_redo/textures/mobs_protector.png differ diff --git a/mods/mobs_redo/textures/mobs_protector2.png b/mods/mobs_redo/textures/mobs_protector2.png new file mode 100644 index 0000000..8c5a17e Binary files /dev/null and b/mods/mobs_redo/textures/mobs_protector2.png differ diff --git a/mods/mobs_redo/textures/mobs_saddle.png b/mods/mobs_redo/textures/mobs_saddle.png new file mode 100644 index 0000000..e9d42f8 Binary files /dev/null and b/mods/mobs_redo/textures/mobs_saddle.png differ diff --git a/mods/mobs_redo/textures/mobs_shears.png b/mods/mobs_redo/textures/mobs_shears.png new file mode 100644 index 0000000..aa16f2e Binary files /dev/null and b/mods/mobs_redo/textures/mobs_shears.png differ diff --git a/mods/mobs_redo/textures/tnt_smoke.png b/mods/mobs_redo/textures/tnt_smoke.png new file mode 100644 index 0000000..488b50f Binary files /dev/null and b/mods/mobs_redo/textures/tnt_smoke.png differ diff --git a/mods/more_fire/changelog.txt b/mods/more_fire/changelog.txt new file mode 100644 index 0000000..920e5c8 --- /dev/null +++ b/mods/more_fire/changelog.txt @@ -0,0 +1,78 @@ +6-4-20: +Code updates and cleaning. No new features. + +8-26-15: +You can finally cook in the fires, there seems to be a little bug yet in the arrow showing the progress of the cooking, but mechanics all seem to work alright. + +6-3-15: +Campfires and embers now have particles, smoke for the embers, and little sparks for the fires. Also lava now spawns little lava particles, the particles do nothing other than add a little visual effect. + +5-30-15: +Napiophelios put together some nice smoke bombs and molotov cocktails for this mod, I(Nathan) did a few tweaks, changed some alignment and took care of some depreciated functions to stop debug spamming. + +5-12-15: +Lanterns are here, both wall mounted a table top. Craft with a piece of glass above a string above a lump of iron. Yields one lantern, craft the lantern to change between wall mounted and table top. +Lanterns burn oil, twelve minutes of light for one bottle of oil. Put six leaves above a glass vessel to create lantern oil. + +4-15-15: +All fires now die after time. When you create embers either by lighting kindling or crafting directly you have about three minutes to add wood. After the wood all burns up you have three minutes to add more wood or the embers turn back into kindling and need to be activated with a lighter again. + +4-13-15: +Changed some how I add the drops to gravel, no longer do I replace the entire node, just add the new drop info to it. This should keep it from breaking anything that does the same to gravel. + +4-12-15: +Some major overhauling, not of code, but layout, no longer is everything stored in the init.lua, it's all broken down into neat files. +I added finite torches, change the settings in the config, right now you can only turn them on or off, settings are not retro-active, only torches placed after the update will burn out. When a torch burns out it turns into a torch stub which can be picked up and burnt as fuel. +I changed a couple textures down to 16x16, they had been 32x32. Renamed textures to follow proper naming methods, this won't change any placed nodes. + +11-22-14: +Changed a couple textures. +Currently using nodeboxes for torches, so they are no longer invisible. + +11-19-14: +Campfires are working altogether now. Craft kindling and add some fuel to it, and then click on it with the lighter until it starts on fire. + +11-12-14: +Removed the ABM for torches, and replaced the two nodes with just one. +Tweaked the lighter, it should last longer and light fires faster. Added a sparking sound effect as well. +The lighter takes damage every time it is used, regardless of if it starts a fire, or is used on kindling. + +11-11-14: +Charcoal blocks are now flammable. + +11-08-14: +Added a kindling that will created contained fire. +Updated the lighter to turn the two different kindling into the two different fires. + +11-05-14: +Corrected the texture for the Charcoal Block. +Added recipe to turn charcoal block back into charcoal lumps. + +11-04-14: +Added recipe for fire that uses torch and kindling. + +10-27-14: +Made the torches a tad bit smaller. +Removed all the formspec stuff from the campfires. I couldn't get them to work, so I'll come back to that when I learn more of the coding needed. +Removed the .mlt files from the models folder as I discovered they aren't needed and just give errors in the debug. + +10-26-14: +Added kindling, craft it from a stick, wood, and two other flammable grouped items. Light it with the lighter, which is made with flint and steel. + +10-25-14: +Torches stick to the wall or the floor according as they should. Copied code from the 3d_torch mod. + +10-24-14: +Campfires now have animated fire. Turns out that I was exporting the file wrong. :S + +10-22-14: +Added 3d models for the torch and campfires. Textures aren't perfect on the campfire yet. + +10-19-14: +Added the 'more_fire = {}' line and now the mod runs again, though the fire doesn't do anything when you right click on it. + +10-17-14: +Renamed and relocated the git repository to match the forum topic +Updated the fire so it can only be placed on the ground. +Added flint that drops from gravel. Will be used for fire starters. +Campfire now drops charcoal. diff --git a/mods/more_fire/init.lua b/mods/more_fire/init.lua new file mode 100644 index 0000000..5c7a053 --- /dev/null +++ b/mods/more_fire/init.lua @@ -0,0 +1,13 @@ +-- A couple variables used throughout. +percent = 100 +-- GUI related stuff +default.gui_bg = 'bgcolor[#080808BB;true]' +default.gui_bg_img = 'background[5,5;1,1;gui_formbg.png;true]' +default.gui_slots = 'listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF]' + +more_fire = {} + +dofile(minetest.get_modpath('more_fire')..'/molotov.lua') +dofile(minetest.get_modpath('more_fire')..'/pipebomb.lua') +dofile(minetest.get_modpath('more_fire')..'/smokebomb.lua') + diff --git a/mods/more_fire/lib/Vec3_1-0.lua b/mods/more_fire/lib/Vec3_1-0.lua new file mode 100644 index 0000000..85d91ae --- /dev/null +++ b/mods/more_fire/lib/Vec3_1-0.lua @@ -0,0 +1,398 @@ +local THIS_VERSION = "1.0" + +--- 3D vector class/operations. + -- + -- Note that methods can be called in either an object-oriented way: + -- v1 = Vec3(1, 2, 3) + -- v2 = v1:add({ x = 2, y = 2, z = 0 }) + -- or as simple functions: + -- Vec3.add({ x = 1, y = 2, z = 3 }, { x = 2, y = 2, z = 0 }) + -- + -- All methods that can be called on a Vec3 using ":" may be called on a table + -- using the second functional syntax, but the first parameter MUST have the + -- expected components "x", "y", and "z". If a vector is used as the second + -- paramter, it may instead be a list/array with numeric indices, like + -- { 1.0, 2.0, 3.0 } in place of { x = 1.0, y = 2.0, z = 3.0 }. + -- + -- @author prestidigitator (as registered at forum.minetest.net) + -- @copyright 2013, licensed under WTFPL + -- +local Vec3 = {} +local Vec3_meta = {} +local Vec3_inst_meta = {} + +Vec3.VERSION = THIS_VERSION + +setmetatable(Vec3, Vec3_meta) +Vec3_inst_meta.__index = Vec3 + +--- Constructs a Vec3 from three numbers. + -- + -- Call with one of: + -- Vec3.new(x, y, z) + -- Vec3(x, y, z) + -- + -- @return a new Vec3 object +local function Vec3_new(x, y, z) + local obj = { x = x or 0.0, y = y or 0.0, z = z or 0.0 } + setmetatable(obj, Vec3_inst_meta) + return obj +end +Vec3.new = Vec3_new + +--- Constructs a new copy of a Vec3. + -- + -- Call with one of: + -- vec:new_copy() + -- Vec3.new_copy(vec) + -- Vec3(vec) + -- + -- @return a new Vec3 object that is a copy of the parameter +local function Vec3_new_copy(v) + local obj = { x = v.x or v[1] or 0.0, + y = v.y or v[2] or 0.0, + z = v.z or v[3] or 0.0 } + setmetatable(obj, Vec3_inst_meta) + return obj +end +Vec3.new_copy = Vec3_new_copy + +Vec3_meta.__call = function(class, a, b, c) + if type(a) == "table" then + return Vec3.new_copy(a) + else + return Vec3.new(a, b, c) + end +end + +--- Computes the square of the length of a Vec3. + -- + -- Call with one of: + -- vec:len_sq() + -- Vec3.len_sq(vec) + -- + -- @return a number +local function Vec3_len_sq(v) + return v.x^2 + v.y^2 + v.z^2 +end +Vec3.len_sq = Vec3_len_sq + +--- Computes the length of a Vec3. + -- + -- Call with one of: + -- vec:len() + -- Vec3.len(vec) + -- + -- @return a number +local function Vec3_len(v) + return math.sqrt(v.x^2 + v.y^2 + v.z^2) +end +Vec3.len = Vec3_len + +--- Computes a unit vector pointing in the same direction as a Vec3. + -- Undefined for a zero-vector and may throw an error. + -- + -- Call with one of: + -- vec:unit() + -- Vec3.unit(vec) + -- + -- @return a new Vec3 with length 1.0 +local function Vec3_unit(v) + local len = math.sqrt(v.x^2 + v.y^2 + v.z^2) + return Vec3.new(v.x/len, v.y/len, v.z/len) +end +Vec3.unit = Vec3_unit + +--- Multiplies a Vec3 by a number. + -- + -- Call with one of: + -- vec:mul(m) + -- Vec3.mul(vec, m) + -- vec*m + -- m*vec + -- + -- @return a new Vec3 object with the result of the operation +local function Vec3_mul(v, m) + local mn = tonumber(m) + if not mn then error("Can't multiply vector by non-scalar") end + return Vec3.new(v.x*mn, v.y*mn, v.z*mn) +end +Vec3.mul = Vec3_mul +Vec3_inst_meta.__mul = function(a, b) + if type(a) == "table" then + return Vec3_mul(a, b) + else + return Vec3_mul(b, a) + end +end + +--- Divides a Vec3 by a number. + -- + -- Call with one of: + -- vec:div(m) + -- Vec3.div(vec, m) + -- vec/m + -- + -- @return a new Vec3 object with the result of the operation +local function Vec3_div(v, m) + return Vec3.new(v.x/m, v.y/m, v.z/m) +end +Vec3.div = Vec3_div +Vec3_inst_meta.__div = Vec3_div + +--- Negates a Vec3 (signs of all components are inverted). + -- + -- Call with one of: + -- vec:unm() + -- Vec3.unm(vec) + -- -vec + -- + -- @return a new Vec3 object with the result of the operation +local function Vec3_unm(v) + return Vec3.new(-v.x, -v.y, -v.z) +end +Vec3.unm = Vec3_unm +Vec3_inst_meta.__unm = Vec3_unm + +--- Adds two Vec3s or a Vec3 composed of three given components. + -- + -- Call with one of: + -- vec1:add(vec2) + -- vec1:add(x, y, z) + -- Vec3.add(vec1, vec2) + -- Vec3.add(vec1, x, y, z) + -- vec1 + vec2 + -- + -- @return a new Vec3 object with the result of the operation +local function Vec3_add(v, a, b, c) + if type(a) == "table" then + return Vec3.new(v.x + (a.x or a[1] or 0.0), + v.y + (a.y or a[2] or 0.0), + v.z + (a.z or a[3] or 0.0)) + else + return Vec3.new(v.x + a, v.y + b, v.z + c) + end +end +Vec3.add = Vec3_add + +--- Subtracts two Vec3s or a Vec3 composed of three given components. + -- + -- Call with one of: + -- vec1:sub(vec2) + -- vec1:sub(x, y, z) + -- Vec3.sub(vec1, vec2) + -- Vec3.sub(vec1, x, y, z) + -- vec1 - vec2 + -- + -- @return a new Vec3 object with the result of the operation +local function Vec3_sub(v, a, b, c) + if type(a) == "table" then + return Vec3.new(v.x - (a.x or a[1] or 0.0), + v.y - (a.y or a[2] or 0.0), + v.z - (a.z or a[3] or 0.0)) + else + return Vec3.new(v.x - a, v.y - b, v.z - c) + end +end +Vec3.sub = Vec3_sub + +--- Tests two Vec3s or a Vec3 composed of three given components for + -- exact component-wise equality. + -- + -- Call with one of: + -- vec1:eq(vec2) + -- vec1:eq(x, y, z) + -- Vec3.eq(vec1, vec2) + -- Vec3.eq(vec1, x, y, z) + -- vec1 == vec2 + -- vec1 ~= vec2 + -- Note that because of built-in Lua logic "==" and "~=" work ONLY if + -- vec1 and vec2 are actually Vec3s (not tables). + -- + -- @return a new Vec3 object with the result of the operation +local function Vec3_eq(v, a, b, c) + if type(a) == "table" then + return v.x == (a.x or a[1] or 0.0) and + v.y == (a.y or a[2] or 0.0) and + v.z == (a.z or a[3] or 0.0) + else + return v.x == a and v.y == b and v.z == c + end +end +Vec3.eq = Vec3_eq + +--- Takes the dot product of a Vec3 and a Vec3s or a Vec3 composed of + -- three given components. + -- + -- Call with one of: + -- vec1:dot(vec2) + -- vec1:dot(x, y, z) + -- Vec3.dot(vec1, vec2) + -- Vec3.dot(vec1, x, y, z) + -- + -- @return a number +local function Vec3_dot(v, a, b, c) + if type(a) == "table" then + return v.x * (a.x or a[1] or 0.0) + + v.y * (a.y or a[2] or 0.0) + + v.z * (a.z or a[3] or 0.0) + else + return v.x * a + v.y * b + v.z * c + end +end +Vec3.dot = Vec3_dot + +--- Takes the cross product of a Vec3 and a Vec3s or a Vec3 composed of + -- three given components. + -- + -- Call with one of: + -- vec1:cross(vec2) + -- vec1:cross(x, y, z) + -- Vec3.cross(vec1, vec2) + -- Vec3.cross(vec1, x, y, z) + -- + -- @return a new Vec3 with the result of the operation +local function Vec3_cross(v, a, b, c) + local ux, uy, uz + if type(a) == "table" then + ux = a.x or a[1] or 0.0 + uy = a.y or a[2] or 0.0 + uz = a.z or a[3] or 0.0 + else + ux = a or 0.0 + uy = b or 0.0 + uz = c or 0.0 + end + + return Vec3.new(v.y*uz - v.z*uy, v.z*ux - v.x*uz, v.x*uy - v.y*ux) +end +Vec3.cross = Vec3_cross + +--- Rotates this (the first) vector around the second vector by the + -- given angle. + -- + -- Call with one of: + -- vec:rot_around(axis, angle) + -- Vec3.rot_around(vec, axis, angle) + -- + -- @param axis + -- The axis about which to rotate. + -- @param angle + -- The angle by which to rotate this vector, in radians. + -- @return + -- a new Vec3 with the result of the operation. +local function Vec3_rot_around(v, axis, angle) + local uaxis = Vec3.new_copy(axis):unit() + + local alen = uaxis:dotvec(v) + local avec = uaxis:mul(alen) + + local pvec = Vec3.subvec(v, avec) + local rvec = uaxis:crossvec(v) + + local v1 = pvec:mul(math.cos(angle)) + local v2 = rvec:mul(math.sin(angle)) + + return avec:addvec(v1):addvec(v2) +end +Vec3.rot_around = Vec3_rot_around + +--- Adds two Vec3s. Optimized for pure Vec3/table operations by removing + -- type checking and conditionals. If called with Vec3-likes table(s), + -- ensure all expected components "x", "y", and "z" exist. + -- + -- Call with one of: + -- vec1:addvec(vec2) + -- Vec3.addvec(vec1, vec2) + -- + -- @return a new Vec3 object with the result of the operation +local function Vec3_addvec(v1, v2) + return Vec3.new(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z) +end +Vec3.addvec = Vec3_addvec +Vec3_inst_meta.__add = Vec3_addvec + +--- Subtracts two Vec3s. Optimized for pure Vec3/table operations by + -- removing type checking and conditionals. If called with Vec3-likes + -- table(s), ensure all expected components "x", "y", and "z" exist. + -- + -- Call with one of: + -- vec1:subvec(vec2) + -- Vec3.subvec(vec1, vec2) + -- + -- @return a new Vec3 object with the result of the operation +local function Vec3_subvec(v1, v2) + return Vec3.new(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z) +end +Vec3.subvec = Vec3_subvec +Vec3_inst_meta.__sub = Vec3_subvec + +--- Tests two Vec3s for exact component-wise equality. Optimized for pure + -- Vec3/table operations by removing type checking and conditionals. + -- If called with Vec3-likes table(s), ensure all expected components + -- "x", "y", and "z" exist. + -- + -- Call with one of: + -- vec1:eqvec(vec2) + -- Vec3.eqvec(vec1, vec2) + -- + -- @return a new Vec3 object with the result of the operation +local function Vec3_eqvec(v1, v2) + return v1.x == v2.x and v1.y == v2.y and v1.z == v2.z +end +Vec3.eqvec = Vec3_eqvec +Vec3_inst_meta.__eq = Vec3_eqvec + +--- Takes the dot product of two Vec3s. Optimized for pure Vec3/table + -- operations by removing type checking and conditionals. If called + -- with Vec3-likes table(s), ensure all expected components "x", "y", + -- and "z" exist. + -- + -- Call with one of: + -- vec1:dotvec(vec2) + -- Vec3.dotvec(vec1, vec2) + -- + -- @return a number +local function Vec3_dotvec(v1, v2) + return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z +end +Vec3.dotvec = Vec3_dotvec + +--- Takes the cross product of two Vec3s. Optimized for pure Vec3/table + -- operations by removing type checking and conditionals. If called + -- with Vec3-likes table(s), ensure all expected components "x", "y", + -- and "z" exist. + -- + -- Call with one of: + -- vec1:crossvec(vec2) + -- Vec3.crossvec(vec1, vec2) + -- + -- @return a new Vec3 with the result of the operation +local function Vec3_crossvec(v1, v2) + return Vec3.new(v1.y*v2.z - v1.z*v2.y, + v1.z*v2.x - v1.x*v2.z, + v1.x*v2.y - v1.y*v2.x) +end +Vec3.crossvec = Vec3_crossvec + +--- Converts Vec3 to a string with format "(x,y,z)". + -- + -- Call with one of: + -- vec:tostring() + -- Vec3.tostring(vec) + -- tostring(vec) + -- + -- @return a string +local function Vec3_tostring(v) + return "(".. + (v.x or v[1] or "0") + ..",".. + (v.y or v[2] or "0") + ..",".. + (v.z or v[3] or "0") + ..")" +end +Vec3.tostring = Vec3_tostring +Vec3_inst_meta.__tostring = Vec3_tostring + +return Vec3 diff --git a/mods/more_fire/license.txt b/mods/more_fire/license.txt new file mode 100644 index 0000000..3db49b1 --- /dev/null +++ b/mods/more_fire/license.txt @@ -0,0 +1,12 @@ +Code is licensed MIT +Smokebomb and Molotov cocktail by Napiophelios. +Everything else by Nathan Salapat + +lib/Vec3_1-0.lua by prestidigitator licensed under WTFPL + +Models and Textures licensed CC by SA Nathan Salapat +Spark sound licensed CC0 by BroAsis, https://freesound.org/people/BroAsis/sounds/106853/ + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/mods/more_fire/mod.conf b/mods/more_fire/mod.conf new file mode 100644 index 0000000..a8a8495 --- /dev/null +++ b/mods/more_fire/mod.conf @@ -0,0 +1,6 @@ +name = more_fire +title = More Fire +depends = explosives, fire, vessels +description = This is a Minetest mod that adds more/better fire related stuff. +author = Nathan, Napiophelios +optional_depends = ethereal diff --git a/mods/more_fire/models/campfire.blend b/mods/more_fire/models/campfire.blend new file mode 100644 index 0000000..6e732cd Binary files /dev/null and b/mods/more_fire/models/campfire.blend differ diff --git a/mods/more_fire/models/campfire.obj b/mods/more_fire/models/campfire.obj new file mode 100644 index 0000000..51c5052 --- /dev/null +++ b/mods/more_fire/models/campfire.obj @@ -0,0 +1,225 @@ +# Blender v2.79 (sub 0) OBJ File: 'campfire.blend' +# www.blender.org +o Plane +v -0.240246 -0.438696 -0.141059 +v 0.205043 -0.438696 0.192756 +v -0.239959 0.135875 -0.141442 +v 0.205331 0.135875 0.192373 +v -0.216088 -0.438696 0.214432 +v 0.181502 -0.438696 -0.162771 +v -0.216417 0.135875 0.214085 +v 0.181172 0.135875 -0.163119 +vt 0.000000 0.875000 +vt 1.000000 0.875000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.875000 +vt 1.000000 0.875000 +vt 1.000000 1.000000 +vt -0.000000 1.000000 +vn -0.5998 0.0008 0.8001 +vn 0.6883 0.0008 0.7255 +g Plane_Plane_Material.001 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 5/5/2 6/6/2 8/7/2 7/8/2 +o nodebox3 +v 0.250000 -0.500000 -0.500000 +v 0.250000 -0.500000 0.500000 +v 0.250000 -0.437500 0.500000 +v 0.250000 -0.437500 -0.500000 +v -0.250000 -0.500000 -0.500000 +v -0.250000 -0.500000 0.500000 +v -0.250000 -0.437500 0.500000 +v -0.250000 -0.437500 -0.500000 +v 0.243779 -0.499707 -0.497529 +v 0.493779 -0.499707 -0.497421 +v 0.493779 -0.249707 -0.497421 +v 0.243779 -0.249707 -0.497529 +v 0.243349 -0.499707 0.502471 +v 0.493349 -0.499707 0.502579 +v 0.493349 -0.249707 0.502578 +v 0.243349 -0.249707 0.502471 +v 0.493779 -0.499707 -0.497421 +v 0.493779 -0.249707 -0.497421 +v 0.493349 -0.499707 0.502579 +v 0.493349 -0.249707 0.502578 +v -0.500021 -0.499707 -0.497848 +v -0.250021 -0.499707 -0.497741 +v -0.250021 -0.249707 -0.497741 +v -0.500021 -0.249707 -0.497848 +v -0.500451 -0.499707 0.502152 +v -0.250451 -0.499707 0.502259 +v -0.250451 -0.249707 0.502259 +v -0.500451 -0.249707 0.502152 +v -0.250021 -0.499707 -0.497741 +v -0.250021 -0.249707 -0.497741 +v -0.250451 -0.499707 0.502259 +v -0.250451 -0.249707 0.502259 +v 0.500000 -0.312500 -0.493800 +v 0.500000 -0.312500 -0.243800 +v 0.500000 -0.062500 -0.243800 +v 0.500000 -0.062500 -0.493800 +v -0.500000 -0.312500 -0.493800 +v -0.500000 -0.312500 -0.243800 +v -0.500000 -0.062500 -0.243800 +v -0.500000 -0.062500 -0.493800 +v 0.500000 -0.312500 -0.243800 +v 0.500000 -0.062500 -0.243800 +v -0.500000 -0.312500 -0.243800 +v -0.500000 -0.062500 -0.243800 +v 0.500000 -0.312500 0.250000 +v 0.500000 -0.312500 0.500000 +v 0.500000 -0.062500 0.500000 +v 0.500000 -0.062500 0.250000 +v -0.500000 -0.312500 0.250000 +v -0.500000 -0.312500 0.500000 +v -0.500000 -0.062500 0.500000 +v -0.500000 -0.062500 0.250000 +v 0.500000 -0.312500 0.500000 +v 0.500000 -0.062500 0.500000 +v -0.500000 -0.312500 0.500000 +v -0.500000 -0.062500 0.500000 +vt 0.999982 0.000018 +vt 0.999982 0.031267 +vt 0.000018 0.031267 +vt 0.000018 0.000018 +vt 0.999982 0.000018 +vt 0.999982 0.031267 +vt 0.000018 0.031267 +vt 0.000018 0.000018 +vt 1.000000 0.109375 +vt 0.000000 0.109375 +vt 0.000071 0.000071 +vt 0.999929 0.000071 +vt 1.000000 0.125000 +vt 0.000000 0.125000 +vt 0.000071 0.000071 +vt 0.000000 0.937500 +vt 0.000000 0.875000 +vt 0.250000 0.875000 +vt 0.250000 0.937500 +vt 0.000000 0.937500 +vt 0.000000 0.875000 +vt 0.250000 0.875000 +vt 0.250000 0.937500 +vt 1.000000 0.937500 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 0.937500 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.937500 +vt 1.000000 0.937500 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.937500 +vt 0.000000 0.937500 +vt 0.000000 0.875000 +vt 0.250000 0.875000 +vt 0.250000 0.937500 +vt 0.000000 0.937500 +vt 0.000000 0.875000 +vt 0.250000 0.875000 +vt 0.250000 0.937500 +vt 1.000000 0.937500 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 0.937500 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.937500 +vt 1.000000 0.937500 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.937500 +vt 0.000000 0.937500 +vt 0.000000 0.875000 +vt 0.250000 0.875000 +vt 0.250000 0.937500 +vt 0.000000 0.937500 +vt 0.000000 0.875000 +vt 0.250000 0.875000 +vt 0.250000 0.937500 +vt 1.000000 0.937500 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 0.937500 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.937500 +vt 1.000000 0.937500 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.937500 +vt 0.000000 0.937500 +vt 0.000000 0.875000 +vt 0.250000 0.875000 +vt 0.250000 0.937500 +vt 0.000000 0.937500 +vt 0.000000 0.875000 +vt 0.250000 0.875000 +vt 0.250000 0.937500 +vt 1.000000 0.937500 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 0.937500 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.937500 +vt 1.000000 0.937500 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.937500 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 -0.0000 +vn -0.0004 0.0000 1.0000 +vn 1.0000 -0.0000 0.0004 +vn -1.0000 0.0000 0.0000 +g nodebox3_nodebox3_none +s off +f 9/9/3 12/10/3 16/11/3 13/12/3 +f 10/13/3 11/14/3 15/15/3 14/16/3 +f 9/9/4 10/17/4 14/18/4 13/19/4 +f 12/20/4 11/21/4 15/22/4 16/23/4 +f 17/24/5 18/25/5 19/26/5 20/27/5 +f 21/28/5 22/29/5 23/30/5 24/31/5 +f 17/32/6 20/33/6 24/34/6 21/28/6 +f 17/32/4 18/35/4 22/36/4 21/28/4 +f 20/37/4 19/38/4 23/39/4 24/40/4 +f 25/41/6 26/42/6 28/43/6 27/44/6 +f 29/45/5 30/46/5 31/47/5 32/48/5 +f 33/49/5 34/50/5 35/51/5 36/52/5 +f 29/53/6 32/54/6 36/55/6 33/49/6 +f 29/53/4 30/56/4 34/57/4 33/49/4 +f 32/58/4 31/59/4 35/60/4 36/61/4 +f 37/62/6 38/63/6 40/64/6 39/65/6 +f 41/66/7 42/67/7 43/68/7 44/69/7 +f 45/70/7 46/71/7 47/72/7 48/73/7 +f 41/74/3 44/75/3 48/76/3 45/70/3 +f 41/74/4 42/77/4 46/78/4 45/70/4 +f 44/79/4 43/80/4 47/81/4 48/82/4 +f 49/83/3 50/84/3 52/85/3 51/86/3 +f 53/87/7 54/88/7 55/89/7 56/90/7 +f 57/91/7 58/92/7 59/93/7 60/94/7 +f 53/95/3 56/96/3 60/97/3 57/91/3 +f 53/95/4 54/98/4 58/99/4 57/91/4 +f 56/100/4 55/101/4 59/102/4 60/103/4 +f 61/104/3 62/105/3 64/106/3 63/107/3 +g nodebox3_nodebox3_none_NONE +f 9/108/7 10/109/7 11/110/7 12/111/7 +f 13/12/7 14/16/7 15/112/7 16/113/7 diff --git a/mods/more_fire/models/lamp.blend b/mods/more_fire/models/lamp.blend new file mode 100644 index 0000000..a5bf528 Binary files /dev/null and b/mods/more_fire/models/lamp.blend differ diff --git a/mods/more_fire/models/more_fire_campfire.obj b/mods/more_fire/models/more_fire_campfire.obj new file mode 100644 index 0000000..ad81f6e --- /dev/null +++ b/mods/more_fire/models/more_fire_campfire.obj @@ -0,0 +1,133 @@ +# Blender v2.72 (sub 2) OBJ File: 'campfire.blend' +# www.blender.org +v 0.353153 -0.337287 0.000000 +v -0.366847 -0.337287 0.000000 +v -0.366847 0.382713 -0.000000 +v -0.186847 -0.337287 0.311769 +v 0.173153 -0.337287 -0.311769 +v -0.186846 0.382713 0.311769 +v 0.173154 0.382713 -0.311769 +v -0.186846 -0.337287 -0.311769 +v 0.173154 -0.337287 0.311769 +v -0.186846 0.382713 -0.311769 +v 0.173153 0.382713 0.311769 +v 0.353153 0.382713 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +g Flames.001_Cube.004_Fire +s off +f 4/1 5/2 7/3 6/4 +f 8/1 9/2 11/3 10/4 +f 1/1 2/2 3/3 12/4 +v 0.151217 -0.347540 0.439253 +v 0.151217 -0.207593 0.411057 +v 0.008458 -0.207593 0.411057 +v 0.008458 -0.347540 0.439253 +v 0.151217 -0.526542 -0.449208 +v 0.151217 -0.386595 -0.477403 +v 0.008458 -0.386595 -0.477403 +v 0.008458 -0.526542 -0.449208 +v -0.419949 -0.512482 0.485423 +v -0.419949 -0.369723 0.485423 +v -0.444739 -0.369723 0.344833 +v -0.444739 -0.512482 0.344833 +v 0.472595 -0.512482 0.328044 +v 0.472595 -0.369723 0.328044 +v 0.447805 -0.369723 0.187453 +v 0.447805 -0.512482 0.187453 +v 0.033402 -0.347540 0.433815 +v 0.025205 -0.207593 0.406838 +v -0.111388 -0.207593 0.448342 +v -0.103191 -0.347540 0.475320 +v -0.224900 -0.526542 -0.416268 +v -0.233097 -0.386595 -0.443246 +v -0.369690 -0.386595 -0.401741 +v -0.361493 -0.526542 -0.374763 +v 0.254175 -0.345963 0.293196 +v 0.254175 -0.277187 0.265611 +v 0.181422 -0.282425 0.252550 +v 0.181422 -0.351201 0.280135 +v 0.343511 -0.517901 -0.135488 +v 0.343511 -0.449125 -0.163073 +v 0.270757 -0.454364 -0.176133 +v 0.270757 -0.523140 -0.148548 +v -0.418506 -0.513914 0.100698 +v -0.418472 -0.439812 0.100704 +v -0.392481 -0.439819 0.031309 +v -0.392514 -0.513921 0.031304 +v 0.022046 -0.514125 0.265705 +v 0.022080 -0.440022 0.265710 +v 0.048071 -0.440029 0.196316 +v 0.048038 -0.514131 0.196310 +v -0.249910 -0.307656 -0.062181 +v -0.249882 -0.234638 -0.074807 +v -0.278776 -0.246254 -0.142048 +v -0.278804 -0.319272 -0.129422 +v 0.183295 -0.339072 -0.242901 +v 0.183323 -0.266053 -0.255527 +v 0.154429 -0.277669 -0.322768 +v 0.154401 -0.350687 -0.310143 +vt 0.418293 0.016195 +vt 0.418293 0.216092 +vt 0.218396 0.216092 +vt 0.218396 0.016195 +vt 0.002609 0.212891 +vt 0.002609 0.012994 +vt 0.989254 0.012994 +vt 0.989254 0.212891 +vt 0.010050 0.219323 +vt 0.010050 0.019426 +vt 0.996695 0.019426 +vt 0.996695 0.219323 +vt 0.618448 0.016195 +vt 0.618448 0.216092 +vt 0.418551 0.216092 +vt 0.418551 0.016195 +vt 0.010050 0.228781 +vt 0.010050 0.028884 +vt 0.996695 0.028884 +vt 0.996695 0.228781 +vt 0.005089 0.207467 +vt 0.005089 0.007570 +vt 0.991734 0.007570 +vt 0.991734 0.207467 +g Campfire_Cube.003_Logs-Stone +s off +f 20/5 19/6 18/7 17/8 +f 14/9 13/10 17/11 18/12 +f 15/13 14/14 18/15 19/16 +f 13/17 14/18 15/19 16/20 +f 13/21 16/22 20/23 17/24 +f 16/25 15/26 19/27 20/28 +f 28/5 27/6 26/7 25/8 +f 22/9 21/10 25/11 26/12 +f 23/13 22/14 26/15 27/16 +f 21/17 22/18 23/19 24/20 +f 21/21 24/22 28/23 25/24 +f 24/25 23/26 27/27 28/28 +f 36/5 35/6 34/7 33/8 +f 30/9 29/10 33/11 34/12 +f 31/13 30/14 34/15 35/16 +f 29/17 30/18 31/19 32/20 +f 29/21 32/22 36/23 33/24 +f 32/25 31/26 35/27 36/28 +f 44/5 43/6 42/7 41/8 +f 38/9 37/10 41/11 42/12 +f 39/13 38/14 42/15 43/16 +f 37/17 38/18 39/19 40/20 +f 37/21 40/22 44/23 41/24 +f 40/25 39/26 43/27 44/28 +f 52/5 51/6 50/7 49/8 +f 46/9 45/10 49/11 50/12 +f 47/13 46/14 50/15 51/16 +f 45/17 46/18 47/19 48/20 +f 45/21 48/22 52/23 49/24 +f 48/25 47/26 51/27 52/28 +f 60/5 59/6 58/7 57/8 +f 54/9 53/10 57/11 58/12 +f 55/13 54/14 58/15 59/16 +f 53/17 54/18 55/19 56/20 +f 53/21 56/22 60/23 57/24 +f 56/25 55/26 59/27 60/28 diff --git a/mods/more_fire/models/more_fire_contained_campfire.obj b/mods/more_fire/models/more_fire_contained_campfire.obj new file mode 100644 index 0000000..3b1324f --- /dev/null +++ b/mods/more_fire/models/more_fire_contained_campfire.obj @@ -0,0 +1,470 @@ +# Blender v2.72 (sub 2) OBJ File: 'campfire.blend' +# www.blender.org +v 0.353153 -0.337287 0.000000 +v -0.366847 -0.337287 0.000000 +v -0.366847 0.382713 -0.000000 +v -0.186847 -0.337287 0.311769 +v 0.173153 -0.337287 -0.311769 +v -0.186846 0.382713 0.311769 +v 0.173154 0.382713 -0.311769 +v -0.186846 -0.337287 -0.311769 +v 0.173154 -0.337287 0.311769 +v -0.186846 0.382713 -0.311769 +v 0.173153 0.382713 0.311769 +v 0.353153 0.382713 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +g Flames_Cube.001_Fire +s off +f 4/1 5/2 7/3 6/4 +f 8/1 9/2 11/3 10/4 +f 1/1 2/2 3/3 12/4 +v 0.109850 -0.357143 0.305314 +v 0.109850 -0.248233 0.283371 +v -0.001248 -0.248233 0.283371 +v -0.001248 -0.357143 0.305314 +v 0.109850 -0.496446 -0.364085 +v 0.109850 -0.387536 -0.386027 +v -0.001248 -0.387536 -0.386027 +v -0.001248 -0.496446 -0.364085 +v -0.334643 -0.485504 0.341245 +v -0.334643 -0.374406 0.341245 +v -0.353935 -0.374406 0.231834 +v -0.353935 -0.485504 0.231834 +v 0.359953 -0.485504 0.218768 +v 0.359953 -0.374406 0.218768 +v 0.340661 -0.374406 0.109358 +v 0.340661 -0.485504 0.109358 +v 0.018164 -0.357143 0.301082 +v 0.011785 -0.248233 0.280088 +v -0.094515 -0.248233 0.312387 +v -0.088135 -0.357143 0.333382 +v -0.182852 -0.496446 -0.360470 +v -0.189231 -0.387536 -0.381465 +v -0.295531 -0.387536 -0.349165 +v -0.289151 -0.496446 -0.328171 +v 0.189974 -0.355916 0.191649 +v 0.189974 -0.302392 0.170182 +v 0.133356 -0.306469 0.160018 +v 0.133356 -0.359992 0.181485 +v 0.259497 -0.489722 -0.141961 +v 0.259497 -0.436199 -0.163429 +v 0.202879 -0.440275 -0.173592 +v 0.202879 -0.493798 -0.152125 +v -0.333520 -0.486619 0.041843 +v -0.333494 -0.428951 0.041848 +v -0.313267 -0.428956 -0.012156 +v -0.313293 -0.486624 -0.012161 +v 0.009327 -0.486782 0.170255 +v 0.009353 -0.429115 0.170259 +v 0.029580 -0.429120 0.116255 +v 0.029554 -0.486787 0.116251 +v -0.202316 -0.326105 -0.084912 +v -0.202294 -0.269280 -0.094738 +v -0.224779 -0.278320 -0.147066 +v -0.224801 -0.335144 -0.137240 +v 0.134814 -0.350553 -0.225553 +v 0.134835 -0.293728 -0.235379 +v 0.112350 -0.302768 -0.287707 +v 0.112328 -0.359592 -0.277881 +v 0.153727 -0.495469 0.450886 +v 0.130774 -0.495469 0.303732 +v 0.277929 -0.495469 0.280779 +v 0.300881 -0.495469 0.427933 +v 0.153727 -0.389072 0.450886 +v 0.130774 -0.389072 0.303732 +v 0.277929 -0.389072 0.280779 +v 0.300881 -0.389072 0.427933 +v -0.416606 -0.495469 -0.045338 +v -0.416606 -0.495469 -0.194272 +v -0.267672 -0.495469 -0.194272 +v -0.267672 -0.495469 -0.045338 +v -0.416606 -0.395652 -0.045338 +v -0.416606 -0.395652 -0.194272 +v -0.267672 -0.395652 -0.194272 +v -0.267672 -0.395652 -0.045338 +v -0.378793 -0.495469 0.237564 +v -0.480454 -0.495469 0.128724 +v -0.371615 -0.495469 0.027062 +v -0.269953 -0.495469 0.135902 +v -0.378793 -0.365755 0.237564 +v -0.480454 -0.365755 0.128724 +v -0.371615 -0.365755 0.027062 +v -0.269953 -0.365755 0.135902 +v -0.134183 -0.495469 -0.320969 +v -0.194093 -0.495469 -0.417106 +v -0.090445 -0.495469 -0.465129 +v -0.030535 -0.495469 -0.368992 +v -0.134183 -0.346536 -0.320969 +v -0.194093 -0.346536 -0.417106 +v -0.090445 -0.346536 -0.465129 +v -0.030535 -0.346536 -0.368992 +v 0.175251 -0.495469 -0.228071 +v 0.133971 -0.495469 -0.371169 +v 0.277070 -0.495469 -0.412449 +v 0.318350 -0.495469 -0.269350 +v 0.175251 -0.380117 -0.228071 +v 0.133971 -0.380117 -0.371169 +v 0.277070 -0.380117 -0.412449 +v 0.318350 -0.380117 -0.269350 +v 0.251956 -0.495469 0.058110 +v 0.281764 -0.495469 -0.087810 +v 0.427684 -0.495469 -0.058002 +v 0.397876 -0.495469 0.087918 +v 0.251956 -0.422654 0.058110 +v 0.281764 -0.422654 -0.087810 +v 0.427684 -0.422654 -0.058002 +v 0.397876 -0.422654 0.087918 +v -0.232717 -0.495469 0.492217 +v -0.255669 -0.495469 0.345062 +v -0.108515 -0.495469 0.322110 +v -0.085563 -0.495469 0.469264 +v -0.232717 -0.382356 0.492217 +v -0.255669 -0.382356 0.345062 +v -0.108515 -0.382356 0.322110 +v -0.085563 -0.382356 0.469264 +v -0.033985 -0.495469 0.350689 +v 0.113554 -0.495469 0.371024 +v 0.101929 -0.495469 0.455372 +v -0.045610 -0.495469 0.435037 +v -0.033985 -0.346536 0.350689 +v 0.113554 -0.346536 0.371024 +v 0.101929 -0.346536 0.455372 +v -0.045610 -0.346536 0.435037 +v 0.339073 -0.495469 0.300291 +v 0.404643 -0.495469 0.166568 +v 0.481092 -0.495469 0.204054 +v 0.415522 -0.495469 0.337777 +v 0.339073 -0.409221 0.300291 +v 0.404643 -0.409221 0.166568 +v 0.481092 -0.409221 0.204054 +v 0.415522 -0.409221 0.337777 +v -0.359990 -0.495469 0.467998 +v -0.461166 -0.495469 0.358706 +v -0.398683 -0.495469 0.300864 +v -0.297508 -0.495469 0.410156 +v -0.359990 -0.409788 0.467998 +v -0.461166 -0.409788 0.358706 +v -0.398683 -0.409788 0.300864 +v -0.297508 -0.409788 0.410156 +v -0.413457 -0.495469 -0.313766 +v -0.368533 -0.495469 -0.455763 +v -0.287353 -0.495469 -0.430081 +v -0.332277 -0.495469 -0.288084 +v -0.413457 -0.409221 -0.313766 +v -0.368533 -0.409221 -0.455763 +v -0.287353 -0.409221 -0.430081 +v -0.332277 -0.409221 -0.288084 +v 0.037431 -0.495469 -0.491183 +v 0.185487 -0.495469 -0.475036 +v 0.176256 -0.495469 -0.390393 +v 0.028200 -0.495469 -0.406539 +v 0.037431 -0.398994 -0.491183 +v 0.185487 -0.398994 -0.475036 +v 0.176256 -0.398994 -0.390393 +v 0.028200 -0.398994 -0.406539 +vt 0.343750 0.203125 +vt 0.156250 0.203125 +vt 0.156250 0.406250 +vt 0.343750 0.406250 +vt 0.015625 0.453125 +vt 1.000000 0.453125 +vt 1.000000 0.250000 +vt 0.015625 0.250000 +vt 0.015625 0.328125 +vt 1.000000 0.328125 +vt 1.000000 0.140625 +vt 0.015625 0.140625 +vt 0.781250 0.250000 +vt 0.578125 0.250000 +vt 0.578125 0.437500 +vt 0.781250 0.437500 +vt 0.015625 0.468750 +vt 1.000000 0.468750 +vt 1.000000 0.265625 +vt 0.015625 0.265625 +vt 0.015625 0.343750 +vt 1.000000 0.343750 +vt 0.921875 0.218750 +vt 0.718750 0.218750 +vt 0.718750 0.421875 +vt 0.921875 0.421875 +vt 0.000000 0.343750 +vt 0.984375 0.343750 +vt 0.984375 0.140625 +vt 0.000000 0.140625 +vt 0.000000 0.312500 +vt 1.000000 0.312500 +vt 1.000000 0.109375 +vt 0.000000 0.109375 +vt 0.828125 0.203125 +vt 0.625000 0.203125 +vt 0.625000 0.406250 +vt 0.828125 0.406250 +vt 0.015625 0.390625 +vt 1.000000 0.390625 +vt 1.000000 0.187500 +vt 0.015625 0.187500 +vt 0.000000 0.296875 +vt 1.000000 0.296875 +vt 1.000000 0.093750 +vt 0.000000 0.093750 +vt 0.343750 0.218750 +vt 0.140625 0.218750 +vt 0.140625 0.406250 +vt 0.002609 0.212891 +vt 0.989254 0.212891 +vt 0.989254 0.012994 +vt 0.002609 0.012994 +vt 0.010050 0.219323 +vt 0.996695 0.219323 +vt 0.996695 0.019426 +vt 0.010050 0.019426 +vt 0.593750 0.234375 +vt 0.406250 0.234375 +vt 0.406250 0.437500 +vt 0.593750 0.437500 +vt 0.010050 0.228781 +vt 0.996695 0.228781 +vt 0.996695 0.028884 +vt 0.010050 0.028884 +vt 0.005089 0.207467 +vt 0.991734 0.207467 +vt 0.991734 0.007570 +vt 0.005089 0.007570 +vt 0.625000 0.187500 +vt 0.421875 0.187500 +vt 0.421875 0.390625 +vt 0.625000 0.390625 +vt 0.796875 0.093750 +vt 0.593750 0.093750 +vt 0.593750 0.296875 +vt 0.796875 0.296875 +vt 0.640625 0.031250 +vt 0.437500 0.031250 +vt 0.437500 0.234375 +vt 0.640625 0.234375 +vt 0.984375 0.031250 +vt 0.781250 0.031250 +vt 0.781250 0.234375 +vt 0.984375 0.234375 +vt 0.687500 0.125000 +vt 0.484375 0.125000 +vt 0.484375 0.328125 +vt 0.687500 0.328125 +vt 0.328125 0.046875 +vt 0.125000 0.046875 +vt 0.125000 0.250000 +vt 0.328125 0.250000 +vt 0.140625 0.781250 +vt 0.250000 0.781250 +vt 0.250000 0.625000 +vt 0.140625 0.625000 +vt 0.453125 0.843750 +vt 0.531250 0.843750 +vt 0.531250 0.718750 +vt 0.453125 0.718750 +vt 0.421875 0.718750 +vt 0.265625 0.718750 +vt 0.265625 0.937500 +vt 0.421875 0.937500 +vt 0.500000 0.609375 +vt 0.500000 1.000000 +vt 0.734375 1.000000 +vt 0.734375 0.609375 +vt 1.000000 0.953125 +vt 1.000000 0.875000 +vt 0.859375 0.875000 +vt 0.859375 0.953125 +vt 0.750000 0.531250 +vt 0.562500 0.531250 +vt 0.562500 0.765625 +vt 0.750000 0.765625 +vt 0.082031 0.968750 +vt 0.136719 0.968750 +vt 0.136719 0.882812 +vt 0.082031 0.882812 +vt 0.781250 0.921875 +vt 0.781250 0.796875 +vt 0.609375 0.796875 +vt 0.609375 0.921875 +vt 0.359375 0.718750 +vt 0.484375 0.718750 +vt 0.484375 0.500000 +vt 0.359375 0.500000 +vt 0.058594 0.882812 +vt 0.058594 0.968750 +vt 0.117188 0.968750 +vt 0.117188 0.882812 +vt 0.023438 0.925781 +vt 0.078125 0.925781 +vt 0.078125 0.839844 +vt 0.023438 0.839844 +vt 0.578125 0.828125 +vt 0.468750 0.828125 +vt 0.468750 1.000000 +vt 0.578125 1.000000 +vt 0.078125 0.750000 +vt 0.234375 0.750000 +vt 0.234375 0.546875 +vt 0.078125 0.546875 +vt 0.750000 0.906250 +vt 0.953125 0.906250 +vt 0.953125 0.546875 +vt 0.750000 0.546875 +vt 0.406250 0.500000 +vt 0.250000 0.500000 +vt 0.250000 0.703125 +vt 0.406250 0.703125 +vt 0.531250 0.890625 +vt 0.718750 0.890625 +vt 0.718750 0.609375 +vt 0.531250 0.609375 +vt 0.125000 1.000000 +vt 0.250000 1.000000 +vt 0.250000 0.828125 +vt 0.125000 0.828125 +vt 0.515625 0.671875 +vt 0.328125 0.671875 +vt 0.328125 0.953125 +vt 0.515625 0.953125 +vt 0.296875 0.984375 +vt 0.484375 0.984375 +vt 0.484375 0.703125 +vt 0.296875 0.703125 +vt 0.500000 0.703125 +vt 0.609375 0.703125 +vt 0.609375 0.500000 +vt 0.500000 0.500000 +vt 0.082031 0.796875 +vt 0.023438 0.796875 +vt 0.023438 0.882812 +vt 0.703125 1.000000 +vt 0.984375 1.000000 +vt 0.984375 0.625000 +vt 0.703125 0.625000 +vt 0.718750 0.687500 +vt 0.843750 0.687500 +vt 0.843750 0.546875 +vt 0.718750 0.546875 +vt 0.042969 0.859375 +vt 0.101562 0.859375 +vt 0.101562 0.773438 +vt 0.042969 0.773438 +vt 0.031250 0.984375 +vt 0.312500 0.984375 +vt 0.312500 0.625000 +vt 0.031250 0.625000 +vt 0.023438 0.968750 +g Contained_Fire_Cube.000_Logs-Stone +s off +f 20/5 17/6 18/7 19/8 +f 14/9 18/10 17/11 13/12 +f 15/13 19/14 18/15 14/16 +f 13/17 16/18 15/19 14/20 +f 13/21 17/22 20/23 16/24 +f 16/25 20/26 19/15 15/16 +f 28/27 25/28 26/29 27/30 +f 22/31 26/32 25/33 21/34 +f 23/35 27/36 26/37 22/38 +f 21/39 24/40 23/41 22/42 +f 21/43 25/44 28/45 24/46 +f 24/47 28/48 27/49 23/50 +f 36/51 33/52 34/53 35/8 +f 30/54 34/55 33/56 29/57 +f 31/58 35/59 34/60 30/61 +f 29/62 32/63 31/64 30/65 +f 29/66 33/67 36/68 32/69 +f 32/70 36/71 35/72 31/73 +f 44/74 41/75 42/76 43/77 +f 38/54 42/55 41/56 37/57 +f 39/58 43/59 42/60 38/61 +f 37/78 40/79 39/80 38/81 +f 37/66 41/67 44/68 40/69 +f 40/70 44/71 43/72 39/73 +f 52/82 49/83 50/84 51/85 +f 46/54 50/55 49/56 45/57 +f 47/58 51/59 50/60 46/61 +f 45/86 48/87 47/88 46/89 +f 45/66 49/67 52/68 48/69 +f 48/70 52/71 51/72 47/73 +f 60/90 57/91 58/92 59/93 +f 54/54 58/55 57/56 53/57 +f 55/58 59/59 58/60 54/61 +f 53/94 56/95 55/96 54/97 +f 53/66 57/67 60/68 56/69 +f 56/70 60/71 59/72 55/73 +f 65/98 61/99 62/100 66/101 +f 66/102 62/103 63/104 67/105 +f 67/106 63/107 64/108 68/109 +f 68/110 64/111 61/112 65/113 +f 61/114 64/115 63/116 62/117 +f 68/118 65/119 66/120 67/121 +f 73/122 69/123 70/124 74/125 +f 74/126 70/127 71/128 75/129 +f 75/130 71/131 72/132 76/133 +f 76/134 72/135 69/136 73/137 +f 69/138 72/139 71/140 70/141 +f 76/142 73/143 74/144 75/145 +f 81/122 77/123 78/124 82/125 +f 82/146 78/147 79/148 83/149 +f 83/150 79/151 80/152 84/153 +f 84/134 80/135 77/136 81/137 +f 77/138 80/139 79/140 78/141 +f 84/154 81/155 82/156 83/157 +f 89/122 85/123 86/124 90/125 +f 90/158 86/159 87/160 91/161 +f 91/162 87/163 88/164 92/165 +f 92/134 88/135 85/136 89/137 +f 85/138 88/139 87/140 86/141 +f 92/166 89/167 90/168 91/169 +f 97/122 93/123 94/124 98/125 +f 98/170 94/171 95/172 99/173 +f 99/174 95/175 96/176 100/177 +f 100/134 96/135 93/136 97/137 +f 93/138 96/139 95/140 94/141 +f 100/178 97/179 98/180 99/125 +f 105/122 101/123 102/124 106/125 +f 106/181 102/182 103/183 107/184 +f 107/185 103/186 104/187 108/188 +f 108/134 104/135 101/136 105/137 +f 101/138 104/139 103/140 102/141 +f 108/178 105/179 106/180 107/125 +f 113/122 109/123 110/124 114/125 +f 114/189 110/190 111/191 115/192 +f 115/193 111/194 112/195 116/196 +f 116/134 112/135 109/136 113/137 +f 109/138 112/139 111/140 110/141 +f 116/178 113/179 114/180 115/125 +f 121/122 117/123 118/124 122/125 +f 122/189 118/190 119/191 123/192 +f 123/197 119/122 120/125 124/180 +f 124/134 120/135 117/136 121/137 +f 117/138 120/139 119/140 118/141 +f 124/178 121/179 122/180 123/125 +f 129/122 125/123 126/124 130/125 +f 130/189 126/190 127/191 131/192 +f 131/197 127/122 128/125 132/180 +f 132/134 128/135 125/136 129/137 +f 125/138 128/139 127/140 126/141 +f 132/178 129/179 130/180 131/125 +f 137/122 133/123 134/124 138/125 +f 138/189 134/190 135/191 139/192 +f 139/197 135/122 136/125 140/180 +f 140/134 136/135 133/136 137/137 +f 133/138 136/139 135/140 134/141 +f 140/178 137/179 138/180 139/125 +f 145/122 141/123 142/124 146/125 +f 146/189 142/190 143/191 147/192 +f 147/197 143/122 144/125 148/180 +f 148/134 144/135 141/136 145/137 +f 141/138 144/139 143/140 142/141 +f 148/178 145/179 146/180 147/125 +f 153/122 149/123 150/124 154/125 +f 154/189 150/190 151/191 155/192 +f 155/197 151/122 152/125 156/180 +f 156/134 152/135 149/136 153/137 +f 149/138 152/139 151/140 150/141 +f 156/178 153/179 154/180 155/125 diff --git a/mods/more_fire/models/more_fire_kindling.obj b/mods/more_fire/models/more_fire_kindling.obj new file mode 100644 index 0000000..5eb8dc8 --- /dev/null +++ b/mods/more_fire/models/more_fire_kindling.obj @@ -0,0 +1,112 @@ +# Blender v2.72 (sub 2) OBJ File: 'campfire.blend' +# www.blender.org +v 0.151217 -0.347540 0.439253 +v 0.151217 -0.207593 0.411057 +v 0.008458 -0.207593 0.411057 +v 0.008458 -0.347540 0.439253 +v 0.151217 -0.526542 -0.449208 +v 0.151217 -0.386595 -0.477403 +v 0.008458 -0.386595 -0.477403 +v 0.008458 -0.526542 -0.449208 +v -0.419949 -0.512482 0.485423 +v -0.419949 -0.369723 0.485423 +v -0.444739 -0.369723 0.344833 +v -0.444739 -0.512482 0.344833 +v 0.472595 -0.512482 0.328044 +v 0.472595 -0.369723 0.328044 +v 0.447805 -0.369723 0.187453 +v 0.447805 -0.512482 0.187453 +v 0.033402 -0.347540 0.433815 +v 0.025205 -0.207593 0.406838 +v -0.111388 -0.207593 0.448342 +v -0.103191 -0.347540 0.475320 +v -0.224900 -0.526542 -0.416268 +v -0.233097 -0.386595 -0.443246 +v -0.369690 -0.386595 -0.401741 +v -0.361493 -0.526542 -0.374763 +v 0.254175 -0.345963 0.293196 +v 0.254175 -0.277187 0.265611 +v 0.181422 -0.282425 0.252550 +v 0.181422 -0.351201 0.280135 +v 0.343511 -0.517901 -0.135488 +v 0.343511 -0.449125 -0.163073 +v 0.270757 -0.454364 -0.176133 +v 0.270757 -0.523140 -0.148548 +v -0.418506 -0.513914 0.100698 +v -0.418472 -0.439812 0.100704 +v -0.392481 -0.439819 0.031309 +v -0.392514 -0.513921 0.031304 +v 0.022046 -0.514125 0.265705 +v 0.022080 -0.440022 0.265710 +v 0.048071 -0.440029 0.196316 +v 0.048038 -0.514131 0.196310 +v -0.249910 -0.307656 -0.062181 +v -0.249882 -0.234638 -0.074807 +v -0.278776 -0.246254 -0.142048 +v -0.278804 -0.319272 -0.129422 +v 0.183295 -0.339072 -0.242901 +v 0.183323 -0.266053 -0.255527 +v 0.154429 -0.277669 -0.322768 +v 0.154401 -0.350687 -0.310143 +vt 0.418293 0.016195 +vt 0.418293 0.216092 +vt 0.218396 0.216092 +vt 0.218396 0.016195 +vt 0.002609 0.212891 +vt 0.002609 0.012994 +vt 0.989254 0.012994 +vt 0.989254 0.212891 +vt 0.010050 0.219323 +vt 0.010050 0.019426 +vt 0.996695 0.019426 +vt 0.996695 0.219323 +vt 0.618448 0.016195 +vt 0.618448 0.216092 +vt 0.418551 0.216092 +vt 0.418551 0.016195 +vt 0.010050 0.228781 +vt 0.010050 0.028884 +vt 0.996695 0.028884 +vt 0.996695 0.228781 +vt 0.005089 0.207467 +vt 0.005089 0.007570 +vt 0.991734 0.007570 +vt 0.991734 0.207467 +g Campfire_Cube.003_Logs-Stone +s off +f 8/1 7/2 6/3 5/4 +f 2/5 1/6 5/7 6/8 +f 3/9 2/10 6/11 7/12 +f 1/13 2/14 3/15 4/16 +f 1/17 4/18 8/19 5/20 +f 4/21 3/22 7/23 8/24 +f 16/1 15/2 14/3 13/4 +f 10/5 9/6 13/7 14/8 +f 11/9 10/10 14/11 15/12 +f 9/13 10/14 11/15 12/16 +f 9/17 12/18 16/19 13/20 +f 12/21 11/22 15/23 16/24 +f 24/1 23/2 22/3 21/4 +f 18/5 17/6 21/7 22/8 +f 19/9 18/10 22/11 23/12 +f 17/13 18/14 19/15 20/16 +f 17/17 20/18 24/19 21/20 +f 20/21 19/22 23/23 24/24 +f 32/1 31/2 30/3 29/4 +f 26/5 25/6 29/7 30/8 +f 27/9 26/10 30/11 31/12 +f 25/13 26/14 27/15 28/16 +f 25/17 28/18 32/19 29/20 +f 28/21 27/22 31/23 32/24 +f 40/1 39/2 38/3 37/4 +f 34/5 33/6 37/7 38/8 +f 35/9 34/10 38/11 39/12 +f 33/13 34/14 35/15 36/16 +f 33/17 36/18 40/19 37/20 +f 36/21 35/22 39/23 40/24 +f 48/1 47/2 46/3 45/4 +f 42/5 41/6 45/7 46/8 +f 43/9 42/10 46/11 47/12 +f 41/13 42/14 43/15 44/16 +f 41/17 44/18 48/19 45/20 +f 44/21 43/22 47/23 48/24 diff --git a/mods/more_fire/models/more_fire_kindling_contained.obj b/mods/more_fire/models/more_fire_kindling_contained.obj new file mode 100644 index 0000000..4a47a6e --- /dev/null +++ b/mods/more_fire/models/more_fire_kindling_contained.obj @@ -0,0 +1,449 @@ +# Blender v2.72 (sub 2) OBJ File: 'campfire.blend' +# www.blender.org +v 0.109850 -0.357143 0.305314 +v 0.109850 -0.248233 0.283371 +v -0.001248 -0.248233 0.283371 +v -0.001248 -0.357143 0.305314 +v 0.109850 -0.496446 -0.364085 +v 0.109850 -0.387536 -0.386027 +v -0.001248 -0.387536 -0.386027 +v -0.001248 -0.496446 -0.364085 +v -0.334643 -0.485504 0.341245 +v -0.334643 -0.374406 0.341245 +v -0.353935 -0.374406 0.231834 +v -0.353935 -0.485504 0.231834 +v 0.359953 -0.485504 0.218768 +v 0.359953 -0.374406 0.218768 +v 0.340661 -0.374406 0.109358 +v 0.340661 -0.485504 0.109358 +v 0.018164 -0.357143 0.301082 +v 0.011785 -0.248233 0.280088 +v -0.094515 -0.248233 0.312387 +v -0.088135 -0.357143 0.333382 +v -0.182852 -0.496446 -0.360470 +v -0.189231 -0.387536 -0.381465 +v -0.295531 -0.387536 -0.349165 +v -0.289151 -0.496446 -0.328171 +v 0.189974 -0.355916 0.191649 +v 0.189974 -0.302392 0.170182 +v 0.133356 -0.306469 0.160018 +v 0.133356 -0.359992 0.181485 +v 0.259497 -0.489722 -0.141961 +v 0.259497 -0.436199 -0.163429 +v 0.202879 -0.440275 -0.173592 +v 0.202879 -0.493798 -0.152125 +v -0.333520 -0.486619 0.041843 +v -0.333494 -0.428951 0.041848 +v -0.313267 -0.428956 -0.012156 +v -0.313293 -0.486624 -0.012161 +v 0.009327 -0.486782 0.170255 +v 0.009353 -0.429115 0.170259 +v 0.029580 -0.429120 0.116255 +v 0.029554 -0.486787 0.116251 +v -0.202316 -0.326105 -0.084912 +v -0.202294 -0.269280 -0.094738 +v -0.224779 -0.278320 -0.147066 +v -0.224801 -0.335144 -0.137240 +v 0.134814 -0.350553 -0.225553 +v 0.134835 -0.293728 -0.235379 +v 0.112350 -0.302768 -0.287707 +v 0.112328 -0.359592 -0.277881 +v 0.153727 -0.495469 0.450886 +v 0.130774 -0.495469 0.303732 +v 0.277929 -0.495469 0.280779 +v 0.300881 -0.495469 0.427933 +v 0.153727 -0.389072 0.450886 +v 0.130774 -0.389072 0.303732 +v 0.277929 -0.389072 0.280779 +v 0.300881 -0.389072 0.427933 +v -0.416606 -0.495469 -0.045338 +v -0.416606 -0.495469 -0.194272 +v -0.267672 -0.495469 -0.194272 +v -0.267672 -0.495469 -0.045338 +v -0.416606 -0.395652 -0.045338 +v -0.416606 -0.395652 -0.194272 +v -0.267672 -0.395652 -0.194272 +v -0.267672 -0.395652 -0.045338 +v -0.378793 -0.495469 0.237564 +v -0.480454 -0.495469 0.128724 +v -0.371615 -0.495469 0.027062 +v -0.269953 -0.495469 0.135902 +v -0.378793 -0.365755 0.237564 +v -0.480454 -0.365755 0.128724 +v -0.371615 -0.365755 0.027062 +v -0.269953 -0.365755 0.135902 +v -0.134183 -0.495469 -0.320969 +v -0.194093 -0.495469 -0.417106 +v -0.090445 -0.495469 -0.465129 +v -0.030535 -0.495469 -0.368992 +v -0.134183 -0.346536 -0.320969 +v -0.194093 -0.346536 -0.417106 +v -0.090445 -0.346536 -0.465129 +v -0.030535 -0.346536 -0.368992 +v 0.175251 -0.495469 -0.228071 +v 0.133971 -0.495469 -0.371169 +v 0.277070 -0.495469 -0.412449 +v 0.318350 -0.495469 -0.269350 +v 0.175251 -0.380117 -0.228071 +v 0.133971 -0.380117 -0.371169 +v 0.277070 -0.380117 -0.412449 +v 0.318350 -0.380117 -0.269350 +v 0.251956 -0.495469 0.058110 +v 0.281764 -0.495469 -0.087810 +v 0.427684 -0.495469 -0.058002 +v 0.397876 -0.495469 0.087918 +v 0.251956 -0.422654 0.058110 +v 0.281764 -0.422654 -0.087810 +v 0.427684 -0.422654 -0.058002 +v 0.397876 -0.422654 0.087918 +v -0.232717 -0.495469 0.492217 +v -0.255669 -0.495469 0.345062 +v -0.108515 -0.495469 0.322110 +v -0.085563 -0.495469 0.469264 +v -0.232717 -0.382356 0.492217 +v -0.255669 -0.382356 0.345062 +v -0.108515 -0.382356 0.322110 +v -0.085563 -0.382356 0.469264 +v -0.033985 -0.495469 0.350689 +v 0.113554 -0.495469 0.371024 +v 0.101929 -0.495469 0.455372 +v -0.045610 -0.495469 0.435037 +v -0.033985 -0.346536 0.350689 +v 0.113554 -0.346536 0.371024 +v 0.101929 -0.346536 0.455372 +v -0.045610 -0.346536 0.435037 +v 0.339073 -0.495469 0.300291 +v 0.404643 -0.495469 0.166568 +v 0.481092 -0.495469 0.204054 +v 0.415522 -0.495469 0.337777 +v 0.339073 -0.409221 0.300291 +v 0.404643 -0.409221 0.166568 +v 0.481092 -0.409221 0.204054 +v 0.415522 -0.409221 0.337777 +v -0.359990 -0.495469 0.467998 +v -0.461166 -0.495469 0.358706 +v -0.398683 -0.495469 0.300864 +v -0.297508 -0.495469 0.410156 +v -0.359990 -0.409788 0.467998 +v -0.461166 -0.409788 0.358706 +v -0.398683 -0.409788 0.300864 +v -0.297508 -0.409788 0.410156 +v -0.413457 -0.495469 -0.313766 +v -0.368533 -0.495469 -0.455763 +v -0.287353 -0.495469 -0.430081 +v -0.332277 -0.495469 -0.288084 +v -0.413457 -0.409221 -0.313766 +v -0.368533 -0.409221 -0.455763 +v -0.287353 -0.409221 -0.430081 +v -0.332277 -0.409221 -0.288084 +v 0.037431 -0.495469 -0.491183 +v 0.185487 -0.495469 -0.475036 +v 0.176256 -0.495469 -0.390393 +v 0.028200 -0.495469 -0.406539 +v 0.037431 -0.398994 -0.491183 +v 0.185487 -0.398994 -0.475036 +v 0.176256 -0.398994 -0.390393 +v 0.028200 -0.398994 -0.406539 +vt 0.343750 0.203125 +vt 0.156250 0.203125 +vt 0.156250 0.406250 +vt 0.343750 0.406250 +vt 0.015625 0.453125 +vt 1.000000 0.453125 +vt 1.000000 0.250000 +vt 0.015625 0.250000 +vt 0.015625 0.328125 +vt 1.000000 0.328125 +vt 1.000000 0.140625 +vt 0.015625 0.140625 +vt 0.781250 0.250000 +vt 0.578125 0.250000 +vt 0.578125 0.437500 +vt 0.781250 0.437500 +vt 0.015625 0.468750 +vt 1.000000 0.468750 +vt 1.000000 0.265625 +vt 0.015625 0.265625 +vt 0.015625 0.343750 +vt 1.000000 0.343750 +vt 0.921875 0.218750 +vt 0.718750 0.218750 +vt 0.718750 0.421875 +vt 0.921875 0.421875 +vt 0.000000 0.343750 +vt 0.984375 0.343750 +vt 0.984375 0.140625 +vt 0.000000 0.140625 +vt 0.000000 0.312500 +vt 1.000000 0.312500 +vt 1.000000 0.109375 +vt 0.000000 0.109375 +vt 0.828125 0.203125 +vt 0.625000 0.203125 +vt 0.625000 0.406250 +vt 0.828125 0.406250 +vt 0.015625 0.390625 +vt 1.000000 0.390625 +vt 1.000000 0.187500 +vt 0.015625 0.187500 +vt 0.000000 0.296875 +vt 1.000000 0.296875 +vt 1.000000 0.093750 +vt 0.000000 0.093750 +vt 0.343750 0.218750 +vt 0.140625 0.218750 +vt 0.140625 0.406250 +vt 0.002609 0.212891 +vt 0.989254 0.212891 +vt 0.989254 0.012994 +vt 0.002609 0.012994 +vt 0.010050 0.219323 +vt 0.996695 0.219323 +vt 0.996695 0.019426 +vt 0.010050 0.019426 +vt 0.593750 0.234375 +vt 0.406250 0.234375 +vt 0.406250 0.437500 +vt 0.593750 0.437500 +vt 0.010050 0.228781 +vt 0.996695 0.228781 +vt 0.996695 0.028884 +vt 0.010050 0.028884 +vt 0.005089 0.207467 +vt 0.991734 0.207467 +vt 0.991734 0.007570 +vt 0.005089 0.007570 +vt 0.625000 0.187500 +vt 0.421875 0.187500 +vt 0.421875 0.390625 +vt 0.625000 0.390625 +vt 0.796875 0.093750 +vt 0.593750 0.093750 +vt 0.593750 0.296875 +vt 0.796875 0.296875 +vt 0.640625 0.031250 +vt 0.437500 0.031250 +vt 0.437500 0.234375 +vt 0.640625 0.234375 +vt 0.984375 0.031250 +vt 0.781250 0.031250 +vt 0.781250 0.234375 +vt 0.984375 0.234375 +vt 0.687500 0.125000 +vt 0.484375 0.125000 +vt 0.484375 0.328125 +vt 0.687500 0.328125 +vt 0.328125 0.046875 +vt 0.125000 0.046875 +vt 0.125000 0.250000 +vt 0.328125 0.250000 +vt 0.140625 0.781250 +vt 0.250000 0.781250 +vt 0.250000 0.625000 +vt 0.140625 0.625000 +vt 0.453125 0.843750 +vt 0.531250 0.843750 +vt 0.531250 0.718750 +vt 0.453125 0.718750 +vt 0.421875 0.718750 +vt 0.265625 0.718750 +vt 0.265625 0.937500 +vt 0.421875 0.937500 +vt 0.500000 0.609375 +vt 0.500000 1.000000 +vt 0.734375 1.000000 +vt 0.734375 0.609375 +vt 1.000000 0.953125 +vt 1.000000 0.875000 +vt 0.859375 0.875000 +vt 0.859375 0.953125 +vt 0.750000 0.531250 +vt 0.562500 0.531250 +vt 0.562500 0.765625 +vt 0.750000 0.765625 +vt 0.082031 0.968750 +vt 0.136719 0.968750 +vt 0.136719 0.882812 +vt 0.082031 0.882812 +vt 0.781250 0.921875 +vt 0.781250 0.796875 +vt 0.609375 0.796875 +vt 0.609375 0.921875 +vt 0.359375 0.718750 +vt 0.484375 0.718750 +vt 0.484375 0.500000 +vt 0.359375 0.500000 +vt 0.058594 0.882812 +vt 0.058594 0.968750 +vt 0.117188 0.968750 +vt 0.117188 0.882812 +vt 0.023438 0.925781 +vt 0.078125 0.925781 +vt 0.078125 0.839844 +vt 0.023438 0.839844 +vt 0.578125 0.828125 +vt 0.468750 0.828125 +vt 0.468750 1.000000 +vt 0.578125 1.000000 +vt 0.078125 0.750000 +vt 0.234375 0.750000 +vt 0.234375 0.546875 +vt 0.078125 0.546875 +vt 0.750000 0.906250 +vt 0.953125 0.906250 +vt 0.953125 0.546875 +vt 0.750000 0.546875 +vt 0.406250 0.500000 +vt 0.250000 0.500000 +vt 0.250000 0.703125 +vt 0.406250 0.703125 +vt 0.531250 0.890625 +vt 0.718750 0.890625 +vt 0.718750 0.609375 +vt 0.531250 0.609375 +vt 0.125000 1.000000 +vt 0.250000 1.000000 +vt 0.250000 0.828125 +vt 0.125000 0.828125 +vt 0.515625 0.671875 +vt 0.328125 0.671875 +vt 0.328125 0.953125 +vt 0.515625 0.953125 +vt 0.296875 0.984375 +vt 0.484375 0.984375 +vt 0.484375 0.703125 +vt 0.296875 0.703125 +vt 0.500000 0.703125 +vt 0.609375 0.703125 +vt 0.609375 0.500000 +vt 0.500000 0.500000 +vt 0.082031 0.796875 +vt 0.023438 0.796875 +vt 0.023438 0.882812 +vt 0.703125 1.000000 +vt 0.984375 1.000000 +vt 0.984375 0.625000 +vt 0.703125 0.625000 +vt 0.718750 0.687500 +vt 0.843750 0.687500 +vt 0.843750 0.546875 +vt 0.718750 0.546875 +vt 0.042969 0.859375 +vt 0.101562 0.859375 +vt 0.101562 0.773438 +vt 0.042969 0.773438 +vt 0.031250 0.984375 +vt 0.312500 0.984375 +vt 0.312500 0.625000 +vt 0.031250 0.625000 +vt 0.023438 0.968750 +g Contained_Fire_Cube.000_Logs-Stone +s off +f 8/1 5/2 6/3 7/4 +f 2/5 6/6 5/7 1/8 +f 3/9 7/10 6/11 2/12 +f 1/13 4/14 3/15 2/16 +f 1/17 5/18 8/19 4/20 +f 4/21 8/22 7/11 3/12 +f 16/23 13/24 14/25 15/26 +f 10/27 14/28 13/29 9/30 +f 11/31 15/32 14/33 10/34 +f 9/35 12/36 11/37 10/38 +f 9/39 13/40 16/41 12/42 +f 12/43 16/44 15/45 11/46 +f 24/47 21/48 22/49 23/4 +f 18/50 22/51 21/52 17/53 +f 19/54 23/55 22/56 18/57 +f 17/58 20/59 19/60 18/61 +f 17/62 21/63 24/64 20/65 +f 20/66 24/67 23/68 19/69 +f 32/70 29/71 30/72 31/73 +f 26/50 30/51 29/52 25/53 +f 27/54 31/55 30/56 26/57 +f 25/74 28/75 27/76 26/77 +f 25/62 29/63 32/64 28/65 +f 28/66 32/67 31/68 27/69 +f 40/78 37/79 38/80 39/81 +f 34/50 38/51 37/52 33/53 +f 35/54 39/55 38/56 34/57 +f 33/82 36/83 35/84 34/85 +f 33/62 37/63 40/64 36/65 +f 36/66 40/67 39/68 35/69 +f 48/86 45/87 46/88 47/89 +f 42/50 46/51 45/52 41/53 +f 43/54 47/55 46/56 42/57 +f 41/90 44/91 43/92 42/93 +f 41/62 45/63 48/64 44/65 +f 44/66 48/67 47/68 43/69 +f 53/94 49/95 50/96 54/97 +f 54/98 50/99 51/100 55/101 +f 55/102 51/103 52/104 56/105 +f 56/106 52/107 49/108 53/109 +f 49/110 52/111 51/112 50/113 +f 56/114 53/115 54/116 55/117 +f 61/118 57/119 58/120 62/121 +f 62/122 58/123 59/124 63/125 +f 63/126 59/127 60/128 64/129 +f 64/130 60/131 57/132 61/133 +f 57/134 60/135 59/136 58/137 +f 64/138 61/139 62/140 63/141 +f 69/118 65/119 66/120 70/121 +f 70/142 66/143 67/144 71/145 +f 71/146 67/147 68/148 72/149 +f 72/130 68/131 65/132 69/133 +f 65/134 68/135 67/136 66/137 +f 72/150 69/151 70/152 71/153 +f 77/118 73/119 74/120 78/121 +f 78/154 74/155 75/156 79/157 +f 79/158 75/159 76/160 80/161 +f 80/130 76/131 73/132 77/133 +f 73/134 76/135 75/136 74/137 +f 80/162 77/163 78/164 79/165 +f 85/118 81/119 82/120 86/121 +f 86/166 82/167 83/168 87/169 +f 87/170 83/171 84/172 88/173 +f 88/130 84/131 81/132 85/133 +f 81/134 84/135 83/136 82/137 +f 88/174 85/175 86/176 87/121 +f 93/118 89/119 90/120 94/121 +f 94/177 90/178 91/179 95/180 +f 95/181 91/182 92/183 96/184 +f 96/130 92/131 89/132 93/133 +f 89/134 92/135 91/136 90/137 +f 96/174 93/175 94/176 95/121 +f 101/118 97/119 98/120 102/121 +f 102/185 98/186 99/187 103/188 +f 103/189 99/190 100/191 104/192 +f 104/130 100/131 97/132 101/133 +f 97/134 100/135 99/136 98/137 +f 104/174 101/175 102/176 103/121 +f 109/118 105/119 106/120 110/121 +f 110/185 106/186 107/187 111/188 +f 111/193 107/118 108/121 112/176 +f 112/130 108/131 105/132 109/133 +f 105/134 108/135 107/136 106/137 +f 112/174 109/175 110/176 111/121 +f 117/118 113/119 114/120 118/121 +f 118/185 114/186 115/187 119/188 +f 119/193 115/118 116/121 120/176 +f 120/130 116/131 113/132 117/133 +f 113/134 116/135 115/136 114/137 +f 120/174 117/175 118/176 119/121 +f 125/118 121/119 122/120 126/121 +f 126/185 122/186 123/187 127/188 +f 127/193 123/118 124/121 128/176 +f 128/130 124/131 121/132 125/133 +f 121/134 124/135 123/136 122/137 +f 128/174 125/175 126/176 127/121 +f 133/118 129/119 130/120 134/121 +f 134/185 130/186 131/187 135/188 +f 135/193 131/118 132/121 136/176 +f 136/130 132/131 129/132 133/133 +f 129/134 132/135 131/136 130/137 +f 136/174 133/175 134/176 135/121 +f 141/118 137/119 138/120 142/121 +f 142/185 138/186 139/187 143/188 +f 143/193 139/118 140/121 144/176 +f 144/130 140/131 137/132 141/133 +f 137/134 140/135 139/136 138/137 +f 144/174 141/175 142/176 143/121 diff --git a/mods/more_fire/models/more_fire_lamp_table.obj b/mods/more_fire/models/more_fire_lamp_table.obj new file mode 100644 index 0000000..4ab5483 --- /dev/null +++ b/mods/more_fire/models/more_fire_lamp_table.obj @@ -0,0 +1,160 @@ +# Blender v2.74 (sub 5) OBJ File: 'lamp.blend' +# www.blender.org +o TabletopLamp_Cube.002 +v 0.140000 -0.399025 -0.139882 +v 0.200000 0.200975 -0.199882 +v 0.140000 -0.399025 0.140118 +v 0.200000 0.200975 0.200118 +v -0.140000 -0.399025 -0.139882 +v -0.200000 0.200975 -0.199882 +v -0.140000 -0.399025 0.140118 +v -0.200000 0.200975 0.200118 +v 0.196000 -0.399025 -0.195882 +v 0.196000 -0.399025 0.196118 +v -0.196000 -0.399025 -0.195882 +v -0.196000 -0.399025 0.196118 +v 0.196000 -0.498858 -0.195882 +v 0.196000 -0.498858 0.196118 +v -0.196000 -0.498857 -0.195882 +v -0.196000 -0.498857 0.196118 +v 0.063585 -0.434677 0.063703 +v 0.063585 -0.434677 -0.063467 +v -0.063585 -0.434677 0.063703 +v -0.063585 -0.434677 -0.063467 +v 0.000000 -0.362197 -0.068012 +v 0.000000 -0.362197 0.067749 +v 0.000000 -0.296697 -0.029923 +v 0.000000 -0.296697 0.029661 +v 0.067880 -0.362197 -0.068012 +v 0.067880 -0.362197 0.067749 +v 0.029792 -0.296697 -0.029923 +v 0.029792 -0.296697 0.029661 +v -0.067880 -0.362197 -0.068011 +v -0.067880 -0.362197 0.067749 +v -0.029792 -0.296697 -0.029923 +v -0.029792 -0.296697 0.029661 +v 0.000000 -0.095525 -0.000131 +v 0.000000 -0.414885 -0.000131 +v 0.029792 -0.296697 -0.000131 +v 0.067880 -0.362197 -0.000131 +v -0.067880 -0.362197 -0.000131 +v -0.029792 -0.296697 -0.000131 +vt 0.000184 0.100646 +vt 0.245094 0.025548 +vt 0.321566 0.406010 +vt 0.150129 0.458578 +vt 0.500000 0.000184 +vt 0.500000 0.388255 +vt 0.754906 0.025548 +vt 0.678434 0.406010 +vt 0.999816 0.100646 +vt 0.849871 0.458578 +vt 0.126413 0.785921 +vt 0.324583 0.785910 +vt 0.364220 0.825542 +vt 0.086781 0.825558 +vt 0.364204 0.548103 +vt 0.086765 0.548119 +vt 0.086761 0.477462 +vt 0.364200 0.477446 +vt 0.324572 0.587740 +vt 0.126401 0.587751 +vt 0.538369 0.694413 +vt 0.828479 0.694413 +vt 0.828479 0.984522 +vt 0.538370 0.984522 +vt 0.434861 0.548099 +vt 0.434876 0.825538 +vt 0.016124 0.825562 +vt 0.016108 0.548123 +vt 0.364224 0.896199 +vt 0.086785 0.896215 +vt 0.128242 0.782956 +vt 0.128359 0.588263 +vt 0.184733 0.643133 +vt 0.183276 0.726280 +vt 0.266422 0.644797 +vt 0.267527 0.727647 +vt 0.321989 0.589472 +vt 0.323247 0.783309 +vt 0.710670 0.483156 +vt 0.731303 0.458009 +vt 0.938416 0.548420 +vt 0.722804 0.505829 +vt 0.668840 0.608672 +vt 0.623856 0.671057 +vt 0.584008 0.546251 +vt 0.665070 0.585205 +vt 0.730212 0.636289 +vt 0.709888 0.610891 +vt 0.722299 0.588369 +vt 0.669598 0.484873 +vt 0.665541 0.508292 +vt 0.625380 0.421942 +vt 0.710294 0.566741 +vt 0.676652 0.564725 +vt 0.670759 0.546782 +vt 0.721862 0.547095 +vt 0.710535 0.527308 +vt 0.676871 0.528913 +vn 0.995000 -0.099500 -0.000000 +vn 0.000000 -0.099500 0.995000 +vn -0.995000 -0.099500 0.000000 +vn -0.000000 -0.099500 -0.995000 +vn 0.000000 1.000000 0.000000 +vn -0.000000 0.000000 -1.000000 +vn -0.000000 -1.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn 1.000000 -0.000000 -0.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.906200 0.422800 +vn 0.422800 0.906200 -0.000000 +vn -0.422800 0.906200 0.000000 +vn -0.000000 0.906200 -0.422800 +vn 0.692100 0.205000 -0.692100 +vn -0.340200 -0.876600 -0.340200 +vn -0.692100 0.205000 -0.692100 +vn 0.864500 0.502700 -0.000000 +vn 0.340200 -0.876600 -0.340200 +vn -0.864500 0.502700 0.000000 +vn -0.000000 0.502700 -0.864500 +vn 0.000000 0.502700 0.864500 +vn 0.692100 0.205000 0.692100 +vn -0.340200 -0.876600 0.340200 +vn -0.692100 0.205000 0.692100 +vn 0.340200 -0.876600 0.340200 +s off +f 2/1/1 4/2/1 3/3/1 1/4/1 +f 4/2/2 8/5/2 7/6/2 3/3/2 +f 8/5/3 6/7/3 5/8/3 7/6/3 +f 6/7/4 2/9/4 1/10/4 5/8/4 +f 3/11/5 7/12/5 12/13/5 10/14/5 +f 11/15/6 9/16/6 13/17/6 15/18/6 +f 5/19/5 1/20/5 9/16/5 11/15/5 +f 7/12/5 5/19/5 11/15/5 12/13/5 +f 1/20/5 3/11/5 10/14/5 9/16/5 +f 13/21/7 14/22/7 16/23/7 15/24/7 +f 12/13/8 11/15/8 15/25/8 16/26/8 +f 9/16/9 10/14/9 14/27/9 13/28/9 +f 10/14/10 12/13/10 16/29/10 14/30/10 +f 1/31/11 5/32/11 20/33/11 18/34/11 +f 19/35/5 17/36/5 18/34/5 20/33/5 +f 5/32/12 7/37/12 19/35/12 20/33/12 +f 3/38/13 1/31/13 18/34/13 17/36/13 +f 7/37/14 3/38/14 17/36/14 19/35/14 +f 27/39/15 23/40/15 33/41/15 35/42/15 +f 29/43/16 21/44/16 34/45/16 37/46/16 +f 23/47/17 31/48/17 38/49/17 33/41/17 +f 25/50/18 27/39/18 35/42/18 36/51/18 +f 21/52/19 25/50/19 36/51/19 34/45/19 +f 31/48/20 29/43/20 37/46/20 38/49/20 +f 27/39/21 25/50/21 21/52/21 23/40/21 +f 32/53/22 30/54/22 22/55/22 24/56/22 +f 35/42/23 33/41/23 24/56/23 28/57/23 +f 37/46/24 34/45/24 22/55/24 30/54/24 +f 23/47/21 21/44/21 29/43/21 31/48/21 +f 24/56/22 22/55/22 26/58/22 28/57/22 +f 33/41/25 38/49/25 32/53/25 24/56/25 +f 36/51/18 35/42/18 28/57/18 26/58/18 +f 34/45/26 36/51/26 26/58/26 22/55/26 +f 38/49/20 37/46/20 30/54/20 32/53/20 diff --git a/mods/more_fire/models/more_fire_lamp_wall.obj b/mods/more_fire/models/more_fire_lamp_wall.obj new file mode 100644 index 0000000..27c0902 --- /dev/null +++ b/mods/more_fire/models/more_fire_lamp_wall.obj @@ -0,0 +1,187 @@ +# Blender v2.74 (sub 5) OBJ File: 'lamp.blend' +# www.blender.org +o Cube.001 +v 0.140000 -0.280515 0.022415 +v 0.200000 0.319485 -0.037585 +v 0.140000 -0.280515 0.302415 +v 0.200000 0.319485 0.362415 +v -0.140000 -0.280515 0.022415 +v -0.200000 0.319485 -0.037585 +v -0.140000 -0.280515 0.302415 +v -0.200000 0.319485 0.362415 +v 0.196000 -0.280515 -0.033585 +v 0.196000 -0.280515 0.358415 +v -0.196000 -0.280515 -0.033585 +v -0.196000 -0.280515 0.358415 +v 0.196000 -0.380348 -0.033585 +v 0.196000 -0.380348 0.358415 +v -0.196000 -0.380348 -0.033585 +v -0.196000 -0.380348 0.358415 +v -0.117783 -0.280515 0.437568 +v 0.117783 -0.280515 0.437568 +v -0.117783 -0.380348 0.437568 +v 0.117783 -0.380348 0.437568 +v -0.222778 -0.190702 0.499030 +v 0.222778 -0.190702 0.499029 +v -0.222778 -0.380348 0.499030 +v 0.222778 -0.380348 0.499029 +v 0.063585 -0.316167 0.226000 +v 0.063585 -0.316167 0.098830 +v -0.063585 -0.316167 0.226000 +v -0.063585 -0.316167 0.098830 +v 0.000000 -0.243687 0.094285 +v 0.000000 -0.243687 0.230046 +v 0.000000 -0.178187 0.132373 +v 0.000000 -0.178187 0.191958 +v 0.067880 -0.243687 0.094285 +v 0.067880 -0.243687 0.230046 +v 0.029792 -0.178187 0.132373 +v 0.029792 -0.178187 0.191958 +v -0.067880 -0.243687 0.094285 +v -0.067880 -0.243687 0.230046 +v -0.029792 -0.178187 0.132373 +v -0.029792 -0.178187 0.191958 +v 0.000000 0.022985 0.162166 +v 0.000000 -0.296375 0.162166 +v 0.029792 -0.178187 0.162166 +v 0.067880 -0.243687 0.162166 +v -0.067880 -0.243687 0.162166 +v -0.029792 -0.178187 0.162166 +vt 0.000184 0.100646 +vt 0.245094 0.025548 +vt 0.321566 0.406010 +vt 0.150129 0.458578 +vt 0.500000 0.000184 +vt 0.500000 0.388255 +vt 0.754906 0.025548 +vt 0.678434 0.406010 +vt 0.999816 0.100646 +vt 0.849871 0.458578 +vt 0.314421 0.800681 +vt 0.318222 0.575143 +vt 0.363809 0.525366 +vt 0.362687 0.863618 +vt 0.105089 0.564675 +vt 0.089347 0.790322 +vt 0.017624 0.857183 +vt 0.018081 0.506752 +vt 0.138376 0.596328 +vt 0.130292 0.760686 +vt 0.605426 0.689137 +vt 0.886635 0.689137 +vt 0.886635 0.970346 +vt 0.605426 0.970346 +vt 0.354343 0.937588 +vt 0.465557 0.832974 +vt 0.442159 0.934100 +vt 0.361926 0.441181 +vt 0.570612 0.907416 +vt 0.489202 0.967153 +vt 0.441846 0.565238 +vt 0.426006 0.454242 +vt 0.943417 0.745248 +vt 0.943417 0.914235 +vt 0.570612 0.498898 +vt 0.485731 0.420788 +vt 0.987508 0.669927 +vt 0.987508 0.989556 +vt 0.315130 0.800066 +vt 0.132668 0.760847 +vt 0.188257 0.717364 +vt 0.266689 0.731056 +vt 0.186969 0.642567 +vt 0.267853 0.635424 +vt 0.138529 0.595618 +vt 0.318539 0.576008 +vt 0.710670 0.483156 +vt 0.731303 0.458009 +vt 0.938416 0.548420 +vt 0.722804 0.505829 +vt 0.668840 0.608672 +vt 0.623856 0.671057 +vt 0.584008 0.546251 +vt 0.665070 0.585205 +vt 0.730212 0.636289 +vt 0.709888 0.610891 +vt 0.722299 0.588369 +vt 0.669598 0.484873 +vt 0.665541 0.508292 +vt 0.625380 0.421942 +vt 0.710294 0.566741 +vt 0.676652 0.564725 +vt 0.670759 0.546782 +vt 0.721862 0.547095 +vt 0.710535 0.527308 +vt 0.676871 0.528913 +vn 0.995000 -0.099500 -0.000000 +vn 0.000000 -0.099500 0.995000 +vn -0.995000 -0.099500 0.000000 +vn -0.000000 -0.099500 -0.995000 +vn 0.000000 1.000000 0.000000 +vn -0.000000 0.000000 -1.000000 +vn -0.000000 -1.000000 0.000000 +vn 0.711300 -0.000000 0.702900 +vn -1.000000 0.000000 0.000000 +vn 1.000000 -0.000000 -0.000000 +vn 0.505200 0.000000 -0.863000 +vn -0.711300 0.000000 0.702900 +vn -0.000000 0.564800 -0.825300 +vn -0.505200 0.000000 -0.863000 +vn 0.000000 0.906200 0.422800 +vn 0.422800 0.906200 -0.000000 +vn -0.422800 0.906200 0.000000 +vn 0.000000 0.906200 -0.422800 +vn 0.692100 0.205000 -0.692100 +vn -0.340200 -0.876600 -0.340200 +vn -0.692100 0.205000 -0.692100 +vn 0.864500 0.502700 -0.000000 +vn 0.340200 -0.876600 -0.340200 +vn -0.864500 0.502700 0.000000 +vn -0.000000 0.502700 -0.864500 +vn 0.000000 0.502700 0.864500 +vn 0.692100 0.205000 0.692100 +vn -0.340200 -0.876600 0.340200 +vn -0.692100 0.205000 0.692100 +vn 0.340200 -0.876600 0.340200 +s off +f 2/1/1 4/2/1 3/3/1 1/4/1 +f 4/2/2 8/5/2 7/6/2 3/3/2 +f 8/5/3 6/7/3 5/8/3 7/6/3 +f 6/7/4 2/9/4 1/10/4 5/8/4 +f 3/11/5 7/12/5 12/13/5 10/14/5 +f 11/15/6 9/16/6 13/17/6 15/18/6 +f 5/19/5 1/20/5 9/16/5 11/15/5 +f 7/12/5 5/19/5 11/15/5 12/13/5 +f 1/20/5 3/11/5 10/14/5 9/16/5 +f 13/21/7 14/22/7 16/23/7 15/24/7 +f 14/25/8 10/14/8 18/26/8 20/27/8 +f 12/13/9 11/15/9 15/18/9 16/28/9 +f 9/16/10 10/14/10 14/25/10 13/17/10 +f 20/27/11 18/26/11 22/29/11 24/30/11 +f 10/14/5 12/13/5 17/31/5 18/26/5 +f 12/13/12 16/28/12 19/32/12 17/31/12 +f 16/23/7 14/22/7 20/33/7 19/34/7 +f 18/26/13 17/31/13 21/35/13 22/29/13 +f 17/31/14 19/32/14 23/36/14 21/35/14 +f 19/34/7 20/33/7 24/37/7 23/38/7 +f 1/39/15 5/40/15 28/41/15 26/42/15 +f 27/43/5 25/44/5 26/42/5 28/41/5 +f 5/40/16 7/45/16 27/43/16 28/41/16 +f 3/46/17 1/39/17 26/42/17 25/44/17 +f 7/45/18 3/46/18 25/44/18 27/43/18 +f 35/47/19 31/48/19 41/49/19 43/50/19 +f 37/51/20 29/52/20 42/53/20 45/54/20 +f 31/55/21 39/56/21 46/57/21 41/49/21 +f 33/58/22 35/47/22 43/50/22 44/59/22 +f 29/60/23 33/58/23 44/59/23 42/53/23 +f 39/56/24 37/51/24 45/54/24 46/57/24 +f 35/47/25 33/58/25 29/60/25 31/48/25 +f 40/61/26 38/62/26 30/63/26 32/64/26 +f 43/50/27 41/49/27 32/64/27 36/65/27 +f 45/54/28 42/53/28 30/63/28 38/62/28 +f 31/55/25 29/52/25 37/51/25 39/56/25 +f 32/64/26 30/63/26 34/66/26 36/65/26 +f 41/49/29 46/57/29 40/61/29 32/64/29 +f 44/59/22 43/50/22 36/65/22 34/66/22 +f 42/53/30 44/59/30 34/66/30 30/63/30 +f 46/57/24 45/54/24 38/62/24 40/61/24 diff --git a/mods/more_fire/models/torch.blend b/mods/more_fire/models/torch.blend new file mode 100644 index 0000000..efff6b4 Binary files /dev/null and b/mods/more_fire/models/torch.blend differ diff --git a/mods/more_fire/molotov.lua b/mods/more_fire/molotov.lua new file mode 100644 index 0000000..204115c --- /dev/null +++ b/mods/more_fire/molotov.lua @@ -0,0 +1,285 @@ + --Molotov Cocktail_[rev002] + --base code is from throwing enhanced and potions mods + +local MOD_NAME = minetest.get_current_modname() +local MOD_PATH = minetest.get_modpath(MOD_NAME) +local Vec3 = dofile(MOD_PATH..'/lib/Vec3_1-0.lua') + +minetest.register_craftitem('more_fire:molotov_cocktail', { + description = 'Throwable Firebomb', + inventory_image = 'more_fire_molotov_cocktail.png', + on_place = function(itemstack, user, pointed_thing) + itemstack:take_item() + minetest.sound_play('more_fire_shatter', {gain = 1.0}) + n = minetest.get_node(pointed_thing) + if pointed_thing.type == 'node' then + minetest.add_node(pointed_thing.above, {name='fire:basic_flame'}) + minetest.sound_play('more_fire_ignite', {pos,pos}) + end + --Shattered glass Particles + minetest.add_particlespawner({ + amount = 40, + time = 0.1, + minpos = pointed_thing.above, + maxpos = pointed_thing.above, + minvel = {x=2, y=0.2, z=2}, + maxvel = {x=-2, y=0.5, z=-2}, + minacc = {x=0, y=-6, z=0}, + maxacc = {x=0, y=-10, z=0}, + minexptim = 0.5, + maxexptime = 2, + minsize = 0.2, + maxsize = 5, + collisiondetection = true, + texture = 'more_fire_shatter.png'}) + --fire ember particles + minetest.add_particlespawner({ + amount = 100, + time = 0.1, + minpos = pointed_thing.above, + maxpos = pointed_thing.above, + minvel = {x=-2, y=0.5, z=-2}, + maxvel = {x=2, y=0.5, z=2}, + minacc = {x=0, y=-10, z=0}, + maxacc = {x=0, y=-6, z=0}, + minexptime = 2, + maxexptime = 3, + minsize = 0.25, + maxsize = 0.5, + collisiondetection = true, + texture = 'more_fire_spark.png'}) + local dir = Vec3(user:get_look_dir()) *20 + minetest.add_particle( + {x=user:getpos().x, y=user:getpos().y+1.5, z=user:getpos().z}, {x=dir.x, y=dir.y, z=dir.z}, {x=0, y=-10, z=0}, 0.2, + 6, false, 'more_fire_molotov_cocktail.png') + return itemstack + end, +}) + +local function throw_cocktail(item, player) + local playerpos = player:getpos() + local obj = minetest.add_entity({x=playerpos.x,y=playerpos.y+1.625,z=playerpos.z}, 'more_fire:molotov_entity') + local dir = player:get_look_dir() + obj:setvelocity({x=dir.x*30, y=dir.y*30, z=dir.z*30}) + obj:setacceleration({x=dir.x*-3, y=-dir.y^8*80-10, z=dir.z*-3}) + if not minetest.settings:get_bool('creative_mode') then + item:take_item() + end + return item +end + +local radius = 5.0 + +local function add_effects(pos, radius) + minetest.add_particlespawner({ + amount = 10, + time = 0.2, + minpos = vector.subtract(pos, radius / 2), + maxpos = vector.add(pos, radius / 2), + minvel = {x=-2, y=-2, z=-2}, + maxvel = {x=2, y=-4, z=2}, + minacc = {x=0, y=-4, z=0}, + --~ maxacc = {x=-20, y=-50, z=-50}, + minexptime = 1, + maxexptime = 1.5, + minsize = 1, + maxsize = 2, + texture = 'more_fire_spark.png', + }) + minetest.add_particlespawner({ + amount = 10, + time = 0.2, + minpos = vector.subtract(pos, radius / 2), + maxpos = vector.add(pos, radius / 2), + minvel = {x=-1.25, y=-1.25, z=-1.25}, + maxvel = {x=0.5, y=-4, z=0.5}, + minacc = {x=1.25, y=-1.25, z=1.25}, + --~ maxacc = {x=-20, y=-50, z=-50}, + minexptime =1, + maxexptime = 1.5, + minsize = 1, + maxsize = 2, + texture = 'more_fire_spark.png', + }) +end + + + +local MORE_FIRE_MOLOTOV_ENTITY = { + timer=0, + collisionbox = {0,0,0,0,0,0}, + physical = false, + textures = {'more_fire_molotov_cocktail.png'}, + lastpos={}, +} + +MORE_FIRE_MOLOTOV_ENTITY.on_step = function(self, dtime) + self.timer = self.timer + dtime + local pos = self.object:getpos() + local node = minetest.get_node(pos) + minetest.add_particlespawner({ + amount = 10, + time = 0.5, + minpos = pos, + maxpos = pos, + minvel = {x=-0, y=0, z=-0.5}, + maxvel = {x=0, y=0, z=-0.75}, + minacc = vector.new(), + maxacc = vector.new(), + minexptime = 0.5, + maxexptime = 1, + minsize = 0.25, + maxsize = 0.5, + texture = 'more_fire_smoke.png', + }) + minetest.add_particlespawner({ + amount = 100, + time = 0.25, + minpos = pos, + maxpos = pos, + minvel = {x=-0, y=0, z=-0.5}, + maxvel = {x=0, y=0, z=-0.75}, + minacc = {x=0, y=0, z=-0.75}, + maxacc = {x=-0, y=0, z=-0.5}, + minexptime = 0.25, + maxexptime = 0.5, + minsize = 0.5, + maxsize = 0.75, + texture = 'more_fire_spark.png', + }) + if self.timer>0.2 then + local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 1) + for k, obj in pairs(objs) do + if obj:get_luaentity() ~= nil then + if obj:get_luaentity().name ~= 'more_fire:molotov_entity' and obj:get_luaentity().name ~= '__builtin:item' then + if self.node ~= '' then + minetest.sound_play('more_fire_shatter', {gain = 1.0}) + for dx=-3,3 do + for dy=-3,3 do + for dz=-3,3 do + local p = {x=pos.x+dx, y=pos.y+dy, z=pos.z+dz} + local n = minetest.get_node(pos).name + if n == "default:grass" then + --if minetest.registered_nodes[n].groups.flammable or math.random(1, 100) <= 20 then + minetest.sound_play('more_fire_ignite', {pos = self.lastpos}) + minetest.set_node(p, {name='fire:basic_flame'}) + + end + end + end + end + end + self.object:remove() + end + else + if self.node ~= '' then + minetest.sound_play('more_fire_shatter', {gain = 1.0}) + for dx=-2,2 do + for dy=-2,2 do + for dz=-2,2 do + local p = {x=pos.x+dx, y=pos.y+dy, z=pos.z+dz} + local n = minetest.get_node(pos).name + if n == "default:grass" then + --if minetest.registered_nodes[n].groups.flammable or math.random(1, 100) <= 20 then + minetest.sound_play('more_fire_ignite', {pos = self.lastpos}) + minetest.set_node(p, {name='fire:basic_flame'}) + + end + end + end + end + end + self.object:remove() + end + end + end + + if self.lastpos.x~=nil then + if node.name ~= 'air' then + if self.node ~= '' then + minetest.sound_play('more_fire_shatter', {gain = 1.0}) + for dx=-1,1 do + for dy=-1,1 do + for dz=-1,1 do + local p = {x = pos.x + dx, y = pos.y + dy, z = pos.z + dz} + local p1 = {x = pos.x + dx, y=pos.y + dy - 1, z = pos.z + dz} + local n = minetest.get_node(p).name + local n1 = minetest.get_node(p1).name + if n == "air" and n1 ~= "fire:basic_flame" or math.random(1, 100) <= 5 then + minetest.sound_play('more_fire_ignite', {pos = self.lastpos}) + minetest.set_node(p, {name='fire:basic_flame'}) + end + end + end + end + end + self.object:remove() + end + end + self.lastpos={x=pos.x, y=pos.y, z=pos.z} +end + +minetest.register_entity('more_fire:molotov_entity', MORE_FIRE_MOLOTOV_ENTITY) + +minetest.override_item('more_fire:molotov_cocktail', {on_use = throw_cocktail}) + + + +minetest.register_abm({ + nodenames={'fire:basic_flame'}, + neighbors={'air'}, + interval = 1, + chance = 2, + action = function(pos, node) + if minetest.get_node({x=pos.x, y=pos.y+1.0, z=pos.z}).name == 'air' and + minetest.get_node({x=pos.x, y=pos.y+2.0, z=pos.z}).name == 'air' then + minetest.add_particlespawner({ + amount = 1, + time = 2, + minpos = pos, + maxpos = pos, + minvel = {x=-2, y=2, z=-2}, + maxvel = {x=1, y=3, z=1}, + minacc = {x=0, y=6, z=0}, + maxacc = {x=0, y=2, z=0}, + minexptime = 1, + maxexptime = 3, + minsize = 10, + maxsize = 20, + collisiondetection = false, + texture = 'more_fire_smoke.png'}) + minetest.add_particlespawner({ + amount = 15, + time = 4, + minpos = pos, + maxpos = pos, + minvel = {x=0, y= 3, z=0}, + maxvel = {x=0, y=5, z=0}, + minacc = {x=0.1, y=0.5, z=-0.1}, + maxacc = {x=-0.2, y=2, z=0.2}, + minexptime = 1, + maxexptime = 3, + minsize = 5, + maxsize = 10, + collisiondetection = false, + texture ='more_fire_smoke.png'}) + end + end +}) + + --crafting recipes +minetest.register_craft( { + output = 'more_fire:molotov_cocktail', + recipe = { + {'farming:cotton'}, + {'more_fire:oil'}, + {'vessels:glass_bottle'}, + } +}) + +-- fuel recipes +minetest.register_craft({ + type = 'fuel', + recipe = 'more_fire:molotov_cocktail', + burntime = 5, +}) diff --git a/mods/more_fire/pipebomb.lua b/mods/more_fire/pipebomb.lua new file mode 100644 index 0000000..b0a036e --- /dev/null +++ b/mods/more_fire/pipebomb.lua @@ -0,0 +1,194 @@ +--Pipe Bomb +--base code is from throwing enhanced and potions mods + +local MOD_NAME = minetest.get_current_modname() +local MOD_PATH = minetest.get_modpath(MOD_NAME) +local Vec3 = dofile(MOD_PATH..'/lib/Vec3_1-0.lua') +local playerWhoThrewObject = minetest.get_player_by_name("singleplayer") + +minetest.register_craftitem('more_fire:pipebomb', { + description = 'Pipe Bomb', + inventory_image = 'more_fire_pipebomb.png', + on_place = function(itemstack, user, pointed_thing) + itemstack:take_item() + minetest.sound_play('more_fire_shatter', {gain = 1.0}) + + --smoke particles + minetest.add_particlespawner({ + amount = 400, + time = 0.1, + minpos = pointed_thing.above, + maxpos = pointed_thing.above, + minvel = {x=2, y=0.2, z=2}, + maxvel = {x=-2, y=0.5, z=-2}, + minacc = {x=0, y=-6, z=0}, + maxacc = {x=0, y=-10, z=0}, + minexptime = 5, + maxexptime = 2, + minsize = 5, + maxsize = 20, + collisiondetection = true, + texture = 'more_fire_smoke.png'}) + --more smoke particles + minetest.add_particlespawner({ + amount = 600, + time = 1, + minpos = pointed_thing.above, + maxpos = pointed_thing.above, + minvel = {x=10, y= 3, z=10}, + maxvel = {x=-10, y= 3, z=-10}, + minacc = {x=2, y=2, z=2}, + maxacc = {x=-2, y=1, z=-2}, + minexptime = 2, + maxexptime = 3, + minsize = 2, + maxsize = 20, + collisiondetection = true, + texture = 'more_fire_smoke.png'}) + --even more smoke particles + minetest.add_particlespawner({ + amount = 400, + time = 1, + minpos = pointed_thing.above, + maxpos = pointed_thing.above, + minvel = {x=0.2, y=0.2, z=0.2}, + maxvel = {x=-0.2, y=0.5, z=-0.2}, + minacc = {x=10, y= 2, z=10}, + maxacc = {x=-10, y= 1, z=-10}, + minexptime = 2, + maxexptime = 3, + minsize = 20, + maxsize = 2, + collisiondetection = true, + texture = 'more_fire_smoke.png'}) + local dir = Vec3(user:get_look_dir()) *20 + minetest.add_particle( + {x=user:getpos().x, y=user:getpos().y+1.5, z=user:getpos().z}, {x=dir.x, y=dir.y, z=dir.z}, {x=0, y=-10, z=0}, 0.2, + 6, false, 'more_fire_smokebomb.png') + return itemstack + end, + }) + +local function throw_pipebomb(item, player) + local playerpos = player:getpos() + local obj = minetest.add_entity({x = playerpos.x, y = playerpos.y + 1.625, z = playerpos.z}, 'more_fire:pipebomb_entity') + local dir = player:get_look_dir() + obj:setvelocity({x = dir.x * 30, y = dir.y * 30, z = dir.z * 30}) + obj:setacceleration({x = dir.x * -3, y = -dir.y^8 * 80 - 10, z = dir.z * -3}) + item:take_item() + playerWhoThrewObject = player + return item +end + +local function add_effects(pos) + minetest.add_particlespawner({ + amount = 200, + time = 0.1, + minpos = vector.subtract(pos, 5 / 3), + maxpos = vector.add(pos, 5 / 3), + minvel = {x=2, y=0.2, z=2}, + maxvel = {x=-2, y=-0.5, z=-2}, + minacc = {x=1, y=-6, z=1}, + maxacc = {x=1, y=-10, z=1}, + minexptime = 1, + maxexptime = 5, + minsize = 10, + maxsize = 20, + texture = 'more_fire_smoke.png',}) + minetest.add_particlespawner({ + amount = 100, + time = 2, + minpos = vector.subtract(pos, 5 / 2), + maxpos = vector.add(pos, 5 / 2), + minvel = {x=0.2, y=0.2, z=0.2}, + maxvel = {x=-0.2, y=0.5, z=-0.2}, + minacc = {x=10, y= 2, z=10}, + maxacc = {x=-10, y= 1, z=-10}, + minexptime =1, + maxexptime = 3, + minsize = 5, + maxsize = 15, + texture = 'more_fire_smoke.png',}) +end + +local function plume(pos) + minetest.set_node(pos, {name='more_fire:plume'}) + minetest.get_node_timer(pos):start(3.0) + add_effects(pos) +end + +local MORE_FIRE_PIPEBOMB_ENTITY = { + timer=0, + collisionbox = {0,0,0,0,0,0}, + physical = false, + textures = {'more_fire_pipebomb.png'}, + lastpos={}, +} + + +MORE_FIRE_PIPEBOMB_ENTITY.on_step = function(self, dtime) + self.timer = self.timer + dtime + local pos = self.object:getpos() + local node = minetest.get_node(pos) + if self.timer > 0.01 then + local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 1) + for k, obj in pairs(objs) do + if obj:get_luaentity() ~= nil then + if obj:get_luaentity().name ~= 'more_fire:pipebomb_entity' and obj:get_luaentity().name ~= '__builtin:item' then + if self.node ~= '' then + explosives.boom(pos, {}) + local damage = 1 + obj:punch(self.object, 1.0, { + full_punch_interval=1.0, + damage_groups={fleshy=damage}, + }, nil) + self.object:remove() + end + end + end + end + if self.lastpos.x ~= nil then + if node.name ~= 'air' then + self.object:remove() + + explosives.boom(pos, { + owner = playerWhoThrewObject + }) + + minetest.add_particlespawner({ + amount = 64, + time = 0.5, + minpos = {x = pos.x - 2, y = pos.y - 2, z = pos.z - 2}, + maxpos = {x = pos.x + 2, y = pos.y + 2, z = pos.z + 2}, + minvel = {x = -10, y = -10, z = -10}, + maxvel = {x = 10, y = 10, z = 10}, + minacc = vector.new(), + maxacc = vector.new(), + minexptime = 1, + maxexptime = 2.5, + minsize = 2, + maxsize = 5, + texture = "tnt_smoke.png", + }) + + end + end + self.lastpos={x=pos.x, y=pos.y, z=pos.z} + end +end + +minetest.register_entity('more_fire:pipebomb_entity', MORE_FIRE_PIPEBOMB_ENTITY) + +minetest.override_item('more_fire:pipebomb', {on_use = throw_pipebomb}) + + + + +minetest.register_craft({ + output = 'more_fire:pipe_bomb', + recipe = { + {'more_fire:flintstone'}, + {'more_fire:charcoal'}, + {'vessels:glass_bottle'}, + } +}) diff --git a/mods/more_fire/readme.md b/mods/more_fire/readme.md new file mode 100644 index 0000000..85aca59 --- /dev/null +++ b/mods/more_fire/readme.md @@ -0,0 +1,31 @@ +If you have any ideas for more fire related things please let me know, or consider forking the project on GIT. I'm always ready to add more good stuff. + +# Mod Contributors +Nathan +Napiophelios + +# More_fire +This is a Minetest mod that adds more/better fire related stuff + +## Forum Topic +https://forum.minetest.net/viewtopic.php?f=11&t=10372 + +## Licensing +CC0 + +## Dependencies +- default +- farming +- fire +- vessels + +# +Items currently included: +- Campfires +- Finite torches, they burn out (configurable in config.txt) +- oil lanterns, use these instead of torches +- oil for the lanterns of course +- a lighter, for starting the campfires. +- charcoal, much like coal, but made by cooking wood +- a smoke bomb +- molotov cocktail diff --git a/mods/more_fire/screenshot.png b/mods/more_fire/screenshot.png new file mode 100644 index 0000000..638b9a9 Binary files /dev/null and b/mods/more_fire/screenshot.png differ diff --git a/mods/more_fire/settingtypes.txt b/mods/more_fire/settingtypes.txt new file mode 100644 index 0000000..3b1997c --- /dev/null +++ b/mods/more_fire/settingtypes.txt @@ -0,0 +1,8 @@ +#How long in seconds a torch will burn. +#Default is 960 seconds (16 minutes) +more_fire.torch_burn_time (Burn time of new torches) int 960 +#How long in seconds a bottle of lamp oil will burn. +#Default is 720 seconds (12 minutes) +more_fire.oillamp_burn_time (Burn time of oil lamp) int 720 +more_fire.finite_torches (Should torches burn out?) bool true +more_fire.pyromania (Enable molotov cocktails?) bool false diff --git a/mods/more_fire/smokebomb.lua b/mods/more_fire/smokebomb.lua new file mode 100644 index 0000000..52a2e1b --- /dev/null +++ b/mods/more_fire/smokebomb.lua @@ -0,0 +1,288 @@ +--Smoke Bomb_[rev001] +--base code is from throwing enhanced and potions mods + + local MOD_NAME = minetest.get_current_modname() + local MOD_PATH = minetest.get_modpath(MOD_NAME) + local Vec3 = dofile(MOD_PATH..'/lib/Vec3_1-0.lua') + +minetest.register_craftitem('more_fire:smokebomb', { + description = 'Smoke Bomb', + inventory_image = 'more_fire_smokebomb.png', + on_place = function(itemstack, user, pointed_thing) + itemstack:take_item() + minetest.sound_play('more_fire_shatter', {gain = 1.0}) + --Shattered glass Particles + minetest.add_particlespawner({ + amount = 40, + time = 0.1, + minpos = pointed_thing.above, + maxpos = pointed_thing.above, + minvel = {x=2, y=0.2, z=2}, + maxvel = {x=-2, y=0.5, z=-2}, + minacc = {x=0, y=-6, z=0}, + maxacc = {x=0, y=-10, z=0}, + minexptime = 0.5, + maxexptime = 2, + minsize = 0.2, + maxsize = 5, + collisiondetection = true, + texture = 'more_fire_shatter.png'}) + --smoke particles + minetest.add_particlespawner({ + amount = 400, + time = 0.1, + minpos = pointed_thing.above, + maxpos = pointed_thing.above, + minvel = {x=2, y=0.2, z=2}, + maxvel = {x=-2, y=0.5, z=-2}, + minacc = {x=0, y=-6, z=0}, + maxacc = {x=0, y=-10, z=0}, + minexptime = 5, + maxexptime = 2, + minsize = 5, + maxsize = 20, + collisiondetection = true, + texture = 'more_fire_smoke.png'}) + --more smoke particles + minetest.add_particlespawner({ + amount = 600, + time = 1, + minpos = pointed_thing.above, + maxpos = pointed_thing.above, + minvel = {x=10, y= 3, z=10}, + maxvel = {x=-10, y= 3, z=-10}, + minacc = {x=2, y=2, z=2}, + maxacc = {x=-2, y=1, z=-2}, + minexptime = 2, + maxexptime = 3, + minsize = 2, + maxsize = 20, + collisiondetection = true, + texture = 'more_fire_smoke.png'}) + --even more smoke particles + minetest.add_particlespawner({ + amount = 400, + time = 1, + minpos = pointed_thing.above, + maxpos = pointed_thing.above, + minvel = {x=0.2, y=0.2, z=0.2}, + maxvel = {x=-0.2, y=0.5, z=-0.2}, + minacc = {x=10, y= 2, z=10}, + maxacc = {x=-10, y= 1, z=-10}, + minexptime = 2, + maxexptime = 3, + minsize = 20, + maxsize = 2, + collisiondetection = true, + texture = 'more_fire_smoke.png'}) + local dir = Vec3(user:get_look_dir()) *20 + minetest.add_particle( + {x=user:getpos().x, y=user:getpos().y+1.5, z=user:getpos().z}, {x=dir.x, y=dir.y, z=dir.z}, {x=0, y=-10, z=0}, 0.2, + 6, false, 'more_fire_smokebomb.png') + return itemstack + end, + }) + +local function throw_smokebomb(item, player) + local playerpos = player:getpos() + local obj = minetest.add_entity({x=playerpos.x,y=playerpos.y+1.625,z=playerpos.z}, 'more_fire:smokebomb_entity') + local dir = player:get_look_dir() + obj:setvelocity({x=dir.x*30, y=dir.y*30, z=dir.z*30}) + obj:setacceleration({x=dir.x*-3, y=-dir.y^8*80-10, z=dir.z*-3}) + if not minetest.settings:get_bool('creative_mode') then + item:take_item() + end + return item +end + +local function add_effects(pos) + minetest.add_particlespawner({ + amount = 200, + time = 0.1, + minpos = vector.subtract(pos, 5 / 3), + maxpos = vector.add(pos, 5 / 3), + minvel = {x=2, y=0.2, z=2}, + maxvel = {x=-2, y=-0.5, z=-2}, + minacc = {x=1, y=-6, z=1}, + maxacc = {x=1, y=-10, z=1}, + minexptime = 1, + maxexptime = 5, + minsize = 10, + maxsize = 20, + texture = 'more_fire_smoke.png',}) + minetest.add_particlespawner({ + amount = 100, + time = 2, + minpos = vector.subtract(pos, 5 / 2), + maxpos = vector.add(pos, 5 / 2), + minvel = {x=0.2, y=0.2, z=0.2}, + maxvel = {x=-0.2, y=0.5, z=-0.2}, + minacc = {x=10, y= 2, z=10}, + maxacc = {x=-10, y= 1, z=-10}, + minexptime =1, + maxexptime = 3, + minsize = 5, + maxsize = 15, + texture = 'more_fire_smoke.png',}) +end + +local function plume(pos) + minetest.set_node(pos, {name='more_fire:plume'}) + minetest.get_node_timer(pos):start(3.0) + add_effects(pos) +end + +local MORE_FIRE_SMOKEBOMB_ENTITY = { + timer=0, + collisionbox = {0,0,0,0,0,0}, + physical = false, + textures = {'more_fire_smokebomb.png'}, + lastpos={}, +} + +MORE_FIRE_SMOKEBOMB_ENTITY.on_step = function(self, dtime) + self.timer = self.timer + dtime + local pos = self.object:getpos() + local node = minetest.get_node(pos) + minetest.add_particlespawner({ + amount = 10, + time = 0.5, + minpos = pos, + maxpos = pos, + minvel = {x=-0, y=0, z=-0.5}, + maxvel = {x=0, y=0, z=-0.75}, + minacc = vector.new(), + maxacc = vector.new(), + minexptime = 0.5, + maxexptime = 1, + minsize = 0.25, + maxsize = 0.5, + texture = 'more_fire_smoke.png',}) + minetest.add_particlespawner({ + amount = 10, + time = 0.25, + minpos = pos, + maxpos = pos, + minvel = {x=-0, y=0, z=-0.5}, + maxvel = {x=0, y=0, z=-0.75}, + minacc = {x=0, y=0, z=-0.75}, + maxacc = {x=-0, y=0, z=-0.5}, + minexptime = 0.25, + maxexptime = 0.5, + minsize = 0.5, + maxsize = 0.75, + texture = 'more_fire_smoke.png',}) + if self.timer>0.2 then + local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 1) + for k, obj in pairs(objs) do + if obj:get_luaentity() ~= nil then + if obj:get_luaentity().name ~= 'more_fire:smokebomb_entity' and obj:get_luaentity().name ~= '__builtin:item' then + if self.node ~= '' then + minetest.sound_play('more_fire_shatter', {gain = 1.0}) + local damage = 1 + obj:punch(self.object, 1.0, { + full_punch_interval=1.0, + damage_groups={fleshy=damage}, + }, nil) + self.object:remove() + end + end + end + end + if self.lastpos.x~=nil then + if node.name ~= 'air' then + self.object:remove() + plume(self.lastpos) + end + end + self.lastpos={x=pos.x, y=pos.y, z=pos.z} + end +end + +minetest.register_entity('more_fire:smokebomb_entity', MORE_FIRE_SMOKEBOMB_ENTITY) + +minetest.override_item('more_fire:smokebomb', {on_use = throw_smokebomb}) + +minetest.register_node('more_fire:plume', { +drawtype = 'plantlike', +description = 'Smoke Plume', + tiles = {{ + name='more_fire_smoke_animated.png', + animation={type='vertical_frames', aspect_w=16, aspect_h=16, length=1}, + }}, + inventory_image = 'more_fire_smoke.png', + light_source = 8, + groups = {dig_immediate=3, not_in_creative_inventory =1, not_in_craft_guide=1}, + drop = '', + walkable = false, + buildable_to = true, + damage_per_second = 1, + on_timer = function(pos, elapsed) + minetest.remove_node(pos) + end, +}) + +minetest.register_abm({ + nodenames={'more_fire:plume'}, + neighbors={'air'}, + interval = 1, + chance = 1, + action = function(pos, node) + if minetest.get_node({x=pos.x, y=pos.y+1.0, z=pos.z}).name == 'air' and + minetest.get_node({x=pos.x, y=pos.y+2.0, z=pos.z}).name == 'air' then + minetest.add_particlespawner({ + amount = 400, + time = 3, + minpos = pos, + maxpos = pos, + minvel = {x=2, y=-0.2, z=2}, + maxvel = {x=-2, y=-0.5, z=-2}, + minacc = {x=0, y=-6, z=0}, + maxacc = {x=0, y=-10, z=0}, + minexptime = 2, + maxexptime = 6, + minsize = 0.05, + maxsize = 0.5, + collisiondetection =false, + texture = 'more_fire_smoke.png'}) + minetest.add_particlespawner({ + amount = 50, + time = 2, + minpos = pos, + maxpos = pos, + minvel = {x=-2, y=0.5, z=-2}, + maxvel = {x=2, y=0.5, z=2}, + minacc = {x=0, y=0.04, z=0}, + maxacc = {x=0, y=0.01, z=0}, + minexptime = 1, + maxexptime = 3, + minsize = 3, + maxsize = 5, + collisiondetection = false, + texture = 'more_fire_smoke.png'}) + minetest.add_particlespawner({ + amount = 400, + time = 2, + minpos = vector.subtract(pos, 5 / 2), + maxpos = vector.add(pos, 5 / 2), + minvel = {x=0.2, y=2, z=0.2}, + maxvel = {x=-0.2, y=2, z=-0.2}, + minacc = {x=10, y= 2, z=10}, + maxacc = {x=-10, y= 1, z=-10}, + minexptime =1, + maxexptime = 3, + minsize = 5, + maxsize = 15, + texture = 'more_fire_smoke.png',}) + end + end +}) + +minetest.register_craft({ + output = 'more_fire:smoke_bomb', + recipe = { + {'more_fire:flintstone'}, + {'more_fire:charcoal'}, + {'vessels:glass_bottle'}, + } +}) diff --git a/mods/more_fire/sounds/more_fire_ignite.0.ogg b/mods/more_fire/sounds/more_fire_ignite.0.ogg new file mode 100644 index 0000000..73494f2 Binary files /dev/null and b/mods/more_fire/sounds/more_fire_ignite.0.ogg differ diff --git a/mods/more_fire/sounds/more_fire_shatter.0.ogg b/mods/more_fire/sounds/more_fire_shatter.0.ogg new file mode 100644 index 0000000..b6cc9e8 Binary files /dev/null and b/mods/more_fire/sounds/more_fire_shatter.0.ogg differ diff --git a/mods/more_fire/sounds/more_fire_shatter.1.ogg b/mods/more_fire/sounds/more_fire_shatter.1.ogg new file mode 100644 index 0000000..2577f40 Binary files /dev/null and b/mods/more_fire/sounds/more_fire_shatter.1.ogg differ diff --git a/mods/more_fire/sounds/spark.ogg b/mods/more_fire/sounds/spark.ogg new file mode 100644 index 0000000..cc35717 Binary files /dev/null and b/mods/more_fire/sounds/spark.ogg differ diff --git a/mods/more_fire/textures/more_fire_gas_can.png b/mods/more_fire/textures/more_fire_gas_can.png new file mode 100644 index 0000000..3e8ccef Binary files /dev/null and b/mods/more_fire/textures/more_fire_gas_can.png differ diff --git a/mods/more_fire/textures/more_fire_molotov_cocktail.png b/mods/more_fire/textures/more_fire_molotov_cocktail.png new file mode 100644 index 0000000..1d18c13 Binary files /dev/null and b/mods/more_fire/textures/more_fire_molotov_cocktail.png differ diff --git a/mods/more_fire/textures/more_fire_oil.png b/mods/more_fire/textures/more_fire_oil.png new file mode 100644 index 0000000..2687f1e Binary files /dev/null and b/mods/more_fire/textures/more_fire_oil.png differ diff --git a/mods/more_fire/textures/more_fire_pipebomb.png b/mods/more_fire/textures/more_fire_pipebomb.png new file mode 100644 index 0000000..3d11fba Binary files /dev/null and b/mods/more_fire/textures/more_fire_pipebomb.png differ diff --git a/mods/more_fire/textures/more_fire_propane_tank.png b/mods/more_fire/textures/more_fire_propane_tank.png new file mode 100644 index 0000000..4c1fe6a Binary files /dev/null and b/mods/more_fire/textures/more_fire_propane_tank.png differ diff --git a/mods/more_fire/textures/more_fire_shatter.png b/mods/more_fire/textures/more_fire_shatter.png new file mode 100644 index 0000000..c68353a Binary files /dev/null and b/mods/more_fire/textures/more_fire_shatter.png differ diff --git a/mods/more_fire/textures/more_fire_smoke.png b/mods/more_fire/textures/more_fire_smoke.png new file mode 100644 index 0000000..362dc74 Binary files /dev/null and b/mods/more_fire/textures/more_fire_smoke.png differ diff --git a/mods/more_fire/textures/more_fire_smokebomb.png b/mods/more_fire/textures/more_fire_smokebomb.png new file mode 100644 index 0000000..bfc3210 Binary files /dev/null and b/mods/more_fire/textures/more_fire_smokebomb.png differ diff --git a/mods/more_fire/textures/more_fire_spark.png b/mods/more_fire/textures/more_fire_spark.png new file mode 100644 index 0000000..b4dddd9 Binary files /dev/null and b/mods/more_fire/textures/more_fire_spark.png differ diff --git a/mods/people/init.lua b/mods/people/init.lua new file mode 100644 index 0000000..d78118d --- /dev/null +++ b/mods/people/init.lua @@ -0,0 +1,55 @@ + +-- People +mobs:register_mob("people:female", { + type = "monster", + passive = false, + attack_type = "dogfight", + pathfinding = true, + reach = 2, + damage = 2, + hp_min = 10, + hp_max = 15, + collisionbox = + { + -.4, 0, -.4, .4, 2, .4 + }, + pushable = true, + visual = "mesh", + mesh = "character.b3d", + textures = + { + {"female_person.png"}, + {"female_person1.png"}, + {"female_person2.png"}, + {"female_person3.png"}, + }, + + makes_footstep_sound = true, + sounds = + { + random = "female_noise", + }, + + walk_velocity = 2, + run_velocity = 8, + jump_height = 1, + stepheight = 0, + floats = 0, + view_range = 45, + fall_damage = true, + + + animation = + { + speed_normal = 30, + speed_run = 50, + stand_start = 0, + stand_end = 79, + walk_start = 168, + walk_end = 187, + run_start = 168, + run_end = 187, + punch_start = 200, + punch_end = 219 + }, +}) \ No newline at end of file diff --git a/mods/people/mod.conf b/mods/people/mod.conf new file mode 100644 index 0000000..e3458e6 --- /dev/null +++ b/mods/people/mod.conf @@ -0,0 +1,2 @@ +name = people +depends = mobs \ No newline at end of file diff --git a/mods/people/textures/female_person.png b/mods/people/textures/female_person.png new file mode 100644 index 0000000..0222153 Binary files /dev/null and b/mods/people/textures/female_person.png differ diff --git a/mods/people/textures/female_person1.png b/mods/people/textures/female_person1.png new file mode 100644 index 0000000..e436313 Binary files /dev/null and b/mods/people/textures/female_person1.png differ diff --git a/mods/people/textures/female_person2.png b/mods/people/textures/female_person2.png new file mode 100644 index 0000000..3e86e69 Binary files /dev/null and b/mods/people/textures/female_person2.png differ diff --git a/mods/people/textures/female_person3.png b/mods/people/textures/female_person3.png new file mode 100644 index 0000000..e9544d5 Binary files /dev/null and b/mods/people/textures/female_person3.png differ diff --git a/mods/people/textures/male_person.png b/mods/people/textures/male_person.png new file mode 100644 index 0000000..683d3f2 Binary files /dev/null and b/mods/people/textures/male_person.png differ diff --git a/mods/people/textures/male_person1.png b/mods/people/textures/male_person1.png new file mode 100644 index 0000000..f930bcb Binary files /dev/null and b/mods/people/textures/male_person1.png differ diff --git a/mods/people/textures/male_person2.png b/mods/people/textures/male_person2.png new file mode 100644 index 0000000..17f9394 Binary files /dev/null and b/mods/people/textures/male_person2.png differ diff --git a/mods/player_api/README.txt b/mods/player_api/README.txt new file mode 100644 index 0000000..37afadf --- /dev/null +++ b/mods/player_api/README.txt @@ -0,0 +1,27 @@ +Minetest Game mod: player_api +============================= +See license.txt for license information. + +Provides an API to allow multiple mods to set player models and textures. +Also sets the default model, texture, and player flags. +This mod is only for content related to the Player API and the player object. + +Authors of source code +---------------------- +Originally by celeron55, Perttu Ahola (LGPLv2.1+) +Various Minetest developers and contributors (LGPLv2.1+) + +Authors of media (textures, models and sounds) +---------------------------------------------- +Original model by MirceaKitsune (CC BY-SA 3.0). +Various alterations and fixes by kilbith, sofar, xunto, Rogier-5, TeTpaAka, Desour, +stujones11, An0n3m0us (CC BY-SA 3.0): + character.b3d + character.blend + +Jordach (CC BY-SA 3.0): + character.png + +celeron55, Perttu Ahola (CC BY-SA 3.0): + player.png + player_back.png diff --git a/mods/player_api/api.lua b/mods/player_api/api.lua new file mode 100644 index 0000000..e39847d --- /dev/null +++ b/mods/player_api/api.lua @@ -0,0 +1,228 @@ +player_api = {} + +-- Player animation blending +-- Note: This is currently broken due to a bug in Irrlicht, leave at 0 +local animation_blend = 0 + +player_api.registered_models = {} + +-- Local for speed. +local models = player_api.registered_models + +local function collisionbox_equals(collisionbox, other_collisionbox) + if collisionbox == other_collisionbox then + return true + end + for index = 1, 6 do + if collisionbox[index] ~= other_collisionbox[index] then + return false + end + end + return true +end + +function player_api.register_model(name, def) + models[name] = def + def.visual_size = def.visual_size or {x = 1, y = 1} + def.collisionbox = def.collisionbox or {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3} + def.stepheight = def.stepheight or 0.6 + def.eye_height = def.eye_height or 1.47 + + -- Sort animations into property classes: + -- Animations with same properties have the same _equals value + for animation_name, animation in pairs(def.animations) do + animation.eye_height = animation.eye_height or def.eye_height + animation.collisionbox = animation.collisionbox or def.collisionbox + animation.override_local = animation.override_local or false + + for _, other_animation in pairs(def.animations) do + if other_animation._equals then + if collisionbox_equals(animation.collisionbox, other_animation.collisionbox) + and animation.eye_height == other_animation.eye_height then + animation._equals = other_animation._equals + break + end + end + end + animation._equals = animation._equals or animation_name + end +end + +-- Player stats and animations +-- model, textures, animation +local players = {} +player_api.player_attached = {} + +local function get_player_data(player) + return assert(players[player:get_player_name()]) +end + +function player_api.get_animation(player) + return get_player_data(player) +end + +-- Called when a player's appearance needs to be updated +function player_api.set_model(player, model_name) + local player_data = get_player_data(player) + if player_data.model == model_name then + return + end + player_data.model = model_name + + local model = models[model_name] + if model then + player:set_properties({ + mesh = model_name, + textures = player_data.textures or model.textures, + visual = "mesh", + visual_size = model.visual_size, + stepheight = model.stepheight + }) + -- sets local_animation, collisionbox & eye_height + player_api.set_animation(player, "stand") + else + player:set_properties({ + textures = {"player.png", "player_back.png"}, + visual = "upright_sprite", + visual_size = {x = 1, y = 2}, + collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.75, 0.3}, + stepheight = 0.6, + eye_height = 1.625, + }) + end +end + +function player_api.get_textures(player) + local player_data = get_player_data(player) + local model = models[player_data.model] + return assert(player_data.textures or (model and model.textures)) +end + +function player_api.set_textures(player, textures) + local player_data = get_player_data(player) + local model = models[player_data.model] + local new_textures = assert(textures or (model and model.textures)) + player_data.textures = new_textures + player:set_properties({textures = new_textures}) +end + +function player_api.set_texture(player, index, texture) + local textures = table.copy(player_api.get_textures(player)) + textures[index] = texture + player_api.set_textures(player, textures) +end + +function player_api.set_animation(player, anim_name, speed) + local player_data = get_player_data(player) + local model = models[player_data.model] + if not (model and model.animations[anim_name]) then + return + end + speed = speed or model.animation_speed + if player_data.animation == anim_name and player_data.animation_speed == speed then + return + end + local previous_anim = model.animations[player_data.animation] or {} + local anim = model.animations[anim_name] + player_data.animation = anim_name + player_data.animation_speed = speed + -- If necessary change the local animation (only seen by the client of *that* player) + -- `override_local` <=> suspend local animations while this one is active + -- (this is basically a hack, proper engine feature needed...) + if anim.override_local ~= previous_anim.override_local then + if anim.override_local then + local none = {x=0, y=0} + player:set_local_animation(none, none, none, none, 1) + else + local a = model.animations -- (not specific to the animation being set) + player:set_local_animation( + a.stand, a.walk, a.mine, a.walk_mine, + model.animation_speed or 30 + ) + end + end + -- Set the animation seen by everyone else + player:set_animation(anim, speed, animation_blend) + -- Update related properties if they changed + if anim._equals ~= previous_anim._equals then + player:set_properties({ + collisionbox = anim.collisionbox, + eye_height = anim.eye_height + }) + end +end + +minetest.register_on_joinplayer(function(player) + local name = player:get_player_name() + players[name] = {} + player_api.player_attached[name] = false +end) + +minetest.register_on_leaveplayer(function(player) + local name = player:get_player_name() + players[name] = nil + player_api.player_attached[name] = nil +end) + +-- Localize for better performance. +local player_set_animation = player_api.set_animation +local player_attached = player_api.player_attached + +-- Prevent knockback for attached players +local old_calculate_knockback = minetest.calculate_knockback +function minetest.calculate_knockback(player, ...) + if player_attached[player:get_player_name()] then + return 0 + end + return old_calculate_knockback(player, ...) +end + +-- Check each player and apply animations +function player_api.globalstep() + for _, player in ipairs(minetest.get_connected_players()) do + local name = player:get_player_name() + local player_data = players[name] + local model = player_data and models[player_data.model] + if model and not player_attached[name] then + local controls = player:get_player_control() + local animation_speed_mod = model.animation_speed or 30 + + -- Determine if the player is sneaking, and reduce animation speed if so + if controls.sneak then + animation_speed_mod = animation_speed_mod / 2 + end + + -- Apply animations based on what the player is doing + if player:get_hp() == 0 then + player_set_animation(player, "lay") + elseif controls.up or controls.down or controls.left or controls.right then + if controls.LMB or controls.RMB then + player_set_animation(player, "walk_mine", animation_speed_mod) + else + player_set_animation(player, "walk", animation_speed_mod) + end + elseif controls.LMB or controls.RMB then + player_set_animation(player, "mine", animation_speed_mod) + else + player_set_animation(player, "stand", animation_speed_mod) + end + end + end +end + +-- Mods can modify the globalstep by overriding player_api.globalstep +minetest.register_globalstep(function(...) + player_api.globalstep(...) +end) + +for _, api_function in pairs({"get_animation", "set_animation", "set_model", "set_textures"}) do + local original_function = player_api[api_function] + player_api[api_function] = function(player, ...) + if not players[player:get_player_name()] then + -- HACK for keeping backwards compatibility + minetest.log("warning", api_function .. " called on offline player") + return + end + return original_function(player, ...) + end +end diff --git a/mods/player_api/init.lua b/mods/player_api/init.lua new file mode 100644 index 0000000..f258aea --- /dev/null +++ b/mods/player_api/init.lua @@ -0,0 +1,26 @@ +dofile(minetest.get_modpath("player_api") .. "/api.lua") + +-- Default player appearance +player_api.register_model("character.b3d", { + animation_speed = 30, + textures = {"character.png"}, + animations = { + -- Standard animations. + stand = {x = 0, y = 79}, + lay = {x = 162, y = 166, eye_height = 0.3, override_local = true, + collisionbox = {-0.6, 0.0, -0.6, 0.6, 0.3, 0.6}}, + walk = {x = 168, y = 187}, + mine = {x = 189, y = 198}, + walk_mine = {x = 200, y = 219}, + sit = {x = 81, y = 160, eye_height = 0.8, override_local = true, + collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.0, 0.3}} + }, + collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3}, + stepheight = 0.6, + eye_height = 1.47, +}) + +-- Update appearance when the player joins +minetest.register_on_joinplayer(function(player) + player_api.set_model(player, "character.b3d") +end) diff --git a/mods/player_api/license.txt b/mods/player_api/license.txt new file mode 100644 index 0000000..bdc4315 --- /dev/null +++ b/mods/player_api/license.txt @@ -0,0 +1,60 @@ +License of source code +---------------------- + +GNU Lesser General Public License, version 2.1 +Copyright (C) 2011 celeron55, Perttu Ahola +Copyright (C) 2011 Various Minetest developers and contributors + +This program is free software; you can redistribute it and/or modify it under the terms +of the GNU Lesser General Public License as published by the Free Software Foundation; +either version 2.1 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU Lesser General Public License for more details: +https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html + + +Licenses of media (textures, models and sounds) +----------------------------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2011 celeron55, Perttu Ahola +Copyright (C) 2012 MirceaKitsune +Copyright (C) 2012 Jordach +Copyright (C) 2015 kilbith +Copyright (C) 2016 sofar +Copyright (C) 2016 xunto +Copyright (C) 2016 Rogier-5 +Copyright (C) 2017 TeTpaAka +Copyright (C) 2017 Desour +Copyright (C) 2018 stujones11 +Copyright (C) 2019 An0n3m0us + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/mods/player_api/mod.conf b/mods/player_api/mod.conf new file mode 100644 index 0000000..bf62327 --- /dev/null +++ b/mods/player_api/mod.conf @@ -0,0 +1,2 @@ +name = player_api +description = Minetest Game mod: Manages player visuals diff --git a/mods/player_api/models/character.b3d b/mods/player_api/models/character.b3d new file mode 100644 index 0000000..3e0827e Binary files /dev/null and b/mods/player_api/models/character.b3d differ diff --git a/mods/player_api/models/character.blend b/mods/player_api/models/character.blend new file mode 100644 index 0000000..a32c343 Binary files /dev/null and b/mods/player_api/models/character.blend differ diff --git a/mods/player_api/models/character.png b/mods/player_api/models/character.png new file mode 100644 index 0000000..0502178 Binary files /dev/null and b/mods/player_api/models/character.png differ diff --git a/mods/player_api/textures/player.png b/mods/player_api/textures/player.png new file mode 100644 index 0000000..6d61c43 Binary files /dev/null and b/mods/player_api/textures/player.png differ diff --git a/mods/player_api/textures/player_back.png b/mods/player_api/textures/player_back.png new file mode 100644 index 0000000..5e9ef05 Binary files /dev/null and b/mods/player_api/textures/player_back.png differ diff --git a/mods/roads/asphalt/depends.txt b/mods/roads/asphalt/depends.txt new file mode 100644 index 0000000..49d2dc1 --- /dev/null +++ b/mods/roads/asphalt/depends.txt @@ -0,0 +1,2 @@ +streetsmod +building_blocks? \ No newline at end of file diff --git a/mods/roads/asphalt/init.lua b/mods/roads/asphalt/init.lua new file mode 100644 index 0000000..958cfd5 --- /dev/null +++ b/mods/roads/asphalt/init.lua @@ -0,0 +1,27 @@ +--[[ + Streets Mod: All kinds of asphalt +]] +minetest.register_node(":streets:asphalt",{ + description = streets.S("Asphalt"), + tiles = {"streets_asphalt.png"}, + groups = {cracky=3} +}) + +if minetest.get_modpath("building_blocks") then + minetest.register_craft({ + type = "shapeless", + output = "streets:asphalt 3", + recipe = { + "default:sand", + "default:gravel", + "building_blocks:Tar" + }, + }) +else + minetest.register_craft({ + type = "cooking", + output = "streets:asphalt", + recipe = "default:gravel", + cooktime = 2 + }) +end diff --git a/mods/roads/constructionarea/depends.txt b/mods/roads/constructionarea/depends.txt new file mode 100644 index 0000000..17850de --- /dev/null +++ b/mods/roads/constructionarea/depends.txt @@ -0,0 +1,2 @@ +streetsmod +wool? \ No newline at end of file diff --git a/mods/roads/constructionarea/init.lua b/mods/roads/constructionarea/init.lua new file mode 100644 index 0000000..9b1aefe --- /dev/null +++ b/mods/roads/constructionarea/init.lua @@ -0,0 +1,70 @@ +minetest.register_node(":streets:constructionfence_bottom",{ + description = streets.S("Construction fence"), + tiles = {"streets_fence_fromtop.png","streets_fence_fromtop.png","streets_fence_fromtop.png","streets_fence_fromtop.png","streets_fence_bottom.png","streets_fence_bottom.png"}, + groups = {cracky = 2, disable_jump = 1}, + paramtype = "light", + inventory_image = "streets_fence_inv.png", + wield_image = "streets_fence_inv.png", + paramtype2 = "facedir", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.5,-0.5,-0.1,0.5,0.0,0.1}, -- lower part + {-0.2,-0.0,-0.1,0.2,0.5,0.1} -- thing in the middle + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5,-0.5,-0.1,0.5,1.0,0.1} + } + }, + after_dig_node = function(pos,node,digger) + pos.y = pos.y + 1 + minetest.remove_node(pos) + end, + after_place_node = function(pos,placer,itemstack) + pos.y = pos.y + 1 + if minetest.get_node(pos).name == "air" then + minetest.add_node(pos,{name = "streets:constructionfence_top", param2 = minetest.dir_to_facedir(placer:get_look_dir())}) + else + minetest.chat_send_player(placer:get_player_name(),"Not enough free space! A construction fence has a height of 2 blocks!") + end + end +}) + +minetest.register_node(":streets:constructionfence_top",{ + description = streets.S("Construction fence"), + tiles = {"streets_fence_fromtop.png","streets_fence_fromtop.png","streets_fence_fromtop.png","streets_fence_fromtop.png","streets_fence_top.png","streets_fence_top.png"}, + groups = {cracky = 2, not_in_creative_inventory = 1, disable_jump = 1}, + paramtype = "light", + paramtype2 = "facedir", + drawtype = "nodebox", + drop = "streets:constructionfence_bottom", + node_box = { + type = "fixed", + fixed = { + {-0.5,-0.5,-0.1,0.5,0.0,0.1} -- upper part + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5,-1.5,-0.1,0.5,0.0,0.1} + } + }, + after_dig_node = function(pos,node,digger) + pos.y = pos.y - 1 + minetest.remove_node(pos) + end +}) + +minetest.register_craft({ + output = "streets:constructionfence_bottom 8", + recipe = { + {"","",""}, + {"","streets:sign_construction",""}, + {"wool:red","wool:white","wool:red"} + } +}) \ No newline at end of file diff --git a/mods/roads/delineator/depends.txt b/mods/roads/delineator/depends.txt new file mode 100644 index 0000000..48ef5e1 --- /dev/null +++ b/mods/roads/delineator/depends.txt @@ -0,0 +1,2 @@ +default +streetsmod \ No newline at end of file diff --git a/mods/roads/delineator/init.lua b/mods/roads/delineator/init.lua new file mode 100644 index 0000000..cf78142 --- /dev/null +++ b/mods/roads/delineator/init.lua @@ -0,0 +1,27 @@ +--[[ + StreetsMod: Delineator +]] +minetest.register_node(":streets:delineator", { + description = streets.S("Delineator"), + tiles = {"streets_delineator_top.png","streets_delineator.png"}, + drawtype = "nodebox", + paramtype = "light", + groups = {cracky=3, oddly_breakable_by_hand=2}, + light_source = 8, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = { + {-0.1, -0.5, -0.1, 0.1, 0.5, 0.1}, + }, + } +}) + +minetest.register_craft({ + output = "streets:delineator 4", + recipe = { + {"","",""}, + {"","default:torch",""}, + {"","default:fence_wood",""} + } +}) \ No newline at end of file diff --git a/mods/roads/description.txt b/mods/roads/description.txt new file mode 100644 index 0000000..a98b6c0 --- /dev/null +++ b/mods/roads/description.txt @@ -0,0 +1 @@ +webdesigner97's "streets" and ragnarok's "infrastructure" put together, then some changes on top of that... diff --git a/mods/roads/emergencyphone/depends.txt b/mods/roads/emergencyphone/depends.txt new file mode 100644 index 0000000..421a27d --- /dev/null +++ b/mods/roads/emergencyphone/depends.txt @@ -0,0 +1 @@ +streetsmod \ No newline at end of file diff --git a/mods/roads/emergencyphone/init.lua b/mods/roads/emergencyphone/init.lua new file mode 100644 index 0000000..8c25c65 --- /dev/null +++ b/mods/roads/emergencyphone/init.lua @@ -0,0 +1,25 @@ +--[[ + StreetsMod: Emergency Phone +]] +minetest.register_node(":streets:emergencyphone",{ + description = streets.S("Emergency Phone"), + tiles = {"streets_sos_top.png","streets_sos_bottom.png","streets_sos_side.png","streets_sos_side.png","streets_sos_side.png","streets_sos_front.png"}, + groups = {cracky = 3}, + paramtype2 = "facedir", + light_source = 5, + on_rightclick = function(pos,node,clicker) + if clicker:is_player() and clicker:get_hp() < 6 then + clicker:set_hp(6) + minetest.log("action",clicker:get_player_name() .. " healed by emergency phone at pos " .. minetest.pos_to_string(pos) .. "") + end + end + }) + minetest.register_alias("streets:emergency_phone","streets:emergencyphone") +minetest.register_craft({ + output = "streets:emergencyphone", + recipe = { + {"wool:orange","default:torch","wool:orange"}, + {"wool:orange","default:apple","wool:orange"}, + {"default:steel_ingot","default:diamondblock","default:steel_ingot"} + } +}) \ No newline at end of file diff --git a/mods/roads/infrastructure/advanced_aircraft_warning_light.lua b/mods/roads/infrastructure/advanced_aircraft_warning_light.lua new file mode 100644 index 0000000..1361f7b --- /dev/null +++ b/mods/roads/infrastructure/advanced_aircraft_warning_light.lua @@ -0,0 +1,55 @@ +-- Aircraft warning light +minetest.register_node("infrastructure:aircraft_warning_light", { + description = "Aircraft warning light", + tiles = { + {name="infrastructure_aircraft_warning_light_top_anim.png",animation={type="vertical_frames", aspect_w=32, aspect_h=32, length=4}}, + "infrastructure_traffic_lights_side.png", + {name="infrastructure_aircraft_warning_light_side_anim.png",animation={type="vertical_frames", aspect_w=32, aspect_h=32, length=4}}, + {name="infrastructure_aircraft_warning_light_side_anim.png",animation={type="vertical_frames", aspect_w=32, aspect_h=32, length=4}}, + {name="infrastructure_aircraft_warning_light_side_anim.png",animation={type="vertical_frames", aspect_w=32, aspect_h=32, length=4}}, + {name="infrastructure_aircraft_warning_light_side_anim.png",animation={type="vertical_frames", aspect_w=32, aspect_h=32, length=4}} + }, + drawtype = "nodebox", + paramtype = "light", + groups = {cracky = 1}, + light_source = AIRCRAFT_WARNING_LIGHT_LIGHT_RANGE, + node_box = { + type = "fixed", + fixed = { + {-1/128, 1/4, -1/128, 1/128, 3/8, 1/128}, + + {-1/4, -1/8, 0, 1/4, 1/4, 0}, + {0, -1/8, -1/4, 0, 1/4, 1/4}, + + {-1/16, -1/8, -1/16, 1/16, 1/16, 1/16}, + + {-1/4, -1/4, -1/8, 1/4, -1/8, 1/8}, + {-1/8, -1/4, -1/4, 1/8, -1/8, 1/4}, + + {-1/8, -3/8, -1/8, 1/8, -1/4, 1/8}, + + {-3/16, -1/2, -3/16, 3/16, -3/8, 3/16} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/128, 1/4, -1/128, 1/128, 3/8, 1/128}, + + {-1/4, -1/8, 0, 1/4, 1/4, 0}, + {0, -1/8, -1/4, 0, 1/4, 1/4}, + + {-1/16, -1/8, -1/16, 1/16, 1/16, 1/16}, + + {-1/4, -1/4, -1/8, 1/4, -1/8, 1/8}, + {-1/8, -1/4, -1/4, 1/8, -1/8, 1/4}, + + {-1/8, -3/8, -1/8, 1/8, -1/4, 1/8}, + + {-3/16, -1/2, -3/16, 3/16, -3/8, 3/16} + } + } +}) + +minetest.register_alias("infrastructure:aircraft_warning_light_bright", "infrastructure:aircraft_warning_light") +minetest.register_alias("infrastructure:aircraft_warning_light_dark", "infrastructure:aircraft_warning_light") diff --git a/mods/roads/infrastructure/advanced_automatic_warning_device.lua b/mods/roads/infrastructure/advanced_automatic_warning_device.lua new file mode 100644 index 0000000..574fc0d --- /dev/null +++ b/mods/roads/infrastructure/advanced_automatic_warning_device.lua @@ -0,0 +1,463 @@ +-- Automatic warning device + +infrastructure.sound_handles = {} + +function infrastructure.play_bell(pos) + local pos_hash = minetest.hash_node_position(pos) + if not infrastructure.sound_handles[pos_hash] then + infrastructure.sound_handles[pos_hash] = minetest.sound_play("infrastructure_ebell", + {pos = pos, gain = AUTOMATIC_WARNING_DEVICE_VOLUME, loop = true, max_hear_distance = 30,}) + end +end + +function infrastructure.stop_bell(pos) + local pos_hash = minetest.hash_node_position(pos) + local sound_handle = infrastructure.sound_handles[pos_hash] + if sound_handle then + minetest.sound_stop(sound_handle) + infrastructure.sound_handles[pos_hash] = nil + end +end +function infrastructure.left_light_direction(pos, param2) + if param2 == 0 then + pos.x = pos.x - 1 + elseif param2 == 1 then + pos.z = pos.z + 1 + elseif param2 == 2 then + pos.x = pos.x + 1 + elseif param2 == 3 then + pos.z = pos.z - 1 + end +end + +function infrastructure.right_light_direction(pos, param2) + if param2 == 0 then + pos.x = pos.x + 2 + elseif param2 == 1 then + pos.z = pos.z - 2 + elseif param2 == 2 then + pos.x = pos.x - 2 + elseif param2 == 3 then + pos.z = pos.z + 2 + end +end + +function infrastructure.lights_enabled(pos) + local node = minetest.get_node(pos) + local param2 = node.param2 + minetest.swap_node(pos, {name = "infrastructure:automatic_warning_device_middle_center_on", param2 = node.param2}) + infrastructure.left_light_direction(pos, param2) + minetest.swap_node(pos, {name = "infrastructure:automatic_warning_device_middle_left_on", param2 = node.param2}) + infrastructure.right_light_direction(pos, param2) + minetest.swap_node(pos, {name = "infrastructure:automatic_warning_device_middle_right_on", param2 = node.param2}) +end + +function infrastructure.lights_disabled(pos) + local node = minetest.get_node(pos) + local param2 = node.param2 + minetest.swap_node(pos, {name = "infrastructure:automatic_warning_device_middle_center_off", param2 = node.param2}) + infrastructure.left_light_direction(pos, param2) + minetest.swap_node(pos, {name = "infrastructure:automatic_warning_device_middle_left_off", param2 = node.param2}) + infrastructure.right_light_direction(pos, param2) + minetest.swap_node(pos, {name = "infrastructure:automatic_warning_device_middle_right_off", param2 = node.param2}) +end + +function infrastructure.activate_lights(pos) + pos.y = pos.y + 2 + local node = minetest.get_node(pos) + if node.name == "infrastructure:automatic_warning_device_middle_center_off" then + infrastructure.play_bell(pos) + infrastructure.lights_enabled(pos) + elseif (node.name == "infrastructure:automatic_warning_device_middle_center_on") then + infrastructure.stop_bell(pos,node) + infrastructure.lights_disabled(pos, node) + end +end + +minetest.register_node("infrastructure:automatic_warning_device_top", { + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_automatic_warning_device_top_side.png", + "infrastructure_automatic_warning_device_top_side.png", + "infrastructure_automatic_warning_device_top_side.png", + "infrastructure_automatic_warning_device_top.png" + }, + on_destruct = stop_bell, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 3, not_in_creative_inventory = 1}, + node_box = { + type = "fixed", + fixed = { + {-1/16, -1/2, -1/16, 1/16, 0, 1/16}, + {-1/8, 0, -1/8, 1/8, 3/8, 1/8}, + {-1/4, 1/8, -1/4, 1/4, 1/4, 1/4}, + {-1/2, -1/2, -1/16, 1/2, 0, -1/16}, + {-1/8, -1/2, -1/16, 1/8, -1/4, 1/8} + } + }, + selection_box = { + type = "fixed", + fixed = {0, 0, 0, 0, 0, 0} + } +}) + +minetest.register_node("infrastructure:automatic_warning_device_middle_right_on", { + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_automatic_warning_device_middle_right_side.png", + {name="infrastructure_automatic_warning_device_middle_right_anim.png",animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.5}} + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + light_source = AUTOMATIC_WARNING_DEVICE_LIGHT_RANGE, + node_box = { + type = "fixed", + fixed = { + {-1/2, -1/2, -1/16, -1/4, 1/2, -1/16}, + {-1/2, -5/16, -1/16, -7/16, 1/16, 3/16}, + {-1/2, 1/32, -5/16, -15/32, 3/32, -1/16}, + {-15/32, -1/8, -3/16, -13/32, 1/32, -1/16} + } + }, + selection_box = { + type = "fixed", + fixed = {0, 0, 0, 0, 0, 0} + } +}) + +minetest.register_node("infrastructure:automatic_warning_device_middle_right_off", { + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_automatic_warning_device_middle_right_side.png", + "infrastructure_automatic_warning_device_middle_right_off.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-1/2, -1/2, -1/16, -1/4, 1/2, -1/16}, + {-1/2, -5/16, -1/16, -7/16, 1/16, 3/16}, + {-1/2, 1/32, -5/16, -15/32, 3/32, -1/16}, + {-15/32, -1/8, -3/16, -13/32, 1/32, -1/16} + } + }, + selection_box = { + type = "fixed", + fixed = {0, 0, 0, 0, 0, 0} + } +}) + +minetest.register_node("infrastructure:automatic_warning_device_middle_left_on", { + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_automatic_warning_device_middle_left_side.png", + {name="infrastructure_automatic_warning_device_middle_left_anim.png",animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.5}} + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + light_source = AUTOMATIC_WARNING_DEVICE_LIGHT_RANGE, + node_box = { + type = "fixed", + fixed = { + {1/4, -1/2, -1/16, 1/2, 1/2, -1/16}, + {7/16, -5/16, -1/16, 1/2, 1/16, 3/16}, + {15/32, 1/32, -5/16, 1/2, 3/32, -1/16}, + {13/32, -1/8, -3/16, 15/32, 1/32, -1/16} + } + }, + selection_box = { + type = "fixed", + fixed = {0, 0, 0, 0, 0, 0} + } +}) + +minetest.register_node("infrastructure:automatic_warning_device_middle_left_off", { + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_automatic_warning_device_middle_left_side.png", + "infrastructure_automatic_warning_device_middle_left_off.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {1/4, -1/2, -1/16, 1/2, 1/2, -1/16}, + {7/16, -5/16, -1/16, 1/2, 1/16, 3/16}, + {15/32, 1/32, -5/16, 1/2, 3/32, -1/16}, + {13/32, -1/8, -3/16, 15/32, 1/32, -1/16} + } + }, + selection_box = { + type = "fixed", + fixed = {0, 0, 0, 0, 0, 0} + } +}) + +minetest.register_node("infrastructure:automatic_warning_device_middle_center_on", { + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_automatic_warning_device_middle_center_side.png", + "infrastructure_automatic_warning_device_middle_center_side.png", + "infrastructure_automatic_warning_device_middle_center_side.png", + {name="infrastructure_automatic_warning_device_middle_center_anim.png",animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.5}} + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + light_source = AUTOMATIC_WARNING_DEVICE_LIGHT_RANGE, + node_box = { + type = "fixed", + fixed = { + {-1/16, -1/2, -1/16, 1/16, 1/2, 1/16}, + {-1/2, -1/2, -1/16, 1/2, 1/2, -1/16}, + {-1/2, -5/16, -1/16, -3/16, 1/16, 3/16}, + {3/16, -5/16, -1/16, 1/2, 1/16, 3/16}, + {-3/16, -3/16, -1/16, 3/16, -1/16, 1/8}, + {-1/2, 1/32, -5/16, -7/32, 3/32, -1/16}, + {-7/32, -1/8, -3/16, -5/32, 1/32, -1/16}, + {7/32, 1/32, -5/16, 1/2, 3/32, -1/16}, + {5/32, -1/8, -3/16, 7/32, 1/32, -1/16} + } + }, + selection_box = { + type = "fixed", + fixed = {0, 0, 0, 0, 0, 0} + } +}) + + +minetest.register_node("infrastructure:automatic_warning_device_middle_center_off", { + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_automatic_warning_device_middle_center_side.png", + "infrastructure_automatic_warning_device_middle_center_side.png", + "infrastructure_automatic_warning_device_middle_center_side.png", + "infrastructure_automatic_warning_device_middle_center_off.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-1/16, -1/2, -1/16, 1/16, 1/2, 1/16}, + {-1/2, -1/2, -1/16, 1/2, 1/2, -1/16}, + {-1/2, -5/16, -1/16, -3/16, 1/16, 3/16}, + {3/16, -5/16, -1/16, 1/2, 1/16, 3/16}, + {-3/16, -3/16, -1/16, 3/16, -1/16, 1/8}, + {-1/2, 1/32, -5/16, -7/32, 3/32, -1/16}, + {-7/32, -1/8, -3/16, -5/32, 1/32, -1/16}, + {7/32, 1/32, -5/16, 1/2, 3/32, -1/16}, + {5/32, -1/8, -3/16, 7/32, 1/32, -1/16} + } + }, + selection_box = { + type = "fixed", + fixed = {0, 0, 0, 0, 0, 0} + } +}) + + +minetest.register_node("infrastructure:automatic_warning_device_middle", { + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_automatic_warning_device_middle_side.png", + "infrastructure_automatic_warning_device_middle_side.png", + "infrastructure_automatic_warning_device_middle_side.png", + "infrastructure_automatic_warning_device_middle.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 3, not_in_creative_inventory = 1}, + node_box = { + type = "fixed", + fixed = { + {-1/16, -1/2, -1/16, 1/16, 1/2, 1/16}, + {-3/8, -3/8, -1/8, 3/8, 3/8, -1/16}, + {-1/8, -1/8, -1/16, 1/8, 1/8, 1/8} + } + }, + selection_box = { + type = "fixed", + fixed = {0, 0, 0, 0, 0, 0} + } +}) + +minetest.register_node("infrastructure:automatic_warning_device_bottom", { + description = "Automatic warning device", + inventory_image = "infrastructure_automatic_warning_device.png", + wield_image = "infrastructure_automatic_warning_device.png", + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_automatic_warning_device_bottom.png", + "infrastructure_automatic_warning_device_bottom.png", + "infrastructure_automatic_warning_device_bottom.png", + "infrastructure_automatic_warning_device_bottom.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 3}, + node_box = { + type = "fixed", + fixed = { + {-1/16, 0, -1/16, 1/16, 1/2, 1/16}, + {-1/2, -1/2, -1/4, 1/2, -3/8, 1/4}, + {-1/4, -1/2, -1/2, 1/4, -3/8, 1/2}, + {-1/8, -3/8, -1/8, 1/8, 0, 1/8} + } + }, + selection_box = { + type = "fixed", + fixed = { + -- top + {-1/8, 0 + 3, -1/8, 1/8, 3/8 + 3, 1/8}, + {-1/4, 1/8 + 3, -1/4, 1/4, 1/4 + 3, 1/4}, + {-1/8, -1/2 + 3, -1/16 + 0.01, 1/8, -1/4 + 3, 1/8}, + -- middle center, left and right + {-9/16, -5/16 + 2, -1/16, -3/16, 1/16 + 2, 3/16}, + {3/16, -5/16 + 2, -1/16, 9/16, 1/16 + 2, 3/16}, + + {-3/16, -3/16 + 2, -1/16 + 0.01, 3/16, -1/16 + 2, 1/8}, + + {-1/2, 1/32 + 2, -5/16, -7/32, 3/32 + 2, -1/16 - 0.01}, + {-7/32, -1/8 + 2, -3/16, -5/32, 1/32 + 2, -1/16 - 0.01}, + {13/32 - 1, -1/8 + 2, -3/16, 15/32 - 1, 1/32 + 2, -1/16 - 0.01}, + + {7/32, 1/32 + 2, -5/16, 1/2, 3/32 + 2, -1/16 - 0.01}, + {5/32, -1/8 + 2, -3/16, 7/32, 1/32 + 2, -1/16 - 0.01}, + {-15/32 + 1, -1/8 + 2, -3/16, -13/32 + 1, 1/32 + 2, -1/16 - 0.01}, + -- middle + {-3/8, -3/8 + 1, -1/8, 3/8, 3/8 + 1, -1/16}, + {-1/8, -1/8 + 1, -1/16, 1/8, 1/8 + 1, 1/8}, + -- bottom + {-1/2, -1/2, -1/4, 1/2, -3/8, 1/4}, + {-1/4, -1/2, -1/2, 1/4, -3/8, 1/2}, + {-1/8, -3/8, -1/8, 1/8, 0, 1/8}, + -- post + {-1/16, 0, -1/16, 1/16, 3, 1/16} + } + }, + + on_construct = function(pos) + local node = minetest.get_node(pos) + local param2 = node.param2 + + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + + pos.y = pos.y + 1 + node.name = "infrastructure:automatic_warning_device_middle" + minetest.set_node(pos, node) + + pos.y = pos.y + 2 + node.name = "infrastructure:automatic_warning_device_top" + minetest.set_node(pos, node) + + pos.y = pos.y - 1 + node.name = "infrastructure:automatic_warning_device_middle_center_1" + minetest.set_node(pos, node) + + infrastructure.left_light_direction(pos, param2) + node.name = "infrastructure:automatic_warning_device_middle_left_1" + minetest.set_node(pos, node) + + infrastructure.right_light_direction(pos, param2) + node.name = "infrastructure:automatic_warning_device_middle_right_1" + minetest.set_node(pos, node) + end, + + on_destruct = function(pos) + local node = minetest.get_node(pos) + local param2 = node.param2 + pos.y=pos.y+2 + infrastructure.stop_bell(pos, node) + pos.y=pos.y-2 + + for i = 1, 3 do + pos.y = pos.y + 1 + minetest.remove_node(pos) + end + + pos.y = pos.y - 1 + + infrastructure.left_light_direction(pos, param2) + minetest.remove_node(pos) + + infrastructure.right_light_direction(pos, param2) + minetest.remove_node(pos) + end, + + on_punch = function(pos, node) + infrastructure.activate_lights(pos, node) + end, + + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, + + digiline = { + receptor = {}, + effector = { + action = function(pos, node, channel, msg) + local setchan = minetest.get_meta(pos):get_string("channel") + if setchan ~= channel then + return + end + if (msg=="bell_on") then + infrastructure.play_bell(pos) + elseif (msg=="bell_off") then + infrastructure.stop_bell(pos) + elseif (msg=="lights_on") then + pos.y = pos.y+2 + infrastructure.lights_enabled(pos) + elseif (msg=="lights_off") then + pos.y = pos.y+2 + infrastructure.lights_disabled(pos) + end + end + } + } +}) + + + + +minetest.register_alias("infrastructure:automatic_warning_device", "infrastructure:automatic_warning_device_bottom") +minetest.register_alias("awd", "infrastructure:automatic_warning_device_bottom") +minetest.register_alias("infrastructure:automatic_warning_device_middle_left_1","infrastructure:automatic_warning_device_middle_left_off") +minetest.register_alias("infrastructure:automatic_warning_device_middle_left_2","infrastructure:automatic_warning_device_middle_left_off") +minetest.register_alias("infrastructure:automatic_warning_device_middle_right_1","infrastructure:automatic_warning_device_middle_right_off") +minetest.register_alias("infrastructure:automatic_warning_device_middle_right_2","infrastructure:automatic_warning_device_middle_right_off") +minetest.register_alias("infrastructure:automatic_warning_device_middle_center_1","infrastructure:automatic_warning_device_middle_center_off") +minetest.register_alias("infrastructure:automatic_warning_device_middle_center_2","infrastructure:automatic_warning_device_middle_center_off") +minetest.register_alias("infrastructure:automatic_warning_device_middle_center_3","infrastructure:automatic_warning_device_middle_center_off") diff --git a/mods/roads/infrastructure/advanced_boom_barrier.lua b/mods/roads/infrastructure/advanced_boom_barrier.lua new file mode 100644 index 0000000..67a9b8b --- /dev/null +++ b/mods/roads/infrastructure/advanced_boom_barrier.lua @@ -0,0 +1,508 @@ +-- Boom barrier +function move_arm(pos, node) + local node = minetest.env:get_node(pos) + local param2 = node.param2 + + if param2 == 0 then + dir = "z-" + elseif param2 == 1 then + dir = "x-" + elseif param2 == 2 then + dir = "z+" + elseif param2 == 3 then + dir = "x+" + end + + minetest.sound_play("infrastructure_boom_barrier", { + pos = pos, + gain = BOOM_BARRIER_VOLUME, + max_hear_distance = 50 + }) + + if node.name == "infrastructure:boom_barrier_top_h" then + minetest.swap_node(pos, {name = "infrastructure:boom_barrier_top_v", param2 = node.param2}) + + if dir == "x+" then + for i = 1, 10 do + pos.x = pos.x + 1 + if (string.match(minetest.env:get_node(pos).name, "infrastructure:boom_barrier_arm_h_lightfirst") + or string.match(minetest.env:get_node(pos).name, "infrastructure:boom_barrier_arm_h_end") + or string.match(minetest.env:get_node(pos).name, "infrastructure:boom_barrier_arm_h_darkfirst")) == nil then + pos.x = pos.x - 1 + break + end + minetest.env:remove_node(pos) + node.name = "infrastructure:boom_barrier_arm_v" + minetest.env:add_node({x=pos.x-i, y=pos.y+i, z=pos.z}, node) + end + elseif dir == "x-" then + for i = 1, 10 do + pos.x = pos.x - 1 + if (string.match(minetest.env:get_node(pos).name, "infrastructure:boom_barrier_arm_h_lightfirst") + or string.match(minetest.env:get_node(pos).name, "infrastructure:boom_barrier_arm_h_end") + or string.match(minetest.env:get_node(pos).name, "infrastructure:boom_barrier_arm_h_darkfirst")) == nil then + break + end + minetest.env:remove_node(pos) + node.name = "infrastructure:boom_barrier_arm_v" + minetest.env:add_node({x=pos.x+i, y=pos.y+i, z=pos.z}, node) + end + elseif dir == "z+" then + for i = 1, 10 do + pos.z = pos.z + 1 + if (string.match(minetest.env:get_node(pos).name, "infrastructure:boom_barrier_arm_h_lightfirst") + or string.match(minetest.env:get_node(pos).name, "infrastructure:boom_barrier_arm_h_end") + or string.match(minetest.env:get_node(pos).name, "infrastructure:boom_barrier_arm_h_darkfirst")) == nil then + break + end + minetest.env:remove_node(pos) + node.name = "infrastructure:boom_barrier_arm_v" + minetest.env:add_node({x=pos.x, y=pos.y+i, z=pos.z-i}, node) + end + elseif dir == "z-" then + for i = 1, 10 do + pos.z = pos.z - 1 + if (string.match(minetest.env:get_node(pos).name, "infrastructure:boom_barrier_arm_h_lightfirst") + or string.match(minetest.env:get_node(pos).name, "infrastructure:boom_barrier_arm_h_end") + or string.match(minetest.env:get_node(pos).name, "infrastructure:boom_barrier_arm_h_darkfirst")) == nil then + break + end + minetest.env:remove_node(pos) + node.name = "infrastructure:boom_barrier_arm_v" + minetest.env:add_node({x=pos.x, y=pos.y+i, z=pos.z+i}, node) + end + end + + elseif node.name == "infrastructure:boom_barrier_top_v" then + minetest.swap_node(pos, {name = "infrastructure:boom_barrier_top_h", param2 = node.param2}) + if dir == "x+" then + for i = 1, 10 do + pos.y = pos.y + 1 + if string.match(minetest.env:get_node(pos).name, "infrastructure:boom_barrier_arm_v") == nil then + break + end + minetest.env:remove_node(pos) + if i % 2 == 1 then + node.name = "infrastructure:boom_barrier_arm_h_lightfirst" + else + node.name = "infrastructure:boom_barrier_arm_h_darkfirst" + end + if minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}).name ~= "infrastructure:boom_barrier_arm_v" then + node.name = "infrastructure:boom_barrier_arm_h_end" + end + minetest.env:add_node({x=pos.x+i, y=pos.y-i, z=pos.z}, node) + end + elseif dir == "x-" then + for i = 1, 10 do + pos.y = pos.y + 1 + if string.match(minetest.env:get_node(pos).name, "infrastructure:boom_barrier_arm_v") == nil then + break + end + minetest.env:remove_node(pos) + if i % 2 == 1 then + node.name = "infrastructure:boom_barrier_arm_h_lightfirst" + else + node.name = "infrastructure:boom_barrier_arm_h_darkfirst" + end + if minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}).name ~= "infrastructure:boom_barrier_arm_v" then + node.name = "infrastructure:boom_barrier_arm_h_end" + end + minetest.env:add_node({x=pos.x-i, y=pos.y-i, z=pos.z}, node) + end + elseif dir == "z+" then + for i = 1, 10 do + pos.y = pos.y + 1 + if string.match(minetest.env:get_node(pos).name, "infrastructure:boom_barrier_arm_v") == nil then + break + end + minetest.env:remove_node(pos) + if i % 2 == 1 then + node.name = "infrastructure:boom_barrier_arm_h_lightfirst" + else + node.name = "infrastructure:boom_barrier_arm_h_darkfirst" + end + if minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}).name ~= "infrastructure:boom_barrier_arm_v" then + node.name = "infrastructure:boom_barrier_arm_h_end" + end + minetest.env:add_node({x=pos.x, y=pos.y-i, z=pos.z+i}, node) + end + elseif dir == "z-" then + for i = 1, 10 do + pos.y = pos.y + 1 + if string.match(minetest.env:get_node(pos).name, "infrastructure:boom_barrier_arm_v") == nil then + break + end + minetest.env:remove_node(pos) + if i % 2 == 1 then + node.name = "infrastructure:boom_barrier_arm_h_lightfirst" + else + node.name = "infrastructure:boom_barrier_arm_h_darkfirst" + end + if minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}).name ~= "infrastructure:boom_barrier_arm_v" then + node.name = "infrastructure:boom_barrier_arm_h_end" + end + minetest.env:add_node({x=pos.x, y=pos.y-i, z=pos.z-i}, node) + end + end + end +end + +minetest.register_node("infrastructure:boom_barrier_top_h", { + description = "Boom barrier mechanism", + tiles = { + "infrastructure_boom_barrier_h_top.png", + "infrastructure_boom_barrier_h_bottom.png", + "infrastructure_boom_barrier_h_right.png", + "infrastructure_boom_barrier_h_left.png", + "infrastructure_boom_barrier_h_front_back.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1}, + node_box = { + type = "fixed", + fixed = { + {-1/4, -1/4, -1/4, 1/4, 1/4, 1/4}, + {-1/8, -1/2, -1/8, 1/8, -1/4, 1/8}, + + {-3/8, -1/2, -1/2, -1/4, -1/4, 1/8}, + {-3/8, -1/2, -1/8, -1/4, 1/8, 1/8}, + {-3/8, -1/8, -1/8, -1/4, 1/8, 1/2}, + {-1/2, -3/16, 1/4, -3/8, 3/16, 1/2}, + {-1/2, -1/8, 3/16, -3/8, 1/8, 1/2}, + {-1/2, -1/16, 1/8, -3/8, 1/16, 1/2}, + + {1/4, -1/2, -1/2, 3/8, -1/4, 1/8}, + {1/4, -1/2, -1/8, 3/8, 1/8, 1/8}, + {1/4, -1/8, -1/8, 3/8, 1/8, 1/2}, + {3/8, -3/16, 1/4, 1/2, 3/16, 1/2}, + {3/8, -1/8, 3/16, 1/2, 1/8, 1/2}, + {3/8, -1/16, 1/8, 1/2, 1/16, 1/2}, + + {-3/8, -1/2, -1/2, 3/8, -1/4, -3/8}, + + {-7/16, -1/16, -1/16, 7/16, 1/16, 1/16} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/4, -1/4, -1/4, 1/4, 1/4, 1/4}, + {-1/8, -1/2, -1/8, 1/8, -1/4, 1/8}, + + {-3/8, -1/2, -1/2, -1/4, -1/4, 1/8}, + {-3/8, -1/2, -1/8, -1/4, 1/8, 1/8}, + {-3/8, -1/8, -1/8, -1/4, 1/8, 1/2}, + {-1/2, -3/16, 1/4, -3/8, 3/16, 1/2}, + {-1/2, -1/8, 3/16, -3/8, 1/8, 1/2}, + {-1/2, -1/16, 1/8, -3/8, 1/16, 1/2}, + + {1/4, -1/2, -1/2, 3/8, -1/4, 1/8}, + {1/4, -1/2, -1/8, 3/8, 1/8, 1/8}, + {1/4, -1/8, -1/8, 3/8, 1/8, 1/2}, + {3/8, -3/16, 1/4, 1/2, 3/16, 1/2}, + {3/8, -1/8, 3/16, 1/2, 1/8, 1/2}, + {3/8, -1/16, 1/8, 1/2, 1/16, 1/2}, + + {-3/8, -1/2, -1/2, 3/8, -1/4, -3/8}, + + {-7/16, -1/16, -1/16, 7/16, 1/16, 1/16} + } + }, + + after_place_node = function(pos) + local node = minetest.env:get_node(pos) + node.name = "infrastructure:boom_barrier_bottom" + minetest.env:add_node(pos, node) + pos.y = pos.y + 1 + node.name = "infrastructure:boom_barrier_top_h" + minetest.env:add_node(pos, node) + end, + + after_dig_node = function(pos) + pos.y = pos.y - 1 + minetest.env:remove_node(pos) + end, + + on_punch = function(pos, node) + move_arm(pos, node) + end +}) + +minetest.register_node("infrastructure:boom_barrier_top_v", { + tiles = { + "infrastructure_boom_barrier_h_front_back.png", + "infrastructure_boom_barrier_v_bottom.png", + "infrastructure_boom_barrier_v_right.png", + "infrastructure_boom_barrier_v_left.png", + "infrastructure_boom_barrier_v_front_back.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1}, + drop = "infrastructure:boom_barrier_top_h", + node_box = { + type = "fixed", + fixed = { + {-1/4, -1/4, -1/4, 1/4, 1/4, 1/4}, + {-1/8, -1/2, -1/8, 1/8, -1/4, 1/8}, + + {-3/8, -1/8, -1/2, -1/4, 1/2, -1/4}, + {-3/8, -1/8, -1/2, -1/4, 1/8, 1/8}, + {-3/8, -1/2, -1/8, -1/4, 1/8, 1/8}, + {-1/2, -1/2, -3/16, -3/8, -1/4, 3/16}, + {-1/2, -1/2, -1/8, -3/8, -3/16, 1/8}, + {-1/2, -1/2, -1/16, -3/8, -1/8, 1/16}, + + {1/4, -1/8, -1/2, 3/8, 1/2, -1/4}, + {1/4, -1/8, -1/2, 3/8, 1/8, 1/8}, + {1/4, -1/2, -1/8, 3/8, 1/8, 1/8}, + {3/8, -1/2, -3/16, 1/2, -1/4, 3/16}, + {3/8, -1/2, -1/8, 1/2, -3/16, 1/8}, + {3/8, -1/2, -1/16, 1/2, -1/8, 1/16}, + + {-3/8, 3/8, -1/2, 3/8, 1/2, -1/4}, + + {-7/16, -1/16, -1/16, 7/16, 1/16, 1/16} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/4, -1/4, -1/4, 1/4, 1/4, 1/4}, + {-1/8, -1/2, -1/8, 1/8, -1/4, 1/8}, + + {-3/8, -1/8, -1/2, -1/4, 1/2, -1/4}, + {-3/8, -1/8, -1/2, -1/4, 1/8, 1/8}, + {-3/8, -1/2, -1/8, -1/4, 1/8, 1/8}, + {-1/2, -1/2, -3/16, -3/8, -1/4, 3/16}, + {-1/2, -1/2, -1/8, -3/8, -3/16, 1/8}, + {-1/2, -1/2, -1/16, -3/8, -1/8, 1/16}, + + {1/4, -1/8, -1/2, 3/8, 1/2, -1/4}, + {1/4, -1/8, -1/2, 3/8, 1/8, 1/8}, + {1/4, -1/2, -1/8, 3/8, 1/8, 1/8}, + {3/8, -1/2, -3/16, 1/2, -1/4, 3/16}, + {3/8, -1/2, -1/8, 1/2, -3/16, 1/8}, + {3/8, -1/2, -1/16, 1/2, -1/8, 1/16}, + + {-3/8, 3/8, -1/2, 3/8, 1/2, -1/4}, + + {-7/16, -1/16, -1/16, 7/16, 1/16, 1/16} + } + }, + + after_dig_node = function(pos) + pos.y = pos.y - 1 + minetest.env:remove_node(pos) + end, + + on_punch = function(pos, node) + move_arm(pos, node) + end +}) + +minetest.register_node("infrastructure:boom_barrier_bottom", { + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_automatic_warning_device_bottom.png", + "infrastructure_automatic_warning_device_bottom.png", + "infrastructure_automatic_warning_device_bottom.png", + "infrastructure_automatic_warning_device_bottom.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1}, + drop = "infrastructure:boom_barrier_top_h", + node_box = { + type = "fixed", + fixed = { + {-1/16, -1/2, -1/16, 1/16, 1/2, 1/16}, + {-1/2, -1/2, -1/4, 1/2, -3/8, 1/4}, + {-1/4, -1/2, -1/2, 1/4, -3/8, 1/2}, + {-1/8, -1/2, -1/8, 1/8, 0, 1/8} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/16, -1/2, -1/16, 1/16, 1/2, 1/16}, + {-1/2, -1/2, -1/4, 1/2, -3/8, 1/4}, + {-1/4, -1/2, -1/2, 1/4, -3/8, 1/2}, + {-1/8, -1/2, -1/8, 1/8, 0, 1/8} + } + }, + + after_dig_node = function(pos) + pos.y = pos.y + 1 + minetest.env:remove_node(pos) + end, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, + + digiline = { + receptor = {}, + effector = { + action = function(pos, node, channel, msg) + local setchan = minetest.get_meta(pos):get_string("channel") + if setchan ~= channel then + return + end + pos.y = pos.y + 1 + local mechnode = minetest.env:get_node(pos) + if ((msg == "up" and mechnode.name=="infrastructure:boom_barrier_top_h") or (msg == "down" and mechnode.name=="infrastructure:boom_barrier_top_v")) then + move_arm(pos, mechnode) + end + end + } + }, +}) + +minetest.register_node("infrastructure:boom_barrier_arm_h_lightfirst", { + description = "Boom barrier arm", + tiles = { + "infrastructure_boom_barrier_arm_h_top.png", + "infrastructure_boom_barrier_arm_h_bottom_front_back.png", + {name="infrastructure_boom_barrier_arm_h_anim_lightfirst.png",animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.5}}, + {name="infrastructure_boom_barrier_arm_h_anim_lightfirst.png",animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.5}}, + "infrastructure_boom_barrier_arm_h_bottom_front_back.png", + "infrastructure_boom_barrier_arm_h_bottom_front_back.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1}, + light_source = BOOM_BARRIER_LIGHT_RANGE, + node_box = { + type = "fixed", + fixed = { + {-1/8, -1/2, -1/2, 1/8, -7/16, 1/2}, + {-1/8, -5/16, -1/2, 1/8, -1/4, 1/2}, + {-1/8, -1/2, -1/2, -1/16, -1/4, 1/2}, + {1/16, -1/2, -1/2, 1/8, -1/4, 1/2}, + {0, -1/4, -1/8, 0, 0, 1/8} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/8, -1/2, -1/2, 1/8, -1/4, 1/2} + } + } +}) + +minetest.register_node("infrastructure:boom_barrier_arm_h_darkfirst", { + tiles = { + "infrastructure_boom_barrier_arm_h_top.png", + "infrastructure_boom_barrier_arm_h_bottom_front_back.png", + {name="infrastructure_boom_barrier_arm_h_anim_darkfirst.png",animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.5}}, + {name="infrastructure_boom_barrier_arm_h_anim_darkfirst.png",animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.5}}, + "infrastructure_boom_barrier_arm_h_bottom_front_back.png", + "infrastructure_boom_barrier_arm_h_bottom_front_back.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1}, + drop = "infrastructure:boom_barrier_arm_h_lightfirst", + node_box = { + type = "fixed", + fixed = { + {-1/8, -1/2, -1/2, 1/8, -7/16, 1/2}, + {-1/8, -5/16, -1/2, 1/8, -1/4, 1/2}, + {-1/8, -1/2, -1/2, -1/16, -1/4, 1/2}, + {1/16, -1/2, -1/2, 1/8, -1/4, 1/2}, + {0, -1/4, -1/8, 0, 0, 1/8} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/8, -1/2, -1/2, 1/8, -1/4, 1/2} + } + } +}) + +minetest.register_node("infrastructure:boom_barrier_arm_h_end", { + tiles = { + "infrastructure_boom_barrier_arm_h_top.png", + "infrastructure_boom_barrier_arm_h_bottom_front_back.png", + "infrastructure_boom_barrier_arm_h_left_right_bright.png", + "infrastructure_boom_barrier_arm_h_left_right_bright.png", + "infrastructure_boom_barrier_arm_h_bottom_front_back.png", + "infrastructure_boom_barrier_arm_h_bottom_front_back.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1}, + drop = "infrastructure:boom_barrier_arm_h_lightfirst", + node_box = { + type = "fixed", + fixed = { + {-1/8, -1/2, -1/2, 1/8, -7/16, 1/2}, + {-1/8, -5/16, -1/2, 1/8, -1/4, 1/2}, + {-1/8, -1/2, -1/2, -1/16, -1/4, 1/2}, + {1/16, -1/2, -1/2, 1/8, -1/4, 1/2}, + {0, -1/4, -1/8, 0, 0, 1/8} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/8, -1/2, -1/2, 1/8, -1/4, 1/2} + } + } +}) + +minetest.register_alias("infrastructure:boom_barrier_arm_h_dark","infrastructure:boom_barrier_arm_h_darkfirst") +minetest.register_alias("infrastructure:boom_barrier_arm_h_bright","infrastructure:boom_barrier_arm_h_lightfirst") + +minetest.register_node("infrastructure:boom_barrier_arm_v", { + tiles = { + "infrastructure_boom_barrier_arm_h_bottom_front_back.png", + "infrastructure_boom_barrier_arm_h_bottom_front_back.png", + "infrastructure_boom_barrier_arm_v_left.png", + "infrastructure_boom_barrier_arm_v_right.png", + "infrastructure_boom_barrier_arm_h_top.png", + "infrastructure_boom_barrier_arm_h_bottom_front_back.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1}, + drop = "infrastructure:boom_barrier_arm_h_lightfirst", + node_box = { + type = "fixed", + fixed = { + {-1/8, -1/2, -1/2, 1/8, 1/2, -7/16}, + {-1/8, -1/2, -5/16, 1/8, 1/2, -1/4}, + {-1/8, -1/2, -1/2, -1/16, 1/2, -1/4}, + {1/16, -1/2, -1/2, 1/8, 1/2, -1/4}, + {0, -1/8, -1/4, 0, 1/8, 0} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/8, -1/2, -1/2, 1/8, 1/2, -1/4} + } + } +}) + +minetest.register_alias("infrastructure:boom_barrier_mechanism", "infrastructure:boom_barrier_top_h") +minetest.register_alias("infrastructure:boom_barrier_arm", "infrastructure:boom_barrier_arm_h_lightfirst") diff --git a/mods/roads/infrastructure/advanced_crosswalk_lighting.lua b/mods/roads/infrastructure/advanced_crosswalk_lighting.lua new file mode 100644 index 0000000..4e669c1 --- /dev/null +++ b/mods/roads/infrastructure/advanced_crosswalk_lighting.lua @@ -0,0 +1,85 @@ +-- Crosswalk lighting + minetest.register_node("infrastructure:crosswalk_lighting_dark", { + description = "Crosswalk lighting", + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_crosswalk_lighting_bottom.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_crosswalk_lighting_back.png", + "infrastructure_crosswalk_lighting_front.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 3}, + node_box = { + type = "fixed", + fixed = { + {-3/8, -1/2, -1/4, 3/8, 1/2, -3/16}, + {-3/8, -1/2, 3/16, 3/8, 1/2, 1/4}, + {-1/4, 1/4, -3/16, -1/8, 3/8, 3/16}, + {1/8, 1/4, -3/16, 1/4, 3/8, 3/16}, + {-1/8, -1/2, -3/16, 1/8, -1/4, 3/16}, + {-1/2, -1/2, -1/8, 1/2, -3/8, 1/8}, + } + }, + selection_box = { + type = "fixed", + fixed = {-3/8, -1/2, -1/4, 3/8, 1/2, 1/4} + }, + + on_punch = function(pos, node) + minetest.swap_node(pos, {name = "infrastructure:crosswalk_lighting_bright", param2 = node.param2}) + end, + + mesecons = {effector = { + action_on = function (pos, node) + minetest.swap_node(pos, {name = "infrastructure:crosswalk_lighting_bright", param2 = node.param2}) + end, + }} + }) + + minetest.register_node("infrastructure:crosswalk_lighting_bright", { + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_crosswalk_lighting_bottom.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_crosswalk_lighting_back.png", + "infrastructure_crosswalk_lighting_front.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 3, not_in_creative_inventory = 1}, + light_source = CROSSWALK_LIGHTING_LIGHT_RANGE, + drop = "infrastructure:crosswalk_lighting_dark", + node_box = { + type = "fixed", + fixed = { + {-3/8, -1/2, -1/4, 3/8, 1/2, -3/16}, + {-3/8, -1/2, 3/16, 3/8, 1/2, 1/4}, + {-1/4, 1/4, -3/16, -1/8, 3/8, 3/16}, + {1/8, 1/4, -3/16, 1/4, 3/8, 3/16}, + {-1/8, -1/2, -3/16, 1/8, -1/4, 3/16}, + {-1/2, -1/2, -1/8, 1/2, -3/8, 1/8}, + } + }, + selection_box = { + type = "fixed", + fixed = {-3/8, -1/2, -1/4, 3/8, 1/2, 1/4} + }, + + on_punch = function(pos, node) + minetest.swap_node(pos, {name = "infrastructure:crosswalk_lighting_dark", param2 = node.param2}) + end, + + mesecons = {effector = { + action_off = function (pos, node) + minetest.swap_node(pos, {name = "infrastructure:crosswalk_lighting_dark", param2 = node.param2}) + end, + }} + }) + + minetest.register_alias("infrastructure:crosswalk_lighting", "infrastructure:crosswalk_lighting_dark") diff --git a/mods/roads/infrastructure/advanced_crosswalk_safety_sign.lua b/mods/roads/infrastructure/advanced_crosswalk_safety_sign.lua new file mode 100644 index 0000000..6183322 --- /dev/null +++ b/mods/roads/infrastructure/advanced_crosswalk_safety_sign.lua @@ -0,0 +1,85 @@ +-- Crosswalk safety sign + minetest.register_node("infrastructure:crosswalk_safety_sign_top", { + tiles = { + "infrastructure_crosswalk_safety_sign_top.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_crosswalk_safety_sign_top_side.png", + "infrastructure_crosswalk_safety_sign_top_side.png", + "infrastructure_crosswalk_safety_sign_top_front_back.png", + "infrastructure_crosswalk_safety_sign_top_front_back.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, not_in_creative_inventory = 1}, + light_source = CROSSWALK_SAFETY_SIGN_LIGHT_RANGE, + node_box = { + type = "fixed", + fixed = { + {-1/4, -1/2, -1/16, 1/4, 0, -1/16}, + {-1/4, -1/2, 1/16, 1/4, 0, 1/16}, + {-1/16, -1/2, -1/16, 1/16, -1/4, 1/16} + } + }, + selection_box = { + type = "fixed", + fixed = {0, 0, 0, 0, 0, 0} + } + }) + + minetest.register_node("infrastructure:crosswalk_safety_sign_bottom", { + description = "Crosswalk safety sign", + inventory_image = "infrastructure_crosswalk_safety_sign.png", + wield_image = "infrastructure_crosswalk_safety_sign.png", + tiles = { + "infrastructure_crosswalk_safety_sign_top.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_crosswalk_safety_sign_bottom_side.png", + "infrastructure_crosswalk_safety_sign_bottom_side.png", + "infrastructure_crosswalk_safety_sign_bottom_front_back.png", + "infrastructure_crosswalk_safety_sign_bottom_front_back.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1}, + light_source = CROSSWALK_SAFETY_SIGN_LIGHT_RANGE, + node_box = { + type = "fixed", + fixed = { + {-1/4, -7/32, -1/16, 1/4, 1/2, -1/16}, + {-1/4, -7/32, 1/16, 1/4, 1/2, 1/16}, + {-1/16, -5/16, -1/16, 1/16, 1/2, 1/16}, + {-1/8, -3/8, -1/8, 1/8, -5/16, 1/8}, + {-1/4, -1/2, -1/2, 1/4, -3/8, 1/2} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/4, -7/32, -1/16, 1/4, 1, -1/16}, + {-1/4, -7/32, 1/16, 1/4, 1, 1/16}, + + {-1/16, -5/16, -1/16 + 0.01, 1/16, 3/4, 1/16 - 0.01}, + + {-1/8, -3/8, -1/8, 1/8, -5/16, 1/8}, + {-1/4, -1/2, -1/2, 1/4, -3/8, 1/2} + } + }, + + after_place_node = function(pos) + local node = minetest.env:get_node(pos) + node.name = "infrastructure:crosswalk_safety_sign_bottom" + minetest.env:add_node(pos, node) + pos.y = pos.y + 1 + node.name = "infrastructure:crosswalk_safety_sign_top" + minetest.env:add_node(pos, node) + end, + + after_dig_node = function(pos) + pos.y = pos.y + 1 + minetest.env:remove_node(pos) + end, + }) + + minetest.register_alias("infrastructure:crosswalk_safety_sign", "infrastructure:crosswalk_safety_sign_bottom") diff --git a/mods/roads/infrastructure/advanced_crosswalk_warning_light.lua b/mods/roads/infrastructure/advanced_crosswalk_warning_light.lua new file mode 100644 index 0000000..213223a --- /dev/null +++ b/mods/roads/infrastructure/advanced_crosswalk_warning_light.lua @@ -0,0 +1,124 @@ +-- Crosswalk warning light +function on_off_light(pos, node) + if node.name == "infrastructure:crosswalk_warning_light_off" then + minetest.swap_node(pos, {name = "infrastructure:crosswalk_warning_light_on", param2 = node.param2}) + elseif (node.name == "infrastructure:crosswalk_warning_light_on") then + minetest.swap_node(pos, {name = "infrastructure:crosswalk_warning_light_off", param2 = node.param2}) + end +end + +minetest.register_node("infrastructure:crosswalk_warning_light_off", { + description = "Crosswalk warning light", + inventory_image = "infrastructure_crosswalk_warning_light_front_bright.png", + wield_image = "infrastructure_crosswalk_warning_light_front_bright.png", + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_crosswalk_warning_light_back.png", + "infrastructure_crosswalk_warning_light_front_dark.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 3, not_in_creative_inventory = 0}, + node_box = { + type = "fixed", + fixed = { + {-5/16, -5/16, -1/8, 5/16, 3/8, 1/8}, + {-1/2, -1/2, -1/8, 1/2, 1/2, -1/8}, + + {-5/16, 1/4, -5/16, 5/16, 5/16, -1/8}, + {-5/16, 0, -1/4, -1/4, 1/4, -1/8}, + {1/4, 0, -1/4, 5/16, 1/4, -1/8}, + + {-1/16, -1/4, 1/8, 1/16, 1/4, 3/8}, + {-1/4, -1/16, 1/8, 1/4, 1/16, 3/8}, + {-1/4, -1/4, 3/8, 1/4, 1/4, 1/2 - 0.001} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-5/16, -5/16, -1/8, 5/16, 3/8, 1/8}, + + {-5/16, 1/4, -5/16, 5/16, 5/16, -1/8}, + {-5/16, 0, -1/4, -1/4, 1/4, -1/8}, + {1/4, 0, -1/4, 5/16, 1/4, -1/8}, + + {-1/16, -1/4, 1/8, 1/16, 1/4, 3/8}, + {-1/4, -1/16, 1/8, 1/4, 1/16, 3/8}, + {-1/4, -1/4, 3/8, 1/4, 1/4, 1/2 - 0.01} + } + }, + + on_punch = function(pos, node) + on_off_light(pos, node) + end, + + mesecons = {effector = { + action_on = function(pos, node) + on_off_light(pos, node) + end, + }} +}) + +minetest.register_node("infrastructure:crosswalk_warning_light_on", { + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_crosswalk_warning_light_back.png", + {name="infrastructure_crosswalk_warning_light_front_anim.png",animation={type="vertical_frames", aspect_w=32, aspect_h=32, length=1.5}} + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 3, not_in_creative_inventory = 1}, + drop = "infrastructure:crosswalk_warning_light_off", + node_box = { + type = "fixed", + fixed = { + {-5/16, -5/16, -1/8, 5/16, 3/8, 1/8}, + {-1/2, -1/2, -1/8, 1/2, 1/2, -1/8}, + + {-5/16, 1/4, -5/16, 5/16, 5/16, -1/8}, + {-5/16, 0, -1/4, -1/4, 1/4, -1/8}, + {1/4, 0, -1/4, 5/16, 1/4, -1/8}, + + {-1/16, -1/4, 1/8, 1/16, 1/4, 3/8}, + {-1/4, -1/16, 1/8, 1/4, 1/16, 3/8}, + {-1/4, -1/4, 3/8, 1/4, 1/4, 1/2 - 0.001} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-5/16, -5/16, -1/8, 5/16, 3/8, 1/8}, + + {-5/16, 1/4, -5/16, 5/16, 5/16, -1/8}, + {-5/16, 0, -1/4, -1/4, 1/4, -1/8}, + {1/4, 0, -1/4, 5/16, 1/4, -1/8}, + + {-1/16, -1/4, 1/8, 1/16, 1/4, 3/8}, + {-1/4, -1/16, 1/8, 1/4, 1/16, 3/8}, + {-1/4, -1/4, 3/8, 1/4, 1/4, 1/2 - 0.01} + } + }, + + on_punch = function(pos, node) + on_off_light(pos, node) + end, + + mesecons = {effector = { + action_on = function(pos, node) + on_off_light(pos, node) + end, + }} +}) + +minetest.register_alias("infrastructure:crosswalk_warning_light", "infrastructure:crosswalk_warning_light_off") +minetest.register_alias("infrastructure:crosswalk_warning_bright", "infrastructure:crosswalk_warning_light_on") +minetest.register_alias("infrastructure:crosswalk_warning_dark", "infrastructure:crosswalk_warning_light_on") diff --git a/mods/roads/infrastructure/advanced_curve_chevron.lua b/mods/roads/infrastructure/advanced_curve_chevron.lua new file mode 100644 index 0000000..7d3b65d --- /dev/null +++ b/mods/roads/infrastructure/advanced_curve_chevron.lua @@ -0,0 +1,85 @@ +-- Curve chevron + minetest.register_node("infrastructure:curve_chevron_dark", { + description = "Flashing curve chevron", + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_curve_chevron_left_dark.png", + "infrastructure_curve_chevron_right_dark.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 3}, + node_box = { + type = "fixed", + fixed = { + {-1/2, -1/2, -1/8, 1/2, 1/2, -1/16}, + {-1/2, -1/2, 1/16, 1/2, 1/2, 1/8}, + {-3/8, 1/4, -1/16, -1/4, 3/8, 1/16}, + {1/4, 1/4, -1/16, 3/8, 3/8, 1/16}, + {-3/8, -3/8, -1/16, -1/4, -1/4, 1/16}, + {1/4, -3/8, -1/16, 3/8, -1/4, 1/16} + } + }, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/8, 1/2, 1/2, 1/8} + }, + + on_punch = function(pos, node) + minetest.swap_node(pos, {name = "infrastructure:curve_chevron_bright", param2 = node.param2}) + end, + + mesecons = {effector = { + action_on = function (pos, node) + minetest.swap_node(pos, {name = "infrastructure:curve_chevron_bright", param2 = node.param2}) + end, + }} + }) + + minetest.register_node("infrastructure:curve_chevron_bright", { + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_curve_chevron_left_bright.png", + "infrastructure_curve_chevron_right_bright.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 3, not_in_creative_inventory = 1}, + light_source = CURVE_CHEVRON_LIGHT_RANGE, + drop = "infrastructure:curve_chevron_dark", + node_box = { + type = "fixed", + fixed = { + {-1/2, -1/2, -1/8, 1/2, 1/2, -1/16}, + {-1/2, -1/2, 1/16, 1/2, 1/2, 1/8}, + {-3/8, 1/4, -1/16, -1/4, 3/8, 1/16}, + {1/4, 1/4, -1/16, 3/8, 3/8, 1/16}, + {-3/8, -3/8, -1/16, -1/4, -1/4, 1/16}, + {1/4, -3/8, -1/16, 3/8, -1/4, 1/16} + } + }, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/8, 1/2, 1/2, 1/8} + }, + + on_punch = function(pos, node) + minetest.swap_node(pos, {name = "infrastructure:curve_chevron_dark", param2 = node.param2}) + end, + + mesecons = {effector = { + action_off = function (pos, node) + minetest.swap_node(pos, {name = "infrastructure:curve_chevron_dark", param2 = node.param2}) + end + }} + }) + + minetest.register_alias("infrastructure:curve_chevron", "infrastructure:curve_chevron_dark") diff --git a/mods/roads/infrastructure/advanced_emergency_phone.lua b/mods/roads/infrastructure/advanced_emergency_phone.lua new file mode 100644 index 0000000..c511db1 --- /dev/null +++ b/mods/roads/infrastructure/advanced_emergency_phone.lua @@ -0,0 +1,107 @@ +-- Emergency phone (only if enabled) + if ENABLE_EMERGENCY_PHONE then + minetest.register_node("infrastructure:emergency_phone_top", { + description = "Emergency phone", + tiles = { + "infrastructure_emergency_phone_top.png", + "infrastructure_emergency_phone_bottom.png", + "infrastructure_emergency_phone_side.png", + "infrastructure_emergency_phone_side.png", + "infrastructure_emergency_phone_side.png", + "infrastructure_emergency_phone_front.png" + }, + drawtype = "nodebox", + drop = "streets:emergencyphone", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky=1,not_in_creative_inventory=1}, + light_source = EMERGENCY_PHONE_LIGHT_RANGE, + node_box = { + type = "fixed", + fixed = { + {-0.25, -0.5, -0.25, 0.25, 0.5, 0.25}, + {-0.25, -0.5, -0.3125, -0.1875, 0.5, -0.25}, + {0.1875, -0.5, -0.3125, 0.25, 0.5, -0.25}, + {-0.1875, 0.4375, -0.3125, 0.1875, 0.5, -0.25} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.25, -0.5, -0.25, 0.25, 0.5, 0.25}, + {-0.25, -0.5, -0.3125, -0.1875, 0.5, -0.25}, + {0.1875, -0.5, -0.3125, 0.25, 0.5, -0.25}, + {-0.1875, 0.4375, -0.3125, 0.1875, 0.5, -0.25}, + } + }, + + after_dig_node = function(pos) + pos.y = pos.y - 1 + if minetest.get_node(pos).name == "infrastructure:emergency_phone_bottom" then + minetest.remove_node(pos) + end + end, + + on_punch = function(pos, node, puncher) + if dial_handler ~= nil then + minetest.sound_stop(dial_handler) + dial_handler = nil + end + dial_handler = minetest.sound_play("infrastructure_emergency_phone", { + pos = pos, + gain = EMERGENCY_PHONE_VOLUME, + max_hear_distance = 50 + }) + if (puncher:is_player() and puncher:get_hp() < HEALTH_TO_RESTORING and puncher:get_hp() <= HEALTH_TO_TRIGGER) then + puncher:set_hp(HEALTH_TO_RESTORING) + minetest.chat_send_player(puncher:get_player_name(), "You got healed!") + minetest.chat_send_all("Server: -!- "..puncher:get_player_name().." used an emergency phone at "..pos.x..","..pos.y..","..pos.z); + end + end + }) + + minetest.register_node("infrastructure:emergency_phone_bottom", { + tiles = {"infrastructure_emergency_phone_bottom.png"}, + drawtype = "nodebox", + drop = "streets:emergencyphone", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky=1,not_in_creative_inventory=1}, + node_box = { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.5, 0.25} + }, + selection_box = { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.5, 0.25} + }, + + after_dig_node = function(pos) + pos.y = pos.y+1 + if minetest.get_node(pos).name == "infrastructure:emergency_phone_top" then + minetest.remove_node(pos) + end + end, + }) + + minetest.register_alias("infrastructure:emergency_phone", "infrastructure:emergency_phone_top") + + minetest.register_abm({ + nodenames = {"streets:emergencyphone"}, + interval = 1, + chance = 1, + action = function(pos, node) + local node = minetest.get_node(pos) + local node_above = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}) + if node_above.name == "air" then + node.name = "infrastructure:emergency_phone_bottom" + minetest.set_node(pos, node) + pos.y = pos.y+1 + end + node.name = "infrastructure:emergency_phone_top" + minetest.set_node(pos, node) + end, + }) + else + print("Infrastructure mod: -!- Emergency-Phone is disabled!") + end diff --git a/mods/roads/infrastructure/advanced_lane_control_lights.lua b/mods/roads/infrastructure/advanced_lane_control_lights.lua new file mode 100644 index 0000000..94d7ce1 --- /dev/null +++ b/mods/roads/infrastructure/advanced_lane_control_lights.lua @@ -0,0 +1,91 @@ +-- Lane control lights + +for i = 1, 6 do + local groups = {} + if i == 1 then + groups = {cracky = 3} + else + groups = {cracky = 3, not_in_creative_inventory = 1} + end + + minetest.register_node("infrastructure:lane_control_lights_"..tostring(i), { + description = "Lane control lights", + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_lane_control_lights_"..tostring(i)..".png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + groups = {cracky = 3, not_in_creative_inventory = (i == 1 and 0 or 1)}, + light_source = TRAFFIC_LIGHTS_LIGHT_RANGE, + drop = "infrastructure:lane_control_lights_1", + node_box = { + type = "fixed", + fixed = { + {-7/16, -7/16, -1/8, 7/16, 7/16, 1/8}, + {-7/16, 0, -1/4, -3/8, 7/16, -1/8}, + {3/8, 0, -1/4, 7/16, 7/16, -1/8}, + {-7/16, 3/8, -5/16, 7/16, 7/16, -1/8}, + {-1/16, -1/4, 0, 1/16, 1/4, 1/2 - 0.001}, + {-1/4, -1/4, 3/8, 1/4, 1/4, 1/2 - 0.001}, + {-1/4, -1/16, 0, 1/4, 1/16, 1/2 - 0.001} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-7/16, -7/16, -1/8, 7/16, 7/16, 1/8}, + {-7/16, 0, -1/4, -3/8, 7/16, -1/8}, + {3/8, 0, -1/4, 7/16, 7/16, -1/8}, + {-7/16, 3/8, -5/16, 7/16, 7/16, -1/8}, + {-1/16, -1/4, 0, 1/16, 1/4, 1/2 - 0.001}, + {-1/4, -1/4, 3/8, 1/4, 1/4, 1/2 - 0.001}, + {-1/4, -1/16, 0, 1/4, 1/16, 1/2 - 0.001} + } + + }, + on_receive_fields = function(pos, formname, fields) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + end + end, + digiline = { + receptor = {}, + effector = { + action = function(pos, node, channel, msg) + local setchan = minetest.get_meta(pos):get_string("channel") + if setchan ~= channel or type(msg) ~= "string" then + return + end + msg = string.lower(msg) + if (msg=="off") then + node.name = "infrastructure:lane_control_lights_1" + elseif (msg=="green") then + node.name = "infrastructure:lane_control_lights_3" + elseif (msg=="red") then + node.name = "infrastructure:lane_control_lights_2" + elseif (msg=="yellowleft") then + node.name = "infrastructure:lane_control_lights_5" + elseif (msg=="yellowright") then + node.name = "infrastructure:lane_control_lights_4" + elseif (msg=="yellow") then + node.name = "infrastructure:lane_control_lights_6" + end + minetest.set_node(pos,node) + minetest.get_meta(pos):set_string("channel",setchan) + end + } + } + }) +end + +minetest.register_alias("infrastructure:lane_control_lights", "infrastructure:lane_control_lights_1") diff --git a/mods/roads/infrastructure/advanced_road_signs.lua b/mods/roads/infrastructure/advanced_road_signs.lua new file mode 100644 index 0000000..b732bfd --- /dev/null +++ b/mods/roads/infrastructure/advanced_road_signs.lua @@ -0,0 +1,237 @@ +-- Road signs + local signs = {"stop", "yield", "right_of_way"} + + for i, sign_name in ipairs(signs) do + minetest.register_node("infrastructure:road_sign_"..sign_name, { + description = "Road sign "..sign_name, + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_road_sign_"..sign_name.."_back.png", + "infrastructure_road_sign_"..sign_name.."_front.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2}, + node_box = { + type = "fixed", + fixed = { + {-1/2, -1/2, 7/16, 1/2, 1/2, 7/16}, + {-3/16, -1/8, 7/16, 3/16, 1/8, 1/2 - 0.001} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/2, -1/2, 7/16, 1/2, 1/2, 7/16}, + {-3/16, -1/8, 7/16 + 0.01, 3/16, 1/8, 1/2 - 0.01} + } + }, + + after_place_node = function(pos, node) + local node = minetest.env:get_node(pos) + local param2 = node.param2 + local sign_pos = {x=pos.x, y=pos.y, z=pos.z} + + if param2 == 0 then + pos.z = pos.z + 1 + elseif param2 == 1 then + pos.x = pos.x + 1 + elseif param2 == 2 then + pos.z = pos.z - 1 + elseif param2 == 3 then + pos.x = pos.x - 1 + end + + local node = minetest.env:get_node(pos) + + if minetest.registered_nodes[node.name].drawtype == "fencelike" then + minetest.set_node(sign_pos, {name="infrastructure:road_sign_"..sign_name.."_on_post", param2=param2}) + end + end + }) + + minetest.register_node("infrastructure:road_sign_"..sign_name.."_on_post", { + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_road_sign_"..sign_name.."_back.png", + "infrastructure_road_sign_"..sign_name.."_front.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2, not_in_creative_inventory = 1}, + drop = "infrastructure:road_sign_"..sign_name, + node_box = { + type = "fixed", + fixed = { + {-1/2, -1/2, 7/16 + 3/8, 1/2, 1/2, 7/16 + 3/8}, + {-3/16, 1/16, 7/16 + 3/8, 3/16, 1/8, 13/16 + 3/8 - 0.001}, + {-3/16, -1/8, 7/16 + 3/8, 3/16, -1/16, 13/16 + 3/8 - 0.001} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/2, -1/2, 7/16 + 3/8, 1/2, 1/2, 7/16 + 3/8}, + {-3/16, 1/16, 7/16 + 3/8 + 0.01, 3/16, 1/8, 13/16 + 3/8 - 0.01}, + {-3/16, -1/8, 7/16 + 3/8 + 0.01, 3/16, -1/16, 13/16 + 3/8 - 0.01} + } + } + }) + end + +-- Road sign crosswalk + minetest.register_node("infrastructure:road_sign_crosswalk", { + description = "Road sign crosswalk", + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_road_sign_crosswalk_back.png", + "infrastructure_road_sign_crosswalk_front.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2}, + node_box = { + type = "fixed", + fixed = { + {-1/2, -1/2, 7/16, 1/2, 1/2, 7/16}, + {-3/16, -1/8, 7/16, 3/16, 1/8, 1/2 - 0.001} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/2, -1/2, 7/16, 1/2, 1/2, 7/16}, + {-3/16, -1/8, 7/16, 3/16, 1/8, 1/2 - 0.001} + } + }, + + after_place_node = function(pos, node) + local node = minetest.env:get_node(pos) + local param2 = node.param2 + local sign_pos = {x=pos.x, y=pos.y, z=pos.z} + + if param2 == 0 then + pos.z = pos.z + 1 + elseif param2 == 1 then + pos.x = pos.x + 1 + elseif param2 == 2 then + pos.z = pos.z - 1 + elseif param2 == 3 then + pos.x = pos.x - 1 + end + + local node = minetest.env:get_node(pos) + + if param2 == 0 then + pos.z = pos.z - 2 + elseif param2 == 1 then + pos.x = pos.x - 2 + elseif param2 == 2 then + pos.z = pos.z + 2 + elseif param2 == 3 then + pos.x = pos.x + 2 + end + + if minetest.registered_nodes[node.name].drawtype == "fencelike" then + minetest.set_node(sign_pos, {name="infrastructure:road_sign_crosswalk_on_post", param2=param2}) + minetest.env:add_node(pos, {name="infrastructure:road_sign_retroreflective_surface_on_post", param2=param2}) + else + minetest.env:add_node(pos, {name="infrastructure:road_sign_retroreflective_surface", param2=param2}) + end + end + }) + + minetest.register_node("infrastructure:road_sign_crosswalk_on_post", { + description = "Road sign crosswalk", + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_road_sign_crosswalk_back.png", + "infrastructure_road_sign_crosswalk_front.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2, not_in_creative_inventory = 1}, + drop = "infrastructure:road_sign_crosswalk", + node_box = { + type = "fixed", + fixed = { + {-1/2, -1/2, 7/16 + 3/8, 1/2, 1/2, 7/16 + 3/8}, + {-3/16, 1/16, 7/16 + 3/8, 3/16, 1/8, 13/16 + 3/8 - 0.001}, + {-3/16, -1/8, 7/16 + 3/8, 3/16, -1/16, 13/16 + 3/8 - 0.001} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/2, -1/2, 7/16 + 3/8, 1/2, 1/2, 7/16 + 3/8}, + {-3/16, 1/16, 7/16 + 3/8 + 0.01, 3/16, 1/8, 13/16 + 3/8 - 0.01}, + {-3/16, -1/8, 7/16 + 3/8 + 0.01, 3/16, -1/16, 13/16 + 3/8 - 0.01} + } + } + }) + + minetest.register_node("infrastructure:road_sign_retroreflective_surface", { + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_road_sign_retroreflective_surface.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2, not_in_creative_inventory = 1}, + light_source = RETROREFLECTIVE_SURFACE_LIGHT_RANGE, + drop = "", + node_box = { + type = "fixed", + fixed = {-3/4, -3/4, 7/16 + 1 + 0.01, 3/4, 3/4, 7/16 + 1 + 0.01} + }, + selection_box = { + type = "fixed", + fixed = {-3/4, -3/4, 7/16 + 1 + 0.01, 3/4, 3/4, 7/16 + 1 + 0.01} + } + }) + + minetest.register_node("infrastructure:road_sign_retroreflective_surface_on_post", { + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_road_sign_retroreflective_surface.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2, not_in_creative_inventory = 1}, + light_source = RETROREFLECTIVE_SURFACE_LIGHT_RANGE, + drop = "", + node_box = { + type = "fixed", + fixed = {-3/4, -3/4, 7/16 + 3/8 + 1 + 0.01, 3/4, 3/4, 7/16 + 3/8 + 1 + 0.01} + }, + selection_box = { + type = "fixed", + fixed = {-3/4, -3/4, 7/16 + 3/8 + 1 + 0.01, 3/4, 3/4, 7/16 + 3/8 + 1 + 0.01} + } + }) diff --git a/mods/roads/infrastructure/advanced_traffic_lights_pedestrians.lua b/mods/roads/infrastructure/advanced_traffic_lights_pedestrians.lua new file mode 100644 index 0000000..02da804 --- /dev/null +++ b/mods/roads/infrastructure/advanced_traffic_lights_pedestrians.lua @@ -0,0 +1,252 @@ +-- Traffic lights for pedestrians + beep_handler = {} + + function semaphores_pedestrians(pos, node) + local p = minetest.hash_node_position(pos) + if node.name == "infrastructure:traffic_lights_pedestrians_bottom_1" then + minetest.swap_node(pos, {name = "infrastructure:traffic_lights_pedestrians_bottom_2", param2 = node.param2}) + pos.y = pos.y + 1 + minetest.swap_node(pos, {name = "infrastructure:traffic_lights_pedestrians_top_2", param2 = node.param2}) + elseif node.name == "infrastructure:traffic_lights_pedestrians_bottom_2" then + minetest.swap_node(pos, {name = "infrastructure:traffic_lights_pedestrians_bottom_3", param2 = node.param2}) + pos.y = pos.y + 1 + minetest.swap_node(pos, {name = "infrastructure:traffic_lights_pedestrians_top_3", param2 = node.param2}) + beep_handler[p] = minetest.sound_play("infrastructure_traffic_lights_1", { + loop = true, + pos = pos, + gain = TRAFFIC_LIGHTS_VOLUME, + max_hear_distance = 50 + }) + elseif node.name == "infrastructure:traffic_lights_pedestrians_bottom_3" then + minetest.swap_node(pos, {name = "infrastructure:traffic_lights_pedestrians_bottom_4", param2 = node.param2}) + if beep_handler[p] ~= nil then + minetest.sound_stop(beep_handler[p]) + beep_handler[p] = nil + end + pos.y = pos.y + 1 + minetest.swap_node(pos, {name = "infrastructure:traffic_lights_pedestrians_top_4", param2 = node.param2}) + beep_handler[p] = minetest.sound_play("infrastructure_traffic_lights_2", { + loop = true, + pos = pos, + gain = TRAFFIC_LIGHTS_VOLUME, + max_hear_distance = 50 + }) + elseif node.name == "infrastructure:traffic_lights_pedestrians_bottom_4" then + minetest.swap_node(pos, {name = "infrastructure:traffic_lights_pedestrians_bottom_1", param2 = node.param2}) + pos.y = pos.y + 1 + minetest.swap_node(pos, {name = "infrastructure:traffic_lights_pedestrians_top_1", param2 = node.param2}) + if beep_handler[p] ~= nil then + minetest.sound_stop(beep_handler[p]) + beep_handler[p] = nil + end + end + end + + function quiet(pos) + local p = minetest.hash_node_position(pos) + if beep_handler[p] ~= nil then + minetest.sound_stop(beep_handler[p]) + beep_handler[p] = nil + end + end + + for i = 1, 4 do + minetest.register_node("infrastructure:traffic_lights_pedestrians_top_"..tostring(i), { + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_pedestrians_top_back.png", + "infrastructure_traffic_lights_pedestrians_top_front_"..tostring(i)..".png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky=3, not_in_creative_inventory = 1}, + light_source = TRAFFIC_LIGHTS_LIGHT_RANGE, + node_box = { + type = "fixed", + fixed = { + {-5/16, -1/2, -1/8, 5/16, 0, 1/8}, + {-1/2, -1/2, -1/8, 1/2, 1/2, -1/8}, + + {-5/16, -1/8, -5/16, 5/16, -1/16, -1/8}, + {-5/16, -3/8, -1/4, -1/4, -1/8, -1/8}, + {1/4, -3/8, -1/4, 5/16, -1/8, -1/8}, + + {-1/8, 1/16, -1/8, 1/8, 5/16, 0}, + {-1/16, 1/8, 0, 1/16, 1/4, 1/8}, + {-1/16, 0, -1/16, 1/16, 1/8, 1/16} + } + }, + selection_box = { + type = "fixed", + fixed = {0, 0, 0, 0, 0, 0} + } + }) + + minetest.register_node("infrastructure:traffic_lights_pedestrians_bottom_"..tostring(i), { + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_pedestrians_bottom_back.png", + "infrastructure_traffic_lights_pedestrians_bottom_front_"..tostring(i)..".png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 3, not_in_creative_inventory = 1}, + light_source = TRAFFIC_LIGHTS_LIGHT_RANGE, + drop = "infrastructure:traffic_lights_pedestrians_bottom_1", + node_box = { + type = "fixed", + fixed = { + {-5/16, -5/16, -1/8, 5/16, 1/2, 1/8}, + {-1/2, -1/2, -1/8, 1/2, 1/2, -1/8}, + + {-5/16, 1/4, -5/16, 5/16, 5/16, -1/8}, + {-5/16, 0, -1/4, -1/4, 1/4, -1/8}, + {1/4, 0, -1/4, 5/16, 1/4, -1/8}, + + {-1/16, -1/4, 1/8, 1/16, 1/4, 3/8}, + {-1/4, -1/16, 1/8, 1/4, 1/16, 3/8}, + {-1/4, -1/4, 3/8, 1/4, 1/4, 1/2 - 0.001} + } + }, + selection_box = { + type = "fixed", + fixed = { + -- box + {-5/16, -5/16, -1/8, 5/16, 1, 1/8}, + -- top + {-5/16, -1/8 + 1, -5/16, 5/16, -1/16 + 1, -1/8}, + {-5/16, -3/8 + 1, -1/4, -1/4, -1/8 + 1, -1/8}, + {1/4, -3/8 + 1, -1/4, 5/16, -1/8 + 1, -1/8}, + + {-1/8, 1/16 + 1, -1/8, 1/8, 5/16 + 1, 0}, + {-1/16, 1/8 + 1, 0, 1/16, 1/4 + 1, 1/8}, + {-1/16, 0 + 1, -1/16, 1/16, 1/4 + 1, 1/16}, + -- bottom + {-5/16, 1/4, -5/16, 5/16, 5/16, -1/8}, + {-5/16, 0, -1/4, -1/4, 1/4, -1/8}, + {1/4, 0, -1/4, 5/16, 1/4, -1/8}, + + {-1/16, -1/4, 1/8, 1/16, 1/4, 3/8}, + {-1/4, -1/16, 1/8, 1/4, 1/16, 3/8}, + {-1/4, -1/4, 3/8, 1/4, 1/4, 1/2 - 0.01} + } + }, + + after_place_node = function(pos) + local node = minetest.env:get_node(pos) + pos.y = pos.y + 1 + node.name = "infrastructure:traffic_lights_pedestrians_top_"..tostring(i) + minetest.env:add_node(pos, node) + end, + + after_dig_node = function(pos) + local node = minetest.env:get_node(pos) + quiet(pos) + pos.y = pos.y + 1 + node.name = "infrastructure:traffic_lights_pedestrians_top_"..tostring(i) + minetest.env:remove_node(pos) + end, + + on_punch = function(pos, node) + semaphores_pedestrians(pos, node) + end, + + mesecons = {effector = { + action_on = function(pos, node) + semaphores_pedestrians(pos, node) + end + }} + }) + end + + minetest.register_node("infrastructure:traffic_lights_pedestrians_bottom_1", { + description = "Traffic lights for pedestrians", + inventory_image = "infrastructure_traffic_lights_pedestrians.png", + wield_image = "infrastructure_traffic_lights_pedestrians.png", + tiles = { + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_side.png", + "infrastructure_traffic_lights_pedestrians_bottom_back.png", + "infrastructure_traffic_lights_pedestrians_bottom_front_1.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 3, not_in_creative_inventory = 0}, + light_source = TRAFFIC_LIGHTS_LIGHT_RANGE, + node_box = { + type = "fixed", + fixed = { + {-5/16, -5/16, -1/8, 5/16, 1/2, 1/8}, + {-1/2, -1/2, -1/8, 1/2, 1/2, -1/8}, + + {-5/16, 1/4, -5/16, 5/16, 5/16, -1/8}, + {-5/16, 0, -1/4, -1/4, 1/4, -1/8}, + {1/4, 0, -1/4, 5/16, 1/4, -1/8}, + + {-1/16, -1/4, 1/8, 1/16, 1/4, 3/8}, + {-1/4, -1/16, 1/8, 1/4, 1/16, 3/8}, + {-1/4, -1/4, 3/8, 1/4, 1/4, 1/2 - 0.001} + } + }, + selection_box = { + type = "fixed", + fixed = { + -- box + {-5/16, -5/16, -1/8, 5/16, 1, 1/8}, + -- top + {-5/16, -1/8 + 1, -5/16, 5/16, -1/16 + 1, -1/8}, + {-5/16, -3/8 + 1, -1/4, -1/4, -1/8 + 1, -1/8}, + {1/4, -3/8 + 1, -1/4, 5/16, -1/8 + 1, -1/8}, + + {-1/8, 1/16 + 1, -1/8, 1/8, 5/16 + 1, 0}, + {-1/16, 1/8 + 1, 0, 1/16, 1/4 + 1, 1/8}, + {-1/16, 0 + 1, -1/16, 1/16, 1/8 + 1, 1/16}, + -- bottom + {-5/16, 1/4, -5/16, 5/16, 5/16, -1/8}, + {-5/16, 0, -1/4, -1/4, 1/4, -1/8}, + {1/4, 0, -1/4, 5/16, 1/4, -1/8}, + + {-1/16, -1/4, 1/8, 1/16, 1/4, 3/8}, + {-1/4, -1/16, 1/8, 1/4, 1/16, 3/8}, + {-1/4, -1/4, 3/8, 1/4, 1/4, 1/2 - 0.01} + } + }, + + after_place_node = function(pos) + local node = minetest.env:get_node(pos) + pos.y = pos.y + 1 + node.name = "infrastructure:traffic_lights_pedestrians_top_1" + minetest.env:add_node(pos, node) + end, + + after_dig_node = function(pos) + local node = minetest.env:get_node(pos) + quiet(pos) + pos.y = pos.y + 1 + node.name = "infrastructure:traffic_lights_pedestrians_top_1" + minetest.env:remove_node(pos) + end, + + on_punch = function(pos, node) + semaphores_pedestrians(pos, node) + end, + + mesecons = {effector = { + action_on = function(pos, node) + semaphores_pedestrians(pos, node) + end + }} + }) + + minetest.register_alias("infrastructure:traffic_lights_pedestrians", "infrastructure:traffic_lights_pedestrians_bottom_1") diff --git a/mods/roads/infrastructure/advanced_warning_light.lua b/mods/roads/infrastructure/advanced_warning_light.lua new file mode 100644 index 0000000..0ed5b62 --- /dev/null +++ b/mods/roads/infrastructure/advanced_warning_light.lua @@ -0,0 +1,47 @@ +-- Warning light + +minetest.register_node("infrastructure:warning_light", { + description = "Warning light", + tiles = { + "infrastructure_warning_light_top.png", + "infrastructure_warning_light_bottom.png", + "infrastructure_warning_light_right.png", + "infrastructure_warning_light_left.png", + "infrastructure_warning_light_back.png", + {name="infrastructure_warning_light_front_anim.png",animation={type="vertical_frames", aspect_w=32, aspect_h=32, length=3}}, + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1}, + light_source = WARNING_LIGHT_LIGHT_RANGE, + node_box = { + type = "fixed", + fixed = { + {-5/16, -3/8, 0, 5/16, 0, 0}, + + {-1/4, -5/16, 0, 0, -1/16, 1/8}, + + {1/16, -1/2, -1/8, 5/16, -1/4, 1/8}, + + {-1/16, -1/2, -1/16, 1/16, -3/8, 1/16} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-5/16, -3/8, 0, 5/16, 0, 0}, + + {-1/4, -5/16, 0 + 0.01, 0, -1/16, 1/8}, + + {1/16, -1/2, -1/8, 5/16, -1/4, 1/8}, + + {-1/16, -1/2, -1/16, 1/16, -3/8, 1/16} + } + } +}) + + + +minetest.register_alias("infrastructure:warning_light_bright", "infrastructure:warning_light") +minetest.register_alias("infrastructure:warning_light_dark", "infrastructure:warning_light") diff --git a/mods/roads/infrastructure/crafts.lua b/mods/roads/infrastructure/crafts.lua new file mode 100644 index 0000000..752b1e0 --- /dev/null +++ b/mods/roads/infrastructure/crafts.lua @@ -0,0 +1,443 @@ +-- **************************************************************************************************** MATERIALS + +-- Galvanized steel + if minetest.get_modpath("technic") then + technic.register_alloy_recipe({input = {"default:steel_ingot 6", "technic:zinc_ingot 1"}, output = "infrastructure:galvanized_steel 6", time = 4}) + else + minetest.register_craft({ + output = '"infrastructure:galvanized_steel" 6', + recipe = { + {'', 'default:copper_ingot', ''}, + {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'}, + {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'} + } + }) + end + +-- Galvanized steel fence + minetest.register_craft({ + output = '"infrastructure:fence_galvanized_steel" 6', + recipe = { + {'infrastructure:galvanized_steel', 'infrastructure:galvanized_steel', 'infrastructure:galvanized_steel'}, + {'infrastructure:galvanized_steel', 'infrastructure:galvanized_steel', 'infrastructure:galvanized_steel'} + } + }) + +-- **************************************************************************************************** PRECAST CONCRETE + +-- Concrete seperating wall + minetest.register_craft({ + output = '"infrastructure:precast_concrete_seperating_wall" 5', + recipe = { + {'', 'infrastructure:concrete', ''}, + {'', 'infrastructure:concrete', ''}, + {'infrastructure:concrete', 'infrastructure:concrete', 'infrastructure:concrete'} + } + }) + +-- Concrete cylinder + minetest.register_craft({ + output = '"infrastructure:precast_concrete_cylinder" 8', + recipe = { + {'infrastructure:concrete', 'infrastructure:concrete', 'infrastructure:concrete'}, + {'infrastructure:concrete', '', 'infrastructure:concrete'}, + {'infrastructure:concrete', 'infrastructure:concrete', 'infrastructure:concrete'} + } + }) + +-- Concrete grid paver + minetest.register_craft({ + output = '"infrastructure:precast_concrete_grid_paver" 5', + recipe = { + {'infrastructure:concrete', '', 'infrastructure:concrete'}, + {'', 'infrastructure:concrete', ''}, + {'infrastructure:concrete', '', 'infrastructure:concrete'} + } + }) + +-- **************************************************************************************************** STEEL STRUCTURES + +-- Truss + minetest.register_craft({ + output = '"infrastructure:truss" 5', + recipe = { + {'infrastructure:galvanized_steel', '', 'infrastructure:galvanized_steel'}, + {'', 'infrastructure:galvanized_steel', ''}, + {'infrastructure:galvanized_steel', '', 'infrastructure:galvanized_steel'} + } + }) + +-- Wire netting + minetest.register_craft({ + output = '"infrastructure:wire_netting" 10', + recipe = { + {'', 'infrastructure:galvanized_steel', ''}, + {'infrastructure:galvanized_steel', '', 'infrastructure:galvanized_steel'}, + {'', 'infrastructure:galvanized_steel', ''} + } + }) + +-- Razor wire + minetest.register_craft({ + output = '"infrastructure:razor_wire" 5', + recipe = { + {'infrastructure:galvanized_steel'}, + {'default:cactus'}, + {'infrastructure:galvanized_steel'} + } + }) + +-- Drainage channel grating + minetest.register_craft({ + output = '"infrastructure:drainage_channel_grating" 2', + recipe = { + {'infrastructure:galvanized_steel', '', 'infrastructure:galvanized_steel'} + } + }) + +-- Louver + minetest.register_craft({ + output = '"infrastructure:drainage_channel_grating" 2', + recipe = { + {'infrastructure:galvanized_steel'}, + {''}, + {'infrastructure:galvanized_steel'} + } + }) + +-- Riffled sheet + minetest.register_craft({ + output = '"infrastructure:riffled_sheet" 4', + recipe = { + {'infrastructure:galvanized_steel', 'infrastructure:fence_galvanized_steel'}, + {'infrastructure:fence_galvanized_steel', 'infrastructure:galvanized_steel'} + } + }) + +-- Corrugated sheet + minetest.register_craft({ + output = '"infrastructure:corrugated_sheet" 4', + recipe = { + {"","infrastructure:galvanized_steel",""}, + {"infrastructure:galvanized_steel","","infrastructure:galvanized_steel"} + } + }) + +-- Louvers + minetest.register_craft({ + output = "infrastructure:louver_opened", + recipe = { + {"infrastructure:fence_galvanized_steel","infrastructure:galvanized_steel","infrastructure:fence_galvanized_steel"}, + {"","",""}, + {"infrastructure:fence_galvanized_steel","infrastructure:galvanized_steel","infrastructure:fence_galvanized_steel"} + } + }) + +-- **************************************************************************************************** ADVANCED ITEMS + +-- Raised pavement marker yellow/yellow + minetest.register_craft({ + output = '"infrastructure:marker_yellow_yellow" 1', + recipe = { + {'wool:yellow', 'infrastructure:asphalt', 'wool:yellow'}, + {'infrastructure:asphalt', 'infrastructure:asphalt', 'infrastructure:asphalt'} + } + }) + +-- Raised pavement marker red/yellow + minetest.register_craft({ + output = '"infrastructure:marker_red_yellow" 1', + recipe = { + {'wool:yellow', 'infrastructure:asphalt', 'wool:red'}, + {'infrastructure:asphalt', 'infrastructure:asphalt', 'infrastructure:asphalt'} + } + }) + +-- Retroreflective delineators + minetest.register_craft({ + output = '"infrastructure:delineator" 1', + recipe = { + {'wool:yellow', 'infrastructure:concrete', 'wool:red'}, + {'', 'infrastructure:concrete', ''}, + {'', 'infrastructure:concrete', ''} + } + }) + + minetest.register_craft({ + output = '"infrastructure:delineator_guardrail" 1', + recipe = { + {'wool:yellow', 'infrastructure:concrete', 'wool:red'}, + {'', 'infrastructure:concrete', ''} + } + }) + +-- Wire rope safety barrier + minetest.register_craft({ + output = '"infrastructure:wire_rope_safety_barrier" 1', + recipe = { + {'default:steel_ingot', '', 'default:steel_ingot'}, + {'', 'default:steel_ingot', ''}, + {'', 'default:steel_ingot', ''} + } + }) + +-- Cable barrier terminal + minetest.register_craft({ + output = '"infrastructure:cable_barrier_terminal" 1', + recipe = { + {'default:steel_ingot', '', ''}, + {'', 'default:steel_ingot', ''}, + {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'} + } + }) + +-- Corrugated guide rail + minetest.register_craft({ + output = '"infrastructure:corrugated_guide_rail" 1', + recipe = { + {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'}, + {'', 'default:steel_ingot', ''}, + {'', 'default:steel_ingot', ''} + } + }) + +-- Energy absorbing terminal + minetest.register_craft({ + output = '"infrastructure:energy_absorbing_terminal" 1', + recipe = { + {'', 'default:steel_ingot', ''}, + {'default:steel_ingot', 'default:steel_ingot', ''}, + {'', 'default:steel_ingot', ''} + } + }) + + minetest.register_craft({ + output = '"infrastructure:energy_absorbing_terminal" 1', + recipe = { + {'infrastructure:energy_absorbing_terminal_inversed'} + } + }) + + minetest.register_craft({ + output = '"infrastructure:energy_absorbing_terminal_inversed" 1', + recipe = { + {'infrastructure:energy_absorbing_terminal'} + } + }) + +-- Fitch barrel + minetest.register_craft({ + output = '"infrastructure:fitch_barrel" 1', + recipe = { + {'wool:black', 'wool:black', 'wool:black'}, + {'wool:yellow', 'default:sand', 'wool:yellow'}, + {'wool:yellow', 'wool:yellow', 'wool:yellow'} + } + }) + +-- Crowd control barricade + minetest.register_craft({ + output = '"infrastructure:crowd_control_barricade" 1', + recipe = { + {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'}, + {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'}, + {'default:steel_ingot', '', 'default:steel_ingot'} + } + }) + +if ENABLE_EMERGENCY_PHONE then +-- Emergency phone + minetest.register_craft({ + output = '"infrastructure:emergency_phone" 1', + recipe = { + {'default:mese_crystal', 'default:mese_crystal', 'default:mese_crystal'}, + {'default:mese_crystal', 'default:apple', 'default:mese_crystal'}, + {'default:mese_crystal', 'default:stick', 'default:mese_crystal'} + } + }) + minetest.register_craft({ + output = '"infrastructure:emergency_phone" 1', + recipe = { + {'default:mese', 'default:mese', 'default:mese'}, + {'default:mese', 'default:apple', 'default:mese'}, + {'default:mese', 'default:stick', 'default:mese'} + } + }) +end + +-- Manhole cover + minetest.register_craft({ + output = '"infrastructure:manhole_cover_closed" 1', + recipe = { + {'infrastructure:concrete', 'infrastructure:concrete', 'infrastructure:concrete'}, + {'infrastructure:concrete', 'default:steel_ingot', 'infrastructure:concrete'}, + {'infrastructure:concrete', 'infrastructure:concrete', 'infrastructure:concrete'} + } + }) + +-- Traffic lights for pedestrians + minetest.register_craft({ + output = '"infrastructure:traffic_lights_pedestrians" 1', + recipe = { + {'', 'default:steel_ingot', ''}, + {'default:steel_ingot', 'wool:red', 'default:steel_ingot'}, + {'default:steel_ingot', 'wool:green', 'default:steel_ingot'} + } + }) + +-- Crosswalk warning light + minetest.register_craft({ + output = '"infrastructure:crosswalk_warning_light" 1', + recipe = { + {'', 'default:steel_ingot', ''}, + {'default:steel_ingot', 'wool:yellow', 'default:steel_ingot'}, + {'', 'wool:green', ''} + } + }) + +-- Curve chevron + minetest.register_craft({ + output = '"infrastructure:curve_chevron" 1', + recipe = { + {'wool:yellow', 'wool:black', 'wool:yellow'}, + {'wool:black', 'wool:yellow', 'wool:yellow'}, + {'wool:yellow', 'wool:black', 'wool:yellow'} + } + }) + +-- Crosswalk lighting + minetest.register_craft({ + output = '"infrastructure:crosswalk_lighting" 1', + recipe = { + {'wool:white', 'wool:white', 'wool:white'}, + {'', 'mesecons_torch:mesecon_torch_on', ''}, + {'wool:white', 'wool:white', 'wool:white'} + } + }) + +-- Crosswalk safety sign + minetest.register_craft({ + output = '"infrastructure:crosswalk_safety_sign" 1', + recipe = { + {'', 'wool:green', ''}, + {'', 'wool:green', ''}, + {'infrastructure:concrete', 'infrastructure:concrete', 'infrastructure:concrete'} + } + }) + +-- Road sign crosswalk + minetest.register_craft({ + output = '"infrastructure:road_sign_crosswalk" 1', + recipe = { + {'wool:green', 'wool:green', 'wool:green'}, + {'wool:green', 'wool:blue', 'wool:green'}, + {'wool:green', 'wool:green', 'wool:green'} + } + }) + +-- Road sign right_of_way + minetest.register_craft({ + output = '"infrastructure:road_sign_right_of_way" 1', + recipe = { + {"", 'wool:white', ""}, + {'wool:white', 'wool:yellow', 'wool:white'}, + {"", 'wool:white', ""} + } + }) + +-- Road sign stop + minetest.register_craft({ + output = '"infrastructure:road_sign_stop" 1', + recipe = { + {'wool:red', 'wool:red', 'wool:red'}, + {'wool:red', 'wool:white', 'wool:red'}, + {'wool:red', 'wool:red', 'wool:red'} + } + }) + +-- Road sign yield + minetest.register_craft({ + output = '"infrastructure:road_sign_yield" 1', + recipe = { + {'wool:orange', 'wool:orange', 'wool:orange'}, + {'wool:red', 'wool:orange', 'wool:red'}, + {'', 'wool:red', ''} + } + }) + +-- Automatic warning device + minetest.register_craft({ + output = '"infrastructure:automatic_warning_device" 1', + recipe = { + {'wool:red', 'default:steel_ingot', 'wool:red'}, + {'', 'default:steel_ingot', ''}, + {'infrastructure:concrete', 'infrastructure:concrete', 'infrastructure:concrete'} + } + }) + +-- Boom barrier + minetest.register_craft({ + output = '"infrastructure:boom_barrier_mechanism" 1', + recipe = { + {'default:steel_ingot', 'default:steel_ingot', ''}, + {'', 'default:steel_ingot', ''}, + {'infrastructure:concrete', 'infrastructure:concrete', 'infrastructure:concrete'} + } + }) + + minetest.register_craft({ + output = '"infrastructure:boom_barrier_arm" 1', + recipe = { + {'', 'wool:red', ''}, + {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'} + } + }) + +-- Aircraft warning light + minetest.register_craft({ + output = '"infrastructure:aircraft_warning_light" 1', + recipe = { + {'', 'wool:red', ''}, + {'wool:red', 'default:torch', 'wool:red'}, + {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'} + } + }) + +-- Warning light + minetest.register_craft({ + output = '"infrastructure:warning_light" 1', + recipe = { + {'wool:yellow', 'wool:yellow', ''}, + {'wool:yellow', 'default:torch', ''}, + {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'} + } + }) + +-- Anti-dazzling panel + minetest.register_craft({ + output = '"infrastructure:anti_dazzling_panel" 1', + recipe = { + {'wool:grey', 'wool:grey'}, + {'wool:grey', 'wool:yellow'}, + {'wool:grey', 'wool:grey'} + } + }) + +-- Traffic cone + minetest.register_craft({ + output = '"infrastructure:traffic_cone" 1', + recipe = { + {'', 'wool:orange', ''}, + {'wool:orange', '', 'wool:orange'}, + } + }) + +-- Noise barrier + minetest.register_craft({ + output = '"infrastructure:noise_barrier" 1', + recipe = { + {'default:steel_ingot', 'wool:green', 'default:steel_ingot'}, + {'wool:green', 'default:steel_ingot', 'wool:green'}, + {'default:steel_ingot', 'wool:green', 'default:steel_ingot'} + } + }) diff --git a/mods/roads/infrastructure/depends.txt b/mods/roads/infrastructure/depends.txt new file mode 100644 index 0000000..e8e7747 --- /dev/null +++ b/mods/roads/infrastructure/depends.txt @@ -0,0 +1,6 @@ +sounds +moreblocks? +wool? +streetsmod +digilines? +technic? diff --git a/mods/roads/infrastructure/init.lua b/mods/roads/infrastructure/init.lua new file mode 100644 index 0000000..56b071e --- /dev/null +++ b/mods/roads/infrastructure/init.lua @@ -0,0 +1,26 @@ +infrastructure = {} + +-- Load settings +dofile(minetest.get_modpath("infrastructure").."/settings.lua") + +-- Register nodes +dofile(minetest.get_modpath("infrastructure").."/nodes.lua") +-- Register special nodes +dofile(minetest.get_modpath("infrastructure").."/nodes_extension.lua") +-- Register advanced devices +dofile(minetest.get_modpath("infrastructure").."/advanced_road_signs.lua") +dofile(minetest.get_modpath("infrastructure").."/advanced_emergency_phone.lua") +dofile(minetest.get_modpath("infrastructure").."/advanced_traffic_lights_pedestrians.lua") +dofile(minetest.get_modpath("infrastructure").."/advanced_crosswalk_warning_light.lua") +dofile(minetest.get_modpath("infrastructure").."/advanced_lane_control_lights.lua") +dofile(minetest.get_modpath("infrastructure").."/advanced_curve_chevron.lua") +dofile(minetest.get_modpath("infrastructure").."/advanced_crosswalk_lighting.lua") +dofile(minetest.get_modpath("infrastructure").."/advanced_crosswalk_safety_sign.lua") +dofile(minetest.get_modpath("infrastructure").."/advanced_automatic_warning_device.lua") +dofile(minetest.get_modpath("infrastructure").."/advanced_boom_barrier.lua") +dofile(minetest.get_modpath("infrastructure").."/advanced_aircraft_warning_light.lua") +dofile(minetest.get_modpath("infrastructure").."/advanced_warning_light.lua") +-- Register crafting recipes +dofile(minetest.get_modpath("infrastructure").."/crafts.lua") + +print("Infrastructure mod loaded succesfully!") diff --git a/mods/roads/infrastructure/models/infrastructure_traffic_cone.obj b/mods/roads/infrastructure/models/infrastructure_traffic_cone.obj new file mode 100644 index 0000000..c309b32 --- /dev/null +++ b/mods/roads/infrastructure/models/infrastructure_traffic_cone.obj @@ -0,0 +1,1045 @@ +# Blender v2.79 (sub 0) OBJ File: 'traffic cone.blend' +# www.blender.org +o Cylinder +v 0.000000 -0.474600 0.203250 +v -0.039652 -0.474600 0.199345 +v -0.077780 -0.474600 0.187779 +v -0.112920 -0.474600 0.168996 +v -0.143719 -0.474600 0.143719 +v -0.168996 -0.474600 0.112920 +v -0.187779 -0.474600 0.077780 +v -0.199345 -0.474600 0.039652 +v -0.203250 -0.474600 0.000000 +v -0.199345 -0.474600 -0.039652 +v -0.187779 -0.474600 -0.077780 +v -0.168996 -0.474600 -0.112920 +v -0.143719 -0.474600 -0.143719 +v -0.112920 -0.474600 -0.168996 +v -0.077780 -0.474600 -0.187779 +v -0.039652 -0.474600 -0.199345 +v 0.000000 -0.474600 -0.203250 +v 0.039652 -0.474600 -0.199345 +v 0.077781 -0.474600 -0.187778 +v 0.112920 -0.474600 -0.168996 +v 0.143720 -0.474600 -0.143719 +v 0.168996 -0.474600 -0.112920 +v 0.187779 -0.474600 -0.077780 +v 0.199345 -0.474600 -0.039652 +v 0.203250 -0.474600 0.000000 +v 0.199345 -0.474600 0.039652 +v 0.187778 -0.474600 0.077781 +v 0.168996 -0.474600 0.112920 +v 0.143719 -0.474600 0.143720 +v 0.112919 -0.474600 0.168996 +v 0.077780 -0.474600 0.187779 +v 0.039652 -0.474600 0.199345 +v 0.191399 -0.500000 -0.250000 +v 0.250000 -0.500000 -0.191399 +v 0.202831 -0.500000 -0.248874 +v 0.213825 -0.500000 -0.245539 +v 0.223956 -0.500000 -0.240124 +v 0.232836 -0.500000 -0.232836 +v 0.240124 -0.500000 -0.223956 +v 0.245539 -0.500000 -0.213825 +v 0.248874 -0.500000 -0.202831 +v -0.250000 -0.500000 -0.191399 +v -0.191399 -0.500000 -0.250000 +v -0.248874 -0.500000 -0.202831 +v -0.245539 -0.500000 -0.213825 +v -0.240124 -0.500000 -0.223956 +v -0.232836 -0.500000 -0.232836 +v -0.223956 -0.500000 -0.240124 +v -0.213825 -0.500000 -0.245539 +v -0.202831 -0.500000 -0.248874 +v 0.250000 -0.500000 0.191399 +v 0.191399 -0.500000 0.250000 +v 0.248874 -0.500000 0.202831 +v 0.245539 -0.500000 0.213825 +v 0.240124 -0.500000 0.223956 +v 0.232836 -0.500000 0.232836 +v 0.223956 -0.500000 0.240124 +v 0.213825 -0.500000 0.245539 +v 0.202831 -0.500000 0.248874 +v -0.191399 -0.500000 0.250000 +v -0.250000 -0.500000 0.191399 +v -0.202831 -0.500000 0.248874 +v -0.213825 -0.500000 0.245539 +v -0.223956 -0.500000 0.240124 +v -0.232836 -0.500000 0.232836 +v -0.240124 -0.500000 0.223956 +v -0.245539 -0.500000 0.213825 +v -0.248874 -0.500000 0.202831 +v 0.191399 -0.474600 0.250000 +v 0.250000 -0.474600 0.191399 +v 0.202831 -0.474600 0.248874 +v 0.213825 -0.474600 0.245539 +v 0.223956 -0.474600 0.240124 +v 0.232836 -0.474600 0.232836 +v 0.240124 -0.474600 0.223956 +v 0.245539 -0.474600 0.213825 +v 0.248874 -0.474600 0.202831 +v 0.250000 -0.474600 -0.191399 +v 0.191399 -0.474600 -0.250000 +v 0.248874 -0.474600 -0.202831 +v 0.245539 -0.474600 -0.213825 +v 0.240124 -0.474600 -0.223956 +v 0.232836 -0.474600 -0.232836 +v 0.223956 -0.474600 -0.240124 +v 0.213825 -0.474600 -0.245539 +v 0.202831 -0.474600 -0.248874 +v -0.191399 -0.474600 -0.250000 +v -0.250000 -0.474600 -0.191399 +v -0.202831 -0.474600 -0.248874 +v -0.213825 -0.474600 -0.245539 +v -0.223956 -0.474600 -0.240124 +v -0.232836 -0.474600 -0.232836 +v -0.240124 -0.474600 -0.223956 +v -0.245539 -0.474600 -0.213825 +v -0.248874 -0.474600 -0.202831 +v -0.250000 -0.474600 0.191399 +v -0.191399 -0.474600 0.250000 +v -0.248874 -0.474600 0.202831 +v -0.245539 -0.474600 0.213825 +v -0.240124 -0.474600 0.223956 +v -0.232836 -0.474600 0.232836 +v -0.223956 -0.474600 0.240124 +v -0.213825 -0.474600 0.245539 +v -0.202831 -0.474600 0.248874 +v -0.000000 0.313000 0.013552 +v 0.000000 0.301498 0.027995 +v -0.000000 0.311459 0.019823 +v -0.000000 0.307249 0.025109 +v -0.002644 0.313000 0.013292 +v -0.005462 0.301498 0.027457 +v -0.003867 0.311459 0.019442 +v -0.004899 0.307249 0.024627 +v -0.005186 0.313000 0.012521 +v -0.010713 0.301498 0.025864 +v -0.007586 0.311459 0.018314 +v -0.009609 0.307249 0.023198 +v -0.007529 0.313000 0.011268 +v -0.015553 0.301498 0.023277 +v -0.011013 0.311459 0.016482 +v -0.013950 0.307249 0.020878 +v -0.009583 0.313000 0.009583 +v -0.019795 0.301498 0.019795 +v -0.014017 0.311459 0.014017 +v -0.017755 0.307249 0.017755 +v -0.011268 0.313000 0.007529 +v -0.023277 0.301498 0.015553 +v -0.016482 0.311459 0.011013 +v -0.020878 0.307249 0.013950 +v -0.012521 0.313000 0.005186 +v -0.025864 0.301498 0.010713 +v -0.018314 0.311459 0.007586 +v -0.023198 0.307249 0.009609 +v -0.013292 0.313000 0.002644 +v -0.027457 0.301498 0.005462 +v -0.019442 0.311459 0.003867 +v -0.024627 0.307249 0.004899 +v -0.013552 0.313000 -0.000000 +v -0.027995 0.301498 0.000000 +v -0.019823 0.311459 0.000000 +v -0.025109 0.307249 0.000000 +v -0.013292 0.313000 -0.002644 +v -0.027457 0.301498 -0.005462 +v -0.019442 0.311459 -0.003867 +v -0.024627 0.307249 -0.004899 +v -0.012521 0.313000 -0.005186 +v -0.025864 0.301498 -0.010713 +v -0.018314 0.311459 -0.007586 +v -0.023198 0.307249 -0.009609 +v -0.011268 0.313000 -0.007529 +v -0.023277 0.301498 -0.015553 +v -0.016482 0.311459 -0.011013 +v -0.020878 0.307249 -0.013950 +v -0.009583 0.313000 -0.009583 +v -0.019795 0.301498 -0.019795 +v -0.014017 0.311459 -0.014017 +v -0.017755 0.307249 -0.017755 +v -0.007529 0.313000 -0.011268 +v -0.015553 0.301498 -0.023277 +v -0.011013 0.311459 -0.016482 +v -0.013950 0.307249 -0.020878 +v -0.005186 0.313000 -0.012521 +v -0.010713 0.301498 -0.025864 +v -0.007586 0.311459 -0.018314 +v -0.009609 0.307249 -0.023198 +v -0.002644 0.313000 -0.013292 +v -0.005462 0.301498 -0.027457 +v -0.003867 0.311459 -0.019442 +v -0.004899 0.307249 -0.024627 +v 0.000000 0.313000 -0.013552 +v 0.000000 0.301498 -0.027995 +v 0.000000 0.311459 -0.019823 +v 0.000000 0.307249 -0.025109 +v 0.002644 0.313000 -0.013292 +v 0.005462 0.301498 -0.027457 +v 0.003867 0.311459 -0.019442 +v 0.004899 0.307249 -0.024627 +v 0.005186 0.313000 -0.012521 +v 0.010713 0.301498 -0.025864 +v 0.007586 0.311459 -0.018314 +v 0.009609 0.307249 -0.023198 +v 0.007529 0.313000 -0.011268 +v 0.015553 0.301498 -0.023277 +v 0.011013 0.311459 -0.016482 +v 0.013950 0.307249 -0.020878 +v 0.009583 0.313000 -0.009583 +v 0.019795 0.301498 -0.019795 +v 0.014017 0.311459 -0.014017 +v 0.017755 0.307249 -0.017755 +v 0.011268 0.313000 -0.007529 +v 0.023277 0.301498 -0.015553 +v 0.016482 0.311459 -0.011013 +v 0.020878 0.307249 -0.013950 +v 0.012521 0.313000 -0.005186 +v 0.025864 0.301498 -0.010713 +v 0.018314 0.311459 -0.007586 +v 0.023198 0.307249 -0.009609 +v 0.013292 0.313000 -0.002644 +v 0.027457 0.301498 -0.005462 +v 0.019442 0.311459 -0.003867 +v 0.024627 0.307249 -0.004899 +v 0.013552 0.313000 0.000000 +v 0.027995 0.301498 0.000000 +v 0.019823 0.311459 0.000000 +v 0.025109 0.307249 0.000000 +v 0.013292 0.313000 0.002644 +v 0.027457 0.301498 0.005462 +v 0.019442 0.311459 0.003867 +v 0.024627 0.307249 0.004899 +v 0.012521 0.313000 0.005186 +v 0.025864 0.301498 0.010713 +v 0.018314 0.311459 0.007586 +v 0.023198 0.307249 0.009609 +v 0.011268 0.313000 0.007529 +v 0.023277 0.301498 0.015553 +v 0.016482 0.311459 0.011013 +v 0.020878 0.307249 0.013950 +v 0.009583 0.313000 0.009583 +v 0.019795 0.301498 0.019795 +v 0.014017 0.311459 0.014017 +v 0.017755 0.307249 0.017755 +v 0.007529 0.313000 0.011268 +v 0.015553 0.301498 0.023277 +v 0.011013 0.311459 0.016482 +v 0.013950 0.307249 0.020878 +v 0.005186 0.313000 0.012521 +v 0.010713 0.301498 0.025864 +v 0.007586 0.311459 0.018314 +v 0.009609 0.307249 0.023198 +v 0.002644 0.313000 0.013292 +v 0.005462 0.301498 0.027457 +v 0.003867 0.311459 0.019442 +v 0.004899 0.307249 0.024627 +vt 0.444971 0.003030 +vt 0.436198 0.003866 +vt 0.427761 0.006342 +vt 0.419987 0.010362 +vt 0.413172 0.015773 +vt 0.407579 0.022366 +vt 0.403423 0.029887 +vt 0.400864 0.038049 +vt 0.400000 0.046537 +vt 0.400000 0.330730 +vt 0.400864 0.339218 +vt 0.403423 0.347380 +vt 0.407579 0.354901 +vt 0.413172 0.361494 +vt 0.419987 0.366905 +vt 0.427761 0.370925 +vt 0.436198 0.373401 +vt 0.444971 0.374237 +vt 0.738735 0.374237 +vt 0.747508 0.373401 +vt 0.755944 0.370925 +vt 0.763719 0.366905 +vt 0.770534 0.361494 +vt 0.776127 0.354901 +vt 0.780283 0.347380 +vt 0.782842 0.339218 +vt 0.783706 0.330730 +vt 0.783706 0.046537 +vt 0.782842 0.038049 +vt 0.780283 0.029887 +vt 0.776127 0.022366 +vt 0.770534 0.015773 +vt 0.763719 0.010362 +vt 0.755944 0.006342 +vt 0.747508 0.003866 +vt 0.738735 0.003030 +vt 0.003125 0.046537 +vt 0.003989 0.038049 +vt 0.006548 0.029887 +vt 0.010704 0.022366 +vt 0.016297 0.015773 +vt 0.023112 0.010362 +vt 0.030886 0.006342 +vt 0.039323 0.003866 +vt 0.048096 0.003030 +vt 0.341860 0.003030 +vt 0.350633 0.003866 +vt 0.359069 0.006342 +vt 0.366844 0.010362 +vt 0.373659 0.015773 +vt 0.379252 0.022366 +vt 0.383408 0.029887 +vt 0.385967 0.038049 +vt 0.386831 0.046537 +vt 0.386831 0.330730 +vt 0.385967 0.339218 +vt 0.383408 0.347380 +vt 0.379252 0.354901 +vt 0.373659 0.361494 +vt 0.366844 0.366905 +vt 0.359069 0.370925 +vt 0.350633 0.373401 +vt 0.341860 0.374237 +vt 0.048096 0.374237 +vt 0.039323 0.373401 +vt 0.030886 0.370925 +vt 0.023112 0.366905 +vt 0.016297 0.361494 +vt 0.010704 0.354901 +vt 0.006548 0.347380 +vt 0.003989 0.339218 +vt 0.003125 0.330730 +vt 1.000000 0.403030 +vt 1.000000 0.988340 +vt 0.968750 0.988340 +vt 0.968750 0.403030 +vt 0.906250 0.403030 +vt 0.906250 0.988340 +vt 0.875000 0.988340 +vt 0.875000 0.403030 +vt 0.843750 0.988340 +vt 0.843750 0.403030 +vt 0.812500 0.988340 +vt 0.812500 0.403030 +vt 0.781250 0.988340 +vt 0.781250 0.403030 +vt 0.750000 0.988340 +vt 0.750000 0.403030 +vt 0.718750 0.988340 +vt 0.718750 0.403030 +vt 0.718750 0.988340 +vt 0.687500 0.988340 +vt 0.687500 0.403030 +vt 0.656250 0.988340 +vt 0.656250 0.403030 +vt 0.625000 0.988340 +vt 0.625000 0.403030 +vt 0.593750 0.988340 +vt 0.593750 0.403030 +vt 0.562500 0.988340 +vt 0.562500 0.403030 +vt 0.531250 0.988340 +vt 0.531250 0.403030 +vt 0.500000 0.988340 +vt 0.500000 0.403030 +vt 0.468750 0.988340 +vt 0.468750 0.403030 +vt 0.437500 0.988340 +vt 0.437500 0.403030 +vt 0.406250 0.988340 +vt 0.406250 0.403030 +vt 0.375000 0.988340 +vt 0.375000 0.403030 +vt 0.343750 0.988340 +vt 0.343750 0.403030 +vt 0.312500 0.988340 +vt 0.312500 0.403030 +vt 0.281250 0.988340 +vt 0.281250 0.403030 +vt 0.250000 0.988340 +vt 0.250000 0.403030 +vt 0.218750 0.988340 +vt 0.218750 0.403030 +vt 0.187500 0.988340 +vt 0.187500 0.403030 +vt 0.156250 0.988340 +vt 0.156250 0.403030 +vt 0.125000 0.988340 +vt 0.125000 0.403030 +vt 0.093750 0.988340 +vt 0.093750 0.403030 +vt 0.062500 0.988340 +vt 0.062500 0.403030 +vt 0.031250 0.988340 +vt 0.031250 0.403030 +vt 0.000000 0.988340 +vt 0.000000 0.403030 +vt 0.968750 0.988340 +vt 0.937500 0.988340 +vt 0.937500 0.403030 +vt 0.300000 0.384848 +vt 0.500000 0.384848 +vt 0.500000 0.396970 +vt 0.300000 0.396970 +vt 0.800000 0.384848 +vt 1.000000 0.384848 +vt 1.000000 0.396970 +vt 0.800000 0.396970 +vt 0.550000 0.384848 +vt 0.750000 0.384848 +vt 0.750000 0.396970 +vt 0.550000 0.396970 +vt 0.793750 0.396970 +vt 0.793750 0.384848 +vt 0.787500 0.396970 +vt 0.787500 0.384848 +vt 0.781250 0.396970 +vt 0.781250 0.384848 +vt 0.775000 0.396970 +vt 0.775000 0.384848 +vt 0.768750 0.396970 +vt 0.768750 0.384848 +vt 0.762500 0.396970 +vt 0.762500 0.384848 +vt 0.756250 0.396970 +vt 0.756250 0.384848 +vt 0.506250 0.384848 +vt 0.506250 0.396970 +vt 0.512500 0.384848 +vt 0.512500 0.396970 +vt 0.518750 0.384848 +vt 0.518750 0.396970 +vt 0.525000 0.384848 +vt 0.525000 0.396970 +vt 0.531250 0.384848 +vt 0.531250 0.396970 +vt 0.537500 0.384848 +vt 0.537500 0.396970 +vt 0.543750 0.384848 +vt 0.543750 0.396970 +vt 0.293750 0.396970 +vt 0.293750 0.384848 +vt 0.287500 0.396970 +vt 0.287500 0.384848 +vt 0.281250 0.396970 +vt 0.281250 0.384848 +vt 0.275000 0.396970 +vt 0.275000 0.384848 +vt 0.268750 0.396970 +vt 0.268750 0.384848 +vt 0.262500 0.396970 +vt 0.262500 0.384848 +vt 0.256250 0.396970 +vt 0.256250 0.384848 +vt 0.250000 0.396970 +vt 0.250000 0.384848 +vt 0.000000 0.396970 +vt 0.000000 0.384848 +vt 0.006250 0.384848 +vt 0.006250 0.396970 +vt 0.012500 0.384848 +vt 0.012500 0.396970 +vt 0.018750 0.384848 +vt 0.018750 0.396970 +vt 0.025000 0.384848 +vt 0.025000 0.396970 +vt 0.031250 0.384848 +vt 0.031250 0.396970 +vt 0.037500 0.384848 +vt 0.037500 0.396970 +vt 0.043750 0.384848 +vt 0.043750 0.396970 +vt 0.050000 0.384848 +vt 0.050000 0.396970 +vt 0.967870 0.992909 +vt 0.938380 0.992909 +vt 0.965320 0.996970 +vt 0.940930 0.996970 +vt 0.200485 0.203811 +vt 0.197517 0.204093 +vt 0.197517 0.199438 +vt 0.199546 0.199244 +vt 0.936620 0.992908 +vt 0.907130 0.992909 +vt 0.934070 0.996970 +vt 0.909680 0.996970 +vt 0.203338 0.202973 +vt 0.201497 0.198672 +vt 0.905370 0.992909 +vt 0.875880 0.992909 +vt 0.902820 0.996970 +vt 0.878429 0.996970 +vt 0.205968 0.201613 +vt 0.203295 0.197742 +vt 0.874120 0.992908 +vt 0.844630 0.992909 +vt 0.871571 0.996970 +vt 0.847180 0.996970 +vt 0.208274 0.199783 +vt 0.204871 0.196491 +vt 0.842870 0.992908 +vt 0.813380 0.992908 +vt 0.840320 0.996970 +vt 0.815929 0.996970 +vt 0.210165 0.197553 +vt 0.206164 0.194966 +vt 0.811620 0.992909 +vt 0.782130 0.992909 +vt 0.809071 0.996970 +vt 0.784680 0.996970 +vt 0.211571 0.195008 +vt 0.207125 0.193227 +vt 0.780370 0.992909 +vt 0.750880 0.992908 +vt 0.777820 0.996970 +vt 0.753429 0.996970 +vt 0.212437 0.192248 +vt 0.207717 0.191339 +vt 0.749120 0.992909 +vt 0.719630 0.992909 +vt 0.746570 0.996970 +vt 0.722180 0.996970 +vt 0.212729 0.189376 +vt 0.207917 0.189376 +vt 0.717870 0.992908 +vt 0.688380 0.992908 +vt 0.715320 0.996970 +vt 0.690930 0.996970 +vt 0.212437 0.186505 +vt 0.207717 0.187414 +vt 0.686620 0.992909 +vt 0.657130 0.992909 +vt 0.684071 0.996970 +vt 0.659680 0.996970 +vt 0.211571 0.183745 +vt 0.207125 0.185526 +vt 0.655370 0.992908 +vt 0.625880 0.992908 +vt 0.652820 0.996970 +vt 0.628429 0.996970 +vt 0.210165 0.181200 +vt 0.206164 0.183787 +vt 0.624120 0.992908 +vt 0.594630 0.992909 +vt 0.621571 0.996970 +vt 0.597180 0.996970 +vt 0.208274 0.178970 +vt 0.204871 0.182262 +vt 0.592870 0.992908 +vt 0.563380 0.992908 +vt 0.590320 0.996970 +vt 0.565930 0.996970 +vt 0.205968 0.177140 +vt 0.203295 0.181011 +vt 0.561620 0.992909 +vt 0.532130 0.992908 +vt 0.559071 0.996970 +vt 0.534680 0.996970 +vt 0.203338 0.175780 +vt 0.201497 0.180081 +vt 0.530370 0.992909 +vt 0.500880 0.992908 +vt 0.527820 0.996970 +vt 0.503430 0.996970 +vt 0.200485 0.174942 +vt 0.199546 0.179508 +vt 0.499120 0.992909 +vt 0.469630 0.992909 +vt 0.496570 0.996970 +vt 0.472180 0.996970 +vt 0.197517 0.174660 +vt 0.197517 0.179315 +vt 0.467870 0.992909 +vt 0.438380 0.992909 +vt 0.465320 0.996970 +vt 0.440930 0.996970 +vt 0.194549 0.174942 +vt 0.195488 0.179508 +vt 0.436620 0.992909 +vt 0.407130 0.992909 +vt 0.434070 0.996970 +vt 0.409680 0.996970 +vt 0.191695 0.175780 +vt 0.193537 0.180081 +vt 0.405370 0.992909 +vt 0.375880 0.992909 +vt 0.402820 0.996970 +vt 0.378430 0.996970 +vt 0.189065 0.177140 +vt 0.191739 0.181011 +vt 0.374120 0.992909 +vt 0.344630 0.992909 +vt 0.371570 0.996970 +vt 0.347180 0.996970 +vt 0.186760 0.178970 +vt 0.190163 0.182262 +vt 0.342870 0.992909 +vt 0.313380 0.992908 +vt 0.340320 0.996970 +vt 0.315930 0.996970 +vt 0.184868 0.181200 +vt 0.188869 0.183787 +vt 0.311620 0.992909 +vt 0.282130 0.992909 +vt 0.309070 0.996970 +vt 0.284680 0.996970 +vt 0.183462 0.183745 +vt 0.187908 0.185526 +vt 0.280370 0.992909 +vt 0.250880 0.992909 +vt 0.277820 0.996970 +vt 0.253430 0.996970 +vt 0.182597 0.186505 +vt 0.187317 0.187414 +vt 0.249120 0.992909 +vt 0.219630 0.992909 +vt 0.246570 0.996970 +vt 0.222180 0.996970 +vt 0.182304 0.189376 +vt 0.187117 0.189376 +vt 0.217870 0.992909 +vt 0.188380 0.992909 +vt 0.215320 0.996970 +vt 0.190930 0.996970 +vt 0.182597 0.192248 +vt 0.187317 0.191339 +vt 0.186620 0.992909 +vt 0.157130 0.992909 +vt 0.184070 0.996970 +vt 0.159680 0.996970 +vt 0.183462 0.195008 +vt 0.187908 0.193227 +vt 0.155370 0.992909 +vt 0.125880 0.992909 +vt 0.152820 0.996970 +vt 0.128430 0.996970 +vt 0.184868 0.197553 +vt 0.188869 0.194966 +vt 0.124120 0.992909 +vt 0.094630 0.992909 +vt 0.121570 0.996970 +vt 0.097180 0.996970 +vt 0.186760 0.199783 +vt 0.190163 0.196491 +vt 0.092870 0.992909 +vt 0.063380 0.992909 +vt 0.090320 0.996970 +vt 0.065930 0.996970 +vt 0.189065 0.201613 +vt 0.191739 0.197742 +vt 0.061620 0.992908 +vt 0.032130 0.992909 +vt 0.059070 0.996970 +vt 0.034680 0.996970 +vt 0.191695 0.202973 +vt 0.193537 0.198672 +vt 0.030370 0.992909 +vt 0.000880 0.992909 +vt 0.027820 0.996970 +vt 0.003429 0.996970 +vt 0.194549 0.203810 +vt 0.195488 0.199244 +vt 0.999120 0.992909 +vt 0.969630 0.992909 +vt 0.996571 0.996970 +vt 0.972180 0.996970 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 -0.0000 +vn 0.1903 0.2203 0.9567 +vn 0.1838 0.3345 0.9243 +vn 0.0000 0.3345 0.9424 +vn 0.0000 0.2203 0.9754 +vn -0.3733 0.2203 0.9012 +vn -0.3606 0.3345 0.8707 +vn -0.5235 0.3345 0.7836 +vn -0.5419 0.2203 0.8110 +vn -0.6664 0.3345 0.6664 +vn -0.6897 0.2203 0.6897 +vn -0.7836 0.3345 0.5235 +vn -0.8110 0.2203 0.5419 +vn -0.8707 0.3345 0.3606 +vn -0.9012 0.2203 0.3733 +vn -0.9243 0.3345 0.1838 +vn -0.9567 0.2203 0.1903 +vn -0.9424 0.3345 0.0000 +vn -0.9754 0.2203 0.0000 +vn -0.9243 0.3345 -0.1838 +vn -0.9567 0.2203 -0.1903 +vn -0.8707 0.3345 -0.3606 +vn -0.9012 0.2203 -0.3733 +vn -0.7836 0.3345 -0.5235 +vn -0.8110 0.2203 -0.5419 +vn -0.6664 0.3345 -0.6664 +vn -0.6897 0.2203 -0.6897 +vn -0.5235 0.3345 -0.7836 +vn -0.5419 0.2203 -0.8110 +vn -0.3606 0.3345 -0.8707 +vn -0.3733 0.2203 -0.9012 +vn -0.1838 0.3345 -0.9243 +vn -0.1903 0.2203 -0.9567 +vn 0.0000 0.3345 -0.9424 +vn 0.0000 0.2203 -0.9754 +vn 0.1838 0.3345 -0.9243 +vn 0.1903 0.2203 -0.9567 +vn 0.3606 0.3345 -0.8707 +vn 0.3733 0.2203 -0.9012 +vn 0.5235 0.3345 -0.7836 +vn 0.5419 0.2203 -0.8110 +vn 0.6664 0.3345 -0.6664 +vn 0.6897 0.2203 -0.6897 +vn 0.7836 0.3345 -0.5235 +vn 0.8110 0.2203 -0.5419 +vn 0.8707 0.3345 -0.3606 +vn 0.9012 0.2203 -0.3733 +vn 0.9243 0.3345 -0.1838 +vn 0.9567 0.2203 -0.1903 +vn 0.9424 0.3345 0.0000 +vn 0.9754 0.2203 0.0000 +vn 0.9243 0.3345 0.1838 +vn 0.9567 0.2203 0.1903 +vn 0.8707 0.3345 0.3606 +vn 0.9012 0.2203 0.3733 +vn 0.7836 0.3345 0.5235 +vn 0.8110 0.2203 0.5419 +vn 0.6664 0.3345 0.6664 +vn 0.6897 0.2203 0.6897 +vn 0.5235 0.3345 0.7836 +vn 0.5419 0.2203 0.8110 +vn 0.3606 0.3345 0.8707 +vn 0.3733 0.2203 0.9012 +vn -0.1838 0.3345 0.9243 +vn -0.1903 0.2203 0.9567 +vn 0.0352 -0.6962 -0.7169 +vn -0.0352 -0.6962 -0.7169 +vn -0.0352 0.6962 -0.7169 +vn 0.0352 0.6962 -0.7169 +vn -0.0352 -0.6962 0.7169 +vn 0.0352 -0.6962 0.7169 +vn 0.0352 0.6962 0.7169 +vn -0.0352 0.6962 0.7169 +vn -0.7169 -0.6962 -0.0352 +vn -0.7169 -0.6962 0.0352 +vn -0.7169 0.6962 0.0352 +vn -0.7169 0.6962 -0.0352 +vn -0.1420 0.6857 0.7139 +vn -0.1420 -0.6857 0.7139 +vn -0.2785 0.6857 0.6725 +vn -0.2785 -0.6857 0.6725 +vn -0.4044 0.6857 0.6052 +vn -0.4044 -0.6857 0.6052 +vn -0.5147 0.6857 0.5147 +vn -0.5147 -0.6857 0.5147 +vn -0.6052 0.6857 0.4044 +vn -0.6052 -0.6857 0.4044 +vn -0.6725 0.6857 0.2785 +vn -0.6725 -0.6857 0.2785 +vn -0.7139 0.6857 0.1420 +vn -0.7139 -0.6857 0.1420 +vn -0.1420 -0.6857 -0.7139 +vn -0.1420 0.6857 -0.7139 +vn -0.2785 -0.6857 -0.6725 +vn -0.2785 0.6857 -0.6725 +vn -0.4044 -0.6857 -0.6052 +vn -0.4044 0.6857 -0.6052 +vn -0.5147 -0.6857 -0.5147 +vn -0.5147 0.6857 -0.5147 +vn -0.6052 -0.6857 -0.4044 +vn -0.6052 0.6857 -0.4044 +vn -0.6725 -0.6857 -0.2785 +vn -0.6725 0.6857 -0.2785 +vn -0.7139 -0.6857 -0.1420 +vn -0.7139 0.6857 -0.1420 +vn 0.1420 0.6857 -0.7139 +vn 0.1420 -0.6857 -0.7139 +vn 0.2785 0.6857 -0.6725 +vn 0.2785 -0.6857 -0.6725 +vn 0.4044 0.6857 -0.6052 +vn 0.4044 -0.6857 -0.6052 +vn 0.5147 0.6857 -0.5147 +vn 0.5147 -0.6857 -0.5147 +vn 0.6052 0.6857 -0.4044 +vn 0.6052 -0.6857 -0.4044 +vn 0.6725 0.6857 -0.2785 +vn 0.6725 -0.6857 -0.2785 +vn 0.7139 0.6857 -0.1420 +vn 0.7139 -0.6857 -0.1420 +vn 0.7169 0.6962 -0.0352 +vn 0.7169 -0.6962 -0.0352 +vn 0.1420 -0.6857 0.7139 +vn 0.1420 0.6857 0.7139 +vn 0.2785 -0.6857 0.6725 +vn 0.2785 0.6857 0.6725 +vn 0.4044 -0.6857 0.6052 +vn 0.4044 0.6857 0.6052 +vn 0.5147 -0.6857 0.5147 +vn 0.5147 0.6857 0.5147 +vn 0.6052 -0.6857 0.4044 +vn 0.6052 0.6857 0.4044 +vn 0.6725 -0.6857 0.2785 +vn 0.6725 0.6857 0.2785 +vn 0.7139 -0.6857 0.1420 +vn 0.7139 0.6857 0.1420 +vn 0.7169 -0.6962 0.0352 +vn 0.7169 0.6962 0.0352 +vn 0.0000 0.6236 0.7817 +vn -0.1525 0.6236 0.7667 +vn 0.0000 0.8922 0.4516 +vn -0.0881 0.8922 0.4430 +vn 0.0000 0.9918 0.1276 +vn -0.0249 0.9918 0.1251 +vn -0.2991 0.6236 0.7222 +vn -0.1728 0.8922 0.4173 +vn -0.0488 0.9918 0.1179 +vn -0.4343 0.6236 0.6500 +vn -0.2509 0.8922 0.3755 +vn -0.0709 0.9918 0.1061 +vn -0.5528 0.6236 0.5528 +vn -0.3194 0.8922 0.3194 +vn -0.0902 0.9918 0.0902 +vn -0.6500 0.6236 0.4343 +vn -0.3755 0.8922 0.2509 +vn -0.1061 0.9918 0.0709 +vn -0.7222 0.6236 0.2991 +vn -0.4173 0.8922 0.1728 +vn -0.1179 0.9918 0.0488 +vn -0.7667 0.6236 0.1525 +vn -0.4430 0.8922 0.0881 +vn -0.1251 0.9918 0.0249 +vn -0.7817 0.6236 0.0000 +vn -0.4516 0.8922 0.0000 +vn -0.1276 0.9918 0.0000 +vn -0.7667 0.6236 -0.1525 +vn -0.4430 0.8922 -0.0881 +vn -0.1251 0.9918 -0.0249 +vn -0.7222 0.6236 -0.2991 +vn -0.4173 0.8922 -0.1728 +vn -0.1179 0.9918 -0.0488 +vn -0.6500 0.6236 -0.4343 +vn -0.3755 0.8922 -0.2509 +vn -0.1061 0.9918 -0.0709 +vn -0.5528 0.6236 -0.5528 +vn -0.3194 0.8922 -0.3194 +vn -0.0902 0.9918 -0.0902 +vn -0.4343 0.6236 -0.6500 +vn -0.2509 0.8922 -0.3755 +vn -0.0709 0.9918 -0.1061 +vn -0.2991 0.6236 -0.7222 +vn -0.1728 0.8922 -0.4173 +vn -0.0488 0.9918 -0.1179 +vn -0.1525 0.6236 -0.7667 +vn -0.0881 0.8922 -0.4430 +vn -0.0249 0.9918 -0.1251 +vn 0.0000 0.6236 -0.7817 +vn 0.0000 0.8922 -0.4516 +vn 0.0000 0.9918 -0.1276 +vn 0.1525 0.6236 -0.7667 +vn 0.0881 0.8922 -0.4430 +vn 0.0249 0.9918 -0.1251 +vn 0.2991 0.6236 -0.7222 +vn 0.1728 0.8922 -0.4173 +vn 0.0488 0.9918 -0.1179 +vn 0.4343 0.6236 -0.6500 +vn 0.2509 0.8922 -0.3755 +vn 0.0709 0.9918 -0.1061 +vn 0.5528 0.6236 -0.5528 +vn 0.3194 0.8922 -0.3194 +vn 0.0902 0.9918 -0.0902 +vn 0.6500 0.6236 -0.4343 +vn 0.3755 0.8922 -0.2509 +vn 0.1061 0.9918 -0.0709 +vn 0.7222 0.6236 -0.2991 +vn 0.4173 0.8922 -0.1728 +vn 0.1179 0.9918 -0.0488 +vn 0.7667 0.6236 -0.1525 +vn 0.4430 0.8922 -0.0881 +vn 0.1251 0.9918 -0.0249 +vn 0.7817 0.6236 0.0000 +vn 0.4516 0.8922 0.0000 +vn 0.1276 0.9918 0.0000 +vn 0.7667 0.6236 0.1525 +vn 0.4430 0.8922 0.0881 +vn 0.1251 0.9918 0.0249 +vn 0.7222 0.6236 0.2991 +vn 0.4173 0.8922 0.1728 +vn 0.1179 0.9918 0.0488 +vn 0.6500 0.6236 0.4343 +vn 0.3755 0.8922 0.2509 +vn 0.1061 0.9918 0.0709 +vn 0.5528 0.6236 0.5528 +vn 0.3194 0.8922 0.3194 +vn 0.0902 0.9918 0.0902 +vn 0.4343 0.6236 0.6500 +vn 0.2509 0.8922 0.3755 +vn 0.0709 0.9918 0.1061 +vn 0.2991 0.6236 0.7222 +vn 0.1728 0.8922 0.4173 +vn 0.0488 0.9918 0.1179 +vn 0.1525 0.6236 0.7667 +vn 0.0881 0.8922 0.4430 +vn 0.0249 0.9918 0.1251 +g Cylinder_Cylinder_None +s off +f 33/1/1 35/2/1 36/3/1 37/4/1 38/5/1 39/6/1 40/7/1 41/8/1 34/9/1 51/10/1 53/11/1 54/12/1 55/13/1 56/14/1 57/15/1 58/16/1 59/17/1 52/18/1 60/19/1 62/20/1 63/21/1 64/22/1 65/23/1 66/24/1 67/25/1 68/26/1 61/27/1 42/28/1 44/29/1 45/30/1 46/31/1 47/32/1 48/33/1 49/34/1 50/35/1 43/36/1 +f 78/37/2 80/38/2 81/39/2 82/40/2 83/41/2 84/42/2 85/43/2 86/44/2 79/45/2 87/46/2 89/47/2 90/48/2 91/49/2 92/50/2 93/51/2 94/52/2 95/53/2 88/54/2 96/55/2 98/56/2 99/57/2 100/58/2 101/59/2 102/60/2 103/61/2 104/62/2 97/63/2 69/64/2 71/65/2 72/66/2 73/67/2 74/68/2 75/69/2 76/70/2 77/71/2 70/72/2 +s 1 +f 32/73/3 230/74/4 106/75/5 1/76/6 +f 3/77/7 114/78/8 118/79/9 4/80/10 +f 4/80/10 118/79/9 122/81/11 5/82/12 +f 5/82/12 122/81/11 126/83/13 6/84/14 +f 6/84/14 126/83/13 130/85/15 7/86/16 +f 7/86/16 130/85/15 134/87/17 8/88/18 +f 8/88/18 134/87/17 138/89/19 9/90/20 +f 9/90/20 138/91/19 142/92/21 10/93/22 +f 10/93/22 142/92/21 146/94/23 11/95/24 +f 11/95/24 146/94/23 150/96/25 12/97/26 +f 12/97/26 150/96/25 154/98/27 13/99/28 +f 13/99/28 154/98/27 158/100/29 14/101/30 +f 14/101/30 158/100/29 162/102/31 15/103/32 +f 15/103/32 162/102/31 166/104/33 16/105/34 +f 16/105/34 166/104/33 170/106/35 17/107/36 +f 17/107/36 170/106/35 174/108/37 18/109/38 +f 18/109/38 174/108/37 178/110/39 19/111/40 +f 19/111/40 178/110/39 182/112/41 20/113/42 +f 20/113/42 182/112/41 186/114/43 21/115/44 +f 21/115/44 186/114/43 190/116/45 22/117/46 +f 22/117/46 190/116/45 194/118/47 23/119/48 +f 23/119/48 194/118/47 198/120/49 24/121/50 +f 24/121/50 198/120/49 202/122/51 25/123/52 +f 25/123/52 202/122/51 206/124/53 26/125/54 +f 26/125/54 206/124/53 210/126/55 27/127/56 +f 27/127/56 210/126/55 214/128/57 28/129/58 +f 28/129/58 214/128/57 218/130/59 29/131/60 +f 29/131/60 218/130/59 222/132/61 30/133/62 +f 30/133/62 222/132/61 226/134/63 31/135/64 +f 31/135/64 226/134/63 230/136/4 32/137/3 +f 1/76/6 106/138/5 110/139/65 2/140/66 +f 2/140/66 110/139/65 114/78/8 3/77/7 +f 33/141/67 43/142/68 87/143/69 79/144/70 +f 60/145/71 52/146/72 69/147/73 97/148/74 +f 42/149/75 61/150/76 96/151/77 88/152/78 +f 60/145/71 97/148/74 104/153/79 62/154/80 +f 62/154/80 104/153/79 103/155/81 63/156/82 +f 63/156/82 103/155/81 102/157/83 64/158/84 +f 64/158/84 102/157/83 101/159/85 65/160/86 +f 65/160/86 101/159/85 100/161/87 66/162/88 +f 66/162/88 100/161/87 99/163/89 67/164/90 +f 67/164/90 99/163/89 98/165/91 68/166/92 +f 68/166/92 98/165/91 96/151/77 61/150/76 +f 87/143/69 43/142/68 50/167/93 89/168/94 +f 89/168/94 50/167/93 49/169/95 90/170/96 +f 90/170/96 49/169/95 48/171/97 91/172/98 +f 91/172/98 48/171/97 47/173/99 92/174/100 +f 92/174/100 47/173/99 46/175/101 93/176/102 +f 93/176/102 46/175/101 45/177/103 94/178/104 +f 94/178/104 45/177/103 44/179/105 95/180/106 +f 95/180/106 44/179/105 42/149/75 88/152/78 +f 33/141/67 79/144/70 86/181/107 35/182/108 +f 35/182/108 86/181/107 85/183/109 36/184/110 +f 36/184/110 85/183/109 84/185/111 37/186/112 +f 37/186/112 84/185/111 83/187/113 38/188/114 +f 38/188/114 83/187/113 82/189/115 39/190/116 +f 39/190/116 82/189/115 81/191/117 40/192/118 +f 40/192/118 81/191/117 80/193/119 41/194/120 +f 41/194/120 80/193/119 78/195/121 34/196/122 +f 69/197/73 52/198/72 59/199/123 71/200/124 +f 71/200/124 59/199/123 58/201/125 72/202/126 +f 72/202/126 58/201/125 57/203/127 73/204/128 +f 73/204/128 57/203/127 56/205/129 74/206/130 +f 74/206/130 56/205/129 55/207/131 75/208/132 +f 75/208/132 55/207/131 54/209/133 76/210/134 +f 76/210/134 54/209/133 53/211/135 77/212/136 +f 77/212/136 53/211/135 51/213/137 70/214/138 +f 51/213/137 34/196/122 78/195/121 70/214/138 +f 110/139/65 106/138/5 108/215/139 112/216/140 +f 112/216/140 108/215/139 107/217/141 111/218/142 +f 111/219/142 107/220/141 105/221/143 109/222/144 +f 114/78/8 110/139/65 112/223/140 116/224/145 +f 116/224/145 112/223/140 111/225/142 115/226/146 +f 115/227/146 111/219/142 109/222/144 113/228/147 +f 118/79/9 114/78/8 116/229/145 120/230/148 +f 120/230/148 116/229/145 115/231/146 119/232/149 +f 119/233/149 115/227/146 113/228/147 117/234/150 +f 122/81/11 118/79/9 120/235/148 124/236/151 +f 124/236/151 120/235/148 119/237/149 123/238/152 +f 123/239/152 119/233/149 117/234/150 121/240/153 +f 126/83/13 122/81/11 124/241/151 128/242/154 +f 128/242/154 124/241/151 123/243/152 127/244/155 +f 127/245/155 123/239/152 121/240/153 125/246/156 +f 130/85/15 126/83/13 128/247/154 132/248/157 +f 132/248/157 128/247/154 127/249/155 131/250/158 +f 131/251/158 127/245/155 125/246/156 129/252/159 +f 134/87/17 130/85/15 132/253/157 136/254/160 +f 136/254/160 132/253/157 131/255/158 135/256/161 +f 135/257/161 131/251/158 129/252/159 133/258/162 +f 138/89/19 134/87/17 136/259/160 140/260/163 +f 140/260/163 136/259/160 135/261/161 139/262/164 +f 139/263/164 135/257/161 133/258/162 137/264/165 +f 142/92/21 138/91/19 140/265/163 144/266/166 +f 144/266/166 140/265/163 139/267/164 143/268/167 +f 143/269/167 139/263/164 137/264/165 141/270/168 +f 146/94/23 142/92/21 144/271/166 148/272/169 +f 148/272/169 144/271/166 143/273/167 147/274/170 +f 147/275/170 143/269/167 141/270/168 145/276/171 +f 150/96/25 146/94/23 148/277/169 152/278/172 +f 152/278/172 148/277/169 147/279/170 151/280/173 +f 151/281/173 147/275/170 145/276/171 149/282/174 +f 154/98/27 150/96/25 152/283/172 156/284/175 +f 156/284/175 152/283/172 151/285/173 155/286/176 +f 155/287/176 151/281/173 149/282/174 153/288/177 +f 158/100/29 154/98/27 156/289/175 160/290/178 +f 160/290/178 156/289/175 155/291/176 159/292/179 +f 159/293/179 155/287/176 153/288/177 157/294/180 +f 162/102/31 158/100/29 160/295/178 164/296/181 +f 164/296/181 160/295/178 159/297/179 163/298/182 +f 163/299/182 159/293/179 157/294/180 161/300/183 +f 166/104/33 162/102/31 164/301/181 168/302/184 +f 168/302/184 164/301/181 163/303/182 167/304/185 +f 167/305/185 163/299/182 161/300/183 165/306/186 +f 170/106/35 166/104/33 168/307/184 172/308/187 +f 172/308/187 168/307/184 167/309/185 171/310/188 +f 171/311/188 167/305/185 165/306/186 169/312/189 +f 174/108/37 170/106/35 172/313/187 176/314/190 +f 176/314/190 172/313/187 171/315/188 175/316/191 +f 175/317/191 171/311/188 169/312/189 173/318/192 +f 178/110/39 174/108/37 176/319/190 180/320/193 +f 180/320/193 176/319/190 175/321/191 179/322/194 +f 179/323/194 175/317/191 173/318/192 177/324/195 +f 182/112/41 178/110/39 180/325/193 184/326/196 +f 184/326/196 180/325/193 179/327/194 183/328/197 +f 183/329/197 179/323/194 177/324/195 181/330/198 +f 186/114/43 182/112/41 184/331/196 188/332/199 +f 188/332/199 184/331/196 183/333/197 187/334/200 +f 187/335/200 183/329/197 181/330/198 185/336/201 +f 190/116/45 186/114/43 188/337/199 192/338/202 +f 192/338/202 188/337/199 187/339/200 191/340/203 +f 191/341/203 187/335/200 185/336/201 189/342/204 +f 194/118/47 190/116/45 192/343/202 196/344/205 +f 196/344/205 192/343/202 191/345/203 195/346/206 +f 195/347/206 191/341/203 189/342/204 193/348/207 +f 198/120/49 194/118/47 196/349/205 200/350/208 +f 200/350/208 196/349/205 195/351/206 199/352/209 +f 199/353/209 195/347/206 193/348/207 197/354/210 +f 202/122/51 198/120/49 200/355/208 204/356/211 +f 204/356/211 200/355/208 199/357/209 203/358/212 +f 203/359/212 199/353/209 197/354/210 201/360/213 +f 206/124/53 202/122/51 204/361/211 208/362/214 +f 208/362/214 204/361/211 203/363/212 207/364/215 +f 207/365/215 203/359/212 201/360/213 205/366/216 +f 210/126/55 206/124/53 208/367/214 212/368/217 +f 212/368/217 208/367/214 207/369/215 211/370/218 +f 211/371/218 207/365/215 205/366/216 209/372/219 +f 214/128/57 210/126/55 212/373/217 216/374/220 +f 216/374/220 212/373/217 211/375/218 215/376/221 +f 215/377/221 211/371/218 209/372/219 213/378/222 +f 218/130/59 214/128/57 216/379/220 220/380/223 +f 220/380/223 216/379/220 215/381/221 219/382/224 +f 219/383/224 215/377/221 213/378/222 217/384/225 +f 222/132/61 218/130/59 220/385/223 224/386/226 +f 224/386/226 220/385/223 219/387/224 223/388/227 +f 223/389/227 219/383/224 217/384/225 221/390/228 +f 226/134/63 222/132/61 224/391/226 228/392/229 +f 228/392/229 224/391/226 223/393/227 227/394/230 +f 227/395/230 223/389/227 221/390/228 225/396/231 +f 230/136/4 226/134/63 228/397/229 232/398/232 +f 232/398/232 228/397/229 227/399/230 231/400/233 +f 231/401/233 227/395/230 225/396/231 229/402/234 +f 106/75/5 230/74/4 232/403/232 108/404/139 +f 108/404/139 232/403/232 231/405/233 107/406/141 +f 107/220/141 231/401/233 229/402/234 105/221/143 +f 109/222/144 105/221/143 229/402/234 225/396/231 221/390/228 217/384/225 213/378/222 209/372/219 205/366/216 201/360/213 197/354/210 193/348/207 189/342/204 185/336/201 181/330/198 177/324/195 173/318/192 169/312/189 165/306/186 161/300/183 157/294/180 153/288/177 149/282/174 145/276/171 141/270/168 137/264/165 133/258/162 129/252/159 125/246/156 121/240/153 117/234/150 113/228/147 diff --git a/mods/roads/infrastructure/models/infrastructure_traffic_cone_i1.obj b/mods/roads/infrastructure/models/infrastructure_traffic_cone_i1.obj new file mode 100644 index 0000000..ca8074c --- /dev/null +++ b/mods/roads/infrastructure/models/infrastructure_traffic_cone_i1.obj @@ -0,0 +1,1045 @@ +# Blender v2.79 (sub 0) OBJ File: 'traffic cone.blend' +# www.blender.org +o Cylinder +v 0.000000 -0.724600 0.203250 +v -0.039652 -0.724600 0.199345 +v -0.077780 -0.724600 0.187779 +v -0.112920 -0.724600 0.168996 +v -0.143719 -0.724600 0.143719 +v -0.168996 -0.724600 0.112920 +v -0.187779 -0.724600 0.077780 +v -0.199345 -0.724600 0.039652 +v -0.203250 -0.724600 0.000000 +v -0.199345 -0.724600 -0.039652 +v -0.187779 -0.724600 -0.077780 +v -0.168996 -0.724600 -0.112920 +v -0.143719 -0.724600 -0.143719 +v -0.112920 -0.724600 -0.168996 +v -0.077780 -0.724600 -0.187779 +v -0.039652 -0.724600 -0.199345 +v 0.000000 -0.724600 -0.203250 +v 0.039652 -0.724600 -0.199345 +v 0.077781 -0.724600 -0.187778 +v 0.112920 -0.724600 -0.168996 +v 0.143720 -0.724600 -0.143719 +v 0.168996 -0.724600 -0.112920 +v 0.187779 -0.724600 -0.077780 +v 0.199345 -0.724600 -0.039652 +v 0.203250 -0.724600 0.000000 +v 0.199345 -0.724600 0.039652 +v 0.187778 -0.724600 0.077781 +v 0.168996 -0.724600 0.112920 +v 0.143719 -0.724600 0.143720 +v 0.112919 -0.724600 0.168996 +v 0.077780 -0.724600 0.187779 +v 0.039652 -0.724600 0.199345 +v 0.191399 -0.750000 -0.250000 +v 0.250000 -0.750000 -0.191399 +v 0.202831 -0.750000 -0.248874 +v 0.213825 -0.750000 -0.245539 +v 0.223956 -0.750000 -0.240124 +v 0.232836 -0.750000 -0.232836 +v 0.240124 -0.750000 -0.223956 +v 0.245539 -0.750000 -0.213825 +v 0.248874 -0.750000 -0.202831 +v -0.250000 -0.750000 -0.191399 +v -0.191399 -0.750000 -0.250000 +v -0.248874 -0.750000 -0.202831 +v -0.245539 -0.750000 -0.213825 +v -0.240124 -0.750000 -0.223956 +v -0.232836 -0.750000 -0.232836 +v -0.223956 -0.750000 -0.240124 +v -0.213825 -0.750000 -0.245539 +v -0.202831 -0.750000 -0.248874 +v 0.250000 -0.750000 0.191399 +v 0.191399 -0.750000 0.250000 +v 0.248874 -0.750000 0.202831 +v 0.245539 -0.750000 0.213825 +v 0.240124 -0.750000 0.223956 +v 0.232836 -0.750000 0.232836 +v 0.223956 -0.750000 0.240124 +v 0.213825 -0.750000 0.245539 +v 0.202831 -0.750000 0.248874 +v -0.191399 -0.750000 0.250000 +v -0.250000 -0.750000 0.191399 +v -0.202831 -0.750000 0.248874 +v -0.213825 -0.750000 0.245539 +v -0.223956 -0.750000 0.240124 +v -0.232836 -0.750000 0.232836 +v -0.240124 -0.750000 0.223956 +v -0.245539 -0.750000 0.213825 +v -0.248874 -0.750000 0.202831 +v 0.191399 -0.724600 0.250000 +v 0.250000 -0.724600 0.191399 +v 0.202831 -0.724600 0.248874 +v 0.213825 -0.724600 0.245539 +v 0.223956 -0.724600 0.240124 +v 0.232836 -0.724600 0.232836 +v 0.240124 -0.724600 0.223956 +v 0.245539 -0.724600 0.213825 +v 0.248874 -0.724600 0.202831 +v 0.250000 -0.724600 -0.191399 +v 0.191399 -0.724600 -0.250000 +v 0.248874 -0.724600 -0.202831 +v 0.245539 -0.724600 -0.213825 +v 0.240124 -0.724600 -0.223956 +v 0.232836 -0.724600 -0.232836 +v 0.223956 -0.724600 -0.240124 +v 0.213825 -0.724600 -0.245539 +v 0.202831 -0.724600 -0.248874 +v -0.191399 -0.724600 -0.250000 +v -0.250000 -0.724600 -0.191399 +v -0.202831 -0.724600 -0.248874 +v -0.213825 -0.724600 -0.245539 +v -0.223956 -0.724600 -0.240124 +v -0.232836 -0.724600 -0.232836 +v -0.240124 -0.724600 -0.223956 +v -0.245539 -0.724600 -0.213825 +v -0.248874 -0.724600 -0.202831 +v -0.250000 -0.724600 0.191399 +v -0.191399 -0.724600 0.250000 +v -0.248874 -0.724600 0.202831 +v -0.245539 -0.724600 0.213825 +v -0.240124 -0.724600 0.223956 +v -0.232836 -0.724600 0.232836 +v -0.223956 -0.724600 0.240124 +v -0.213825 -0.724600 0.245539 +v -0.202831 -0.724600 0.248874 +v -0.000000 0.063000 0.013552 +v 0.000000 0.051498 0.027995 +v -0.000000 0.061459 0.019823 +v -0.000000 0.057249 0.025109 +v -0.002644 0.063000 0.013292 +v -0.005462 0.051498 0.027457 +v -0.003867 0.061459 0.019442 +v -0.004899 0.057249 0.024627 +v -0.005186 0.063000 0.012521 +v -0.010713 0.051498 0.025864 +v -0.007586 0.061459 0.018314 +v -0.009609 0.057249 0.023198 +v -0.007529 0.063000 0.011268 +v -0.015553 0.051498 0.023277 +v -0.011013 0.061459 0.016482 +v -0.013950 0.057249 0.020878 +v -0.009583 0.063000 0.009583 +v -0.019795 0.051498 0.019795 +v -0.014017 0.061459 0.014017 +v -0.017755 0.057249 0.017755 +v -0.011268 0.063000 0.007529 +v -0.023277 0.051498 0.015553 +v -0.016482 0.061459 0.011013 +v -0.020878 0.057249 0.013950 +v -0.012521 0.063000 0.005186 +v -0.025864 0.051498 0.010713 +v -0.018314 0.061459 0.007586 +v -0.023198 0.057249 0.009609 +v -0.013292 0.063000 0.002644 +v -0.027457 0.051498 0.005462 +v -0.019442 0.061459 0.003867 +v -0.024627 0.057249 0.004899 +v -0.013552 0.063000 -0.000000 +v -0.027995 0.051498 0.000000 +v -0.019823 0.061459 0.000000 +v -0.025109 0.057249 0.000000 +v -0.013292 0.063000 -0.002644 +v -0.027457 0.051498 -0.005462 +v -0.019442 0.061459 -0.003867 +v -0.024627 0.057249 -0.004899 +v -0.012521 0.063000 -0.005186 +v -0.025864 0.051498 -0.010713 +v -0.018314 0.061459 -0.007586 +v -0.023198 0.057249 -0.009609 +v -0.011268 0.063000 -0.007529 +v -0.023277 0.051498 -0.015553 +v -0.016482 0.061459 -0.011013 +v -0.020878 0.057249 -0.013950 +v -0.009583 0.063000 -0.009583 +v -0.019795 0.051498 -0.019795 +v -0.014017 0.061459 -0.014017 +v -0.017755 0.057249 -0.017755 +v -0.007529 0.063000 -0.011268 +v -0.015553 0.051498 -0.023277 +v -0.011013 0.061459 -0.016482 +v -0.013950 0.057249 -0.020878 +v -0.005186 0.063000 -0.012521 +v -0.010713 0.051498 -0.025864 +v -0.007586 0.061459 -0.018314 +v -0.009609 0.057249 -0.023198 +v -0.002644 0.063000 -0.013292 +v -0.005462 0.051498 -0.027457 +v -0.003867 0.061459 -0.019442 +v -0.004899 0.057249 -0.024627 +v 0.000000 0.063000 -0.013552 +v 0.000000 0.051498 -0.027995 +v 0.000000 0.061459 -0.019823 +v 0.000000 0.057249 -0.025109 +v 0.002644 0.063000 -0.013292 +v 0.005462 0.051498 -0.027457 +v 0.003867 0.061459 -0.019442 +v 0.004899 0.057249 -0.024627 +v 0.005186 0.063000 -0.012521 +v 0.010713 0.051498 -0.025864 +v 0.007586 0.061459 -0.018314 +v 0.009609 0.057249 -0.023198 +v 0.007529 0.063000 -0.011268 +v 0.015553 0.051498 -0.023277 +v 0.011013 0.061459 -0.016482 +v 0.013950 0.057249 -0.020878 +v 0.009583 0.063000 -0.009583 +v 0.019795 0.051498 -0.019795 +v 0.014017 0.061459 -0.014017 +v 0.017755 0.057249 -0.017755 +v 0.011268 0.063000 -0.007529 +v 0.023277 0.051498 -0.015553 +v 0.016482 0.061459 -0.011013 +v 0.020878 0.057249 -0.013950 +v 0.012521 0.063000 -0.005186 +v 0.025864 0.051498 -0.010713 +v 0.018314 0.061459 -0.007586 +v 0.023198 0.057249 -0.009609 +v 0.013292 0.063000 -0.002644 +v 0.027457 0.051498 -0.005462 +v 0.019442 0.061459 -0.003867 +v 0.024627 0.057249 -0.004899 +v 0.013552 0.063000 0.000000 +v 0.027995 0.051498 0.000000 +v 0.019823 0.061459 0.000000 +v 0.025109 0.057249 0.000000 +v 0.013292 0.063000 0.002644 +v 0.027457 0.051498 0.005462 +v 0.019442 0.061459 0.003867 +v 0.024627 0.057249 0.004899 +v 0.012521 0.063000 0.005186 +v 0.025864 0.051498 0.010713 +v 0.018314 0.061459 0.007586 +v 0.023198 0.057249 0.009609 +v 0.011268 0.063000 0.007529 +v 0.023277 0.051498 0.015553 +v 0.016482 0.061459 0.011013 +v 0.020878 0.057249 0.013950 +v 0.009583 0.063000 0.009583 +v 0.019795 0.051498 0.019795 +v 0.014017 0.061459 0.014017 +v 0.017755 0.057249 0.017755 +v 0.007529 0.063000 0.011268 +v 0.015553 0.051498 0.023277 +v 0.011013 0.061459 0.016482 +v 0.013950 0.057249 0.020878 +v 0.005186 0.063000 0.012521 +v 0.010713 0.051498 0.025864 +v 0.007586 0.061459 0.018314 +v 0.009609 0.057249 0.023198 +v 0.002644 0.063000 0.013292 +v 0.005462 0.051498 0.027457 +v 0.003867 0.061459 0.019442 +v 0.004899 0.057249 0.024627 +vt 0.444971 0.003030 +vt 0.436198 0.003866 +vt 0.427761 0.006342 +vt 0.419987 0.010362 +vt 0.413172 0.015773 +vt 0.407579 0.022366 +vt 0.403423 0.029887 +vt 0.400864 0.038049 +vt 0.400000 0.046537 +vt 0.400000 0.330730 +vt 0.400864 0.339218 +vt 0.403423 0.347380 +vt 0.407579 0.354901 +vt 0.413172 0.361494 +vt 0.419987 0.366905 +vt 0.427761 0.370925 +vt 0.436198 0.373401 +vt 0.444971 0.374237 +vt 0.738735 0.374237 +vt 0.747508 0.373401 +vt 0.755944 0.370925 +vt 0.763719 0.366905 +vt 0.770534 0.361494 +vt 0.776127 0.354901 +vt 0.780283 0.347380 +vt 0.782842 0.339218 +vt 0.783706 0.330730 +vt 0.783706 0.046537 +vt 0.782842 0.038049 +vt 0.780283 0.029887 +vt 0.776127 0.022366 +vt 0.770534 0.015773 +vt 0.763719 0.010362 +vt 0.755944 0.006342 +vt 0.747508 0.003866 +vt 0.738735 0.003030 +vt 0.003125 0.046537 +vt 0.003989 0.038049 +vt 0.006548 0.029887 +vt 0.010704 0.022366 +vt 0.016297 0.015773 +vt 0.023112 0.010362 +vt 0.030886 0.006342 +vt 0.039323 0.003866 +vt 0.048096 0.003030 +vt 0.341860 0.003030 +vt 0.350633 0.003866 +vt 0.359069 0.006342 +vt 0.366844 0.010362 +vt 0.373659 0.015773 +vt 0.379252 0.022366 +vt 0.383408 0.029887 +vt 0.385967 0.038049 +vt 0.386831 0.046537 +vt 0.386831 0.330730 +vt 0.385967 0.339218 +vt 0.383408 0.347380 +vt 0.379252 0.354901 +vt 0.373659 0.361494 +vt 0.366844 0.366905 +vt 0.359069 0.370925 +vt 0.350633 0.373401 +vt 0.341860 0.374237 +vt 0.048096 0.374237 +vt 0.039323 0.373401 +vt 0.030886 0.370925 +vt 0.023112 0.366905 +vt 0.016297 0.361494 +vt 0.010704 0.354901 +vt 0.006548 0.347380 +vt 0.003989 0.339218 +vt 0.003125 0.330730 +vt 1.000000 0.403030 +vt 1.000000 0.988340 +vt 0.968750 0.988340 +vt 0.968750 0.403030 +vt 0.906250 0.403030 +vt 0.906250 0.988340 +vt 0.875000 0.988340 +vt 0.875000 0.403030 +vt 0.843750 0.988340 +vt 0.843750 0.403030 +vt 0.812500 0.988340 +vt 0.812500 0.403030 +vt 0.781250 0.988340 +vt 0.781250 0.403030 +vt 0.750000 0.988340 +vt 0.750000 0.403030 +vt 0.718750 0.988340 +vt 0.718750 0.403030 +vt 0.718750 0.988340 +vt 0.687500 0.988340 +vt 0.687500 0.403030 +vt 0.656250 0.988340 +vt 0.656250 0.403030 +vt 0.625000 0.988340 +vt 0.625000 0.403030 +vt 0.593750 0.988340 +vt 0.593750 0.403030 +vt 0.562500 0.988340 +vt 0.562500 0.403030 +vt 0.531250 0.988340 +vt 0.531250 0.403030 +vt 0.500000 0.988340 +vt 0.500000 0.403030 +vt 0.468750 0.988340 +vt 0.468750 0.403030 +vt 0.437500 0.988340 +vt 0.437500 0.403030 +vt 0.406250 0.988340 +vt 0.406250 0.403030 +vt 0.375000 0.988340 +vt 0.375000 0.403030 +vt 0.343750 0.988340 +vt 0.343750 0.403030 +vt 0.312500 0.988340 +vt 0.312500 0.403030 +vt 0.281250 0.988340 +vt 0.281250 0.403030 +vt 0.250000 0.988340 +vt 0.250000 0.403030 +vt 0.218750 0.988340 +vt 0.218750 0.403030 +vt 0.187500 0.988340 +vt 0.187500 0.403030 +vt 0.156250 0.988340 +vt 0.156250 0.403030 +vt 0.125000 0.988340 +vt 0.125000 0.403030 +vt 0.093750 0.988340 +vt 0.093750 0.403030 +vt 0.062500 0.988340 +vt 0.062500 0.403030 +vt 0.031250 0.988340 +vt 0.031250 0.403030 +vt 0.000000 0.988340 +vt 0.000000 0.403030 +vt 0.968750 0.988340 +vt 0.937500 0.988340 +vt 0.937500 0.403030 +vt 0.300000 0.384848 +vt 0.500000 0.384848 +vt 0.500000 0.396970 +vt 0.300000 0.396970 +vt 0.800000 0.384848 +vt 1.000000 0.384848 +vt 1.000000 0.396970 +vt 0.800000 0.396970 +vt 0.550000 0.384848 +vt 0.750000 0.384848 +vt 0.750000 0.396970 +vt 0.550000 0.396970 +vt 0.793750 0.396970 +vt 0.793750 0.384848 +vt 0.787500 0.396970 +vt 0.787500 0.384848 +vt 0.781250 0.396970 +vt 0.781250 0.384848 +vt 0.775000 0.396970 +vt 0.775000 0.384848 +vt 0.768750 0.396970 +vt 0.768750 0.384848 +vt 0.762500 0.396970 +vt 0.762500 0.384848 +vt 0.756250 0.396970 +vt 0.756250 0.384848 +vt 0.506250 0.384848 +vt 0.506250 0.396970 +vt 0.512500 0.384848 +vt 0.512500 0.396970 +vt 0.518750 0.384848 +vt 0.518750 0.396970 +vt 0.525000 0.384848 +vt 0.525000 0.396970 +vt 0.531250 0.384848 +vt 0.531250 0.396970 +vt 0.537500 0.384848 +vt 0.537500 0.396970 +vt 0.543750 0.384848 +vt 0.543750 0.396970 +vt 0.293750 0.396970 +vt 0.293750 0.384848 +vt 0.287500 0.396970 +vt 0.287500 0.384848 +vt 0.281250 0.396970 +vt 0.281250 0.384848 +vt 0.275000 0.396970 +vt 0.275000 0.384848 +vt 0.268750 0.396970 +vt 0.268750 0.384848 +vt 0.262500 0.396970 +vt 0.262500 0.384848 +vt 0.256250 0.396970 +vt 0.256250 0.384848 +vt 0.250000 0.396970 +vt 0.250000 0.384848 +vt 0.000000 0.396970 +vt 0.000000 0.384848 +vt 0.006250 0.384848 +vt 0.006250 0.396970 +vt 0.012500 0.384848 +vt 0.012500 0.396970 +vt 0.018750 0.384848 +vt 0.018750 0.396970 +vt 0.025000 0.384848 +vt 0.025000 0.396970 +vt 0.031250 0.384848 +vt 0.031250 0.396970 +vt 0.037500 0.384848 +vt 0.037500 0.396970 +vt 0.043750 0.384848 +vt 0.043750 0.396970 +vt 0.050000 0.384848 +vt 0.050000 0.396970 +vt 0.967870 0.992909 +vt 0.938380 0.992909 +vt 0.965320 0.996970 +vt 0.940930 0.996970 +vt 0.200485 0.203811 +vt 0.197517 0.204093 +vt 0.197517 0.199438 +vt 0.199546 0.199244 +vt 0.936620 0.992908 +vt 0.907130 0.992909 +vt 0.934070 0.996970 +vt 0.909680 0.996970 +vt 0.203338 0.202973 +vt 0.201497 0.198672 +vt 0.905370 0.992909 +vt 0.875880 0.992909 +vt 0.902820 0.996970 +vt 0.878429 0.996970 +vt 0.205968 0.201613 +vt 0.203295 0.197742 +vt 0.874120 0.992908 +vt 0.844630 0.992909 +vt 0.871571 0.996970 +vt 0.847180 0.996970 +vt 0.208274 0.199783 +vt 0.204871 0.196491 +vt 0.842870 0.992908 +vt 0.813380 0.992908 +vt 0.840320 0.996970 +vt 0.815929 0.996970 +vt 0.210165 0.197553 +vt 0.206164 0.194966 +vt 0.811620 0.992909 +vt 0.782130 0.992909 +vt 0.809071 0.996970 +vt 0.784680 0.996970 +vt 0.211571 0.195008 +vt 0.207125 0.193227 +vt 0.780370 0.992909 +vt 0.750880 0.992908 +vt 0.777820 0.996970 +vt 0.753429 0.996970 +vt 0.212437 0.192248 +vt 0.207717 0.191339 +vt 0.749120 0.992909 +vt 0.719630 0.992909 +vt 0.746570 0.996970 +vt 0.722180 0.996970 +vt 0.212729 0.189376 +vt 0.207917 0.189376 +vt 0.717870 0.992908 +vt 0.688380 0.992908 +vt 0.715320 0.996970 +vt 0.690930 0.996970 +vt 0.212437 0.186505 +vt 0.207717 0.187414 +vt 0.686620 0.992909 +vt 0.657130 0.992909 +vt 0.684071 0.996970 +vt 0.659680 0.996970 +vt 0.211571 0.183745 +vt 0.207125 0.185526 +vt 0.655370 0.992908 +vt 0.625880 0.992908 +vt 0.652820 0.996970 +vt 0.628429 0.996970 +vt 0.210165 0.181200 +vt 0.206164 0.183787 +vt 0.624120 0.992908 +vt 0.594630 0.992909 +vt 0.621571 0.996970 +vt 0.597180 0.996970 +vt 0.208274 0.178970 +vt 0.204871 0.182262 +vt 0.592870 0.992908 +vt 0.563380 0.992908 +vt 0.590320 0.996970 +vt 0.565930 0.996970 +vt 0.205968 0.177140 +vt 0.203295 0.181011 +vt 0.561620 0.992909 +vt 0.532130 0.992908 +vt 0.559071 0.996970 +vt 0.534680 0.996970 +vt 0.203338 0.175780 +vt 0.201497 0.180081 +vt 0.530370 0.992909 +vt 0.500880 0.992908 +vt 0.527820 0.996970 +vt 0.503430 0.996970 +vt 0.200485 0.174942 +vt 0.199546 0.179508 +vt 0.499120 0.992909 +vt 0.469630 0.992909 +vt 0.496570 0.996970 +vt 0.472180 0.996970 +vt 0.197517 0.174660 +vt 0.197517 0.179315 +vt 0.467870 0.992909 +vt 0.438380 0.992909 +vt 0.465320 0.996970 +vt 0.440930 0.996970 +vt 0.194549 0.174942 +vt 0.195488 0.179508 +vt 0.436620 0.992909 +vt 0.407130 0.992909 +vt 0.434070 0.996970 +vt 0.409680 0.996970 +vt 0.191695 0.175780 +vt 0.193537 0.180081 +vt 0.405370 0.992909 +vt 0.375880 0.992909 +vt 0.402820 0.996970 +vt 0.378430 0.996970 +vt 0.189065 0.177140 +vt 0.191739 0.181011 +vt 0.374120 0.992909 +vt 0.344630 0.992909 +vt 0.371570 0.996970 +vt 0.347180 0.996970 +vt 0.186760 0.178970 +vt 0.190163 0.182262 +vt 0.342870 0.992909 +vt 0.313380 0.992908 +vt 0.340320 0.996970 +vt 0.315930 0.996970 +vt 0.184868 0.181200 +vt 0.188869 0.183787 +vt 0.311620 0.992909 +vt 0.282130 0.992909 +vt 0.309070 0.996970 +vt 0.284680 0.996970 +vt 0.183462 0.183745 +vt 0.187908 0.185526 +vt 0.280370 0.992909 +vt 0.250880 0.992909 +vt 0.277820 0.996970 +vt 0.253430 0.996970 +vt 0.182597 0.186505 +vt 0.187317 0.187414 +vt 0.249120 0.992909 +vt 0.219630 0.992909 +vt 0.246570 0.996970 +vt 0.222180 0.996970 +vt 0.182304 0.189376 +vt 0.187117 0.189376 +vt 0.217870 0.992909 +vt 0.188380 0.992909 +vt 0.215320 0.996970 +vt 0.190930 0.996970 +vt 0.182597 0.192248 +vt 0.187317 0.191339 +vt 0.186620 0.992909 +vt 0.157130 0.992909 +vt 0.184070 0.996970 +vt 0.159680 0.996970 +vt 0.183462 0.195008 +vt 0.187908 0.193227 +vt 0.155370 0.992909 +vt 0.125880 0.992909 +vt 0.152820 0.996970 +vt 0.128430 0.996970 +vt 0.184868 0.197553 +vt 0.188869 0.194966 +vt 0.124120 0.992909 +vt 0.094630 0.992909 +vt 0.121570 0.996970 +vt 0.097180 0.996970 +vt 0.186760 0.199783 +vt 0.190163 0.196491 +vt 0.092870 0.992909 +vt 0.063380 0.992909 +vt 0.090320 0.996970 +vt 0.065930 0.996970 +vt 0.189065 0.201613 +vt 0.191739 0.197742 +vt 0.061620 0.992908 +vt 0.032130 0.992909 +vt 0.059070 0.996970 +vt 0.034680 0.996970 +vt 0.191695 0.202973 +vt 0.193537 0.198672 +vt 0.030370 0.992909 +vt 0.000880 0.992909 +vt 0.027820 0.996970 +vt 0.003429 0.996970 +vt 0.194549 0.203810 +vt 0.195488 0.199244 +vt 0.999120 0.992909 +vt 0.969630 0.992909 +vt 0.996571 0.996970 +vt 0.972180 0.996970 +vn 0.0000 -1.0000 -0.0000 +vn 0.0000 1.0000 0.0000 +vn 0.1903 0.2203 0.9567 +vn 0.1838 0.3345 0.9243 +vn 0.0000 0.3345 0.9424 +vn 0.0000 0.2203 0.9754 +vn -0.3733 0.2203 0.9012 +vn -0.3606 0.3345 0.8707 +vn -0.5235 0.3345 0.7836 +vn -0.5419 0.2203 0.8110 +vn -0.6664 0.3345 0.6664 +vn -0.6897 0.2203 0.6897 +vn -0.7836 0.3345 0.5235 +vn -0.8110 0.2203 0.5419 +vn -0.8707 0.3345 0.3606 +vn -0.9012 0.2203 0.3733 +vn -0.9243 0.3345 0.1838 +vn -0.9567 0.2203 0.1903 +vn -0.9424 0.3345 0.0000 +vn -0.9754 0.2203 0.0000 +vn -0.9243 0.3345 -0.1838 +vn -0.9567 0.2203 -0.1903 +vn -0.8707 0.3345 -0.3606 +vn -0.9012 0.2203 -0.3733 +vn -0.7836 0.3345 -0.5235 +vn -0.8110 0.2203 -0.5419 +vn -0.6664 0.3345 -0.6664 +vn -0.6897 0.2203 -0.6897 +vn -0.5235 0.3345 -0.7836 +vn -0.5419 0.2203 -0.8110 +vn -0.3606 0.3345 -0.8707 +vn -0.3733 0.2203 -0.9012 +vn -0.1838 0.3345 -0.9243 +vn -0.1903 0.2203 -0.9567 +vn 0.0000 0.3345 -0.9424 +vn 0.0000 0.2203 -0.9754 +vn 0.1838 0.3345 -0.9243 +vn 0.1903 0.2203 -0.9567 +vn 0.3606 0.3345 -0.8707 +vn 0.3733 0.2203 -0.9012 +vn 0.5235 0.3345 -0.7836 +vn 0.5419 0.2203 -0.8110 +vn 0.6664 0.3345 -0.6664 +vn 0.6897 0.2203 -0.6897 +vn 0.7836 0.3345 -0.5235 +vn 0.8110 0.2203 -0.5419 +vn 0.8707 0.3345 -0.3606 +vn 0.9012 0.2203 -0.3733 +vn 0.9243 0.3345 -0.1838 +vn 0.9567 0.2203 -0.1903 +vn 0.9424 0.3345 0.0000 +vn 0.9754 0.2203 0.0000 +vn 0.9243 0.3345 0.1838 +vn 0.9567 0.2203 0.1903 +vn 0.8707 0.3345 0.3606 +vn 0.9012 0.2203 0.3733 +vn 0.7836 0.3345 0.5235 +vn 0.8110 0.2203 0.5419 +vn 0.6664 0.3345 0.6664 +vn 0.6897 0.2203 0.6897 +vn 0.5235 0.3345 0.7836 +vn 0.5419 0.2203 0.8110 +vn 0.3606 0.3345 0.8707 +vn 0.3733 0.2203 0.9012 +vn -0.1838 0.3345 0.9243 +vn -0.1903 0.2203 0.9567 +vn 0.0352 -0.6962 -0.7169 +vn -0.0352 -0.6962 -0.7169 +vn -0.0352 0.6962 -0.7169 +vn 0.0352 0.6962 -0.7169 +vn -0.0352 -0.6962 0.7169 +vn 0.0352 -0.6962 0.7169 +vn 0.0352 0.6962 0.7169 +vn -0.0352 0.6962 0.7169 +vn -0.7169 -0.6962 -0.0352 +vn -0.7169 -0.6962 0.0352 +vn -0.7169 0.6962 0.0352 +vn -0.7169 0.6962 -0.0352 +vn -0.1420 0.6857 0.7139 +vn -0.1420 -0.6857 0.7139 +vn -0.2785 0.6857 0.6725 +vn -0.2785 -0.6857 0.6725 +vn -0.4044 0.6857 0.6052 +vn -0.4044 -0.6857 0.6052 +vn -0.5147 0.6857 0.5147 +vn -0.5147 -0.6857 0.5147 +vn -0.6052 0.6857 0.4044 +vn -0.6052 -0.6857 0.4044 +vn -0.6725 0.6857 0.2785 +vn -0.6725 -0.6857 0.2785 +vn -0.7139 0.6857 0.1420 +vn -0.7139 -0.6857 0.1420 +vn -0.1420 -0.6857 -0.7139 +vn -0.1420 0.6857 -0.7139 +vn -0.2785 -0.6857 -0.6725 +vn -0.2785 0.6857 -0.6725 +vn -0.4044 -0.6857 -0.6052 +vn -0.4044 0.6857 -0.6052 +vn -0.5147 -0.6857 -0.5147 +vn -0.5147 0.6857 -0.5147 +vn -0.6052 -0.6857 -0.4044 +vn -0.6052 0.6857 -0.4044 +vn -0.6725 -0.6857 -0.2785 +vn -0.6725 0.6857 -0.2785 +vn -0.7139 -0.6857 -0.1420 +vn -0.7139 0.6857 -0.1420 +vn 0.1420 0.6857 -0.7139 +vn 0.1420 -0.6857 -0.7139 +vn 0.2785 0.6857 -0.6725 +vn 0.2785 -0.6857 -0.6725 +vn 0.4044 0.6857 -0.6052 +vn 0.4044 -0.6857 -0.6052 +vn 0.5147 0.6857 -0.5147 +vn 0.5147 -0.6857 -0.5147 +vn 0.6052 0.6857 -0.4044 +vn 0.6052 -0.6857 -0.4044 +vn 0.6725 0.6857 -0.2785 +vn 0.6725 -0.6857 -0.2785 +vn 0.7139 0.6857 -0.1420 +vn 0.7139 -0.6857 -0.1420 +vn 0.7169 0.6962 -0.0352 +vn 0.7169 -0.6962 -0.0352 +vn 0.1420 -0.6857 0.7139 +vn 0.1420 0.6857 0.7139 +vn 0.2785 -0.6857 0.6725 +vn 0.2785 0.6857 0.6725 +vn 0.4044 -0.6857 0.6052 +vn 0.4044 0.6857 0.6052 +vn 0.5147 -0.6857 0.5147 +vn 0.5147 0.6857 0.5147 +vn 0.6052 -0.6857 0.4044 +vn 0.6052 0.6857 0.4044 +vn 0.6725 -0.6857 0.2785 +vn 0.6725 0.6857 0.2785 +vn 0.7139 -0.6857 0.1420 +vn 0.7139 0.6857 0.1420 +vn 0.7169 -0.6962 0.0352 +vn 0.7169 0.6962 0.0352 +vn 0.0000 0.6236 0.7817 +vn -0.1525 0.6236 0.7667 +vn 0.0000 0.8922 0.4517 +vn -0.0881 0.8922 0.4430 +vn 0.0000 0.9918 0.1276 +vn -0.0249 0.9918 0.1251 +vn -0.2991 0.6236 0.7222 +vn -0.1728 0.8922 0.4173 +vn -0.0488 0.9918 0.1179 +vn -0.4343 0.6236 0.6500 +vn -0.2509 0.8922 0.3755 +vn -0.0709 0.9918 0.1061 +vn -0.5528 0.6236 0.5528 +vn -0.3194 0.8922 0.3194 +vn -0.0902 0.9918 0.0902 +vn -0.6500 0.6236 0.4343 +vn -0.3755 0.8922 0.2509 +vn -0.1061 0.9918 0.0709 +vn -0.7222 0.6236 0.2991 +vn -0.4173 0.8922 0.1728 +vn -0.1179 0.9918 0.0488 +vn -0.7667 0.6236 0.1525 +vn -0.4430 0.8922 0.0881 +vn -0.1251 0.9918 0.0249 +vn -0.7817 0.6236 0.0000 +vn -0.4517 0.8922 0.0000 +vn -0.1276 0.9918 0.0000 +vn -0.7667 0.6236 -0.1525 +vn -0.4430 0.8922 -0.0881 +vn -0.1251 0.9918 -0.0249 +vn -0.7222 0.6236 -0.2991 +vn -0.4173 0.8922 -0.1728 +vn -0.1179 0.9918 -0.0488 +vn -0.6500 0.6236 -0.4343 +vn -0.3755 0.8922 -0.2509 +vn -0.1061 0.9918 -0.0709 +vn -0.5528 0.6236 -0.5528 +vn -0.3194 0.8922 -0.3194 +vn -0.0902 0.9918 -0.0902 +vn -0.4343 0.6236 -0.6500 +vn -0.2509 0.8922 -0.3755 +vn -0.0709 0.9918 -0.1061 +vn -0.2991 0.6236 -0.7222 +vn -0.1728 0.8922 -0.4173 +vn -0.0488 0.9918 -0.1179 +vn -0.1525 0.6236 -0.7667 +vn -0.0881 0.8922 -0.4430 +vn -0.0249 0.9918 -0.1251 +vn 0.0000 0.6236 -0.7817 +vn 0.0000 0.8922 -0.4517 +vn 0.0000 0.9918 -0.1276 +vn 0.1525 0.6236 -0.7667 +vn 0.0881 0.8922 -0.4430 +vn 0.0249 0.9918 -0.1251 +vn 0.2991 0.6236 -0.7222 +vn 0.1728 0.8922 -0.4173 +vn 0.0488 0.9918 -0.1179 +vn 0.4343 0.6236 -0.6500 +vn 0.2509 0.8922 -0.3755 +vn 0.0709 0.9918 -0.1061 +vn 0.5528 0.6236 -0.5528 +vn 0.3194 0.8922 -0.3194 +vn 0.0902 0.9918 -0.0902 +vn 0.6500 0.6236 -0.4343 +vn 0.3755 0.8922 -0.2509 +vn 0.1061 0.9918 -0.0709 +vn 0.7222 0.6236 -0.2991 +vn 0.4173 0.8922 -0.1728 +vn 0.1179 0.9918 -0.0488 +vn 0.7667 0.6236 -0.1525 +vn 0.4430 0.8922 -0.0881 +vn 0.1251 0.9918 -0.0249 +vn 0.7817 0.6236 0.0000 +vn 0.4517 0.8922 0.0000 +vn 0.1276 0.9918 0.0000 +vn 0.7667 0.6236 0.1525 +vn 0.4430 0.8922 0.0881 +vn 0.1251 0.9918 0.0249 +vn 0.7222 0.6236 0.2991 +vn 0.4173 0.8922 0.1728 +vn 0.1179 0.9918 0.0488 +vn 0.6500 0.6236 0.4343 +vn 0.3755 0.8922 0.2509 +vn 0.1061 0.9918 0.0709 +vn 0.5528 0.6236 0.5528 +vn 0.3194 0.8922 0.3194 +vn 0.0902 0.9918 0.0902 +vn 0.4343 0.6236 0.6500 +vn 0.2509 0.8922 0.3755 +vn 0.0709 0.9918 0.1061 +vn 0.2991 0.6236 0.7222 +vn 0.1728 0.8922 0.4173 +vn 0.0488 0.9918 0.1179 +vn 0.1525 0.6236 0.7667 +vn 0.0881 0.8922 0.4430 +vn 0.0249 0.9918 0.1251 +g Cylinder_Cylinder_None +s off +f 33/1/1 35/2/1 36/3/1 37/4/1 38/5/1 39/6/1 40/7/1 41/8/1 34/9/1 51/10/1 53/11/1 54/12/1 55/13/1 56/14/1 57/15/1 58/16/1 59/17/1 52/18/1 60/19/1 62/20/1 63/21/1 64/22/1 65/23/1 66/24/1 67/25/1 68/26/1 61/27/1 42/28/1 44/29/1 45/30/1 46/31/1 47/32/1 48/33/1 49/34/1 50/35/1 43/36/1 +f 78/37/2 80/38/2 81/39/2 82/40/2 83/41/2 84/42/2 85/43/2 86/44/2 79/45/2 87/46/2 89/47/2 90/48/2 91/49/2 92/50/2 93/51/2 94/52/2 95/53/2 88/54/2 96/55/2 98/56/2 99/57/2 100/58/2 101/59/2 102/60/2 103/61/2 104/62/2 97/63/2 69/64/2 71/65/2 72/66/2 73/67/2 74/68/2 75/69/2 76/70/2 77/71/2 70/72/2 +s 1 +f 32/73/3 230/74/4 106/75/5 1/76/6 +f 3/77/7 114/78/8 118/79/9 4/80/10 +f 4/80/10 118/79/9 122/81/11 5/82/12 +f 5/82/12 122/81/11 126/83/13 6/84/14 +f 6/84/14 126/83/13 130/85/15 7/86/16 +f 7/86/16 130/85/15 134/87/17 8/88/18 +f 8/88/18 134/87/17 138/89/19 9/90/20 +f 9/90/20 138/91/19 142/92/21 10/93/22 +f 10/93/22 142/92/21 146/94/23 11/95/24 +f 11/95/24 146/94/23 150/96/25 12/97/26 +f 12/97/26 150/96/25 154/98/27 13/99/28 +f 13/99/28 154/98/27 158/100/29 14/101/30 +f 14/101/30 158/100/29 162/102/31 15/103/32 +f 15/103/32 162/102/31 166/104/33 16/105/34 +f 16/105/34 166/104/33 170/106/35 17/107/36 +f 17/107/36 170/106/35 174/108/37 18/109/38 +f 18/109/38 174/108/37 178/110/39 19/111/40 +f 19/111/40 178/110/39 182/112/41 20/113/42 +f 20/113/42 182/112/41 186/114/43 21/115/44 +f 21/115/44 186/114/43 190/116/45 22/117/46 +f 22/117/46 190/116/45 194/118/47 23/119/48 +f 23/119/48 194/118/47 198/120/49 24/121/50 +f 24/121/50 198/120/49 202/122/51 25/123/52 +f 25/123/52 202/122/51 206/124/53 26/125/54 +f 26/125/54 206/124/53 210/126/55 27/127/56 +f 27/127/56 210/126/55 214/128/57 28/129/58 +f 28/129/58 214/128/57 218/130/59 29/131/60 +f 29/131/60 218/130/59 222/132/61 30/133/62 +f 30/133/62 222/132/61 226/134/63 31/135/64 +f 31/135/64 226/134/63 230/136/4 32/137/3 +f 1/76/6 106/138/5 110/139/65 2/140/66 +f 2/140/66 110/139/65 114/78/8 3/77/7 +f 33/141/67 43/142/68 87/143/69 79/144/70 +f 60/145/71 52/146/72 69/147/73 97/148/74 +f 42/149/75 61/150/76 96/151/77 88/152/78 +f 60/145/71 97/148/74 104/153/79 62/154/80 +f 62/154/80 104/153/79 103/155/81 63/156/82 +f 63/156/82 103/155/81 102/157/83 64/158/84 +f 64/158/84 102/157/83 101/159/85 65/160/86 +f 65/160/86 101/159/85 100/161/87 66/162/88 +f 66/162/88 100/161/87 99/163/89 67/164/90 +f 67/164/90 99/163/89 98/165/91 68/166/92 +f 68/166/92 98/165/91 96/151/77 61/150/76 +f 87/143/69 43/142/68 50/167/93 89/168/94 +f 89/168/94 50/167/93 49/169/95 90/170/96 +f 90/170/96 49/169/95 48/171/97 91/172/98 +f 91/172/98 48/171/97 47/173/99 92/174/100 +f 92/174/100 47/173/99 46/175/101 93/176/102 +f 93/176/102 46/175/101 45/177/103 94/178/104 +f 94/178/104 45/177/103 44/179/105 95/180/106 +f 95/180/106 44/179/105 42/149/75 88/152/78 +f 33/141/67 79/144/70 86/181/107 35/182/108 +f 35/182/108 86/181/107 85/183/109 36/184/110 +f 36/184/110 85/183/109 84/185/111 37/186/112 +f 37/186/112 84/185/111 83/187/113 38/188/114 +f 38/188/114 83/187/113 82/189/115 39/190/116 +f 39/190/116 82/189/115 81/191/117 40/192/118 +f 40/192/118 81/191/117 80/193/119 41/194/120 +f 41/194/120 80/193/119 78/195/121 34/196/122 +f 69/197/73 52/198/72 59/199/123 71/200/124 +f 71/200/124 59/199/123 58/201/125 72/202/126 +f 72/202/126 58/201/125 57/203/127 73/204/128 +f 73/204/128 57/203/127 56/205/129 74/206/130 +f 74/206/130 56/205/129 55/207/131 75/208/132 +f 75/208/132 55/207/131 54/209/133 76/210/134 +f 76/210/134 54/209/133 53/211/135 77/212/136 +f 77/212/136 53/211/135 51/213/137 70/214/138 +f 51/213/137 34/196/122 78/195/121 70/214/138 +f 110/139/65 106/138/5 108/215/139 112/216/140 +f 112/216/140 108/215/139 107/217/141 111/218/142 +f 111/219/142 107/220/141 105/221/143 109/222/144 +f 114/78/8 110/139/65 112/223/140 116/224/145 +f 116/224/145 112/223/140 111/225/142 115/226/146 +f 115/227/146 111/219/142 109/222/144 113/228/147 +f 118/79/9 114/78/8 116/229/145 120/230/148 +f 120/230/148 116/229/145 115/231/146 119/232/149 +f 119/233/149 115/227/146 113/228/147 117/234/150 +f 122/81/11 118/79/9 120/235/148 124/236/151 +f 124/236/151 120/235/148 119/237/149 123/238/152 +f 123/239/152 119/233/149 117/234/150 121/240/153 +f 126/83/13 122/81/11 124/241/151 128/242/154 +f 128/242/154 124/241/151 123/243/152 127/244/155 +f 127/245/155 123/239/152 121/240/153 125/246/156 +f 130/85/15 126/83/13 128/247/154 132/248/157 +f 132/248/157 128/247/154 127/249/155 131/250/158 +f 131/251/158 127/245/155 125/246/156 129/252/159 +f 134/87/17 130/85/15 132/253/157 136/254/160 +f 136/254/160 132/253/157 131/255/158 135/256/161 +f 135/257/161 131/251/158 129/252/159 133/258/162 +f 138/89/19 134/87/17 136/259/160 140/260/163 +f 140/260/163 136/259/160 135/261/161 139/262/164 +f 139/263/164 135/257/161 133/258/162 137/264/165 +f 142/92/21 138/91/19 140/265/163 144/266/166 +f 144/266/166 140/265/163 139/267/164 143/268/167 +f 143/269/167 139/263/164 137/264/165 141/270/168 +f 146/94/23 142/92/21 144/271/166 148/272/169 +f 148/272/169 144/271/166 143/273/167 147/274/170 +f 147/275/170 143/269/167 141/270/168 145/276/171 +f 150/96/25 146/94/23 148/277/169 152/278/172 +f 152/278/172 148/277/169 147/279/170 151/280/173 +f 151/281/173 147/275/170 145/276/171 149/282/174 +f 154/98/27 150/96/25 152/283/172 156/284/175 +f 156/284/175 152/283/172 151/285/173 155/286/176 +f 155/287/176 151/281/173 149/282/174 153/288/177 +f 158/100/29 154/98/27 156/289/175 160/290/178 +f 160/290/178 156/289/175 155/291/176 159/292/179 +f 159/293/179 155/287/176 153/288/177 157/294/180 +f 162/102/31 158/100/29 160/295/178 164/296/181 +f 164/296/181 160/295/178 159/297/179 163/298/182 +f 163/299/182 159/293/179 157/294/180 161/300/183 +f 166/104/33 162/102/31 164/301/181 168/302/184 +f 168/302/184 164/301/181 163/303/182 167/304/185 +f 167/305/185 163/299/182 161/300/183 165/306/186 +f 170/106/35 166/104/33 168/307/184 172/308/187 +f 172/308/187 168/307/184 167/309/185 171/310/188 +f 171/311/188 167/305/185 165/306/186 169/312/189 +f 174/108/37 170/106/35 172/313/187 176/314/190 +f 176/314/190 172/313/187 171/315/188 175/316/191 +f 175/317/191 171/311/188 169/312/189 173/318/192 +f 178/110/39 174/108/37 176/319/190 180/320/193 +f 180/320/193 176/319/190 175/321/191 179/322/194 +f 179/323/194 175/317/191 173/318/192 177/324/195 +f 182/112/41 178/110/39 180/325/193 184/326/196 +f 184/326/196 180/325/193 179/327/194 183/328/197 +f 183/329/197 179/323/194 177/324/195 181/330/198 +f 186/114/43 182/112/41 184/331/196 188/332/199 +f 188/332/199 184/331/196 183/333/197 187/334/200 +f 187/335/200 183/329/197 181/330/198 185/336/201 +f 190/116/45 186/114/43 188/337/199 192/338/202 +f 192/338/202 188/337/199 187/339/200 191/340/203 +f 191/341/203 187/335/200 185/336/201 189/342/204 +f 194/118/47 190/116/45 192/343/202 196/344/205 +f 196/344/205 192/343/202 191/345/203 195/346/206 +f 195/347/206 191/341/203 189/342/204 193/348/207 +f 198/120/49 194/118/47 196/349/205 200/350/208 +f 200/350/208 196/349/205 195/351/206 199/352/209 +f 199/353/209 195/347/206 193/348/207 197/354/210 +f 202/122/51 198/120/49 200/355/208 204/356/211 +f 204/356/211 200/355/208 199/357/209 203/358/212 +f 203/359/212 199/353/209 197/354/210 201/360/213 +f 206/124/53 202/122/51 204/361/211 208/362/214 +f 208/362/214 204/361/211 203/363/212 207/364/215 +f 207/365/215 203/359/212 201/360/213 205/366/216 +f 210/126/55 206/124/53 208/367/214 212/368/217 +f 212/368/217 208/367/214 207/369/215 211/370/218 +f 211/371/218 207/365/215 205/366/216 209/372/219 +f 214/128/57 210/126/55 212/373/217 216/374/220 +f 216/374/220 212/373/217 211/375/218 215/376/221 +f 215/377/221 211/371/218 209/372/219 213/378/222 +f 218/130/59 214/128/57 216/379/220 220/380/223 +f 220/380/223 216/379/220 215/381/221 219/382/224 +f 219/383/224 215/377/221 213/378/222 217/384/225 +f 222/132/61 218/130/59 220/385/223 224/386/226 +f 224/386/226 220/385/223 219/387/224 223/388/227 +f 223/389/227 219/383/224 217/384/225 221/390/228 +f 226/134/63 222/132/61 224/391/226 228/392/229 +f 228/392/229 224/391/226 223/393/227 227/394/230 +f 227/395/230 223/389/227 221/390/228 225/396/231 +f 230/136/4 226/134/63 228/397/229 232/398/232 +f 232/398/232 228/397/229 227/399/230 231/400/233 +f 231/401/233 227/395/230 225/396/231 229/402/234 +f 106/75/5 230/74/4 232/403/232 108/404/139 +f 108/404/139 232/403/232 231/405/233 107/406/141 +f 107/220/141 231/401/233 229/402/234 105/221/143 +f 109/222/144 105/221/143 229/402/234 225/396/231 221/390/228 217/384/225 213/378/222 209/372/219 205/366/216 201/360/213 197/354/210 193/348/207 189/342/204 185/336/201 181/330/198 177/324/195 173/318/192 169/312/189 165/306/186 161/300/183 157/294/180 153/288/177 149/282/174 145/276/171 141/270/168 137/264/165 133/258/162 129/252/159 125/246/156 121/240/153 117/234/150 113/228/147 diff --git a/mods/roads/infrastructure/models/infrastructure_traffic_cone_i2.obj b/mods/roads/infrastructure/models/infrastructure_traffic_cone_i2.obj new file mode 100644 index 0000000..3a4a9c7 --- /dev/null +++ b/mods/roads/infrastructure/models/infrastructure_traffic_cone_i2.obj @@ -0,0 +1,1045 @@ +# Blender v2.79 (sub 0) OBJ File: 'traffic cone.blend' +# www.blender.org +o Cylinder +v 0.000000 -0.974600 0.203250 +v -0.039652 -0.974600 0.199345 +v -0.077780 -0.974600 0.187779 +v -0.112920 -0.974600 0.168996 +v -0.143719 -0.974600 0.143719 +v -0.168996 -0.974600 0.112920 +v -0.187779 -0.974600 0.077780 +v -0.199345 -0.974600 0.039652 +v -0.203250 -0.974600 0.000000 +v -0.199345 -0.974600 -0.039652 +v -0.187779 -0.974600 -0.077780 +v -0.168996 -0.974600 -0.112920 +v -0.143719 -0.974600 -0.143719 +v -0.112920 -0.974600 -0.168996 +v -0.077780 -0.974600 -0.187779 +v -0.039652 -0.974600 -0.199345 +v 0.000000 -0.974600 -0.203250 +v 0.039652 -0.974600 -0.199345 +v 0.077781 -0.974600 -0.187778 +v 0.112920 -0.974600 -0.168996 +v 0.143720 -0.974600 -0.143719 +v 0.168996 -0.974600 -0.112920 +v 0.187779 -0.974600 -0.077780 +v 0.199345 -0.974600 -0.039652 +v 0.203250 -0.974600 0.000000 +v 0.199345 -0.974600 0.039652 +v 0.187778 -0.974600 0.077781 +v 0.168996 -0.974600 0.112920 +v 0.143719 -0.974600 0.143720 +v 0.112919 -0.974600 0.168996 +v 0.077780 -0.974600 0.187779 +v 0.039652 -0.974600 0.199345 +v 0.191399 -1.000000 -0.250000 +v 0.250000 -1.000000 -0.191399 +v 0.202831 -1.000000 -0.248874 +v 0.213825 -1.000000 -0.245539 +v 0.223956 -1.000000 -0.240124 +v 0.232836 -1.000000 -0.232836 +v 0.240124 -1.000000 -0.223956 +v 0.245539 -1.000000 -0.213825 +v 0.248874 -1.000000 -0.202831 +v -0.250000 -1.000000 -0.191399 +v -0.191399 -1.000000 -0.250000 +v -0.248874 -1.000000 -0.202831 +v -0.245539 -1.000000 -0.213825 +v -0.240124 -1.000000 -0.223956 +v -0.232836 -1.000000 -0.232836 +v -0.223956 -1.000000 -0.240124 +v -0.213825 -1.000000 -0.245539 +v -0.202831 -1.000000 -0.248874 +v 0.250000 -1.000000 0.191399 +v 0.191399 -1.000000 0.250000 +v 0.248874 -1.000000 0.202831 +v 0.245539 -1.000000 0.213825 +v 0.240124 -1.000000 0.223956 +v 0.232836 -1.000000 0.232836 +v 0.223956 -1.000000 0.240124 +v 0.213825 -1.000000 0.245539 +v 0.202831 -1.000000 0.248874 +v -0.191399 -1.000000 0.250000 +v -0.250000 -1.000000 0.191399 +v -0.202831 -1.000000 0.248874 +v -0.213825 -1.000000 0.245539 +v -0.223956 -1.000000 0.240124 +v -0.232836 -1.000000 0.232836 +v -0.240124 -1.000000 0.223956 +v -0.245539 -1.000000 0.213825 +v -0.248874 -1.000000 0.202831 +v 0.191399 -0.974600 0.250000 +v 0.250000 -0.974600 0.191399 +v 0.202831 -0.974600 0.248874 +v 0.213825 -0.974600 0.245539 +v 0.223956 -0.974600 0.240124 +v 0.232836 -0.974600 0.232836 +v 0.240124 -0.974600 0.223956 +v 0.245539 -0.974600 0.213825 +v 0.248874 -0.974600 0.202831 +v 0.250000 -0.974600 -0.191399 +v 0.191399 -0.974600 -0.250000 +v 0.248874 -0.974600 -0.202831 +v 0.245539 -0.974600 -0.213825 +v 0.240124 -0.974600 -0.223956 +v 0.232836 -0.974600 -0.232836 +v 0.223956 -0.974600 -0.240124 +v 0.213825 -0.974600 -0.245539 +v 0.202831 -0.974600 -0.248874 +v -0.191399 -0.974600 -0.250000 +v -0.250000 -0.974600 -0.191399 +v -0.202831 -0.974600 -0.248874 +v -0.213825 -0.974600 -0.245539 +v -0.223956 -0.974600 -0.240124 +v -0.232836 -0.974600 -0.232836 +v -0.240124 -0.974600 -0.223956 +v -0.245539 -0.974600 -0.213825 +v -0.248874 -0.974600 -0.202831 +v -0.250000 -0.974600 0.191399 +v -0.191399 -0.974600 0.250000 +v -0.248874 -0.974600 0.202831 +v -0.245539 -0.974600 0.213825 +v -0.240124 -0.974600 0.223956 +v -0.232836 -0.974600 0.232836 +v -0.223956 -0.974600 0.240124 +v -0.213825 -0.974600 0.245539 +v -0.202831 -0.974600 0.248874 +v -0.000000 -0.187000 0.013552 +v 0.000000 -0.198502 0.027995 +v -0.000000 -0.188541 0.019823 +v -0.000000 -0.192751 0.025109 +v -0.002644 -0.187000 0.013292 +v -0.005462 -0.198502 0.027457 +v -0.003867 -0.188541 0.019442 +v -0.004899 -0.192751 0.024627 +v -0.005186 -0.187000 0.012521 +v -0.010713 -0.198502 0.025864 +v -0.007586 -0.188541 0.018314 +v -0.009609 -0.192751 0.023198 +v -0.007529 -0.187000 0.011268 +v -0.015553 -0.198502 0.023277 +v -0.011013 -0.188541 0.016482 +v -0.013950 -0.192751 0.020878 +v -0.009583 -0.187000 0.009583 +v -0.019795 -0.198502 0.019795 +v -0.014017 -0.188541 0.014017 +v -0.017755 -0.192751 0.017755 +v -0.011268 -0.187000 0.007529 +v -0.023277 -0.198502 0.015553 +v -0.016482 -0.188541 0.011013 +v -0.020878 -0.192751 0.013950 +v -0.012521 -0.187000 0.005186 +v -0.025864 -0.198502 0.010713 +v -0.018314 -0.188541 0.007586 +v -0.023198 -0.192751 0.009609 +v -0.013292 -0.187000 0.002644 +v -0.027457 -0.198502 0.005462 +v -0.019442 -0.188541 0.003867 +v -0.024627 -0.192751 0.004899 +v -0.013552 -0.187000 -0.000000 +v -0.027995 -0.198502 0.000000 +v -0.019823 -0.188541 0.000000 +v -0.025109 -0.192751 0.000000 +v -0.013292 -0.187000 -0.002644 +v -0.027457 -0.198502 -0.005462 +v -0.019442 -0.188541 -0.003867 +v -0.024627 -0.192751 -0.004899 +v -0.012521 -0.187000 -0.005186 +v -0.025864 -0.198502 -0.010713 +v -0.018314 -0.188541 -0.007586 +v -0.023198 -0.192751 -0.009609 +v -0.011268 -0.187000 -0.007529 +v -0.023277 -0.198502 -0.015553 +v -0.016482 -0.188541 -0.011013 +v -0.020878 -0.192751 -0.013950 +v -0.009583 -0.187000 -0.009583 +v -0.019795 -0.198502 -0.019795 +v -0.014017 -0.188541 -0.014017 +v -0.017755 -0.192751 -0.017755 +v -0.007529 -0.187000 -0.011268 +v -0.015553 -0.198502 -0.023277 +v -0.011013 -0.188541 -0.016482 +v -0.013950 -0.192751 -0.020878 +v -0.005186 -0.187000 -0.012521 +v -0.010713 -0.198502 -0.025864 +v -0.007586 -0.188541 -0.018314 +v -0.009609 -0.192751 -0.023198 +v -0.002644 -0.187000 -0.013292 +v -0.005462 -0.198502 -0.027457 +v -0.003867 -0.188541 -0.019442 +v -0.004899 -0.192751 -0.024627 +v 0.000000 -0.187000 -0.013552 +v 0.000000 -0.198502 -0.027995 +v 0.000000 -0.188541 -0.019823 +v 0.000000 -0.192751 -0.025109 +v 0.002644 -0.187000 -0.013292 +v 0.005462 -0.198502 -0.027457 +v 0.003867 -0.188541 -0.019442 +v 0.004899 -0.192751 -0.024627 +v 0.005186 -0.187000 -0.012521 +v 0.010713 -0.198502 -0.025864 +v 0.007586 -0.188541 -0.018314 +v 0.009609 -0.192751 -0.023198 +v 0.007529 -0.187000 -0.011268 +v 0.015553 -0.198502 -0.023277 +v 0.011013 -0.188541 -0.016482 +v 0.013950 -0.192751 -0.020878 +v 0.009583 -0.187000 -0.009583 +v 0.019795 -0.198502 -0.019795 +v 0.014017 -0.188541 -0.014017 +v 0.017755 -0.192751 -0.017755 +v 0.011268 -0.187000 -0.007529 +v 0.023277 -0.198502 -0.015553 +v 0.016482 -0.188541 -0.011013 +v 0.020878 -0.192751 -0.013950 +v 0.012521 -0.187000 -0.005186 +v 0.025864 -0.198502 -0.010713 +v 0.018314 -0.188541 -0.007586 +v 0.023198 -0.192751 -0.009609 +v 0.013292 -0.187000 -0.002644 +v 0.027457 -0.198502 -0.005462 +v 0.019442 -0.188541 -0.003867 +v 0.024627 -0.192751 -0.004899 +v 0.013552 -0.187000 0.000000 +v 0.027995 -0.198502 0.000000 +v 0.019823 -0.188541 0.000000 +v 0.025109 -0.192751 0.000000 +v 0.013292 -0.187000 0.002644 +v 0.027457 -0.198502 0.005462 +v 0.019442 -0.188541 0.003867 +v 0.024627 -0.192751 0.004899 +v 0.012521 -0.187000 0.005186 +v 0.025864 -0.198502 0.010713 +v 0.018314 -0.188541 0.007586 +v 0.023198 -0.192751 0.009609 +v 0.011268 -0.187000 0.007529 +v 0.023277 -0.198502 0.015553 +v 0.016482 -0.188541 0.011013 +v 0.020878 -0.192751 0.013950 +v 0.009583 -0.187000 0.009583 +v 0.019795 -0.198502 0.019795 +v 0.014017 -0.188541 0.014017 +v 0.017755 -0.192751 0.017755 +v 0.007529 -0.187000 0.011268 +v 0.015553 -0.198502 0.023277 +v 0.011013 -0.188541 0.016482 +v 0.013950 -0.192751 0.020878 +v 0.005186 -0.187000 0.012521 +v 0.010713 -0.198502 0.025864 +v 0.007586 -0.188541 0.018314 +v 0.009609 -0.192751 0.023198 +v 0.002644 -0.187000 0.013292 +v 0.005462 -0.198502 0.027457 +v 0.003867 -0.188541 0.019442 +v 0.004899 -0.192751 0.024627 +vt 0.444971 0.003030 +vt 0.436198 0.003866 +vt 0.427761 0.006342 +vt 0.419987 0.010362 +vt 0.413172 0.015773 +vt 0.407579 0.022366 +vt 0.403423 0.029887 +vt 0.400864 0.038049 +vt 0.400000 0.046537 +vt 0.400000 0.330730 +vt 0.400864 0.339218 +vt 0.403423 0.347380 +vt 0.407579 0.354901 +vt 0.413172 0.361494 +vt 0.419987 0.366905 +vt 0.427761 0.370925 +vt 0.436198 0.373401 +vt 0.444971 0.374237 +vt 0.738735 0.374237 +vt 0.747508 0.373401 +vt 0.755944 0.370925 +vt 0.763719 0.366905 +vt 0.770534 0.361494 +vt 0.776127 0.354901 +vt 0.780283 0.347380 +vt 0.782842 0.339218 +vt 0.783706 0.330730 +vt 0.783706 0.046537 +vt 0.782842 0.038049 +vt 0.780283 0.029887 +vt 0.776127 0.022366 +vt 0.770534 0.015773 +vt 0.763719 0.010362 +vt 0.755944 0.006342 +vt 0.747508 0.003866 +vt 0.738735 0.003030 +vt 0.003125 0.046537 +vt 0.003989 0.038049 +vt 0.006548 0.029887 +vt 0.010704 0.022366 +vt 0.016297 0.015773 +vt 0.023112 0.010362 +vt 0.030886 0.006342 +vt 0.039323 0.003866 +vt 0.048096 0.003030 +vt 0.341860 0.003030 +vt 0.350633 0.003866 +vt 0.359069 0.006342 +vt 0.366844 0.010362 +vt 0.373659 0.015773 +vt 0.379252 0.022366 +vt 0.383408 0.029887 +vt 0.385967 0.038049 +vt 0.386831 0.046537 +vt 0.386831 0.330730 +vt 0.385967 0.339218 +vt 0.383408 0.347380 +vt 0.379252 0.354901 +vt 0.373659 0.361494 +vt 0.366844 0.366905 +vt 0.359069 0.370925 +vt 0.350633 0.373401 +vt 0.341860 0.374237 +vt 0.048096 0.374237 +vt 0.039323 0.373401 +vt 0.030886 0.370925 +vt 0.023112 0.366905 +vt 0.016297 0.361494 +vt 0.010704 0.354901 +vt 0.006548 0.347380 +vt 0.003989 0.339218 +vt 0.003125 0.330730 +vt 1.000000 0.403030 +vt 1.000000 0.988340 +vt 0.968750 0.988340 +vt 0.968750 0.403030 +vt 0.906250 0.403030 +vt 0.906250 0.988340 +vt 0.875000 0.988340 +vt 0.875000 0.403030 +vt 0.843750 0.988340 +vt 0.843750 0.403030 +vt 0.812500 0.988340 +vt 0.812500 0.403030 +vt 0.781250 0.988340 +vt 0.781250 0.403030 +vt 0.750000 0.988340 +vt 0.750000 0.403030 +vt 0.718750 0.988340 +vt 0.718750 0.403030 +vt 0.718750 0.988340 +vt 0.687500 0.988340 +vt 0.687500 0.403030 +vt 0.656250 0.988340 +vt 0.656250 0.403030 +vt 0.625000 0.988340 +vt 0.625000 0.403030 +vt 0.593750 0.988340 +vt 0.593750 0.403030 +vt 0.562500 0.988340 +vt 0.562500 0.403030 +vt 0.531250 0.988340 +vt 0.531250 0.403030 +vt 0.500000 0.988340 +vt 0.500000 0.403030 +vt 0.468750 0.988340 +vt 0.468750 0.403030 +vt 0.437500 0.988340 +vt 0.437500 0.403030 +vt 0.406250 0.988340 +vt 0.406250 0.403030 +vt 0.375000 0.988340 +vt 0.375000 0.403030 +vt 0.343750 0.988340 +vt 0.343750 0.403030 +vt 0.312500 0.988340 +vt 0.312500 0.403030 +vt 0.281250 0.988340 +vt 0.281250 0.403030 +vt 0.250000 0.988340 +vt 0.250000 0.403030 +vt 0.218750 0.988340 +vt 0.218750 0.403030 +vt 0.187500 0.988340 +vt 0.187500 0.403030 +vt 0.156250 0.988340 +vt 0.156250 0.403030 +vt 0.125000 0.988340 +vt 0.125000 0.403030 +vt 0.093750 0.988340 +vt 0.093750 0.403030 +vt 0.062500 0.988340 +vt 0.062500 0.403030 +vt 0.031250 0.988340 +vt 0.031250 0.403030 +vt 0.000000 0.988340 +vt 0.000000 0.403030 +vt 0.968750 0.988340 +vt 0.937500 0.988340 +vt 0.937500 0.403030 +vt 0.300000 0.384848 +vt 0.500000 0.384848 +vt 0.500000 0.396970 +vt 0.300000 0.396970 +vt 0.800000 0.384848 +vt 1.000000 0.384848 +vt 1.000000 0.396970 +vt 0.800000 0.396970 +vt 0.550000 0.384848 +vt 0.750000 0.384848 +vt 0.750000 0.396970 +vt 0.550000 0.396970 +vt 0.793750 0.396970 +vt 0.793750 0.384848 +vt 0.787500 0.396970 +vt 0.787500 0.384848 +vt 0.781250 0.396970 +vt 0.781250 0.384848 +vt 0.775000 0.396970 +vt 0.775000 0.384848 +vt 0.768750 0.396970 +vt 0.768750 0.384848 +vt 0.762500 0.396970 +vt 0.762500 0.384848 +vt 0.756250 0.396970 +vt 0.756250 0.384848 +vt 0.506250 0.384848 +vt 0.506250 0.396970 +vt 0.512500 0.384848 +vt 0.512500 0.396970 +vt 0.518750 0.384848 +vt 0.518750 0.396970 +vt 0.525000 0.384848 +vt 0.525000 0.396970 +vt 0.531250 0.384848 +vt 0.531250 0.396970 +vt 0.537500 0.384848 +vt 0.537500 0.396970 +vt 0.543750 0.384848 +vt 0.543750 0.396970 +vt 0.293750 0.396970 +vt 0.293750 0.384848 +vt 0.287500 0.396970 +vt 0.287500 0.384848 +vt 0.281250 0.396970 +vt 0.281250 0.384848 +vt 0.275000 0.396970 +vt 0.275000 0.384848 +vt 0.268750 0.396970 +vt 0.268750 0.384848 +vt 0.262500 0.396970 +vt 0.262500 0.384848 +vt 0.256250 0.396970 +vt 0.256250 0.384848 +vt 0.250000 0.396970 +vt 0.250000 0.384848 +vt 0.000000 0.396970 +vt 0.000000 0.384848 +vt 0.006250 0.384848 +vt 0.006250 0.396970 +vt 0.012500 0.384848 +vt 0.012500 0.396970 +vt 0.018750 0.384848 +vt 0.018750 0.396970 +vt 0.025000 0.384848 +vt 0.025000 0.396970 +vt 0.031250 0.384848 +vt 0.031250 0.396970 +vt 0.037500 0.384848 +vt 0.037500 0.396970 +vt 0.043750 0.384848 +vt 0.043750 0.396970 +vt 0.050000 0.384848 +vt 0.050000 0.396970 +vt 0.967870 0.992909 +vt 0.938380 0.992909 +vt 0.965320 0.996970 +vt 0.940930 0.996970 +vt 0.200485 0.203811 +vt 0.197517 0.204093 +vt 0.197517 0.199438 +vt 0.199546 0.199244 +vt 0.936620 0.992908 +vt 0.907130 0.992909 +vt 0.934070 0.996970 +vt 0.909680 0.996970 +vt 0.203338 0.202973 +vt 0.201497 0.198672 +vt 0.905370 0.992909 +vt 0.875880 0.992909 +vt 0.902820 0.996970 +vt 0.878429 0.996970 +vt 0.205968 0.201613 +vt 0.203295 0.197742 +vt 0.874120 0.992908 +vt 0.844630 0.992909 +vt 0.871571 0.996970 +vt 0.847180 0.996970 +vt 0.208274 0.199783 +vt 0.204871 0.196491 +vt 0.842870 0.992908 +vt 0.813380 0.992908 +vt 0.840320 0.996970 +vt 0.815929 0.996970 +vt 0.210165 0.197553 +vt 0.206164 0.194966 +vt 0.811620 0.992909 +vt 0.782130 0.992909 +vt 0.809071 0.996970 +vt 0.784680 0.996970 +vt 0.211571 0.195008 +vt 0.207125 0.193227 +vt 0.780370 0.992909 +vt 0.750880 0.992908 +vt 0.777820 0.996970 +vt 0.753429 0.996970 +vt 0.212437 0.192248 +vt 0.207717 0.191339 +vt 0.749120 0.992909 +vt 0.719630 0.992909 +vt 0.746570 0.996970 +vt 0.722180 0.996970 +vt 0.212729 0.189376 +vt 0.207917 0.189376 +vt 0.717870 0.992908 +vt 0.688380 0.992908 +vt 0.715320 0.996970 +vt 0.690930 0.996970 +vt 0.212437 0.186505 +vt 0.207717 0.187414 +vt 0.686620 0.992909 +vt 0.657130 0.992909 +vt 0.684071 0.996970 +vt 0.659680 0.996970 +vt 0.211571 0.183745 +vt 0.207125 0.185526 +vt 0.655370 0.992908 +vt 0.625880 0.992908 +vt 0.652820 0.996970 +vt 0.628429 0.996970 +vt 0.210165 0.181200 +vt 0.206164 0.183787 +vt 0.624120 0.992908 +vt 0.594630 0.992909 +vt 0.621571 0.996970 +vt 0.597180 0.996970 +vt 0.208274 0.178970 +vt 0.204871 0.182262 +vt 0.592870 0.992908 +vt 0.563380 0.992908 +vt 0.590320 0.996970 +vt 0.565930 0.996970 +vt 0.205968 0.177140 +vt 0.203295 0.181011 +vt 0.561620 0.992909 +vt 0.532130 0.992908 +vt 0.559071 0.996970 +vt 0.534680 0.996970 +vt 0.203338 0.175780 +vt 0.201497 0.180081 +vt 0.530370 0.992909 +vt 0.500880 0.992908 +vt 0.527820 0.996970 +vt 0.503430 0.996970 +vt 0.200485 0.174942 +vt 0.199546 0.179508 +vt 0.499120 0.992909 +vt 0.469630 0.992909 +vt 0.496570 0.996970 +vt 0.472180 0.996970 +vt 0.197517 0.174660 +vt 0.197517 0.179315 +vt 0.467870 0.992909 +vt 0.438380 0.992909 +vt 0.465320 0.996970 +vt 0.440930 0.996970 +vt 0.194549 0.174942 +vt 0.195488 0.179508 +vt 0.436620 0.992909 +vt 0.407130 0.992909 +vt 0.434070 0.996970 +vt 0.409680 0.996970 +vt 0.191695 0.175780 +vt 0.193537 0.180081 +vt 0.405370 0.992909 +vt 0.375880 0.992909 +vt 0.402820 0.996970 +vt 0.378430 0.996970 +vt 0.189065 0.177140 +vt 0.191739 0.181011 +vt 0.374120 0.992909 +vt 0.344630 0.992909 +vt 0.371570 0.996970 +vt 0.347180 0.996970 +vt 0.186760 0.178970 +vt 0.190163 0.182262 +vt 0.342870 0.992909 +vt 0.313380 0.992908 +vt 0.340320 0.996970 +vt 0.315930 0.996970 +vt 0.184868 0.181200 +vt 0.188869 0.183787 +vt 0.311620 0.992909 +vt 0.282130 0.992909 +vt 0.309070 0.996970 +vt 0.284680 0.996970 +vt 0.183462 0.183745 +vt 0.187908 0.185526 +vt 0.280370 0.992909 +vt 0.250880 0.992909 +vt 0.277820 0.996970 +vt 0.253430 0.996970 +vt 0.182597 0.186505 +vt 0.187317 0.187414 +vt 0.249120 0.992909 +vt 0.219630 0.992909 +vt 0.246570 0.996970 +vt 0.222180 0.996970 +vt 0.182304 0.189376 +vt 0.187117 0.189376 +vt 0.217870 0.992909 +vt 0.188380 0.992909 +vt 0.215320 0.996970 +vt 0.190930 0.996970 +vt 0.182597 0.192248 +vt 0.187317 0.191339 +vt 0.186620 0.992909 +vt 0.157130 0.992909 +vt 0.184070 0.996970 +vt 0.159680 0.996970 +vt 0.183462 0.195008 +vt 0.187908 0.193227 +vt 0.155370 0.992909 +vt 0.125880 0.992909 +vt 0.152820 0.996970 +vt 0.128430 0.996970 +vt 0.184868 0.197553 +vt 0.188869 0.194966 +vt 0.124120 0.992909 +vt 0.094630 0.992909 +vt 0.121570 0.996970 +vt 0.097180 0.996970 +vt 0.186760 0.199783 +vt 0.190163 0.196491 +vt 0.092870 0.992909 +vt 0.063380 0.992909 +vt 0.090320 0.996970 +vt 0.065930 0.996970 +vt 0.189065 0.201613 +vt 0.191739 0.197742 +vt 0.061620 0.992908 +vt 0.032130 0.992909 +vt 0.059070 0.996970 +vt 0.034680 0.996970 +vt 0.191695 0.202973 +vt 0.193537 0.198672 +vt 0.030370 0.992909 +vt 0.000880 0.992909 +vt 0.027820 0.996970 +vt 0.003429 0.996970 +vt 0.194549 0.203810 +vt 0.195488 0.199244 +vt 0.999120 0.992909 +vt 0.969630 0.992909 +vt 0.996571 0.996970 +vt 0.972180 0.996970 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +vn 0.1903 0.2203 0.9567 +vn 0.1838 0.3345 0.9243 +vn 0.0000 0.3345 0.9424 +vn 0.0000 0.2203 0.9754 +vn -0.3733 0.2203 0.9012 +vn -0.3606 0.3345 0.8707 +vn -0.5235 0.3345 0.7836 +vn -0.5419 0.2203 0.8110 +vn -0.6664 0.3345 0.6664 +vn -0.6897 0.2203 0.6897 +vn -0.7836 0.3345 0.5235 +vn -0.8110 0.2203 0.5419 +vn -0.8707 0.3345 0.3606 +vn -0.9012 0.2203 0.3733 +vn -0.9243 0.3345 0.1838 +vn -0.9567 0.2203 0.1903 +vn -0.9424 0.3345 0.0000 +vn -0.9754 0.2203 0.0000 +vn -0.9243 0.3345 -0.1838 +vn -0.9567 0.2203 -0.1903 +vn -0.8707 0.3345 -0.3606 +vn -0.9012 0.2203 -0.3733 +vn -0.7836 0.3345 -0.5235 +vn -0.8110 0.2203 -0.5419 +vn -0.6664 0.3345 -0.6664 +vn -0.6897 0.2203 -0.6897 +vn -0.5235 0.3345 -0.7836 +vn -0.5419 0.2203 -0.8110 +vn -0.3606 0.3345 -0.8707 +vn -0.3733 0.2203 -0.9012 +vn -0.1838 0.3345 -0.9243 +vn -0.1903 0.2203 -0.9567 +vn 0.0000 0.3345 -0.9424 +vn 0.0000 0.2203 -0.9754 +vn 0.1838 0.3345 -0.9243 +vn 0.1903 0.2203 -0.9567 +vn 0.3606 0.3345 -0.8707 +vn 0.3733 0.2203 -0.9012 +vn 0.5235 0.3345 -0.7836 +vn 0.5419 0.2203 -0.8110 +vn 0.6664 0.3345 -0.6664 +vn 0.6897 0.2203 -0.6897 +vn 0.7836 0.3345 -0.5235 +vn 0.8110 0.2203 -0.5419 +vn 0.8707 0.3345 -0.3606 +vn 0.9012 0.2203 -0.3733 +vn 0.9243 0.3345 -0.1838 +vn 0.9567 0.2203 -0.1903 +vn 0.9424 0.3345 0.0000 +vn 0.9754 0.2203 0.0000 +vn 0.9243 0.3345 0.1838 +vn 0.9567 0.2203 0.1903 +vn 0.8707 0.3345 0.3606 +vn 0.9012 0.2203 0.3733 +vn 0.7836 0.3345 0.5235 +vn 0.8110 0.2203 0.5419 +vn 0.6664 0.3345 0.6664 +vn 0.6897 0.2203 0.6897 +vn 0.5235 0.3345 0.7836 +vn 0.5419 0.2203 0.8110 +vn 0.3606 0.3345 0.8707 +vn 0.3733 0.2203 0.9012 +vn -0.1838 0.3345 0.9243 +vn -0.1903 0.2203 0.9567 +vn 0.0352 -0.6962 -0.7169 +vn -0.0352 -0.6962 -0.7169 +vn -0.0352 0.6962 -0.7169 +vn 0.0352 0.6962 -0.7169 +vn -0.0352 -0.6962 0.7169 +vn 0.0352 -0.6962 0.7169 +vn 0.0352 0.6962 0.7169 +vn -0.0352 0.6962 0.7169 +vn -0.7169 -0.6962 -0.0352 +vn -0.7169 -0.6962 0.0352 +vn -0.7169 0.6962 0.0352 +vn -0.7169 0.6962 -0.0352 +vn -0.1420 0.6857 0.7139 +vn -0.1420 -0.6857 0.7139 +vn -0.2785 0.6857 0.6725 +vn -0.2785 -0.6857 0.6725 +vn -0.4044 0.6857 0.6052 +vn -0.4044 -0.6857 0.6052 +vn -0.5147 0.6857 0.5147 +vn -0.5147 -0.6857 0.5147 +vn -0.6052 0.6857 0.4044 +vn -0.6052 -0.6857 0.4044 +vn -0.6725 0.6857 0.2785 +vn -0.6725 -0.6857 0.2785 +vn -0.7139 0.6857 0.1420 +vn -0.7139 -0.6857 0.1420 +vn -0.1420 -0.6857 -0.7139 +vn -0.1420 0.6857 -0.7139 +vn -0.2785 -0.6857 -0.6725 +vn -0.2785 0.6857 -0.6725 +vn -0.4044 -0.6857 -0.6052 +vn -0.4044 0.6857 -0.6052 +vn -0.5147 -0.6857 -0.5147 +vn -0.5147 0.6857 -0.5147 +vn -0.6052 -0.6857 -0.4044 +vn -0.6052 0.6857 -0.4044 +vn -0.6725 -0.6857 -0.2785 +vn -0.6725 0.6857 -0.2785 +vn -0.7139 -0.6857 -0.1420 +vn -0.7139 0.6857 -0.1420 +vn 0.1420 0.6857 -0.7139 +vn 0.1420 -0.6857 -0.7139 +vn 0.2785 0.6857 -0.6725 +vn 0.2785 -0.6857 -0.6725 +vn 0.4044 0.6857 -0.6052 +vn 0.4044 -0.6857 -0.6052 +vn 0.5147 0.6857 -0.5147 +vn 0.5147 -0.6857 -0.5147 +vn 0.6052 0.6857 -0.4044 +vn 0.6052 -0.6857 -0.4044 +vn 0.6725 0.6857 -0.2785 +vn 0.6725 -0.6857 -0.2785 +vn 0.7139 0.6857 -0.1420 +vn 0.7139 -0.6857 -0.1420 +vn 0.7169 0.6962 -0.0352 +vn 0.7169 -0.6962 -0.0352 +vn 0.1420 -0.6857 0.7139 +vn 0.1420 0.6857 0.7139 +vn 0.2785 -0.6857 0.6725 +vn 0.2785 0.6857 0.6725 +vn 0.4044 -0.6857 0.6052 +vn 0.4044 0.6857 0.6052 +vn 0.5147 -0.6857 0.5147 +vn 0.5147 0.6857 0.5147 +vn 0.6052 -0.6857 0.4044 +vn 0.6052 0.6857 0.4044 +vn 0.6725 -0.6857 0.2785 +vn 0.6725 0.6857 0.2785 +vn 0.7139 -0.6857 0.1420 +vn 0.7139 0.6857 0.1420 +vn 0.7169 -0.6962 0.0352 +vn 0.7169 0.6962 0.0352 +vn 0.0000 0.6236 0.7817 +vn -0.1525 0.6236 0.7667 +vn 0.0000 0.8922 0.4517 +vn -0.0881 0.8922 0.4430 +vn 0.0000 0.9918 0.1276 +vn -0.0249 0.9918 0.1251 +vn -0.2991 0.6236 0.7222 +vn -0.1728 0.8922 0.4173 +vn -0.0488 0.9918 0.1179 +vn -0.4343 0.6236 0.6500 +vn -0.2509 0.8922 0.3755 +vn -0.0709 0.9918 0.1061 +vn -0.5528 0.6236 0.5528 +vn -0.3194 0.8922 0.3194 +vn -0.0902 0.9918 0.0902 +vn -0.6500 0.6236 0.4343 +vn -0.3755 0.8922 0.2509 +vn -0.1061 0.9918 0.0709 +vn -0.7222 0.6236 0.2991 +vn -0.4173 0.8922 0.1728 +vn -0.1179 0.9918 0.0488 +vn -0.7667 0.6236 0.1525 +vn -0.4430 0.8922 0.0881 +vn -0.1251 0.9918 0.0249 +vn -0.7817 0.6236 0.0000 +vn -0.4517 0.8922 0.0000 +vn -0.1276 0.9918 0.0000 +vn -0.7667 0.6236 -0.1525 +vn -0.4430 0.8922 -0.0881 +vn -0.1251 0.9918 -0.0249 +vn -0.7222 0.6236 -0.2991 +vn -0.4173 0.8922 -0.1728 +vn -0.1179 0.9918 -0.0488 +vn -0.6500 0.6236 -0.4343 +vn -0.3755 0.8922 -0.2509 +vn -0.1061 0.9918 -0.0709 +vn -0.5528 0.6236 -0.5528 +vn -0.3194 0.8922 -0.3194 +vn -0.0902 0.9918 -0.0902 +vn -0.4343 0.6236 -0.6500 +vn -0.2509 0.8922 -0.3755 +vn -0.0709 0.9918 -0.1061 +vn -0.2991 0.6236 -0.7222 +vn -0.1728 0.8922 -0.4173 +vn -0.0488 0.9918 -0.1179 +vn -0.1525 0.6236 -0.7667 +vn -0.0881 0.8922 -0.4430 +vn -0.0249 0.9918 -0.1251 +vn 0.0000 0.6236 -0.7817 +vn 0.0000 0.8922 -0.4517 +vn 0.0000 0.9918 -0.1276 +vn 0.1525 0.6236 -0.7667 +vn 0.0881 0.8922 -0.4430 +vn 0.0249 0.9918 -0.1251 +vn 0.2991 0.6236 -0.7222 +vn 0.1728 0.8922 -0.4173 +vn 0.0488 0.9918 -0.1179 +vn 0.4343 0.6236 -0.6500 +vn 0.2509 0.8922 -0.3755 +vn 0.0709 0.9918 -0.1061 +vn 0.5528 0.6236 -0.5528 +vn 0.3194 0.8922 -0.3194 +vn 0.0902 0.9918 -0.0902 +vn 0.6500 0.6236 -0.4343 +vn 0.3755 0.8922 -0.2509 +vn 0.1061 0.9918 -0.0709 +vn 0.7222 0.6236 -0.2991 +vn 0.4173 0.8922 -0.1728 +vn 0.1179 0.9918 -0.0488 +vn 0.7667 0.6236 -0.1525 +vn 0.4430 0.8922 -0.0881 +vn 0.1251 0.9918 -0.0249 +vn 0.7817 0.6236 0.0000 +vn 0.4517 0.8922 0.0000 +vn 0.1276 0.9918 0.0000 +vn 0.7667 0.6236 0.1525 +vn 0.4430 0.8922 0.0881 +vn 0.1251 0.9918 0.0249 +vn 0.7222 0.6236 0.2991 +vn 0.4173 0.8922 0.1728 +vn 0.1179 0.9918 0.0488 +vn 0.6500 0.6236 0.4343 +vn 0.3755 0.8922 0.2509 +vn 0.1061 0.9918 0.0709 +vn 0.5528 0.6236 0.5528 +vn 0.3194 0.8922 0.3194 +vn 0.0902 0.9918 0.0902 +vn 0.4343 0.6236 0.6500 +vn 0.2509 0.8922 0.3755 +vn 0.0709 0.9918 0.1061 +vn 0.2991 0.6236 0.7222 +vn 0.1728 0.8922 0.4173 +vn 0.0488 0.9918 0.1179 +vn 0.1525 0.6236 0.7667 +vn 0.0881 0.8922 0.4430 +vn 0.0249 0.9918 0.1251 +g Cylinder_Cylinder_None +s off +f 33/1/1 35/2/1 36/3/1 37/4/1 38/5/1 39/6/1 40/7/1 41/8/1 34/9/1 51/10/1 53/11/1 54/12/1 55/13/1 56/14/1 57/15/1 58/16/1 59/17/1 52/18/1 60/19/1 62/20/1 63/21/1 64/22/1 65/23/1 66/24/1 67/25/1 68/26/1 61/27/1 42/28/1 44/29/1 45/30/1 46/31/1 47/32/1 48/33/1 49/34/1 50/35/1 43/36/1 +f 78/37/2 80/38/2 81/39/2 82/40/2 83/41/2 84/42/2 85/43/2 86/44/2 79/45/2 87/46/2 89/47/2 90/48/2 91/49/2 92/50/2 93/51/2 94/52/2 95/53/2 88/54/2 96/55/2 98/56/2 99/57/2 100/58/2 101/59/2 102/60/2 103/61/2 104/62/2 97/63/2 69/64/2 71/65/2 72/66/2 73/67/2 74/68/2 75/69/2 76/70/2 77/71/2 70/72/2 +s 1 +f 32/73/3 230/74/4 106/75/5 1/76/6 +f 3/77/7 114/78/8 118/79/9 4/80/10 +f 4/80/10 118/79/9 122/81/11 5/82/12 +f 5/82/12 122/81/11 126/83/13 6/84/14 +f 6/84/14 126/83/13 130/85/15 7/86/16 +f 7/86/16 130/85/15 134/87/17 8/88/18 +f 8/88/18 134/87/17 138/89/19 9/90/20 +f 9/90/20 138/91/19 142/92/21 10/93/22 +f 10/93/22 142/92/21 146/94/23 11/95/24 +f 11/95/24 146/94/23 150/96/25 12/97/26 +f 12/97/26 150/96/25 154/98/27 13/99/28 +f 13/99/28 154/98/27 158/100/29 14/101/30 +f 14/101/30 158/100/29 162/102/31 15/103/32 +f 15/103/32 162/102/31 166/104/33 16/105/34 +f 16/105/34 166/104/33 170/106/35 17/107/36 +f 17/107/36 170/106/35 174/108/37 18/109/38 +f 18/109/38 174/108/37 178/110/39 19/111/40 +f 19/111/40 178/110/39 182/112/41 20/113/42 +f 20/113/42 182/112/41 186/114/43 21/115/44 +f 21/115/44 186/114/43 190/116/45 22/117/46 +f 22/117/46 190/116/45 194/118/47 23/119/48 +f 23/119/48 194/118/47 198/120/49 24/121/50 +f 24/121/50 198/120/49 202/122/51 25/123/52 +f 25/123/52 202/122/51 206/124/53 26/125/54 +f 26/125/54 206/124/53 210/126/55 27/127/56 +f 27/127/56 210/126/55 214/128/57 28/129/58 +f 28/129/58 214/128/57 218/130/59 29/131/60 +f 29/131/60 218/130/59 222/132/61 30/133/62 +f 30/133/62 222/132/61 226/134/63 31/135/64 +f 31/135/64 226/134/63 230/136/4 32/137/3 +f 1/76/6 106/138/5 110/139/65 2/140/66 +f 2/140/66 110/139/65 114/78/8 3/77/7 +f 33/141/67 43/142/68 87/143/69 79/144/70 +f 60/145/71 52/146/72 69/147/73 97/148/74 +f 42/149/75 61/150/76 96/151/77 88/152/78 +f 60/145/71 97/148/74 104/153/79 62/154/80 +f 62/154/80 104/153/79 103/155/81 63/156/82 +f 63/156/82 103/155/81 102/157/83 64/158/84 +f 64/158/84 102/157/83 101/159/85 65/160/86 +f 65/160/86 101/159/85 100/161/87 66/162/88 +f 66/162/88 100/161/87 99/163/89 67/164/90 +f 67/164/90 99/163/89 98/165/91 68/166/92 +f 68/166/92 98/165/91 96/151/77 61/150/76 +f 87/143/69 43/142/68 50/167/93 89/168/94 +f 89/168/94 50/167/93 49/169/95 90/170/96 +f 90/170/96 49/169/95 48/171/97 91/172/98 +f 91/172/98 48/171/97 47/173/99 92/174/100 +f 92/174/100 47/173/99 46/175/101 93/176/102 +f 93/176/102 46/175/101 45/177/103 94/178/104 +f 94/178/104 45/177/103 44/179/105 95/180/106 +f 95/180/106 44/179/105 42/149/75 88/152/78 +f 33/141/67 79/144/70 86/181/107 35/182/108 +f 35/182/108 86/181/107 85/183/109 36/184/110 +f 36/184/110 85/183/109 84/185/111 37/186/112 +f 37/186/112 84/185/111 83/187/113 38/188/114 +f 38/188/114 83/187/113 82/189/115 39/190/116 +f 39/190/116 82/189/115 81/191/117 40/192/118 +f 40/192/118 81/191/117 80/193/119 41/194/120 +f 41/194/120 80/193/119 78/195/121 34/196/122 +f 69/197/73 52/198/72 59/199/123 71/200/124 +f 71/200/124 59/199/123 58/201/125 72/202/126 +f 72/202/126 58/201/125 57/203/127 73/204/128 +f 73/204/128 57/203/127 56/205/129 74/206/130 +f 74/206/130 56/205/129 55/207/131 75/208/132 +f 75/208/132 55/207/131 54/209/133 76/210/134 +f 76/210/134 54/209/133 53/211/135 77/212/136 +f 77/212/136 53/211/135 51/213/137 70/214/138 +f 51/213/137 34/196/122 78/195/121 70/214/138 +f 110/139/65 106/138/5 108/215/139 112/216/140 +f 112/216/140 108/215/139 107/217/141 111/218/142 +f 111/219/142 107/220/141 105/221/143 109/222/144 +f 114/78/8 110/139/65 112/223/140 116/224/145 +f 116/224/145 112/223/140 111/225/142 115/226/146 +f 115/227/146 111/219/142 109/222/144 113/228/147 +f 118/79/9 114/78/8 116/229/145 120/230/148 +f 120/230/148 116/229/145 115/231/146 119/232/149 +f 119/233/149 115/227/146 113/228/147 117/234/150 +f 122/81/11 118/79/9 120/235/148 124/236/151 +f 124/236/151 120/235/148 119/237/149 123/238/152 +f 123/239/152 119/233/149 117/234/150 121/240/153 +f 126/83/13 122/81/11 124/241/151 128/242/154 +f 128/242/154 124/241/151 123/243/152 127/244/155 +f 127/245/155 123/239/152 121/240/153 125/246/156 +f 130/85/15 126/83/13 128/247/154 132/248/157 +f 132/248/157 128/247/154 127/249/155 131/250/158 +f 131/251/158 127/245/155 125/246/156 129/252/159 +f 134/87/17 130/85/15 132/253/157 136/254/160 +f 136/254/160 132/253/157 131/255/158 135/256/161 +f 135/257/161 131/251/158 129/252/159 133/258/162 +f 138/89/19 134/87/17 136/259/160 140/260/163 +f 140/260/163 136/259/160 135/261/161 139/262/164 +f 139/263/164 135/257/161 133/258/162 137/264/165 +f 142/92/21 138/91/19 140/265/163 144/266/166 +f 144/266/166 140/265/163 139/267/164 143/268/167 +f 143/269/167 139/263/164 137/264/165 141/270/168 +f 146/94/23 142/92/21 144/271/166 148/272/169 +f 148/272/169 144/271/166 143/273/167 147/274/170 +f 147/275/170 143/269/167 141/270/168 145/276/171 +f 150/96/25 146/94/23 148/277/169 152/278/172 +f 152/278/172 148/277/169 147/279/170 151/280/173 +f 151/281/173 147/275/170 145/276/171 149/282/174 +f 154/98/27 150/96/25 152/283/172 156/284/175 +f 156/284/175 152/283/172 151/285/173 155/286/176 +f 155/287/176 151/281/173 149/282/174 153/288/177 +f 158/100/29 154/98/27 156/289/175 160/290/178 +f 160/290/178 156/289/175 155/291/176 159/292/179 +f 159/293/179 155/287/176 153/288/177 157/294/180 +f 162/102/31 158/100/29 160/295/178 164/296/181 +f 164/296/181 160/295/178 159/297/179 163/298/182 +f 163/299/182 159/293/179 157/294/180 161/300/183 +f 166/104/33 162/102/31 164/301/181 168/302/184 +f 168/302/184 164/301/181 163/303/182 167/304/185 +f 167/305/185 163/299/182 161/300/183 165/306/186 +f 170/106/35 166/104/33 168/307/184 172/308/187 +f 172/308/187 168/307/184 167/309/185 171/310/188 +f 171/311/188 167/305/185 165/306/186 169/312/189 +f 174/108/37 170/106/35 172/313/187 176/314/190 +f 176/314/190 172/313/187 171/315/188 175/316/191 +f 175/317/191 171/311/188 169/312/189 173/318/192 +f 178/110/39 174/108/37 176/319/190 180/320/193 +f 180/320/193 176/319/190 175/321/191 179/322/194 +f 179/323/194 175/317/191 173/318/192 177/324/195 +f 182/112/41 178/110/39 180/325/193 184/326/196 +f 184/326/196 180/325/193 179/327/194 183/328/197 +f 183/329/197 179/323/194 177/324/195 181/330/198 +f 186/114/43 182/112/41 184/331/196 188/332/199 +f 188/332/199 184/331/196 183/333/197 187/334/200 +f 187/335/200 183/329/197 181/330/198 185/336/201 +f 190/116/45 186/114/43 188/337/199 192/338/202 +f 192/338/202 188/337/199 187/339/200 191/340/203 +f 191/341/203 187/335/200 185/336/201 189/342/204 +f 194/118/47 190/116/45 192/343/202 196/344/205 +f 196/344/205 192/343/202 191/345/203 195/346/206 +f 195/347/206 191/341/203 189/342/204 193/348/207 +f 198/120/49 194/118/47 196/349/205 200/350/208 +f 200/350/208 196/349/205 195/351/206 199/352/209 +f 199/353/209 195/347/206 193/348/207 197/354/210 +f 202/122/51 198/120/49 200/355/208 204/356/211 +f 204/356/211 200/355/208 199/357/209 203/358/212 +f 203/359/212 199/353/209 197/354/210 201/360/213 +f 206/124/53 202/122/51 204/361/211 208/362/214 +f 208/362/214 204/361/211 203/363/212 207/364/215 +f 207/365/215 203/359/212 201/360/213 205/366/216 +f 210/126/55 206/124/53 208/367/214 212/368/217 +f 212/368/217 208/367/214 207/369/215 211/370/218 +f 211/371/218 207/365/215 205/366/216 209/372/219 +f 214/128/57 210/126/55 212/373/217 216/374/220 +f 216/374/220 212/373/217 211/375/218 215/376/221 +f 215/377/221 211/371/218 209/372/219 213/378/222 +f 218/130/59 214/128/57 216/379/220 220/380/223 +f 220/380/223 216/379/220 215/381/221 219/382/224 +f 219/383/224 215/377/221 213/378/222 217/384/225 +f 222/132/61 218/130/59 220/385/223 224/386/226 +f 224/386/226 220/385/223 219/387/224 223/388/227 +f 223/389/227 219/383/224 217/384/225 221/390/228 +f 226/134/63 222/132/61 224/391/226 228/392/229 +f 228/392/229 224/391/226 223/393/227 227/394/230 +f 227/395/230 223/389/227 221/390/228 225/396/231 +f 230/136/4 226/134/63 228/397/229 232/398/232 +f 232/398/232 228/397/229 227/399/230 231/400/233 +f 231/401/233 227/395/230 225/396/231 229/402/234 +f 106/75/5 230/74/4 232/403/232 108/404/139 +f 108/404/139 232/403/232 231/405/233 107/406/141 +f 107/220/141 231/401/233 229/402/234 105/221/143 +f 109/222/144 105/221/143 229/402/234 225/396/231 221/390/228 217/384/225 213/378/222 209/372/219 205/366/216 201/360/213 197/354/210 193/348/207 189/342/204 185/336/201 181/330/198 177/324/195 173/318/192 169/312/189 165/306/186 161/300/183 157/294/180 153/288/177 149/282/174 145/276/171 141/270/168 137/264/165 133/258/162 129/252/159 125/246/156 121/240/153 117/234/150 113/228/147 diff --git a/mods/roads/infrastructure/models/infrastructure_traffic_cone_i3.obj b/mods/roads/infrastructure/models/infrastructure_traffic_cone_i3.obj new file mode 100644 index 0000000..4714cce --- /dev/null +++ b/mods/roads/infrastructure/models/infrastructure_traffic_cone_i3.obj @@ -0,0 +1,1045 @@ +# Blender v2.79 (sub 0) OBJ File: 'traffic cone.blend' +# www.blender.org +o Cylinder +v 0.000000 -1.224600 0.203250 +v -0.039652 -1.224600 0.199345 +v -0.077780 -1.224600 0.187779 +v -0.112920 -1.224600 0.168996 +v -0.143719 -1.224600 0.143719 +v -0.168996 -1.224600 0.112920 +v -0.187779 -1.224600 0.077780 +v -0.199345 -1.224600 0.039652 +v -0.203250 -1.224600 0.000000 +v -0.199345 -1.224600 -0.039652 +v -0.187779 -1.224600 -0.077780 +v -0.168996 -1.224600 -0.112920 +v -0.143719 -1.224600 -0.143719 +v -0.112920 -1.224600 -0.168996 +v -0.077780 -1.224600 -0.187779 +v -0.039652 -1.224600 -0.199345 +v 0.000000 -1.224600 -0.203250 +v 0.039652 -1.224600 -0.199345 +v 0.077781 -1.224600 -0.187778 +v 0.112920 -1.224600 -0.168996 +v 0.143720 -1.224600 -0.143719 +v 0.168996 -1.224600 -0.112920 +v 0.187779 -1.224600 -0.077780 +v 0.199345 -1.224600 -0.039652 +v 0.203250 -1.224600 0.000000 +v 0.199345 -1.224600 0.039652 +v 0.187778 -1.224600 0.077781 +v 0.168996 -1.224600 0.112920 +v 0.143719 -1.224600 0.143720 +v 0.112919 -1.224600 0.168996 +v 0.077780 -1.224600 0.187779 +v 0.039652 -1.224600 0.199345 +v 0.191399 -1.250000 -0.250000 +v 0.250000 -1.250000 -0.191399 +v 0.202831 -1.250000 -0.248874 +v 0.213825 -1.250000 -0.245539 +v 0.223956 -1.250000 -0.240124 +v 0.232836 -1.250000 -0.232836 +v 0.240124 -1.250000 -0.223956 +v 0.245539 -1.250000 -0.213825 +v 0.248874 -1.250000 -0.202831 +v -0.250000 -1.250000 -0.191399 +v -0.191399 -1.250000 -0.250000 +v -0.248874 -1.250000 -0.202831 +v -0.245539 -1.250000 -0.213825 +v -0.240124 -1.250000 -0.223956 +v -0.232836 -1.250000 -0.232836 +v -0.223956 -1.250000 -0.240124 +v -0.213825 -1.250000 -0.245539 +v -0.202831 -1.250000 -0.248874 +v 0.250000 -1.250000 0.191399 +v 0.191399 -1.250000 0.250000 +v 0.248874 -1.250000 0.202831 +v 0.245539 -1.250000 0.213825 +v 0.240124 -1.250000 0.223956 +v 0.232836 -1.250000 0.232836 +v 0.223956 -1.250000 0.240124 +v 0.213825 -1.250000 0.245539 +v 0.202831 -1.250000 0.248874 +v -0.191399 -1.250000 0.250000 +v -0.250000 -1.250000 0.191399 +v -0.202831 -1.250000 0.248874 +v -0.213825 -1.250000 0.245539 +v -0.223956 -1.250000 0.240124 +v -0.232836 -1.250000 0.232836 +v -0.240124 -1.250000 0.223956 +v -0.245539 -1.250000 0.213825 +v -0.248874 -1.250000 0.202831 +v 0.191399 -1.224600 0.250000 +v 0.250000 -1.224600 0.191399 +v 0.202831 -1.224600 0.248874 +v 0.213825 -1.224600 0.245539 +v 0.223956 -1.224600 0.240124 +v 0.232836 -1.224600 0.232836 +v 0.240124 -1.224600 0.223956 +v 0.245539 -1.224600 0.213825 +v 0.248874 -1.224600 0.202831 +v 0.250000 -1.224600 -0.191399 +v 0.191399 -1.224600 -0.250000 +v 0.248874 -1.224600 -0.202831 +v 0.245539 -1.224600 -0.213825 +v 0.240124 -1.224600 -0.223956 +v 0.232836 -1.224600 -0.232836 +v 0.223956 -1.224600 -0.240124 +v 0.213825 -1.224600 -0.245539 +v 0.202831 -1.224600 -0.248874 +v -0.191399 -1.224600 -0.250000 +v -0.250000 -1.224600 -0.191399 +v -0.202831 -1.224600 -0.248874 +v -0.213825 -1.224600 -0.245539 +v -0.223956 -1.224600 -0.240124 +v -0.232836 -1.224600 -0.232836 +v -0.240124 -1.224600 -0.223956 +v -0.245539 -1.224600 -0.213825 +v -0.248874 -1.224600 -0.202831 +v -0.250000 -1.224600 0.191399 +v -0.191399 -1.224600 0.250000 +v -0.248874 -1.224600 0.202831 +v -0.245539 -1.224600 0.213825 +v -0.240124 -1.224600 0.223956 +v -0.232836 -1.224600 0.232836 +v -0.223956 -1.224600 0.240124 +v -0.213825 -1.224600 0.245539 +v -0.202831 -1.224600 0.248874 +v -0.000000 -0.437000 0.013552 +v 0.000000 -0.448502 0.027995 +v -0.000000 -0.438541 0.019823 +v -0.000000 -0.442751 0.025109 +v -0.002644 -0.437000 0.013292 +v -0.005462 -0.448502 0.027457 +v -0.003867 -0.438541 0.019442 +v -0.004899 -0.442751 0.024627 +v -0.005186 -0.437000 0.012521 +v -0.010713 -0.448502 0.025864 +v -0.007586 -0.438541 0.018314 +v -0.009609 -0.442751 0.023198 +v -0.007529 -0.437000 0.011268 +v -0.015553 -0.448502 0.023277 +v -0.011013 -0.438541 0.016482 +v -0.013950 -0.442751 0.020878 +v -0.009583 -0.437000 0.009583 +v -0.019795 -0.448502 0.019795 +v -0.014017 -0.438541 0.014017 +v -0.017755 -0.442751 0.017755 +v -0.011268 -0.437000 0.007529 +v -0.023277 -0.448502 0.015553 +v -0.016482 -0.438541 0.011013 +v -0.020878 -0.442751 0.013950 +v -0.012521 -0.437000 0.005186 +v -0.025864 -0.448502 0.010713 +v -0.018314 -0.438541 0.007586 +v -0.023198 -0.442751 0.009609 +v -0.013292 -0.437000 0.002644 +v -0.027457 -0.448502 0.005462 +v -0.019442 -0.438541 0.003867 +v -0.024627 -0.442751 0.004899 +v -0.013552 -0.437000 -0.000000 +v -0.027995 -0.448502 0.000000 +v -0.019823 -0.438541 0.000000 +v -0.025109 -0.442751 0.000000 +v -0.013292 -0.437000 -0.002644 +v -0.027457 -0.448502 -0.005462 +v -0.019442 -0.438541 -0.003867 +v -0.024627 -0.442751 -0.004899 +v -0.012521 -0.437000 -0.005186 +v -0.025864 -0.448502 -0.010713 +v -0.018314 -0.438541 -0.007586 +v -0.023198 -0.442751 -0.009609 +v -0.011268 -0.437000 -0.007529 +v -0.023277 -0.448502 -0.015553 +v -0.016482 -0.438541 -0.011013 +v -0.020878 -0.442751 -0.013950 +v -0.009583 -0.437000 -0.009583 +v -0.019795 -0.448502 -0.019795 +v -0.014017 -0.438541 -0.014017 +v -0.017755 -0.442751 -0.017755 +v -0.007529 -0.437000 -0.011268 +v -0.015553 -0.448502 -0.023277 +v -0.011013 -0.438541 -0.016482 +v -0.013950 -0.442751 -0.020878 +v -0.005186 -0.437000 -0.012521 +v -0.010713 -0.448502 -0.025864 +v -0.007586 -0.438541 -0.018314 +v -0.009609 -0.442751 -0.023198 +v -0.002644 -0.437000 -0.013292 +v -0.005462 -0.448502 -0.027457 +v -0.003867 -0.438541 -0.019442 +v -0.004899 -0.442751 -0.024627 +v 0.000000 -0.437000 -0.013552 +v 0.000000 -0.448502 -0.027995 +v 0.000000 -0.438541 -0.019823 +v 0.000000 -0.442751 -0.025109 +v 0.002644 -0.437000 -0.013292 +v 0.005462 -0.448502 -0.027457 +v 0.003867 -0.438541 -0.019442 +v 0.004899 -0.442751 -0.024627 +v 0.005186 -0.437000 -0.012521 +v 0.010713 -0.448502 -0.025864 +v 0.007586 -0.438541 -0.018314 +v 0.009609 -0.442751 -0.023198 +v 0.007529 -0.437000 -0.011268 +v 0.015553 -0.448502 -0.023277 +v 0.011013 -0.438541 -0.016482 +v 0.013950 -0.442751 -0.020878 +v 0.009583 -0.437000 -0.009583 +v 0.019795 -0.448502 -0.019795 +v 0.014017 -0.438541 -0.014017 +v 0.017755 -0.442751 -0.017755 +v 0.011268 -0.437000 -0.007529 +v 0.023277 -0.448502 -0.015553 +v 0.016482 -0.438541 -0.011013 +v 0.020878 -0.442751 -0.013950 +v 0.012521 -0.437000 -0.005186 +v 0.025864 -0.448502 -0.010713 +v 0.018314 -0.438541 -0.007586 +v 0.023198 -0.442751 -0.009609 +v 0.013292 -0.437000 -0.002644 +v 0.027457 -0.448502 -0.005462 +v 0.019442 -0.438541 -0.003867 +v 0.024627 -0.442751 -0.004899 +v 0.013552 -0.437000 0.000000 +v 0.027995 -0.448502 0.000000 +v 0.019823 -0.438541 0.000000 +v 0.025109 -0.442751 0.000000 +v 0.013292 -0.437000 0.002644 +v 0.027457 -0.448502 0.005462 +v 0.019442 -0.438541 0.003867 +v 0.024627 -0.442751 0.004899 +v 0.012521 -0.437000 0.005186 +v 0.025864 -0.448502 0.010713 +v 0.018314 -0.438541 0.007586 +v 0.023198 -0.442751 0.009609 +v 0.011268 -0.437000 0.007529 +v 0.023277 -0.448502 0.015553 +v 0.016482 -0.438541 0.011013 +v 0.020878 -0.442751 0.013950 +v 0.009583 -0.437000 0.009583 +v 0.019795 -0.448502 0.019795 +v 0.014017 -0.438541 0.014017 +v 0.017755 -0.442751 0.017755 +v 0.007529 -0.437000 0.011268 +v 0.015553 -0.448502 0.023277 +v 0.011013 -0.438541 0.016482 +v 0.013950 -0.442751 0.020878 +v 0.005186 -0.437000 0.012521 +v 0.010713 -0.448502 0.025864 +v 0.007586 -0.438541 0.018314 +v 0.009609 -0.442751 0.023198 +v 0.002644 -0.437000 0.013292 +v 0.005462 -0.448502 0.027457 +v 0.003867 -0.438541 0.019442 +v 0.004899 -0.442751 0.024627 +vt 0.444971 0.003030 +vt 0.436198 0.003866 +vt 0.427761 0.006342 +vt 0.419987 0.010362 +vt 0.413172 0.015773 +vt 0.407579 0.022366 +vt 0.403423 0.029887 +vt 0.400864 0.038049 +vt 0.400000 0.046537 +vt 0.400000 0.330730 +vt 0.400864 0.339218 +vt 0.403423 0.347380 +vt 0.407579 0.354901 +vt 0.413172 0.361494 +vt 0.419987 0.366905 +vt 0.427761 0.370925 +vt 0.436198 0.373401 +vt 0.444971 0.374237 +vt 0.738735 0.374237 +vt 0.747508 0.373401 +vt 0.755944 0.370925 +vt 0.763719 0.366905 +vt 0.770534 0.361494 +vt 0.776127 0.354901 +vt 0.780283 0.347380 +vt 0.782842 0.339218 +vt 0.783706 0.330730 +vt 0.783706 0.046537 +vt 0.782842 0.038049 +vt 0.780283 0.029887 +vt 0.776127 0.022366 +vt 0.770534 0.015773 +vt 0.763719 0.010362 +vt 0.755944 0.006342 +vt 0.747508 0.003866 +vt 0.738735 0.003030 +vt 0.003125 0.046537 +vt 0.003989 0.038049 +vt 0.006548 0.029887 +vt 0.010704 0.022366 +vt 0.016297 0.015773 +vt 0.023112 0.010362 +vt 0.030886 0.006342 +vt 0.039323 0.003866 +vt 0.048096 0.003030 +vt 0.341860 0.003030 +vt 0.350633 0.003866 +vt 0.359069 0.006342 +vt 0.366844 0.010362 +vt 0.373659 0.015773 +vt 0.379252 0.022366 +vt 0.383408 0.029887 +vt 0.385967 0.038049 +vt 0.386831 0.046537 +vt 0.386831 0.330730 +vt 0.385967 0.339218 +vt 0.383408 0.347380 +vt 0.379252 0.354901 +vt 0.373659 0.361494 +vt 0.366844 0.366905 +vt 0.359069 0.370925 +vt 0.350633 0.373401 +vt 0.341860 0.374237 +vt 0.048096 0.374237 +vt 0.039323 0.373401 +vt 0.030886 0.370925 +vt 0.023112 0.366905 +vt 0.016297 0.361494 +vt 0.010704 0.354901 +vt 0.006548 0.347380 +vt 0.003989 0.339218 +vt 0.003125 0.330730 +vt 1.000000 0.403030 +vt 1.000000 0.988340 +vt 0.968750 0.988340 +vt 0.968750 0.403030 +vt 0.906250 0.403030 +vt 0.906250 0.988340 +vt 0.875000 0.988340 +vt 0.875000 0.403030 +vt 0.843750 0.988340 +vt 0.843750 0.403030 +vt 0.812500 0.988340 +vt 0.812500 0.403030 +vt 0.781250 0.988340 +vt 0.781250 0.403030 +vt 0.750000 0.988340 +vt 0.750000 0.403030 +vt 0.718750 0.988340 +vt 0.718750 0.403030 +vt 0.718750 0.988340 +vt 0.687500 0.988340 +vt 0.687500 0.403030 +vt 0.656250 0.988340 +vt 0.656250 0.403030 +vt 0.625000 0.988340 +vt 0.625000 0.403030 +vt 0.593750 0.988340 +vt 0.593750 0.403030 +vt 0.562500 0.988340 +vt 0.562500 0.403030 +vt 0.531250 0.988340 +vt 0.531250 0.403030 +vt 0.500000 0.988340 +vt 0.500000 0.403030 +vt 0.468750 0.988340 +vt 0.468750 0.403030 +vt 0.437500 0.988340 +vt 0.437500 0.403030 +vt 0.406250 0.988340 +vt 0.406250 0.403030 +vt 0.375000 0.988340 +vt 0.375000 0.403030 +vt 0.343750 0.988340 +vt 0.343750 0.403030 +vt 0.312500 0.988340 +vt 0.312500 0.403030 +vt 0.281250 0.988340 +vt 0.281250 0.403030 +vt 0.250000 0.988340 +vt 0.250000 0.403030 +vt 0.218750 0.988340 +vt 0.218750 0.403030 +vt 0.187500 0.988340 +vt 0.187500 0.403030 +vt 0.156250 0.988340 +vt 0.156250 0.403030 +vt 0.125000 0.988340 +vt 0.125000 0.403030 +vt 0.093750 0.988340 +vt 0.093750 0.403030 +vt 0.062500 0.988340 +vt 0.062500 0.403030 +vt 0.031250 0.988340 +vt 0.031250 0.403030 +vt 0.000000 0.988340 +vt 0.000000 0.403030 +vt 0.968750 0.988340 +vt 0.937500 0.988340 +vt 0.937500 0.403030 +vt 0.300000 0.384848 +vt 0.500000 0.384848 +vt 0.500000 0.396970 +vt 0.300000 0.396970 +vt 0.800000 0.384848 +vt 1.000000 0.384848 +vt 1.000000 0.396970 +vt 0.800000 0.396970 +vt 0.550000 0.384848 +vt 0.750000 0.384848 +vt 0.750000 0.396970 +vt 0.550000 0.396970 +vt 0.793750 0.396970 +vt 0.793750 0.384848 +vt 0.787500 0.396970 +vt 0.787500 0.384848 +vt 0.781250 0.396970 +vt 0.781250 0.384848 +vt 0.775000 0.396970 +vt 0.775000 0.384848 +vt 0.768750 0.396970 +vt 0.768750 0.384848 +vt 0.762500 0.396970 +vt 0.762500 0.384848 +vt 0.756250 0.396970 +vt 0.756250 0.384848 +vt 0.506250 0.384848 +vt 0.506250 0.396970 +vt 0.512500 0.384848 +vt 0.512500 0.396970 +vt 0.518750 0.384848 +vt 0.518750 0.396970 +vt 0.525000 0.384848 +vt 0.525000 0.396970 +vt 0.531250 0.384848 +vt 0.531250 0.396970 +vt 0.537500 0.384848 +vt 0.537500 0.396970 +vt 0.543750 0.384848 +vt 0.543750 0.396970 +vt 0.293750 0.396970 +vt 0.293750 0.384848 +vt 0.287500 0.396970 +vt 0.287500 0.384848 +vt 0.281250 0.396970 +vt 0.281250 0.384848 +vt 0.275000 0.396970 +vt 0.275000 0.384848 +vt 0.268750 0.396970 +vt 0.268750 0.384848 +vt 0.262500 0.396970 +vt 0.262500 0.384848 +vt 0.256250 0.396970 +vt 0.256250 0.384848 +vt 0.250000 0.396970 +vt 0.250000 0.384848 +vt 0.000000 0.396970 +vt 0.000000 0.384848 +vt 0.006250 0.384848 +vt 0.006250 0.396970 +vt 0.012500 0.384848 +vt 0.012500 0.396970 +vt 0.018750 0.384848 +vt 0.018750 0.396970 +vt 0.025000 0.384848 +vt 0.025000 0.396970 +vt 0.031250 0.384848 +vt 0.031250 0.396970 +vt 0.037500 0.384848 +vt 0.037500 0.396970 +vt 0.043750 0.384848 +vt 0.043750 0.396970 +vt 0.050000 0.384848 +vt 0.050000 0.396970 +vt 0.967870 0.992909 +vt 0.938380 0.992909 +vt 0.965320 0.996970 +vt 0.940930 0.996970 +vt 0.200485 0.203811 +vt 0.197517 0.204093 +vt 0.197517 0.199438 +vt 0.199546 0.199244 +vt 0.936620 0.992908 +vt 0.907130 0.992909 +vt 0.934070 0.996970 +vt 0.909680 0.996970 +vt 0.203338 0.202973 +vt 0.201497 0.198672 +vt 0.905370 0.992909 +vt 0.875880 0.992909 +vt 0.902820 0.996970 +vt 0.878429 0.996970 +vt 0.205968 0.201613 +vt 0.203295 0.197742 +vt 0.874120 0.992908 +vt 0.844630 0.992909 +vt 0.871571 0.996970 +vt 0.847180 0.996970 +vt 0.208274 0.199783 +vt 0.204871 0.196491 +vt 0.842870 0.992908 +vt 0.813380 0.992908 +vt 0.840320 0.996970 +vt 0.815929 0.996970 +vt 0.210165 0.197553 +vt 0.206164 0.194966 +vt 0.811620 0.992909 +vt 0.782130 0.992909 +vt 0.809071 0.996970 +vt 0.784680 0.996970 +vt 0.211571 0.195008 +vt 0.207125 0.193227 +vt 0.780370 0.992909 +vt 0.750880 0.992908 +vt 0.777820 0.996970 +vt 0.753429 0.996970 +vt 0.212437 0.192248 +vt 0.207717 0.191339 +vt 0.749120 0.992909 +vt 0.719630 0.992909 +vt 0.746570 0.996970 +vt 0.722180 0.996970 +vt 0.212729 0.189376 +vt 0.207917 0.189376 +vt 0.717870 0.992908 +vt 0.688380 0.992908 +vt 0.715320 0.996970 +vt 0.690930 0.996970 +vt 0.212437 0.186505 +vt 0.207717 0.187414 +vt 0.686620 0.992909 +vt 0.657130 0.992909 +vt 0.684071 0.996970 +vt 0.659680 0.996970 +vt 0.211571 0.183745 +vt 0.207125 0.185526 +vt 0.655370 0.992908 +vt 0.625880 0.992908 +vt 0.652820 0.996970 +vt 0.628429 0.996970 +vt 0.210165 0.181200 +vt 0.206164 0.183787 +vt 0.624120 0.992908 +vt 0.594630 0.992909 +vt 0.621571 0.996970 +vt 0.597180 0.996970 +vt 0.208274 0.178970 +vt 0.204871 0.182262 +vt 0.592870 0.992908 +vt 0.563380 0.992908 +vt 0.590320 0.996970 +vt 0.565930 0.996970 +vt 0.205968 0.177140 +vt 0.203295 0.181011 +vt 0.561620 0.992909 +vt 0.532130 0.992908 +vt 0.559071 0.996970 +vt 0.534680 0.996970 +vt 0.203338 0.175780 +vt 0.201497 0.180081 +vt 0.530370 0.992909 +vt 0.500880 0.992908 +vt 0.527820 0.996970 +vt 0.503430 0.996970 +vt 0.200485 0.174942 +vt 0.199546 0.179508 +vt 0.499120 0.992909 +vt 0.469630 0.992909 +vt 0.496570 0.996970 +vt 0.472180 0.996970 +vt 0.197517 0.174660 +vt 0.197517 0.179315 +vt 0.467870 0.992909 +vt 0.438380 0.992909 +vt 0.465320 0.996970 +vt 0.440930 0.996970 +vt 0.194549 0.174942 +vt 0.195488 0.179508 +vt 0.436620 0.992909 +vt 0.407130 0.992909 +vt 0.434070 0.996970 +vt 0.409680 0.996970 +vt 0.191695 0.175780 +vt 0.193537 0.180081 +vt 0.405370 0.992909 +vt 0.375880 0.992909 +vt 0.402820 0.996970 +vt 0.378430 0.996970 +vt 0.189065 0.177140 +vt 0.191739 0.181011 +vt 0.374120 0.992909 +vt 0.344630 0.992909 +vt 0.371570 0.996970 +vt 0.347180 0.996970 +vt 0.186760 0.178970 +vt 0.190163 0.182262 +vt 0.342870 0.992909 +vt 0.313380 0.992908 +vt 0.340320 0.996970 +vt 0.315930 0.996970 +vt 0.184868 0.181200 +vt 0.188869 0.183787 +vt 0.311620 0.992909 +vt 0.282130 0.992909 +vt 0.309070 0.996970 +vt 0.284680 0.996970 +vt 0.183462 0.183745 +vt 0.187908 0.185526 +vt 0.280370 0.992909 +vt 0.250880 0.992909 +vt 0.277820 0.996970 +vt 0.253430 0.996970 +vt 0.182597 0.186505 +vt 0.187317 0.187414 +vt 0.249120 0.992909 +vt 0.219630 0.992909 +vt 0.246570 0.996970 +vt 0.222180 0.996970 +vt 0.182304 0.189376 +vt 0.187117 0.189376 +vt 0.217870 0.992909 +vt 0.188380 0.992909 +vt 0.215320 0.996970 +vt 0.190930 0.996970 +vt 0.182597 0.192248 +vt 0.187317 0.191339 +vt 0.186620 0.992909 +vt 0.157130 0.992909 +vt 0.184070 0.996970 +vt 0.159680 0.996970 +vt 0.183462 0.195008 +vt 0.187908 0.193227 +vt 0.155370 0.992909 +vt 0.125880 0.992909 +vt 0.152820 0.996970 +vt 0.128430 0.996970 +vt 0.184868 0.197553 +vt 0.188869 0.194966 +vt 0.124120 0.992909 +vt 0.094630 0.992909 +vt 0.121570 0.996970 +vt 0.097180 0.996970 +vt 0.186760 0.199783 +vt 0.190163 0.196491 +vt 0.092870 0.992909 +vt 0.063380 0.992909 +vt 0.090320 0.996970 +vt 0.065930 0.996970 +vt 0.189065 0.201613 +vt 0.191739 0.197742 +vt 0.061620 0.992908 +vt 0.032130 0.992909 +vt 0.059070 0.996970 +vt 0.034680 0.996970 +vt 0.191695 0.202973 +vt 0.193537 0.198672 +vt 0.030370 0.992909 +vt 0.000880 0.992909 +vt 0.027820 0.996970 +vt 0.003429 0.996970 +vt 0.194549 0.203810 +vt 0.195488 0.199244 +vt 0.999120 0.992909 +vt 0.969630 0.992909 +vt 0.996571 0.996970 +vt 0.972180 0.996970 +vn 0.0000 -1.0000 -0.0000 +vn 0.0000 1.0000 -0.0000 +vn 0.1903 0.2203 0.9567 +vn 0.1838 0.3345 0.9243 +vn 0.0000 0.3345 0.9424 +vn 0.0000 0.2203 0.9754 +vn -0.3733 0.2203 0.9012 +vn -0.3606 0.3345 0.8707 +vn -0.5235 0.3345 0.7836 +vn -0.5419 0.2203 0.8110 +vn -0.6664 0.3345 0.6664 +vn -0.6897 0.2203 0.6897 +vn -0.7836 0.3345 0.5235 +vn -0.8110 0.2203 0.5419 +vn -0.8707 0.3345 0.3606 +vn -0.9012 0.2203 0.3733 +vn -0.9243 0.3345 0.1838 +vn -0.9567 0.2203 0.1903 +vn -0.9424 0.3345 0.0000 +vn -0.9754 0.2203 0.0000 +vn -0.9243 0.3345 -0.1838 +vn -0.9567 0.2203 -0.1903 +vn -0.8707 0.3345 -0.3606 +vn -0.9012 0.2203 -0.3733 +vn -0.7836 0.3345 -0.5235 +vn -0.8110 0.2203 -0.5419 +vn -0.6664 0.3345 -0.6664 +vn -0.6897 0.2203 -0.6897 +vn -0.5235 0.3345 -0.7836 +vn -0.5419 0.2203 -0.8110 +vn -0.3606 0.3345 -0.8707 +vn -0.3733 0.2203 -0.9012 +vn -0.1838 0.3345 -0.9243 +vn -0.1903 0.2203 -0.9567 +vn 0.0000 0.3345 -0.9424 +vn 0.0000 0.2203 -0.9754 +vn 0.1838 0.3345 -0.9243 +vn 0.1903 0.2203 -0.9567 +vn 0.3606 0.3345 -0.8707 +vn 0.3733 0.2203 -0.9012 +vn 0.5235 0.3345 -0.7836 +vn 0.5419 0.2203 -0.8110 +vn 0.6664 0.3345 -0.6664 +vn 0.6897 0.2203 -0.6897 +vn 0.7836 0.3345 -0.5235 +vn 0.8110 0.2203 -0.5419 +vn 0.8707 0.3345 -0.3606 +vn 0.9012 0.2203 -0.3733 +vn 0.9243 0.3345 -0.1838 +vn 0.9567 0.2203 -0.1903 +vn 0.9424 0.3345 0.0000 +vn 0.9754 0.2203 0.0000 +vn 0.9243 0.3345 0.1838 +vn 0.9567 0.2203 0.1903 +vn 0.8707 0.3345 0.3606 +vn 0.9012 0.2203 0.3733 +vn 0.7836 0.3345 0.5235 +vn 0.8110 0.2203 0.5419 +vn 0.6664 0.3345 0.6664 +vn 0.6897 0.2203 0.6897 +vn 0.5235 0.3345 0.7836 +vn 0.5419 0.2203 0.8110 +vn 0.3606 0.3345 0.8707 +vn 0.3733 0.2203 0.9012 +vn -0.1838 0.3345 0.9243 +vn -0.1903 0.2203 0.9567 +vn 0.0352 -0.6962 -0.7169 +vn -0.0352 -0.6962 -0.7169 +vn -0.0352 0.6962 -0.7169 +vn 0.0352 0.6962 -0.7169 +vn -0.0352 -0.6962 0.7169 +vn 0.0352 -0.6962 0.7169 +vn 0.0352 0.6962 0.7169 +vn -0.0352 0.6962 0.7169 +vn -0.7169 -0.6962 -0.0352 +vn -0.7169 -0.6962 0.0352 +vn -0.7169 0.6962 0.0352 +vn -0.7169 0.6962 -0.0352 +vn -0.1420 0.6857 0.7139 +vn -0.1420 -0.6857 0.7139 +vn -0.2785 0.6857 0.6725 +vn -0.2785 -0.6857 0.6725 +vn -0.4044 0.6857 0.6052 +vn -0.4044 -0.6857 0.6052 +vn -0.5147 0.6857 0.5147 +vn -0.5147 -0.6857 0.5147 +vn -0.6052 0.6857 0.4044 +vn -0.6052 -0.6857 0.4044 +vn -0.6725 0.6857 0.2785 +vn -0.6725 -0.6857 0.2785 +vn -0.7139 0.6857 0.1420 +vn -0.7139 -0.6857 0.1420 +vn -0.1420 -0.6857 -0.7139 +vn -0.1420 0.6857 -0.7139 +vn -0.2785 -0.6857 -0.6725 +vn -0.2785 0.6857 -0.6725 +vn -0.4044 -0.6857 -0.6052 +vn -0.4044 0.6857 -0.6052 +vn -0.5147 -0.6857 -0.5147 +vn -0.5147 0.6857 -0.5147 +vn -0.6052 -0.6857 -0.4044 +vn -0.6052 0.6857 -0.4044 +vn -0.6725 -0.6857 -0.2785 +vn -0.6725 0.6857 -0.2785 +vn -0.7139 -0.6857 -0.1420 +vn -0.7139 0.6857 -0.1420 +vn 0.1420 0.6857 -0.7139 +vn 0.1420 -0.6857 -0.7139 +vn 0.2785 0.6857 -0.6725 +vn 0.2785 -0.6857 -0.6725 +vn 0.4044 0.6857 -0.6052 +vn 0.4044 -0.6857 -0.6052 +vn 0.5147 0.6857 -0.5147 +vn 0.5147 -0.6857 -0.5147 +vn 0.6052 0.6857 -0.4044 +vn 0.6052 -0.6857 -0.4044 +vn 0.6725 0.6857 -0.2785 +vn 0.6725 -0.6857 -0.2785 +vn 0.7139 0.6857 -0.1420 +vn 0.7139 -0.6857 -0.1420 +vn 0.7169 0.6962 -0.0352 +vn 0.7169 -0.6962 -0.0352 +vn 0.1420 -0.6857 0.7139 +vn 0.1420 0.6857 0.7139 +vn 0.2785 -0.6857 0.6725 +vn 0.2785 0.6857 0.6725 +vn 0.4044 -0.6857 0.6052 +vn 0.4044 0.6857 0.6052 +vn 0.5147 -0.6857 0.5147 +vn 0.5147 0.6857 0.5147 +vn 0.6052 -0.6857 0.4044 +vn 0.6052 0.6857 0.4044 +vn 0.6725 -0.6857 0.2785 +vn 0.6725 0.6857 0.2785 +vn 0.7139 -0.6857 0.1420 +vn 0.7139 0.6857 0.1420 +vn 0.7169 -0.6962 0.0352 +vn 0.7169 0.6962 0.0352 +vn 0.0000 0.6236 0.7817 +vn -0.1525 0.6236 0.7667 +vn 0.0000 0.8922 0.4517 +vn -0.0881 0.8922 0.4430 +vn 0.0000 0.9918 0.1276 +vn -0.0249 0.9918 0.1251 +vn -0.2991 0.6236 0.7222 +vn -0.1728 0.8922 0.4173 +vn -0.0488 0.9918 0.1179 +vn -0.4343 0.6236 0.6500 +vn -0.2509 0.8922 0.3755 +vn -0.0709 0.9918 0.1061 +vn -0.5528 0.6236 0.5528 +vn -0.3194 0.8922 0.3194 +vn -0.0902 0.9918 0.0902 +vn -0.6500 0.6236 0.4343 +vn -0.3755 0.8922 0.2509 +vn -0.1061 0.9918 0.0709 +vn -0.7222 0.6236 0.2991 +vn -0.4173 0.8922 0.1728 +vn -0.1179 0.9918 0.0488 +vn -0.7667 0.6236 0.1525 +vn -0.4430 0.8922 0.0881 +vn -0.1251 0.9918 0.0249 +vn -0.7817 0.6236 0.0000 +vn -0.4517 0.8922 0.0000 +vn -0.1276 0.9918 0.0000 +vn -0.7667 0.6236 -0.1525 +vn -0.4430 0.8922 -0.0881 +vn -0.1251 0.9918 -0.0249 +vn -0.7222 0.6236 -0.2991 +vn -0.4173 0.8922 -0.1728 +vn -0.1179 0.9918 -0.0488 +vn -0.6500 0.6236 -0.4343 +vn -0.3755 0.8922 -0.2509 +vn -0.1061 0.9918 -0.0709 +vn -0.5528 0.6236 -0.5528 +vn -0.3194 0.8922 -0.3194 +vn -0.0902 0.9918 -0.0902 +vn -0.4343 0.6236 -0.6500 +vn -0.2509 0.8922 -0.3755 +vn -0.0709 0.9918 -0.1061 +vn -0.2991 0.6236 -0.7222 +vn -0.1728 0.8922 -0.4173 +vn -0.0488 0.9918 -0.1179 +vn -0.1525 0.6236 -0.7667 +vn -0.0881 0.8922 -0.4430 +vn -0.0249 0.9918 -0.1251 +vn 0.0000 0.6236 -0.7817 +vn 0.0000 0.8922 -0.4517 +vn 0.0000 0.9918 -0.1276 +vn 0.1525 0.6236 -0.7667 +vn 0.0881 0.8922 -0.4430 +vn 0.0249 0.9918 -0.1251 +vn 0.2991 0.6236 -0.7222 +vn 0.1728 0.8922 -0.4173 +vn 0.0488 0.9918 -0.1179 +vn 0.4343 0.6236 -0.6500 +vn 0.2509 0.8922 -0.3755 +vn 0.0709 0.9918 -0.1061 +vn 0.5528 0.6236 -0.5528 +vn 0.3194 0.8922 -0.3194 +vn 0.0902 0.9918 -0.0902 +vn 0.6500 0.6236 -0.4343 +vn 0.3755 0.8922 -0.2509 +vn 0.1061 0.9918 -0.0709 +vn 0.7222 0.6236 -0.2991 +vn 0.4173 0.8922 -0.1728 +vn 0.1179 0.9918 -0.0488 +vn 0.7667 0.6236 -0.1525 +vn 0.4430 0.8922 -0.0881 +vn 0.1251 0.9918 -0.0249 +vn 0.7817 0.6236 0.0000 +vn 0.4517 0.8922 0.0000 +vn 0.1276 0.9918 0.0000 +vn 0.7667 0.6236 0.1525 +vn 0.4430 0.8922 0.0881 +vn 0.1251 0.9918 0.0249 +vn 0.7222 0.6236 0.2991 +vn 0.4173 0.8922 0.1728 +vn 0.1179 0.9918 0.0488 +vn 0.6500 0.6236 0.4343 +vn 0.3755 0.8922 0.2509 +vn 0.1061 0.9918 0.0709 +vn 0.5528 0.6236 0.5528 +vn 0.3194 0.8922 0.3194 +vn 0.0902 0.9918 0.0902 +vn 0.4343 0.6236 0.6500 +vn 0.2509 0.8922 0.3755 +vn 0.0709 0.9918 0.1061 +vn 0.2991 0.6236 0.7222 +vn 0.1728 0.8922 0.4173 +vn 0.0488 0.9918 0.1179 +vn 0.1525 0.6236 0.7667 +vn 0.0881 0.8922 0.4430 +vn 0.0249 0.9918 0.1251 +g Cylinder_Cylinder_None +s off +f 33/1/1 35/2/1 36/3/1 37/4/1 38/5/1 39/6/1 40/7/1 41/8/1 34/9/1 51/10/1 53/11/1 54/12/1 55/13/1 56/14/1 57/15/1 58/16/1 59/17/1 52/18/1 60/19/1 62/20/1 63/21/1 64/22/1 65/23/1 66/24/1 67/25/1 68/26/1 61/27/1 42/28/1 44/29/1 45/30/1 46/31/1 47/32/1 48/33/1 49/34/1 50/35/1 43/36/1 +f 78/37/2 80/38/2 81/39/2 82/40/2 83/41/2 84/42/2 85/43/2 86/44/2 79/45/2 87/46/2 89/47/2 90/48/2 91/49/2 92/50/2 93/51/2 94/52/2 95/53/2 88/54/2 96/55/2 98/56/2 99/57/2 100/58/2 101/59/2 102/60/2 103/61/2 104/62/2 97/63/2 69/64/2 71/65/2 72/66/2 73/67/2 74/68/2 75/69/2 76/70/2 77/71/2 70/72/2 +s 1 +f 32/73/3 230/74/4 106/75/5 1/76/6 +f 3/77/7 114/78/8 118/79/9 4/80/10 +f 4/80/10 118/79/9 122/81/11 5/82/12 +f 5/82/12 122/81/11 126/83/13 6/84/14 +f 6/84/14 126/83/13 130/85/15 7/86/16 +f 7/86/16 130/85/15 134/87/17 8/88/18 +f 8/88/18 134/87/17 138/89/19 9/90/20 +f 9/90/20 138/91/19 142/92/21 10/93/22 +f 10/93/22 142/92/21 146/94/23 11/95/24 +f 11/95/24 146/94/23 150/96/25 12/97/26 +f 12/97/26 150/96/25 154/98/27 13/99/28 +f 13/99/28 154/98/27 158/100/29 14/101/30 +f 14/101/30 158/100/29 162/102/31 15/103/32 +f 15/103/32 162/102/31 166/104/33 16/105/34 +f 16/105/34 166/104/33 170/106/35 17/107/36 +f 17/107/36 170/106/35 174/108/37 18/109/38 +f 18/109/38 174/108/37 178/110/39 19/111/40 +f 19/111/40 178/110/39 182/112/41 20/113/42 +f 20/113/42 182/112/41 186/114/43 21/115/44 +f 21/115/44 186/114/43 190/116/45 22/117/46 +f 22/117/46 190/116/45 194/118/47 23/119/48 +f 23/119/48 194/118/47 198/120/49 24/121/50 +f 24/121/50 198/120/49 202/122/51 25/123/52 +f 25/123/52 202/122/51 206/124/53 26/125/54 +f 26/125/54 206/124/53 210/126/55 27/127/56 +f 27/127/56 210/126/55 214/128/57 28/129/58 +f 28/129/58 214/128/57 218/130/59 29/131/60 +f 29/131/60 218/130/59 222/132/61 30/133/62 +f 30/133/62 222/132/61 226/134/63 31/135/64 +f 31/135/64 226/134/63 230/136/4 32/137/3 +f 1/76/6 106/138/5 110/139/65 2/140/66 +f 2/140/66 110/139/65 114/78/8 3/77/7 +f 33/141/67 43/142/68 87/143/69 79/144/70 +f 60/145/71 52/146/72 69/147/73 97/148/74 +f 42/149/75 61/150/76 96/151/77 88/152/78 +f 60/145/71 97/148/74 104/153/79 62/154/80 +f 62/154/80 104/153/79 103/155/81 63/156/82 +f 63/156/82 103/155/81 102/157/83 64/158/84 +f 64/158/84 102/157/83 101/159/85 65/160/86 +f 65/160/86 101/159/85 100/161/87 66/162/88 +f 66/162/88 100/161/87 99/163/89 67/164/90 +f 67/164/90 99/163/89 98/165/91 68/166/92 +f 68/166/92 98/165/91 96/151/77 61/150/76 +f 87/143/69 43/142/68 50/167/93 89/168/94 +f 89/168/94 50/167/93 49/169/95 90/170/96 +f 90/170/96 49/169/95 48/171/97 91/172/98 +f 91/172/98 48/171/97 47/173/99 92/174/100 +f 92/174/100 47/173/99 46/175/101 93/176/102 +f 93/176/102 46/175/101 45/177/103 94/178/104 +f 94/178/104 45/177/103 44/179/105 95/180/106 +f 95/180/106 44/179/105 42/149/75 88/152/78 +f 33/141/67 79/144/70 86/181/107 35/182/108 +f 35/182/108 86/181/107 85/183/109 36/184/110 +f 36/184/110 85/183/109 84/185/111 37/186/112 +f 37/186/112 84/185/111 83/187/113 38/188/114 +f 38/188/114 83/187/113 82/189/115 39/190/116 +f 39/190/116 82/189/115 81/191/117 40/192/118 +f 40/192/118 81/191/117 80/193/119 41/194/120 +f 41/194/120 80/193/119 78/195/121 34/196/122 +f 69/197/73 52/198/72 59/199/123 71/200/124 +f 71/200/124 59/199/123 58/201/125 72/202/126 +f 72/202/126 58/201/125 57/203/127 73/204/128 +f 73/204/128 57/203/127 56/205/129 74/206/130 +f 74/206/130 56/205/129 55/207/131 75/208/132 +f 75/208/132 55/207/131 54/209/133 76/210/134 +f 76/210/134 54/209/133 53/211/135 77/212/136 +f 77/212/136 53/211/135 51/213/137 70/214/138 +f 51/213/137 34/196/122 78/195/121 70/214/138 +f 110/139/65 106/138/5 108/215/139 112/216/140 +f 112/216/140 108/215/139 107/217/141 111/218/142 +f 111/219/142 107/220/141 105/221/143 109/222/144 +f 114/78/8 110/139/65 112/223/140 116/224/145 +f 116/224/145 112/223/140 111/225/142 115/226/146 +f 115/227/146 111/219/142 109/222/144 113/228/147 +f 118/79/9 114/78/8 116/229/145 120/230/148 +f 120/230/148 116/229/145 115/231/146 119/232/149 +f 119/233/149 115/227/146 113/228/147 117/234/150 +f 122/81/11 118/79/9 120/235/148 124/236/151 +f 124/236/151 120/235/148 119/237/149 123/238/152 +f 123/239/152 119/233/149 117/234/150 121/240/153 +f 126/83/13 122/81/11 124/241/151 128/242/154 +f 128/242/154 124/241/151 123/243/152 127/244/155 +f 127/245/155 123/239/152 121/240/153 125/246/156 +f 130/85/15 126/83/13 128/247/154 132/248/157 +f 132/248/157 128/247/154 127/249/155 131/250/158 +f 131/251/158 127/245/155 125/246/156 129/252/159 +f 134/87/17 130/85/15 132/253/157 136/254/160 +f 136/254/160 132/253/157 131/255/158 135/256/161 +f 135/257/161 131/251/158 129/252/159 133/258/162 +f 138/89/19 134/87/17 136/259/160 140/260/163 +f 140/260/163 136/259/160 135/261/161 139/262/164 +f 139/263/164 135/257/161 133/258/162 137/264/165 +f 142/92/21 138/91/19 140/265/163 144/266/166 +f 144/266/166 140/265/163 139/267/164 143/268/167 +f 143/269/167 139/263/164 137/264/165 141/270/168 +f 146/94/23 142/92/21 144/271/166 148/272/169 +f 148/272/169 144/271/166 143/273/167 147/274/170 +f 147/275/170 143/269/167 141/270/168 145/276/171 +f 150/96/25 146/94/23 148/277/169 152/278/172 +f 152/278/172 148/277/169 147/279/170 151/280/173 +f 151/281/173 147/275/170 145/276/171 149/282/174 +f 154/98/27 150/96/25 152/283/172 156/284/175 +f 156/284/175 152/283/172 151/285/173 155/286/176 +f 155/287/176 151/281/173 149/282/174 153/288/177 +f 158/100/29 154/98/27 156/289/175 160/290/178 +f 160/290/178 156/289/175 155/291/176 159/292/179 +f 159/293/179 155/287/176 153/288/177 157/294/180 +f 162/102/31 158/100/29 160/295/178 164/296/181 +f 164/296/181 160/295/178 159/297/179 163/298/182 +f 163/299/182 159/293/179 157/294/180 161/300/183 +f 166/104/33 162/102/31 164/301/181 168/302/184 +f 168/302/184 164/301/181 163/303/182 167/304/185 +f 167/305/185 163/299/182 161/300/183 165/306/186 +f 170/106/35 166/104/33 168/307/184 172/308/187 +f 172/308/187 168/307/184 167/309/185 171/310/188 +f 171/311/188 167/305/185 165/306/186 169/312/189 +f 174/108/37 170/106/35 172/313/187 176/314/190 +f 176/314/190 172/313/187 171/315/188 175/316/191 +f 175/317/191 171/311/188 169/312/189 173/318/192 +f 178/110/39 174/108/37 176/319/190 180/320/193 +f 180/320/193 176/319/190 175/321/191 179/322/194 +f 179/323/194 175/317/191 173/318/192 177/324/195 +f 182/112/41 178/110/39 180/325/193 184/326/196 +f 184/326/196 180/325/193 179/327/194 183/328/197 +f 183/329/197 179/323/194 177/324/195 181/330/198 +f 186/114/43 182/112/41 184/331/196 188/332/199 +f 188/332/199 184/331/196 183/333/197 187/334/200 +f 187/335/200 183/329/197 181/330/198 185/336/201 +f 190/116/45 186/114/43 188/337/199 192/338/202 +f 192/338/202 188/337/199 187/339/200 191/340/203 +f 191/341/203 187/335/200 185/336/201 189/342/204 +f 194/118/47 190/116/45 192/343/202 196/344/205 +f 196/344/205 192/343/202 191/345/203 195/346/206 +f 195/347/206 191/341/203 189/342/204 193/348/207 +f 198/120/49 194/118/47 196/349/205 200/350/208 +f 200/350/208 196/349/205 195/351/206 199/352/209 +f 199/353/209 195/347/206 193/348/207 197/354/210 +f 202/122/51 198/120/49 200/355/208 204/356/211 +f 204/356/211 200/355/208 199/357/209 203/358/212 +f 203/359/212 199/353/209 197/354/210 201/360/213 +f 206/124/53 202/122/51 204/361/211 208/362/214 +f 208/362/214 204/361/211 203/363/212 207/364/215 +f 207/365/215 203/359/212 201/360/213 205/366/216 +f 210/126/55 206/124/53 208/367/214 212/368/217 +f 212/368/217 208/367/214 207/369/215 211/370/218 +f 211/371/218 207/365/215 205/366/216 209/372/219 +f 214/128/57 210/126/55 212/373/217 216/374/220 +f 216/374/220 212/373/217 211/375/218 215/376/221 +f 215/377/221 211/371/218 209/372/219 213/378/222 +f 218/130/59 214/128/57 216/379/220 220/380/223 +f 220/380/223 216/379/220 215/381/221 219/382/224 +f 219/383/224 215/377/221 213/378/222 217/384/225 +f 222/132/61 218/130/59 220/385/223 224/386/226 +f 224/386/226 220/385/223 219/387/224 223/388/227 +f 223/389/227 219/383/224 217/384/225 221/390/228 +f 226/134/63 222/132/61 224/391/226 228/392/229 +f 228/392/229 224/391/226 223/393/227 227/394/230 +f 227/395/230 223/389/227 221/390/228 225/396/231 +f 230/136/4 226/134/63 228/397/229 232/398/232 +f 232/398/232 228/397/229 227/399/230 231/400/233 +f 231/401/233 227/395/230 225/396/231 229/402/234 +f 106/75/5 230/74/4 232/403/232 108/404/139 +f 108/404/139 232/403/232 231/405/233 107/406/141 +f 107/220/141 231/401/233 229/402/234 105/221/143 +f 109/222/144 105/221/143 229/402/234 225/396/231 221/390/228 217/384/225 213/378/222 209/372/219 205/366/216 201/360/213 197/354/210 193/348/207 189/342/204 185/336/201 181/330/198 177/324/195 173/318/192 169/312/189 165/306/186 161/300/183 157/294/180 153/288/177 149/282/174 145/276/171 141/270/168 137/264/165 133/258/162 129/252/159 125/246/156 121/240/153 117/234/150 113/228/147 diff --git a/mods/roads/infrastructure/nodes.lua b/mods/roads/infrastructure/nodes.lua new file mode 100644 index 0000000..1872779 --- /dev/null +++ b/mods/roads/infrastructure/nodes.lua @@ -0,0 +1,1440 @@ +-- **************************************************************************************************** MATERIALS + +-- Asphalt block + minetest.register_alias("infrastructure:asphalt", "streets:asphalt") + +-- Concrete block + minetest.register_alias("infrastructure:concrete", "technic:concrete") + +-- Concrete fence + minetest.register_alias("infrastructure:fence_concrete", "prefab:concrete_fence") + +-- Galvanized steel block + minetest.register_node("infrastructure:galvanized_steel", { + description = "Galvanized steel", + tiles = {"infrastructure_galvanized_steel.png"}, + drawtype = "normal", + paramtype = "light", + groups = {cracky = 2}, + }) + minetest.register_alias("galvanized_steel", "infrastructure:galvanized_steel") + +-- Galvanized steel fence + minetest.register_node("infrastructure:fence_galvanized_steel", { + description = "Galvanized steel fence", + drawtype = "fencelike", + tiles = {"infrastructure_galvanized_steel.png"}, + paramtype = "light", + is_ground_content = true, + selection_box = { + type = "fixed", + fixed = {-1/8, -1/2, -1/8, 1/8, 1/2, 1/8}, + }, + groups = {cracky = 2}, + }) + + +-- **************************************************************************************************** PRECAST CONCRETE + +-- Concrete seperating wall + minetest.register_node("infrastructure:precast_concrete_seperating_wall", { + description = "Precast concrete seperating wall", + tiles = {"infrastructure_concrete.png"}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2}, + node_box = { + type = "fixed", + fixed = { + {-5/16, -1/2, -7/16, 5/16, -1/4, 7/16}, + {-1/16, -1/4, -7/16, 1/16, 1/2, 7/16}, + {-3/16, -1/2, -5/16, 3/16, 0, -1/4}, + {-3/16, -1/2, 1/4, 3/16, 0, 5/16} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-5/16, -1/2, -7/16, 5/16, -1/4, 7/16}, + {-1/16, -1/4, -7/16, 1/16, 1/2, 7/16}, + {-3/16, -1/2, -5/16, 3/16, 0, -1/4}, + {-3/16, -1/2, 1/4, 3/16, 0, 5/16} + } + } + }) + +-- Concrete cylinder + minetest.register_node("infrastructure:precast_concrete_cylinder", { + description = "Precast concrete cylinder", + tiles = {"infrastructure_concrete.png"}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2}, + walkable = false, + climbable = true, + node_box = { + type = "fixed", + fixed = { + {3/8, -1/2, -1/2, 1/2, 1/2, 1/2}, + {-1/2, -1/2, -1/2, -3/8, 1/2, 1/2}, + {-1/2, -1/2, 3/8, 1/2, 1/2, 1/2}, + {-1/2, -1/2, -1/2, 1/2, 1/2, -3/8} + } + }, + selection_box = { + type = "fixed", + fixed = { + {3/8, -1/2, -1/2, 1/2, 1/2, 1/2}, + {-1/2, -1/2, -1/2, -3/8, 1/2, 1/2}, + {-1/2, -1/2, 3/8, 1/2, 1/2, 1/2}, + {-1/2, -1/2, -1/2, 1/2, 1/2, -3/8} + } + } + }) + +-- Concrete grid paver + minetest.register_node("infrastructure:precast_concrete_grid_paver", { + description = "Precast concrete grid paver", + tiles = { + "infrastructure_grid_paver_top.png", + "infrastructure_grid_paver_bottom.png", + "infrastructure_concrete.png", + "infrastructure_concrete.png", + "infrastructure_concrete.png", + "infrastructure_concrete.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2}, + node_box = { + type = "fixed", + fixed = { + {-1/2, -1/2, -1/2, 1/2, -1/2, 1/2}, + {-1/2, -1/2 + 1/128, -1/2, 1/2, -1/2 + 1/128, 1/2}, + {-1/2, -1/2 + 2/128, -1/2, 1/2, -1/2 + 2/128, 1/2}, + {-1/2, -1/2 + 3/128, -1/2, 1/2, -1/2 + 3/128, 1/2}, + {-1/2, -1/2 + 4/128, -1/2, 1/2, -1/2 + 4/128, 1/2}, + {-1/2, -1/2 + 5/128, -1/2, 1/2, -1/2 + 5/128, 1/2}, + {-1/2, -1/2 + 6/128, -1/2, 1/2, -1/2 + 6/128, 1/2}, + {-1/2, -1/2 + 7/128, -1/2, 1/2, -1/2 + 7/128, 1/2}, + {-1/2, -1/2 + 8/128, -1/2, 1/2, -1/2 + 8/128, 1/2}, + } + }, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/2, 1/2, -1/2 + 8/128, 1/2} + }, + + after_place_node = function(pos) + pos.y = pos.y - 1 + local node = minetest.get_node(pos) + if (node.name == "default:dirt_with_grass") then + pos.y = pos.y + 1 + local node = minetest.get_node(pos) + node.name = "infrastructure:precast_concrete_grid_paver_with_grass" + minetest.swap_node(pos, node) + end + end + }) + + minetest.register_node("infrastructure:precast_concrete_grid_paver_with_grass", { + description = "Precast concrete grid paver with grass", + tiles = { + "infrastructure_grid_paver_top.png", + "infrastructure_grid_paver_bottom.png", + "infrastructure_grid_paver_grass.png", + "infrastructure_grid_paver_grass.png", + "infrastructure_grid_paver_grass.png", + "infrastructure_grid_paver_grass.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2,not_in_creative_inventory = 1}, + drop = "infrastructure:precast_concrete_grid_paver", + node_box = { + type = "fixed", + fixed = { + {-1/2, -1/2, -1/2, 1/2, -1/2, 1/2}, + {-1/2, -1/2 + 1/128, -1/2, 1/2, -1/2 + 1/128, 1/2}, + {-1/2, -1/2 + 2/128, -1/2, 1/2, -1/2 + 2/128, 1/2}, + {-1/2, -1/2 + 3/128, -1/2, 1/2, -1/2 + 3/128, 1/2}, + {-1/2, -1/2 + 4/128, -1/2, 1/2, -1/2 + 4/128, 1/2}, + {-1/2, -1/2 + 5/128, -1/2, 1/2, -1/2 + 5/128, 1/2}, + {-1/2, -1/2 + 6/128, -1/2, 1/2, -1/2 + 6/128, 1/2}, + {-1/2, -1/2 + 7/128, -1/2, 1/2, -1/2 + 7/128, 1/2}, + {-1/2, -1/2 + 8/128, -1/2, 1/2, -1/2 + 8/128, 1/2}, + + {-3/8, -1/2, 1/4, -1/8, 0, 1/4}, + {1/8, -1/2, 1/4, 3/8, 0, 1/4}, + + {-1/8, -1/2, 0, 1/8, 0, 0}, + + {-3/8, -1/2, -1/4, -1/8, 0, -1/4}, + {1/8, -1/2, -1/4, 3/8, 0, -1/4}, + + {1/4, -1/2, -3/8, 1/4, 0, -1/8}, + {1/4, -1/2, 1/8, 1/4, 0, 3/8}, + + {0, -1/2, -1/8, 0, 0, 1/8}, + + {-1/4, -1/2, -3/8, -1/4, 0, -1/8}, + {-1/4, -1/2, 1/8, -1/4, 0, 3/8} + } + }, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/2, 1/2, -1/2 + 8/128, 1/2} + }, + + on_punch = function(pos, node) + local node = minetest.get_node(pos) + node.name = "infrastructure:precast_concrete_grid_paver" + minetest.swap_node(pos, node) + end + }) + +-- **************************************************************************************************** STEEL STRUCTURES + +-- Truss + minetest.register_node("infrastructure:truss", { + description = "Truss", + tiles = {"infrastructure_truss.png"}, + drawtype = "nodebox", + paramtype = "light", + groups = {cracky = 2}, + node_box = { + type = "fixed", + fixed = { + {1/2, -1/2, -1/2, 1/2, 1/2, 1/2}, + {-1/2, 1/2, -1/2, 1/2, 1/2, 1/2}, + {-1/2, -1/2, 1/2, 1/2, 1/2, 1/2}, + {-1/2, -1/2, -1/2, -1/2, 1/2, 1/2}, + {-1/2, -1/2, -1/2, 1/2, -1/2, 1/2}, + {-1/2, -1/2, -1/2, 1/2, 1/2, -1/2} + } + }, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/2, 1/2, 1/2, 1/2} + } + }) + +-- Wire netting + minetest.register_node("infrastructure:wire_netting", { + description = "Wire netting", + tiles = {"infrastructure_wire_netting.png"}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2}, + node_box = { + type = "fixed", + fixed = {-1/2, -1/2, 0, 1/2, 1/2, 0} + }, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/8, 1/2, 1/2, 1/8} + } + }) + +-- Razor wire + minetest.register_node("infrastructure:razor_wire", { + description = "Razor wire", + tiles = {"infrastructure_razor_wire.png"}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2}, + node_box = { + type = "fixed", + fixed = { + {-1/2, 1/2, -1/2, 1/2, 1/2, 1/2}, + {-1/2, -1/2, -1/2, 1/2, -1/2, 1/2}, + {-1/2, -1/2, 1/2, 1/2, 1/2, 1/2}, + {-1/2, -1/2, -1/2, 1/2, 1/2, -1/2} + } + }, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/2, 1/2, 1/2, 1/2} + }, + + walkable = false, + damage_per_second = 8 + }) + +-- Drainage channel grating + minetest.register_node("infrastructure:drainage_channel_grating", { + description = "Truss", + tiles = { + "infrastructure_drainage_channel_grating.png", + "infrastructure_drainage_channel_grating.png", + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2}, + node_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/2, 0, -3/8, 1/2} + }, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/2, 0, -3/8, 1/2} + } + }) + +-- Louver + minetest.register_node("infrastructure:louver_opened", { + description = "Louver", + tiles = {"infrastructure_galvanized_steel.png"}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2}, + node_box = { + type = "fixed", + fixed = { + {-1/2, 7/16, 0, 1/2, 1/2, 1/2}, + {-1/2, -1/16, 0, 1/2, 0, 1/2} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/2, 7/16, 0, 1/2, 1/2, 1/2}, + {-1/2, -1/16, 0, 1/2, 0, 1/2} + } + }, + + on_punch = function(pos, node) + minetest.swap_node(pos, {name = "infrastructure:louver_closed", param2 = node.param2}) + end + }) + + minetest.register_node("infrastructure:louver_closed", { + tiles = {"infrastructure_galvanized_steel.png"}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2}, + drop = "infrastructure:louver_opened", + node_box = { + type = "fixed", + fixed = { + {-1/2, 1/16, 7/16, 1/2, 1/2, 1/2}, + {-1/2, -7/16, 7/16, 1/2, 0, 1/2} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/2, 1/16, 7/16, 1/2, 1/2, 1/2}, + {-1/2, -7/16, 7/16, 1/2, 0, 1/2} + } + }, + + on_punch = function(pos, node) + minetest.swap_node(pos, {name = "infrastructure:louver_opened", param2 = node.param2}) + end + }) + + minetest.register_alias("infrastructure:louver", "infrastructure:louver_opened") + +-- Riffled sheet + + minetest.register_node("infrastructure:riffled_sheet", { + description = "Riffled Sheet", + tiles = {"infrastructure_riffled_sheet.png"}, + is_ground_content = false, + groups = {cracky = 2}, + sounds = default.node_sound_stone_defaults(), + paramtype2 = "wallmounted", + drawtype = "nodebox", + paramtype = "light", + node_box = { + type = "wallmounted", + fixed = { + {-0.5, -0.5, 0.4375, 0.5, 0.5, 0.5}, + } + } +}) + +-- Corrugated sheet + minetest.register_node("infrastructure:corrugated_sheet", { + description = "corrugated sheet", + tiles = {"infrastructure_corrugated_sheet.png"}, + inventory_image = "infrastructure_corrugated_sheet.png", + wield_image = "infrastructure_corrugated_sheet.png", + drawtype = "raillike", + paramtype = "light", + groups = {cracky = 2, oddly_breakable_by_hand = 1}, + }) + +-- **************************************************************************************************** ADVANCED ITEMS + +-- Displacement + function displacement(pos, placer) + local displaced_node = minetest.get_node(pos) + local fdir = minetest.dir_to_facedir(placer:get_look_dir()) + pos.y = pos.y - 1 + local node = minetest.get_node(pos) + + if string.find(node.name, "slab_") then + if (string.find(node.name, "_1") + and not (string.find(node.name, "_14") + or string.find(node.name, "_15"))) + or string.find(node.name, "_2") + or (string.find(node.name, "_quarter") and not string.find(node.name, "_three_quarter")) + or string.find(node.name, "_two_sides") + or string.find(node.name, "_three_sides") + or string.find(node.name, "_displacement_3") then + pos.y = pos.y + 1 + minetest.set_node(pos, {name = displaced_node.name.."_displacement_3", param2 = fdir}) + elseif string.find(node.name, "_three_quarter") or string.find(node.name, "_displacement_1") then + pos.y = pos.y + 1 + minetest.set_node(pos, {name = displaced_node.name.."_displacement_1", param2 = fdir}) + elseif not (string.find(node.name, "_14") + or string.find(node.name, "_15")) + or string.find(node.name, "_displacement_2") then + pos.y = pos.y + 1 + minetest.set_node(pos, {name = displaced_node.name.."_displacement_2", param2 = fdir}) + end + end + end + +-- Raised pavement marker yellow/yellow + minetest.register_node("infrastructure:marker_yellow_yellow", { + description = "Raised pavement marker with yellow & yellow retroreflectors", + tiles = { + "infrastructure_marker_top_yellow_yellow.png", + "infrastructure_marker_bottom_side.png", + "infrastructure_marker_bottom_side.png", + "infrastructure_marker_bottom_side.png", + "infrastructure_marker_side_yellow.png", + "infrastructure_marker_side_yellow.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 3}, + walkable = false, + light_source = MARKER_LIGHT_RANGE, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = { + {-1/8, -1/2, -1/8, -1/16, -3/8, 1/8}, + {-1/16, -1/2, -1/8, 1/16, -7/16, 1/8}, + {1/16, -1/2, -1/8, 1/8, -3/8, 1/8}, + {-1/16, -7/16, -1/16, 1/16, -3/8, 1/16} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/8, -1/2, -1/8, -1/16, -3/8, 1/8}, + {-1/16, -1/2, -1/8, 1/16, -7/16, 1/8}, + {1/16, -1/2, -1/8, 1/8, -3/8, 1/8}, + {-1/16, -7/16, -1/16, 1/16, -3/8, 1/16} + } + }, + + after_place_node = function(pos, placer) + displacement(pos, placer) + end + }) + + for i = 1, 3 do + minetest.register_node("infrastructure:marker_yellow_yellow_displacement_"..tostring(i), { + tiles = { + "infrastructure_marker_top_yellow_yellow.png", + "infrastructure_marker_bottom_side.png", + "infrastructure_marker_bottom_side.png", + "infrastructure_marker_bottom_side.png", + "infrastructure_marker_side_yellow.png", + "infrastructure_marker_side_yellow.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 3, not_in_creative_inventory = 1}, + walkable = false, + light_source = MARKER_LIGHT_RANGE, + sunlight_propagates = true, + drop = "infrastructure:marker_yellow_yellow", + node_box = { + type = "fixed", + fixed = { + {-1/8, -1/2 - i/4, -1/8, -1/16, -3/8 - i/4, 1/8}, + {-1/16, -1/2 - i/4, -1/8, 1/16, -7/16 - i/4, 1/8}, + {1/16, -1/2 - i/4, -1/8, 1/8, -3/8 - i/4, 1/8}, + {-1/16, -7/16 - i/4, -1/16, 1/16, -3/8 - i/4, 1/16} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/8, -1/2 - i/4, -1/8, -1/16, -3/8 - i/4, 1/8}, + {-1/16, -1/2 - i/4, -1/8, 1/16, -7/16 - i/4, 1/8}, + {1/16, -1/2 - i/4, -1/8, 1/8, -3/8 - i/4, 1/8}, + {-1/16, -7/16 - i/4, -1/16, 1/16, -3/8 - i/4, 1/16} + } + } + }) + end + +-- Raised pavement marker red/yellow + minetest.register_node("infrastructure:marker_red_yellow", { + description = "Raised pavement marker with red & yellow retroreflectors", + tiles = { + "infrastructure_marker_top_red_yellow.png", + "infrastructure_marker_bottom_side.png", + "infrastructure_marker_bottom_side.png", + "infrastructure_marker_bottom_side.png", + "infrastructure_marker_side_yellow.png", + "infrastructure_marker_side_red.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 3}, + walkable = false, + light_source = MARKER_LIGHT_RANGE, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = { + {-1/8, -1/2, -1/8, -1/16, -3/8, 1/8}, + {-1/16, -1/2, -1/8, 1/16, -7/16, 1/8}, + {1/16, -1/2, -1/8, 1/8, -3/8, 1/8}, + {-1/16, -7/16, -1/16, 1/16, -3/8, 1/16} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/8, -1/2, -1/8, -1/16, -3/8, 1/8}, + {-1/16, -1/2, -1/8, 1/16, -7/16, 1/8}, + {1/16, -1/2, -1/8, 1/8, -3/8, 1/8}, + {-1/16, -7/16, -1/16, 1/16, -3/8, 1/16} + } + }, + + after_place_node = function(pos, placer) + displacement(pos, placer) + end + }) + + for i = 1, 3 do + minetest.register_node("infrastructure:marker_red_yellow_displacement_"..tostring(i), { + tiles = { + "infrastructure_marker_top_red_yellow.png", + "infrastructure_marker_bottom_side.png", + "infrastructure_marker_bottom_side.png", + "infrastructure_marker_bottom_side.png", + "infrastructure_marker_side_yellow.png", + "infrastructure_marker_side_red.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 3, not_in_creative_inventory = 1}, + walkable = false, + light_source = MARKER_LIGHT_RANGE, + sunlight_propagates = true, + drop = "infrastructure:marker_red_yellow", + node_box = { + type = "fixed", + fixed = { + {-1/8, -1/2 - i/4, -1/8, -1/16, -3/8 - i/4, 1/8}, + {-1/16, -1/2 - i/4, -1/8, 1/16, -7/16 - i/4, 1/8}, + {1/16, -1/2 - i/4, -1/8, 1/8, -3/8 - i/4, 1/8}, + {-1/16, -7/16 - i/4, -1/16, 1/16, -3/8 - i/4, 1/16} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/8, -1/2 - i/4, -1/8, -1/16, -3/8 - i/4, 1/8}, + {-1/16, -1/2 - i/4, -1/8, 1/16, -7/16 - i/4, 1/8}, + {1/16, -1/2 - i/4, -1/8, 1/8, -3/8 - i/4, 1/8}, + {-1/16, -7/16 - i/4, -1/16, 1/16, -3/8 - i/4, 1/16} + } + } + }) + end + +-- Retroreflective delineators + minetest.register_node("infrastructure:delineator", { + description = "Retroreflective delineator", + tiles = { + "infrastructure_concrete.png", + "infrastructure_concrete.png", + "infrastructure_delineator_wrapper_right.png", + "infrastructure_delineator_wrapper_left.png", + "infrastructure_delineator_retroreflector_yellow.png", + "infrastructure_delineator_retroreflector_red.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 3}, + light_source = DELINEATOR_LIGHT_RANGE, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = { + {-1/8, -1/2, -1/8, 1/8, 1/2, -1/16}, + {-1/16, -1/2, -1/16, 1/16, 1/2, 1/16}, + {-1/8, -1/2, 1/16, 1/8, 1/2, 1/8} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/8, -1/2, -1/8, 1/8, 1/2, -1/16}, + {-1/16, -1/2, -1/16, 1/16, 1/2, 1/16}, + {-1/8, -1/2, 1/16, 1/8, 1/2, 1/8} + } + }, + + after_place_node = function(pos, placer) + displacement(pos, placer) + end + }) + + minetest.register_node("infrastructure:delineator_guardrail", { + description = "Retroreflective delineator for guardrail", + tiles = { + "infrastructure_concrete.png", + "infrastructure_concrete.png", + "infrastructure_delineator_wrapper_right.png", + "infrastructure_delineator_wrapper_left.png", + "[combine:32x32:0,12=infrastructure_delineator_retroreflector_yellow.png:0,-20=infrastructure_delineator_retroreflector_yellow.png", + "[combine:32x32:0,12=infrastructure_delineator_retroreflector_red.png:0,-20=infrastructure_delineator_retroreflector_red.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 3}, + light_source = DELINEATOR_LIGHT_RANGE, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = { + {-1/8, -3/8, -1/32, 1/8, 1/8, 1/32}, + {1/8, -5/8, -1/16, 3/16, -1/4, 1/16} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/8, -3/8, -1/32, 1/8, 1/8, 1/32}, + {1/8, -5/8, -1/16, 3/16, -1/4, 1/16} + } + }, + + after_place_node = function(pos, placer) + displacement(pos, placer) + end + }) + + for i = 1, 3 do + minetest.register_node("infrastructure:delineator_displacement_"..tostring(i), { + tiles = { + "infrastructure_concrete.png", + "infrastructure_concrete.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_delineator_wrapper_right.png:0,"..tostring(i * 8 - 32).."=infrastructure_delineator_wrapper_right.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_delineator_wrapper_left.png:0,"..tostring(i * 8 - 32).."=infrastructure_delineator_wrapper_left.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_delineator_retroreflector_yellow.png:0,"..tostring(i * 8 - 32).."=infrastructure_delineator_retroreflector_yellow.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_delineator_retroreflector_red.png:0,"..tostring(i * 8 - 32).."=infrastructure_delineator_retroreflector_red.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 3, not_in_creative_inventory = 1}, + light_source = DELINEATOR_LIGHT_RANGE, + sunlight_propagates = true, + drop = "infrastructure:delineator", + node_box = { + type = "fixed", + fixed = { + {-1/8, -1/2 - i/4, -1/8, 1/8, 1/2 - i/4, -1/16}, + {-1/16, -1/2 - i/4, -1/16, 1/16, 1/2 - i/4, 1/16}, + {-1/8, -1/2 - i/4, 1/16, 1/8, 1/2 - i/4, 1/8} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/8, -1/2 - i/4, -1/8, 1/8, 1/2 - i/4, -1/16}, + {-1/16, -1/2 - i/4, -1/16, 1/16, 1/2 - i/4, 1/16}, + {-1/8, -1/2 - i/4, 1/16, 1/8, 1/2 - i/4, 1/8} + } + } + }) + + minetest.register_node("infrastructure:delineator_guardrail_displacement_"..tostring(i), { + tiles = { + "infrastructure_concrete.png", + "infrastructure_concrete.png", + "[combine:32x32:0,"..tostring(12 + i * 8).."=infrastructure_delineator_wrapper_right.png:0,"..tostring(i * 8 - 20).."=infrastructure_delineator_wrapper_right.png", + "[combine:32x32:0,"..tostring(12 + i * 8).."=infrastructure_delineator_wrapper_left.png:0,"..tostring(i * 8 - 20).."=infrastructure_delineator_wrapper_left.png", + "[combine:32x32:0,"..tostring(12 + i * 8).."=infrastructure_delineator_retroreflector_yellow.png:0,"..tostring(i * 8 - 20).."=infrastructure_delineator_retroreflector_yellow.png", + "[combine:32x32:0,"..tostring(12 + i * 8).."=infrastructure_delineator_retroreflector_red.png:0,"..tostring(i * 8 - 20).."=infrastructure_delineator_retroreflector_red.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 3, not_in_creative_inventory = 1}, + light_source = DELINEATOR_LIGHT_RANGE, + sunlight_propagates = true, + drop = "infrastructure:delineator_guardrail", + node_box = { + type = "fixed", + fixed = { + {-1/8, -3/8 - i/4, -1/32, 1/8, 1/8 - i/4, 1/32}, + {1/8, -5/8 - i/4, -1/16, 3/16, -1/4 - i/4, 1/16} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/8, -3/8 - i/4, -1/32, 1/8, 1/8 - i/4, 1/32}, + {1/8, -5/8 - i/4, -1/16, 3/16, -1/4 - i/4, 1/16} + } + } + }) + end + +-- Wire rope safety barrier + minetest.register_node("infrastructure:wire_rope_safety_barrier", { + description = "Wire rope safety barrier", + tiles = { + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_wire_rope_safety_barrier_back.png", + "infrastructure_wire_rope_safety_barrier_front.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2}, + light_source = 1, + node_box = { + type = "fixed", + fixed = { + {-1/8, -1/2, -1/16, 1/8, -1/4, 1/16}, + {-1/8, -1/2, -1/16, -1/16, -3/16, 1/16}, + {1/16, -1/2, -1/16, 1/8, 1/16, 1/16}, + {-1/8, -1/8, -1/16, 1/8, 0, 1/16}, + {-1/8, -1/8, -1/16, -1/16, 1/2, 1/16}, + {-1/8, 1/8, -1/16, 1/8, 1/4, 1/16}, + {1/16, 1/8, -1/16, 1/8, 1/2, 1/16}, + + {-1/32, 1/4, -1/2, 1/32, 5/16, 1/2}, + {-1/32, 0, -1/2, 1/32, 1/16, 1/2}, + {-1/32, -1/4, -1/2, 1/32, -3/16, 1/2} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/8, -1/2, -1/16, 1/8, 1/2, 1/16}, + + {-1/32, 1/4, -1/2, 1/32, 5/16, 1/2}, + {-1/32, 0, -1/2, 1/32, 1/16, 1/2}, + {-1/32, -1/4, -1/2, 1/32, -3/16, 1/2} + } + }, + + after_place_node = function(pos, placer) + displacement(pos, placer) + end + }) + + for i = 1, 3 do + minetest.register_node("infrastructure:wire_rope_safety_barrier_displacement_"..tostring(i), { + tiles = { + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_galvanized_steel.png:0,"..tostring(i * 8 - 32).."=infrastructure_galvanized_steel.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_galvanized_steel.png:0,"..tostring(i * 8 - 32).."=infrastructure_galvanized_steel.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_wire_rope_safety_barrier_back.png:0,"..tostring(i * 8 - 32).."=infrastructure_wire_rope_safety_barrier_back.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_wire_rope_safety_barrier_front.png:0,"..tostring(i * 8 - 32).."=infrastructure_wire_rope_safety_barrier_front.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2, not_in_creative_inventory = 1}, + light_source = 1, + drop = "infrastructure:wire_rope_safety_barrier", + node_box = { + type = "fixed", + fixed = { + {-1/8, -1/2 - i/4, -1/16, 1/8, -1/4 - i/4, 1/16}, + {-1/8, -1/2 - i/4, -1/16, -1/16, -3/16 - i/4, 1/16}, + {1/16, -1/2 - i/4, -1/16, 1/8, 1/16 - i/4, 1/16}, + {-1/8, -1/8 - i/4, -1/16, 1/8, 0 - i/4, 1/16}, + {-1/8, -1/8 - i/4, -1/16, -1/16, 1/2 - i/4, 1/16}, + {-1/8, 1/8 - i/4, -1/16, 1/8, 1/4 - i/4, 1/16}, + {1/16, 1/8 - i/4, -1/16, 1/8, 1/2 - i/4, 1/16}, + + {-1/32, 1/4 - i/4, -1/2, 1/32, 5/16 - i/4, 1/2}, + {-1/32, 0 - i/4, -1/2, 1/32, 1/16 - i/4, 1/2}, + {-1/32, -1/4 - i/4, -1/2, 1/32, -3/16 - i/4, 1/2} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/8, -1/2 - i/4, -1/16, 1/8, 1/2 - i/4, 1/16}, + + {-1/32, 1/4 - i/4, -1/2, 1/32, 5/16 - i/4, 1/2}, + {-1/32, 0 - i/4, -1/2, 1/32, 1/16 - i/4, 1/2}, + {-1/32, -1/4 - i/4, -1/2, 1/32, -3/16 - i/4, 1/2} + } + } + }) + end + +-- Cable barrier terminal + minetest.register_node("infrastructure:cable_barrier_terminal", { + description = "Cable barrier terminal", + tiles = { + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_cable_barrier_terminal_back.png", + "infrastructure_cable_barrier_terminal_front.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2}, + light_source = 1, + node_box = { + type = "fixed", + fixed = { + {-1/4, -1/2, -1/2, 1/4, -3/8, 1/2}, + {-1/4, -3/8, -1/4, 1/4, 1/2, -1/8}, + {-1/4, -3/8, -1/8, -3/16, 0, 1/8}, + {3/16, -3/8, -1/8, 1/4, 0, 1/8}, + + {-1/16, 7/32, -3/8, 1/16, 11/32, 1/4}, + {-1/16, -1/32, -3/8, 1/16, 3/32, 1/4}, + {-1/16, -9/32, -3/8, 1/16, -5/32, 1/4}, + + {-1/32, 1/4, 0, 1/32, 5/16, 1/2}, + {-1/32, 0, 0, 1/32, 1/16, 1/2}, + {-1/32, -1/4, 0, 1/32, -3/16, 1/2} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/4, -1/2, -1/2, 1/4, -3/8, 1/2}, + {-1/4, -3/8, -1/4, 1/4, 1/2, -1/8}, + {-1/4, -3/8, -1/8, -3/16, 0, 1/8}, + {3/16, -3/8, -1/8, 1/4, 0, 1/8}, + + {-1/16, 7/32, -3/8, 1/16, 11/32, 1/4}, + {-1/16, -1/32, -3/8, 1/16, 3/32, 1/4}, + {-1/16, -9/32, -3/8, 1/16, -5/32, 1/4}, + + {-1/32, 1/4, 0, 1/32, 5/16, 1/2}, + {-1/32, 0, 0, 1/32, 1/16, 1/2}, + {-1/32, -1/4, 0, 1/32, -3/16, 1/2} + } + }, + + after_place_node = function(pos, placer) + displacement(pos, placer) + end + }) + + for i = 1, 3 do + minetest.register_node("infrastructure:cable_barrier_terminal_displacement_"..tostring(i), { + tiles = { + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_galvanized_steel.png:0,"..tostring(i * 8 - 32).."=infrastructure_galvanized_steel.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_galvanized_steel.png:0,"..tostring(i * 8 - 32).."=infrastructure_galvanized_steel.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_cable_barrier_terminal_back.png:0,"..tostring(i * 8 - 32).."=infrastructure_cable_barrier_terminal_back.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_cable_barrier_terminal_front.png:0,"..tostring(i * 8 - 32).."=infrastructure_cable_barrier_terminal_front.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2, not_in_creative_inventory = 1}, + light_source = 1, + drop = "infrastructure:cable_barrier_terminal", + node_box = { + type = "fixed", + fixed = { + {-1/4, -1/2 - i/4, -1/2, 1/4, -3/8 - i/4, 1/2}, + {-1/4, -3/8 - i/4, -1/4, 1/4, 1/2 - i/4, -1/8}, + {-1/4, -3/8 - i/4, -1/8, -3/16, 0 - i/4, 1/8}, + {3/16, -3/8 - i/4, -1/8, 1/4, 0 - i/4, 1/8}, + + {-1/16, 7/32 - i/4, -3/8, 1/16, 11/32 - i/4, 1/4}, + {-1/16, -1/32 - i/4, -3/8, 1/16, 3/32 - i/4, 1/4}, + {-1/16, -9/32 - i/4, -3/8, 1/16, -5/32 - i/4, 1/4}, + + {-1/32, 1/4 - i/4, 0, 1/32, 5/16 - i/4, 1/2}, + {-1/32, 0 - i/4, 0, 1/32, 1/16 - i/4, 1/2}, + {-1/32, -1/4 - i/4, 0, 1/32, -3/16 - i/4, 1/2} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/4, -1/2 - i/4, -1/2, 1/4, -3/8 - i/4, 1/2}, + {-1/4, -3/8 - i/4, -1/4, 1/4, 1/2 - i/4, -1/8}, + {-1/4, -3/8 - i/4, -1/8, -3/16, 0 - i/4, 1/8}, + {3/16, -3/8 - i/4, -1/8, 1/4, 0 - i/4, 1/8}, + + {-1/16, 7/32 - i/4, -3/8, 1/16, 11/32 - i/4, 1/4}, + {-1/16, -1/32 - i/4, -3/8, 1/16, 3/32 - i/4, 1/4}, + {-1/16, -9/32 - i/4, -3/8, 1/16, -5/32 - i/4, 1/4}, + + {-1/32, 1/4 - i/4, 0, 1/32, 5/16 - i/4, 1/2}, + {-1/32, 0 - i/4, 0, 1/32, 1/16 - i/4, 1/2}, + {-1/32, -1/4 - i/4, 0, 1/32, -3/16 - i/4, 1/2} + } + } + }) + end + +-- Corrugated guide rail + minetest.register_node("infrastructure:corrugated_guide_rail", { + description = "Corrugated guide rail", + tiles = { + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_corrugated_guide_rail_side.png", + "infrastructure_corrugated_guide_rail_side.png", + "infrastructure_corrugated_guide_rail_back.png", + "infrastructure_corrugated_guide_rail_front.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2}, + light_source = 1, + node_box = { + type = "fixed", + fixed = { + {-1/8, -1/2, -1/8, 1/8, 1/2, -1/16}, + {-1/16, -1/2, -1/16, 1/16, 1/2, 1/16}, + {-1/8, -1/2, 1/16, 1/8, 1/2, 1/8}, + + {-1/2, 1/4, -1/4, 1/2, 3/8, -1/8}, + {-1/2, 1/8, -3/8, 1/2, 1/4, -1/4}, + {-1/2, 0, -1/4, 1/2, 1/8, -1/8}, + {-1/2, -1/8, -3/8, 1/2, 0, -1/4}, + {-1/2, -1/4, -1/4, 1/2, -1/8, -1/8} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/8, -1/2, -1/8, 1/8, 1/2, 1/8}, + + {-1/2, 1/4, -1/4, 1/2, 3/8, -1/8}, + {-1/2, 1/8, -3/8, 1/2, 1/4, -1/4}, + {-1/2, 0, -1/4, 1/2, 1/8, -1/8}, + {-1/2, -1/8, -3/8, 1/2, 0, -1/4}, + {-1/2, -1/4, -1/4, 1/2, -1/8, -1/8} + } + }, + + after_place_node = function(pos, placer) + displacement(pos, placer) + end + }) + + for i = 1, 3 do + minetest.register_node("infrastructure:corrugated_guide_rail_displacement_"..tostring(i), { + tiles = { + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_corrugated_guide_rail_side.png:0,"..tostring(i * 8 - 32).."=infrastructure_corrugated_guide_rail_side.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_corrugated_guide_rail_side.png:0,"..tostring(i * 8 - 32).."=infrastructure_corrugated_guide_rail_side.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_corrugated_guide_rail_back.png:0,"..tostring(i * 8 - 32).."=infrastructure_corrugated_guide_rail_back.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_corrugated_guide_rail_front.png:0,"..tostring(i * 8 - 32).."=infrastructure_corrugated_guide_rail_front.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2, not_in_creative_inventory = 1}, + light_source = 1, + drop = "infrastructure:corrugated_guide_rail", + node_box = { + type = "fixed", + fixed = { + {-1/8, -1/2 - i/4, -1/8, 1/8, 1/2 - i/4, -1/16}, + {-1/16, -1/2 - i/4, -1/16, 1/16, 1/2 - i/4, 1/16}, + {-1/8, -1/2 - i/4, 1/16, 1/8, 1/2 - i/4, 1/8}, + + {-1/2, 1/4 - i/4, -1/4, 1/2, 3/8 - i/4, -1/8}, + {-1/2, 1/8 - i/4, -3/8, 1/2, 1/4 - i/4, -1/4}, + {-1/2, 0 - i/4, -1/4, 1/2, 1/8 - i/4, -1/8}, + {-1/2, -1/8 - i/4, -3/8, 1/2, 0 - i/4, -1/4}, + {-1/2, -1/4 - i/4, -1/4, 1/2, -1/8 - i/4, -1/8} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/8, -1/2 - i/4, -1/8, 1/8, 1/2 - i/4, 1/8}, + + {-1/2, 1/4 - i/4, -1/4, 1/2, 3/8 - i/4, -1/8}, + {-1/2, 1/8 - i/4, -3/8, 1/2, 1/4 - i/4, -1/4}, + {-1/2, 0 - i/4, -1/4, 1/2, 1/8 - i/4, -1/8}, + {-1/2, -1/8 - i/4, -3/8, 1/2, 0 - i/4, -1/4}, + {-1/2, -1/4 - i/4, -1/4, 1/2, -1/8 - i/4, -1/8} + } + } + }) + end + +-- Energy absorbing terminal + minetest.register_node("infrastructure:energy_absorbing_terminal", { + description = "Energy absorbing terminal", + tiles = { + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_energy_absorbing_terminal_back.png", + "infrastructure_energy_absorbing_terminal_front.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2}, + light_source = ENERGY_ABSORBING_TERMINAL_LIGHT_RANGE, + node_box = { + type = "fixed", + fixed = { + {-1/2, -1/4, 1/8, 0, 1/2, 1/4}, + {-3/8, -1/4, 1/4, -1/8, 3/8, 1/2} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/2, -1/4, 1/8, 0, 1/2, 1/4}, + {-3/8, -1/4, 1/4, -1/8, 3/8, 1/2} + } + }, + + after_place_node = function(pos, placer) + displacement(pos, placer) + end + }) + + minetest.register_node("infrastructure:energy_absorbing_terminal_inversed", { + description = "Energy absorbing terminal inversed", + tiles = { + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_energy_absorbing_terminal_back.png", + "infrastructure_energy_absorbing_terminal_front.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2}, + light_source = ENERGY_ABSORBING_TERMINAL_LIGHT_RANGE, + node_box = { + type = "fixed", + fixed = { + {0, -1/4, 1/8, 1/2, 1/2, 1/4}, + {1/8, -1/4, 1/4, 3/8, 3/8, 1/2} + } + }, + selection_box = { + type = "fixed", + fixed = { + {0, -1/4, 1/8, 1/2, 1/2, 1/4}, + {1/8, -1/4, 1/4, 3/8, 3/8, 1/2} + } + }, + + after_place_node = function(pos, placer) + displacement(pos, placer) + end + }) + + for i = 1, 3 do + minetest.register_node("infrastructure:energy_absorbing_terminal_displacement_"..tostring(i), { + tiles = { + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_galvanized_steel.png:0,"..tostring(i * 8 - 32).."=infrastructure_galvanized_steel.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_galvanized_steel.png:0,"..tostring(i * 8 - 32).."=infrastructure_galvanized_steel.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_energy_absorbing_terminal_back.png:0,"..tostring(i * 8 - 32).."=infrastructure_energy_absorbing_terminal_back.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_energy_absorbing_terminal_front.png:0,"..tostring(i * 8 - 32).."=infrastructure_energy_absorbing_terminal_front.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2, not_in_creative_inventory = 1}, + light_source = ENERGY_ABSORBING_TERMINAL_LIGHT_RANGE, + drop = "infrastructure:energy_absorbing_terminal", + node_box = { + type = "fixed", + fixed = { + {-1/2, -1/4 - i/4, 1/8, 0, 1/2 - i/4, 1/4}, + {-3/8, -1/4 - i/4, 1/4, -1/8, 3/8 - i/4, 1/2} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/2, -1/4 - i/4, 1/8, 0, 1/2 - i/4, 1/4}, + {-3/8, -1/4 - i/4, 1/4, -1/8, 3/8 - i/4, 1/2} + } + } + }) + + minetest.register_node("infrastructure:energy_absorbing_terminal_inversed_displacement_"..tostring(i), { + tiles = { + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_galvanized_steel.png:0,"..tostring(i * 8 - 32).."=infrastructure_galvanized_steel.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_galvanized_steel.png:0,"..tostring(i * 8 - 32).."=infrastructure_galvanized_steel.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_energy_absorbing_terminal_back.png:0,"..tostring(i * 8 - 32).."=infrastructure_energy_absorbing_terminal_back.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_energy_absorbing_terminal_front.png:0,"..tostring(i * 8 - 32).."=infrastructure_energy_absorbing_terminal_front.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2, not_in_creative_inventory = 1}, + light_source = ENERGY_ABSORBING_TERMINAL_LIGHT_RANGE, + drop = "infrastructure:energy_absorbing_terminal_inversed", + node_box = { + type = "fixed", + fixed = { + {0, -1/4 - i/4, 1/8, 1/2, 1/2 - i/4, 1/4}, + {1/8, -1/4 - i/4, 1/4, 3/8, 3/8 - i/4, 1/2} + } + }, + selection_box = { + type = "fixed", + fixed = { + {0, -1/4 - i/4, 1/8, 1/2, 1/2 - i/4, 1/4}, + {1/8, -1/4 - i/4, 1/4, 3/8, 3/8 - i/4, 1/2} + } + } + }) + end + +-- Fitch barrel + minetest.register_node("infrastructure:fitch_barrel", { + description = "Fitch barrel", + tiles = { + "infrastructure_fitch_barrel_top.png", + "infrastructure_fitch_barrel_bottom.png", + "infrastructure_fitch_barrel_side.png", + "infrastructure_fitch_barrel_side.png", + "infrastructure_fitch_barrel_side.png", + "infrastructure_fitch_barrel_side.png" + }, + drawtype = "nodebox", + paramtype = "light", + groups = {cracky = 2}, + light_source = ENERGY_ABSORBING_TERMINAL_LIGHT_RANGE, + node_box = { + type = "fixed", + fixed = {-3/8, -1/2, -3/8, 3/8, 1/2, 3/8} + }, + selection_box = { + type = "fixed", + fixed = {-3/8, -1/2, -3/8, 3/8, 1/2, 3/8} + }, + + after_place_node = function(pos, placer) + displacement(pos, placer) + end + }) + + for i = 1, 3 do + minetest.register_node("infrastructure:fitch_barrel_displacement_"..tostring(i), { + tiles = { + "infrastructure_fitch_barrel_top.png", + "infrastructure_fitch_barrel_bottom.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_fitch_barrel_side.png:0,"..tostring(i * 8 - 32).."=infrastructure_fitch_barrel_side.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_fitch_barrel_side.png:0,"..tostring(i * 8 - 32).."=infrastructure_fitch_barrel_side.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_fitch_barrel_side.png:0,"..tostring(i * 8 - 32).."=infrastructure_fitch_barrel_side.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_fitch_barrel_side.png:0,"..tostring(i * 8 - 32).."=infrastructure_fitch_barrel_side.png" + }, + drawtype = "nodebox", + paramtype = "light", + groups = {cracky = 2, not_in_creative_inventory = 1}, + light_source = ENERGY_ABSORBING_TERMINAL_LIGHT_RANGE, + drop = "infrastructure:fitch_barrel", + node_box = { + type = "fixed", + fixed = {-3/8, -1/2 - i/4, -3/8, 3/8, 1/2 - i/4, 3/8} + }, + selection_box = { + type = "fixed", + fixed = {-3/8, -1/2 - i/4, -3/8, 3/8, 1/2 - i/4, 3/8} + } + }) + end + +-- Crowd control barricade + minetest.register_node("infrastructure:crowd_control_barricade", { + description = "Crowd control barricade", + tiles = { + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_crowd_control_barricade_back.png", + "infrastructure_crowd_control_barricade_front.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2}, + light_source = 1, + node_box = { + type = "fixed", + fixed = { + {-1/2, -1/4, 0, 1/2, 1/2, 0}, + + {-7/16, -1/2, -1/32, -3/8, 1/8, 1/32}, + {3/8, -1/2, -1/32, 7/16, 1/8, 1/32}, + + {-7/16, -1/2, -1/4, -3/8, -7/16, 1/4}, + {3/8, -1/2, -1/4, 7/16, -7/16, 1/4} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/2, -1/4, 0, 1/2, 1/2, 0}, + + {-7/16, -1/2, -1/32, -3/8, 1/8, 1/32}, + {3/8, -1/2, -1/32, 7/16, 1/8, 1/32}, + + {-7/16, -1/2, -1/4, -3/8, -7/16, 1/4}, + {3/8, -1/2, -1/4, 7/16, -7/16, 1/4} + } + }, + + after_place_node = function(pos, placer) + displacement(pos, placer) + end + }) + + for i = 1, 3 do + minetest.register_node("infrastructure:crowd_control_barricade_"..tostring(i), { + tiles = { + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_crowd_control_barricade_back.png:0,"..tostring(i * 8 - 32).."=infrastructure_crowd_control_barricade_back.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_crowd_control_barricade_front.png:0,"..tostring(i * 8 - 32).."=infrastructure_crowd_control_barricade_front.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2, not_in_creative_inventory = 1}, + light_source = 1, + drop = "infrastructure:crowd_control_barricade", + node_box = { + type = "fixed", + fixed = { + {-1/2, -1/4 - i/4, 0, 1/2, 1/2 - i/4, 0}, + + {-7/16, -1/2 - i/4, -1/32, -3/8, 1/8 - i/4, 1/32}, + {3/8, -1/2 - i/4, -1/32, 7/16, 1/8 - i/4, 1/32}, + + {-7/16, -1/2 - i/4, -1/4, -3/8, -7/16 - i/4, 1/4}, + {3/8, -1/2 - i/4, -1/4, 7/16, -7/16 - i/4, 1/4} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/2, -1/4 - i/4, 0, 1/2, 1/2 - i/4, 0}, + + {-7/16, -1/2 - i/4, -1/32, -3/8, 1/8 - i/4, 1/32}, + {3/8, -1/2 - i/4, -1/32, 7/16, 1/8 - i/4, 1/32}, + + {-7/16, -1/2 - i/4, -1/4, -3/8, -7/16 - i/4, 1/4}, + {3/8, -1/2 - i/4, -1/4, 7/16, -7/16 - i/4, 1/4} + } + } + }) + end + +-- Anti-dazzling panel + minetest.register_node("infrastructure:anti_dazzling_panel", { + description = "Anti-dazzling panel", + tiles = { + "infrastructure_anti_dazzling_panel_top_bottom.png", + "infrastructure_anti_dazzling_panel_top_bottom.png", + "infrastructure_anti_dazzling_panel_side.png", + "infrastructure_anti_dazzling_panel_side.png", + "infrastructure_anti_dazzling_panel_side.png", + "infrastructure_anti_dazzling_panel_side.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2}, + light_source = 1, + node_box = { + type = "fixed", + fixed = { + {-1/4, -1/2, 0, 1/4, 1/2, 0}, + {-1/8, -1/2, -1/16, 1/8, -3/8, 1/16} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/4, -1/2, 0, 1/4, 1/2, 0}, + {-1/8, -1/2, -1/16, 1/8, -3/8, 1/16} + } + }, + + after_place_node = function(pos, placer) + displacement(pos, placer) + end + }) + + for i = 1, 3 do + minetest.register_node("infrastructure:anti_dazzling_panel_displacement_"..tostring(i), { + tiles = { + "infrastructure_anti_dazzling_panel_top_bottom.png", + "infrastructure_anti_dazzling_panel_top_bottom.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_anti_dazzling_panel_side.png:0,"..tostring(i * 8 - 32).."=infrastructure_anti_dazzling_panel_side.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_anti_dazzling_panel_side.png:0,"..tostring(i * 8 - 32).."=infrastructure_anti_dazzling_panel_side.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_anti_dazzling_panel_side.png:0,"..tostring(i * 8 - 32).."=infrastructure_anti_dazzling_panel_side.png", + "[combine:32x32:0,"..tostring(i * 8).."=infrastructure_anti_dazzling_panel_side.png:0,"..tostring(i * 8 - 32).."=infrastructure_anti_dazzling_panel_side.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2, not_in_creative_inventory = 1}, + light_source = 1, + drop = "infrastructure:anti_dazzling_panel", + node_box = { + type = "fixed", + fixed = { + {-1/4, -1/2 - i/4, 0, 1/4, 1/2 - i/4, 0}, + {-1/8, -1/2 - i/4, -1/16, 1/8, -3/8 - i/4, 1/16} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/4, -1/2 - i/4, 0, 1/4, 1/2 - i/4, 0}, + {-1/8, -1/2 - i/4, -1/16, 1/8, -3/8 - i/4, 1/16} + } + } + }) + end + +-- Traffic cone + + local cbox = { + type = "fixed", + fixed = { -0.25, -0.5, -0.25, 0.25, 0.4065, 0.25 } + } + + minetest.register_node("infrastructure:traffic_cone", { + description = "Traffic cone", + tiles = { "infrastructure_traffic_cone.png" }, + drawtype = "mesh", + mesh = "infrastructure_traffic_cone.obj", + paramtype = "light", + groups = {cracky = 2}, + walkable = false, + light_source = ENERGY_ABSORBING_TERMINAL_LIGHT_RANGE, + collision_box = cbox, + selection_box = cbox, + after_place_node = function(pos, placer) + displacement(pos, placer) + end + }) + + for i = 1, 3 do + + local cbox = { + type = "fixed", + fixed = { -0.25, -0.5 - i/4, -0.25, 0.25, 0.4065 - i/4, 0.25 } + } + + minetest.register_node("infrastructure:traffic_cone_displacement_"..tostring(i), { + tiles = { "infrastructure_traffic_cone.png" }, + drawtype = "mesh", + mesh = "infrastructure_traffic_cone_i"..i..".obj", + paramtype = "light", + groups = {cracky = 2, not_in_creative_inventory = 1}, + walkable = false, + light_source = ENERGY_ABSORBING_TERMINAL_LIGHT_RANGE, + drop = "infrastructure:traffic_cone", + collision_box = cbox, + selection_box = cbox, + }) + end + +-- Noise barrier + minetest.register_node("infrastructure:noise_barrier", { + description = "Noise barrier", + tiles = { + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_galvanized_steel.png", + "infrastructure_noise_barrier.png", + "infrastructure_noise_barrier.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2}, + light_source = 1, + node_box = { + type = "fixed", + fixed = { + {-1/2, -1/2, 5/16, 1/2, 1/2, 7/16}, + + {-1/2, -1/2, 1/4, 1/2, -7/16, 1/2}, + {-1/2, 7/16, 1/4, 1/2, 1/2, 1/2}, + {-1/2, -1/2, 1/4, -7/16, 1/2, 1/2}, + {7/16, -1/2, 1/4, 1/2, 1/2, 1/2} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-1/2, -1/2, 1/4, 1/2, 1/2, 1/2}, + } + } + }) + diff --git a/mods/roads/infrastructure/nodes_extension.lua b/mods/roads/infrastructure/nodes_extension.lua new file mode 100644 index 0000000..2e4d548 --- /dev/null +++ b/mods/roads/infrastructure/nodes_extension.lua @@ -0,0 +1,163 @@ +--[[-- **************************************************************************************************** MATERIALS + +-- Galvanized steel stair, slab, panel and microblock + register_stair_slab_panel_micro("infrastructure", "galvanized_steel", "infrastructure:galvanized_steel", + {not_in_creative_inventory=NOT_IN_CREATIVE_INVENTORY, cracky=2}, + {"infrastructure_galvanized_steel.png"}, + "Galvanized steel", + "galvanized_steel", + 0) + +-- **************************************************************************************************** CENTER LINES + +-- Asphalt stair, slab, panel and microblock with center solid line + register_stair_slab_panel_micro("infrastructure", "asphalt_center_solid_line", "infrastructure:asphalt_center_solid_line", + {not_in_creative_inventory=NOT_IN_CREATIVE_INVENTORY, cracky=1}, + { + "streets_asphalt.png^infrastructure_single_yellow_line.png", + "streets_asphalt.png", + "streets_asphalt.png", + "streets_asphalt.png", + "streets_asphalt.png", + "streets_asphalt.png" + }, + "Asphalt with center solid line", + "asphalt_center_solid_line", + 0) + +-- Asphalt stair, slab, panel and microblock with center solid line on one side + register_stair_slab_panel_micro("infrastructure", "asphalt_center_solid_one_side", "infrastructure:asphalt_center_solid_one_side", + {not_in_creative_inventory=NOT_IN_CREATIVE_INVENTORY, cracky=1}, + { + "streets_asphalt.png^infrastructure_solid_yellow_line_one_side.png", + "streets_asphalt.png", + "streets_asphalt.png", + "streets_asphalt.png", + "streets_asphalt.png", + "streets_asphalt.png" + }, + "Asphalt with center solid line on one side", + "asphalt_center_solid_one_side", + 0) + +-- Asphalt stair, slab, panel and microblock with center solid double line + register_stair_slab_panel_micro("infrastructure", "asphalt_center_solid_double", "infrastructure:asphalt_center_solid_double", + {not_in_creative_inventory=NOT_IN_CREATIVE_INVENTORY, cracky=1}, + { + "streets_asphalt.png^infrastructure_double_yellow_line.png", + "streets_asphalt.png", + "streets_asphalt.png", + "streets_asphalt.png", + "streets_asphalt.png", + "streets_asphalt.png" + }, + "Asphalt with center solid double line", + "asphalt_center_solid_double", + 0) + +-- Asphalt block with center corner single line + register_stair_slab_panel_micro("infrastructure", "asphalt_center_corner_single", "infrastructure:asphalt_center_corner_single", + {not_in_creative_inventory=NOT_IN_CREATIVE_INVENTORY, cracky=1}, + { + "streets_asphalt.png^infrastructure_single_yellow_line_corner.png", + "streets_asphalt.png", + "streets_asphalt.png", + "streets_asphalt.png", + "streets_asphalt.png", + "streets_asphalt.png" + }, + "Asphalt with center corner single line", + "asphalt_center_corner_single", + 0) + +-- Asphalt block with center corner double line + register_stair_slab_panel_micro("infrastructure", "asphalt_center_corner_double", "infrastructure:asphalt_center_corner_double", + {not_in_creative_inventory=NOT_IN_CREATIVE_INVENTORY, cracky=1}, + { + "streets_asphalt.png^infrastructure_solid_double_yellow_line_corner.png", + "streets_asphalt.png", + "streets_asphalt.png", + "streets_asphalt.png", + "streets_asphalt.png", + "streets_asphalt.png" + }, + "Asphalt with center corner double line", + "asphalt_center_corner_double", + 0) + +-- **************************************************************************************************** TRAFFIC MARKS + +-- Asphalt stair, slab, panel and microblock with arrow straight + register_stair_slab_panel_micro("infrastructure", "asphalt_arrow_straight", "infrastructure:asphalt_arrow_straight", + {not_in_creative_inventory=NOT_IN_CREATIVE_INVENTORY, cracky=1}, + {"streets_arrow_straight.png", "infrastructure_asphalt.png"}, + "Asphalt with arrow straight", + "asphalt_arrow_straight", + 0) + +-- Asphalt stair, slab, panel and microblock with arrow straight + left + register_stair_slab_panel_micro("infrastructure", "asphalt_arrow_straight_left", "infrastructure:asphalt_arrow_straight_left", + {not_in_creative_inventory=NOT_IN_CREATIVE_INVENTORY, cracky=1}, + {"streets_asphalt.png^streets_arrow_straight_left.png", "infrastructure_asphalt.png"}, + "Asphalt with arrow straight + left", + "asphalt_arrow_straight_left", + 0) + +-- Asphalt stair, slab, panel and microblock with arrow straight + right + register_stair_slab_panel_micro("infrastructure", "asphalt_arrow_straight_right", "infrastructure:asphalt_arrow_straight_right", + {not_in_creative_inventory=NOT_IN_CREATIVE_INVENTORY, cracky=1}, + {"streets_asphalt.png^streets_arrow_straight_right.png", "infrastructure_asphalt.png"}, + "Asphalt with arrow straight + right", + "asphalt_arrow_straight_right", + 0) + +-- Asphalt stair, slab, panel and microblock with arrow left + register_stair_slab_panel_micro("infrastructure", "asphalt_arrow_left", "infrastructure:asphalt_arrow_left", + {not_in_creative_inventory=NOT_IN_CREATIVE_INVENTORY, cracky=1}, + {"streets_asphalt.png^streets_arrow_left.png", "infrastructure_asphalt.png"}, + "Asphalt with arrow left", + "asphalt_arrow_left", + 0) + +-- Asphalt stair, slab, panel and microblock with arrow right + register_stair_slab_panel_micro("infrastructure", "asphalt_arrow_right", "infrastructure:asphalt_arrow_right", + {not_in_creative_inventory=NOT_IN_CREATIVE_INVENTORY, cracky=1}, + {"streets_asphalt.png^streets_arrow_right.png", "infrastructure_asphalt.png"}, + "Asphalt with arrow right", + "asphalt_arrow_right", + 0) + +-- Asphalt stair, slab, panel and microblock with "P"-sign + register_stair_slab_panel_micro("infrastructure", "asphalt_parking", "infrastructure:asphalt_parking", + {not_in_creative_inventory=NOT_IN_CREATIVE_INVENTORY, cracky=1}, + {"streets_asphalt.png^streets_parking.png", "infrastructure_asphalt.png"}, + "Asphalt with a parking sign", + "asphalt_parking", + 0) + +-- Register known infrastructure nodes in circular saw if avaiable + if circular_saw then + for i,v in ipairs({ +-- Materials + "asphalt", + "concrete", + "galvanized_steel", +-- Center lines + "asphalt_center_dashed", + "asphalt_center_solid", + "asphalt_center_solid_one_side", + "asphalt_center_solid_double", + "asphalt_center_corner_single", + "asphalt_center_corner_double", +-- Traffic marks + "asphalt_arrow_straight", + "asphalt_arrow_straight_left", + "asphalt_arrow_straight_right", + "asphalt_arrow_left", + "asphalt_arrow_right", + "asphalt_parking" + }) do + table.insert(circular_saw.known_stairs, "infrastructure:"..v); + end + end +]]-- \ No newline at end of file diff --git a/mods/roads/infrastructure/settings.lua b/mods/roads/infrastructure/settings.lua new file mode 100644 index 0000000..7778d7b --- /dev/null +++ b/mods/roads/infrastructure/settings.lua @@ -0,0 +1,49 @@ +-- This file stores all settings for the "Infrastructure mod" + +-- Stairs, slabs, panels and microblocks + NOT_IN_CREATIVE_INVENTORY = 1 -- an integer 0 or 1 -> default = 1 | Do you want it to be hide in your creative inventory? + +-- Raised pavement marker + MARKER_LIGHT_RANGE = 4 -- an integer -> default = 4 | How much light do you want it to give? + +-- Retroreflective delineator + DELINEATOR_LIGHT_RANGE = 8 -- an integer -> default = 8 | How much light do you want it to give? + +-- Energy absorbing terminal + ENERGY_ABSORBING_TERMINAL_LIGHT_RANGE = 8 -- an integer -> default = 8 | How much light do you want it to give? + +-- Emergency phone + ENABLE_EMERGENCY_PHONE = true -- true or false -> default = true | Do you want it to be enabled in your game? + HEALTH_TO_TRIGGER = 5 -- an integer -> default = 5 | When will the player be healed? How low must his health be? + HEALTH_TO_RESTORING = 10 -- an integer -> default = 10 | To what will the health be set? + EMERGENCY_PHONE_LIGHT_RANGE = 12 -- an integer -> default = 12 | How much light do you want it to give? + EMERGENCY_PHONE_VOLUME = 0.1 -- a float -> default = 0.1 | How noisy should be the dialing sound? + +-- Traffic lights + TRAFFIC_LIGHTS_LIGHT_RANGE = 12 -- an integer -> default = 12 | How much light do you want it to give? + TRAFFIC_LIGHTS_VOLUME = 0 -- a float -> default = 0.1 | How noisy should be the beep sound? + +-- Automatic warning device + AUTOMATIC_WARNING_DEVICE_LIGHT_RANGE = 12 -- an integer -> default = 12 | How much light do you want it to give? + AUTOMATIC_WARNING_DEVICE_VOLUME = 0.5 -- a float -> default = 0.5 | How noisy should be the bell sound? + +-- Boom barrier + BOOM_BARRIER_LIGHT_RANGE = 6 -- an integer -> default = 6 | How much light do you want it to give? + BOOM_BARRIER_VOLUME = 0.4 -- a float -> default = 0.1 | How noisy should be the mechanism sound? + +-- Curve chevron + CURVE_CHEVRON_LIGHT_RANGE = 12 -- an integer -> default = 12 | How much light do you want it to give? + +-- Crosswalk lighting + CROSSWALK_LIGHTING_LIGHT_RANGE = 14 -- an integer -> default = 14 | How much light do you want it to give? + +-- Crosswalk safety sign + CROSSWALK_SAFETY_SIGN_LIGHT_RANGE = 8 -- an integer -> default = 8 | How much light do you want it to give? + +-- Crosswalk safety sign + RETROREFLECTIVE_SURFACE_LIGHT_RANGE = 8 -- an integer -> default = 8 | How much light do you want it to give? + +-- Aircraft warning light + AIRCRAFT_WARNING_LIGHT_LIGHT_RANGE = 14 -- an integer -> default = 14 | How much light do you want it to give? +-- Warning light + WARNING_LIGHT_LIGHT_RANGE = 14 -- an integer -> default = 14 | How much light do you want it to give? diff --git a/mods/roads/infrastructure/sounds/infrastructure_automatic_warning_device.ogg b/mods/roads/infrastructure/sounds/infrastructure_automatic_warning_device.ogg new file mode 100644 index 0000000..71d1679 Binary files /dev/null and b/mods/roads/infrastructure/sounds/infrastructure_automatic_warning_device.ogg differ diff --git a/mods/roads/infrastructure/sounds/infrastructure_boom_barrier.ogg b/mods/roads/infrastructure/sounds/infrastructure_boom_barrier.ogg new file mode 100644 index 0000000..4106df2 Binary files /dev/null and b/mods/roads/infrastructure/sounds/infrastructure_boom_barrier.ogg differ diff --git a/mods/roads/infrastructure/sounds/infrastructure_ebell.ogg b/mods/roads/infrastructure/sounds/infrastructure_ebell.ogg new file mode 100644 index 0000000..d59d1b9 Binary files /dev/null and b/mods/roads/infrastructure/sounds/infrastructure_ebell.ogg differ diff --git a/mods/roads/infrastructure/sounds/infrastructure_emergency_phone.ogg b/mods/roads/infrastructure/sounds/infrastructure_emergency_phone.ogg new file mode 100644 index 0000000..7e84eb2 Binary files /dev/null and b/mods/roads/infrastructure/sounds/infrastructure_emergency_phone.ogg differ diff --git a/mods/roads/infrastructure/sounds/infrastructure_traffic_lights_1.ogg b/mods/roads/infrastructure/sounds/infrastructure_traffic_lights_1.ogg new file mode 100644 index 0000000..d790e9a Binary files /dev/null and b/mods/roads/infrastructure/sounds/infrastructure_traffic_lights_1.ogg differ diff --git a/mods/roads/infrastructure/sounds/infrastructure_traffic_lights_2.ogg b/mods/roads/infrastructure/sounds/infrastructure_traffic_lights_2.ogg new file mode 100644 index 0000000..8fa7753 Binary files /dev/null and b/mods/roads/infrastructure/sounds/infrastructure_traffic_lights_2.ogg differ diff --git a/mods/roads/infrastructure/textures/infrastructure_aircraft_warning_light_side_anim.png b/mods/roads/infrastructure/textures/infrastructure_aircraft_warning_light_side_anim.png new file mode 100644 index 0000000..40c1558 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_aircraft_warning_light_side_anim.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_aircraft_warning_light_top_anim.png b/mods/roads/infrastructure/textures/infrastructure_aircraft_warning_light_top_anim.png new file mode 100644 index 0000000..8f223dc Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_aircraft_warning_light_top_anim.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_anti_dazzling_panel_side.png b/mods/roads/infrastructure/textures/infrastructure_anti_dazzling_panel_side.png new file mode 100644 index 0000000..5965006 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_anti_dazzling_panel_side.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_anti_dazzling_panel_top_bottom.png b/mods/roads/infrastructure/textures/infrastructure_anti_dazzling_panel_top_bottom.png new file mode 100644 index 0000000..0f257bd Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_anti_dazzling_panel_top_bottom.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_asphalt.png b/mods/roads/infrastructure/textures/infrastructure_asphalt.png new file mode 100644 index 0000000..2906a0d Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_asphalt.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device.png b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device.png new file mode 100644 index 0000000..d5f6c62 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_bottom.png b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_bottom.png new file mode 100644 index 0000000..87ddf0c Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_bottom.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle.png b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle.png new file mode 100644 index 0000000..5185a29 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_center_anim.png b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_center_anim.png new file mode 100644 index 0000000..575ebca Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_center_anim.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_center_off.png b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_center_off.png new file mode 100644 index 0000000..ac85b26 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_center_off.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_center_side.png b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_center_side.png new file mode 100644 index 0000000..7c50472 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_center_side.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_left_anim.png b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_left_anim.png new file mode 100644 index 0000000..6d6851b Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_left_anim.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_left_off.png b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_left_off.png new file mode 100644 index 0000000..3acc761 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_left_off.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_left_side.png b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_left_side.png new file mode 100644 index 0000000..8d73676 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_left_side.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_right_anim.png b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_right_anim.png new file mode 100644 index 0000000..5517f0d Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_right_anim.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_right_off.png b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_right_off.png new file mode 100644 index 0000000..d3e378a Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_right_off.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_right_side.png b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_right_side.png new file mode 100644 index 0000000..cb6a9bc Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_right_side.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_side.png b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_side.png new file mode 100644 index 0000000..469addf Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_middle_side.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_top.png b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_top.png new file mode 100644 index 0000000..a9fb96f Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_top.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_top_side.png b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_top_side.png new file mode 100644 index 0000000..49412ec Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_automatic_warning_device_top_side.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_h_anim_darkfirst.png b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_h_anim_darkfirst.png new file mode 100644 index 0000000..70b1cd3 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_h_anim_darkfirst.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_h_anim_lightfirst.png b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_h_anim_lightfirst.png new file mode 100644 index 0000000..ea7368e Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_h_anim_lightfirst.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_h_bottom_front_back.png b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_h_bottom_front_back.png new file mode 100644 index 0000000..e283612 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_h_bottom_front_back.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_h_left_right_bright.png b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_h_left_right_bright.png new file mode 100644 index 0000000..0e6e50c Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_h_left_right_bright.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_h_top.png b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_h_top.png new file mode 100644 index 0000000..5f997a4 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_h_top.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_v_left.png b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_v_left.png new file mode 100644 index 0000000..87b3bbb Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_v_left.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_v_right.png b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_v_right.png new file mode 100644 index 0000000..c777597 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_arm_v_right.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_boom_barrier_h_bottom.png b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_h_bottom.png new file mode 100644 index 0000000..c7fbfea Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_h_bottom.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_boom_barrier_h_front_back.png b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_h_front_back.png new file mode 100644 index 0000000..5d019fc Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_h_front_back.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_boom_barrier_h_left.png b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_h_left.png new file mode 100644 index 0000000..08348fb Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_h_left.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_boom_barrier_h_right.png b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_h_right.png new file mode 100644 index 0000000..5399be8 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_h_right.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_boom_barrier_h_top.png b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_h_top.png new file mode 100644 index 0000000..7796232 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_h_top.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_boom_barrier_v_bottom.png b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_v_bottom.png new file mode 100644 index 0000000..9ae9ed3 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_v_bottom.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_boom_barrier_v_front_back.png b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_v_front_back.png new file mode 100644 index 0000000..d7b7a3b Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_v_front_back.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_boom_barrier_v_left.png b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_v_left.png new file mode 100644 index 0000000..4ddd606 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_v_left.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_boom_barrier_v_right.png b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_v_right.png new file mode 100644 index 0000000..91c5600 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_boom_barrier_v_right.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_cable_barrier_terminal_back.png b/mods/roads/infrastructure/textures/infrastructure_cable_barrier_terminal_back.png new file mode 100644 index 0000000..5f90cf2 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_cable_barrier_terminal_back.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_cable_barrier_terminal_front.png b/mods/roads/infrastructure/textures/infrastructure_cable_barrier_terminal_front.png new file mode 100644 index 0000000..607f6d9 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_cable_barrier_terminal_front.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_concrete.png b/mods/roads/infrastructure/textures/infrastructure_concrete.png new file mode 100644 index 0000000..3be0c52 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_concrete.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_corrugated_guide_rail_back.png b/mods/roads/infrastructure/textures/infrastructure_corrugated_guide_rail_back.png new file mode 100644 index 0000000..d7aaf99 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_corrugated_guide_rail_back.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_corrugated_guide_rail_front.png b/mods/roads/infrastructure/textures/infrastructure_corrugated_guide_rail_front.png new file mode 100644 index 0000000..c3a7b37 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_corrugated_guide_rail_front.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_corrugated_guide_rail_side.png b/mods/roads/infrastructure/textures/infrastructure_corrugated_guide_rail_side.png new file mode 100644 index 0000000..739e6de Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_corrugated_guide_rail_side.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_corrugated_sheet.png b/mods/roads/infrastructure/textures/infrastructure_corrugated_sheet.png new file mode 100644 index 0000000..9b6bef4 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_corrugated_sheet.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_crosswalk_lighting_back.png b/mods/roads/infrastructure/textures/infrastructure_crosswalk_lighting_back.png new file mode 100644 index 0000000..fd73443 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_crosswalk_lighting_back.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_crosswalk_lighting_bottom.png b/mods/roads/infrastructure/textures/infrastructure_crosswalk_lighting_bottom.png new file mode 100644 index 0000000..f6f5db9 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_crosswalk_lighting_bottom.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_crosswalk_lighting_front.png b/mods/roads/infrastructure/textures/infrastructure_crosswalk_lighting_front.png new file mode 100644 index 0000000..38e6188 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_crosswalk_lighting_front.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_crosswalk_safety_sign.png b/mods/roads/infrastructure/textures/infrastructure_crosswalk_safety_sign.png new file mode 100644 index 0000000..b20ca91 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_crosswalk_safety_sign.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_crosswalk_safety_sign_bottom_front_back.png b/mods/roads/infrastructure/textures/infrastructure_crosswalk_safety_sign_bottom_front_back.png new file mode 100644 index 0000000..2ff6832 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_crosswalk_safety_sign_bottom_front_back.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_crosswalk_safety_sign_bottom_side.png b/mods/roads/infrastructure/textures/infrastructure_crosswalk_safety_sign_bottom_side.png new file mode 100644 index 0000000..9e7c58c Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_crosswalk_safety_sign_bottom_side.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_crosswalk_safety_sign_top.png b/mods/roads/infrastructure/textures/infrastructure_crosswalk_safety_sign_top.png new file mode 100644 index 0000000..6ba1c7b Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_crosswalk_safety_sign_top.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_crosswalk_safety_sign_top_front_back.png b/mods/roads/infrastructure/textures/infrastructure_crosswalk_safety_sign_top_front_back.png new file mode 100644 index 0000000..f115876 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_crosswalk_safety_sign_top_front_back.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_crosswalk_safety_sign_top_side.png b/mods/roads/infrastructure/textures/infrastructure_crosswalk_safety_sign_top_side.png new file mode 100644 index 0000000..9db3518 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_crosswalk_safety_sign_top_side.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_crosswalk_warning_light_back.png b/mods/roads/infrastructure/textures/infrastructure_crosswalk_warning_light_back.png new file mode 100644 index 0000000..51d024b Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_crosswalk_warning_light_back.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_crosswalk_warning_light_front_anim.png b/mods/roads/infrastructure/textures/infrastructure_crosswalk_warning_light_front_anim.png new file mode 100644 index 0000000..a21529f Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_crosswalk_warning_light_front_anim.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_crosswalk_warning_light_front_bright.png b/mods/roads/infrastructure/textures/infrastructure_crosswalk_warning_light_front_bright.png new file mode 100644 index 0000000..3525a3c Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_crosswalk_warning_light_front_bright.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_crosswalk_warning_light_front_dark.png b/mods/roads/infrastructure/textures/infrastructure_crosswalk_warning_light_front_dark.png new file mode 100644 index 0000000..357bda3 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_crosswalk_warning_light_front_dark.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_crowd_control_barricade_back.png b/mods/roads/infrastructure/textures/infrastructure_crowd_control_barricade_back.png new file mode 100644 index 0000000..edde3ec Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_crowd_control_barricade_back.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_crowd_control_barricade_front.png b/mods/roads/infrastructure/textures/infrastructure_crowd_control_barricade_front.png new file mode 100644 index 0000000..72b7b77 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_crowd_control_barricade_front.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_curve_chevron_left_bright.png b/mods/roads/infrastructure/textures/infrastructure_curve_chevron_left_bright.png new file mode 100644 index 0000000..199751f Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_curve_chevron_left_bright.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_curve_chevron_left_dark.png b/mods/roads/infrastructure/textures/infrastructure_curve_chevron_left_dark.png new file mode 100644 index 0000000..f7d68f5 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_curve_chevron_left_dark.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_curve_chevron_right_bright.png b/mods/roads/infrastructure/textures/infrastructure_curve_chevron_right_bright.png new file mode 100644 index 0000000..d1bae78 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_curve_chevron_right_bright.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_curve_chevron_right_dark.png b/mods/roads/infrastructure/textures/infrastructure_curve_chevron_right_dark.png new file mode 100644 index 0000000..b8f442f Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_curve_chevron_right_dark.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_delineator_retroreflector_red.png b/mods/roads/infrastructure/textures/infrastructure_delineator_retroreflector_red.png new file mode 100644 index 0000000..b2d4336 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_delineator_retroreflector_red.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_delineator_retroreflector_yellow.png b/mods/roads/infrastructure/textures/infrastructure_delineator_retroreflector_yellow.png new file mode 100644 index 0000000..b6fe651 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_delineator_retroreflector_yellow.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_delineator_wrapper_left.png b/mods/roads/infrastructure/textures/infrastructure_delineator_wrapper_left.png new file mode 100644 index 0000000..a4d0edd Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_delineator_wrapper_left.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_delineator_wrapper_right.png b/mods/roads/infrastructure/textures/infrastructure_delineator_wrapper_right.png new file mode 100644 index 0000000..2743183 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_delineator_wrapper_right.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_drainage_channel_grating.png b/mods/roads/infrastructure/textures/infrastructure_drainage_channel_grating.png new file mode 100644 index 0000000..d805557 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_drainage_channel_grating.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_emergency_phone_bottom.png b/mods/roads/infrastructure/textures/infrastructure_emergency_phone_bottom.png new file mode 100644 index 0000000..8106816 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_emergency_phone_bottom.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_emergency_phone_front.png b/mods/roads/infrastructure/textures/infrastructure_emergency_phone_front.png new file mode 100644 index 0000000..1153717 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_emergency_phone_front.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_emergency_phone_side.png b/mods/roads/infrastructure/textures/infrastructure_emergency_phone_side.png new file mode 100644 index 0000000..930437c Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_emergency_phone_side.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_emergency_phone_top.png b/mods/roads/infrastructure/textures/infrastructure_emergency_phone_top.png new file mode 100644 index 0000000..2ff4038 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_emergency_phone_top.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_energy_absorbing_terminal_back.png b/mods/roads/infrastructure/textures/infrastructure_energy_absorbing_terminal_back.png new file mode 100644 index 0000000..6264bd5 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_energy_absorbing_terminal_back.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_energy_absorbing_terminal_front.png b/mods/roads/infrastructure/textures/infrastructure_energy_absorbing_terminal_front.png new file mode 100644 index 0000000..cd20a40 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_energy_absorbing_terminal_front.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_fitch_barrel_bottom.png b/mods/roads/infrastructure/textures/infrastructure_fitch_barrel_bottom.png new file mode 100644 index 0000000..7664b97 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_fitch_barrel_bottom.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_fitch_barrel_side.png b/mods/roads/infrastructure/textures/infrastructure_fitch_barrel_side.png new file mode 100644 index 0000000..7471830 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_fitch_barrel_side.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_fitch_barrel_top.png b/mods/roads/infrastructure/textures/infrastructure_fitch_barrel_top.png new file mode 100644 index 0000000..223e119 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_fitch_barrel_top.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_galvanized_steel.png b/mods/roads/infrastructure/textures/infrastructure_galvanized_steel.png new file mode 100644 index 0000000..841e68b Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_galvanized_steel.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_grid_paver_bottom.png b/mods/roads/infrastructure/textures/infrastructure_grid_paver_bottom.png new file mode 100644 index 0000000..de051cf Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_grid_paver_bottom.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_grid_paver_grass.png b/mods/roads/infrastructure/textures/infrastructure_grid_paver_grass.png new file mode 100644 index 0000000..87bae79 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_grid_paver_grass.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_grid_paver_top.png b/mods/roads/infrastructure/textures/infrastructure_grid_paver_top.png new file mode 100644 index 0000000..da54206 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_grid_paver_top.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_lane_control_lights_1.png b/mods/roads/infrastructure/textures/infrastructure_lane_control_lights_1.png new file mode 100644 index 0000000..e2c5d16 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_lane_control_lights_1.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_lane_control_lights_2.png b/mods/roads/infrastructure/textures/infrastructure_lane_control_lights_2.png new file mode 100644 index 0000000..913572a Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_lane_control_lights_2.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_lane_control_lights_3.png b/mods/roads/infrastructure/textures/infrastructure_lane_control_lights_3.png new file mode 100644 index 0000000..ffe4e01 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_lane_control_lights_3.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_lane_control_lights_4.png b/mods/roads/infrastructure/textures/infrastructure_lane_control_lights_4.png new file mode 100644 index 0000000..6b24780 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_lane_control_lights_4.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_lane_control_lights_5.png b/mods/roads/infrastructure/textures/infrastructure_lane_control_lights_5.png new file mode 100644 index 0000000..1a8afcb Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_lane_control_lights_5.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_lane_control_lights_6.png b/mods/roads/infrastructure/textures/infrastructure_lane_control_lights_6.png new file mode 100644 index 0000000..0838d91 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_lane_control_lights_6.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_manhole_cover_side.png b/mods/roads/infrastructure/textures/infrastructure_manhole_cover_side.png new file mode 100644 index 0000000..11bf08e Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_manhole_cover_side.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_manhole_cover_top_bottom.png b/mods/roads/infrastructure/textures/infrastructure_manhole_cover_top_bottom.png new file mode 100644 index 0000000..4338a82 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_manhole_cover_top_bottom.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_marker_bottom_side.png b/mods/roads/infrastructure/textures/infrastructure_marker_bottom_side.png new file mode 100644 index 0000000..6cf3e60 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_marker_bottom_side.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_marker_side_red.png b/mods/roads/infrastructure/textures/infrastructure_marker_side_red.png new file mode 100644 index 0000000..5a5ae22 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_marker_side_red.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_marker_side_yellow.png b/mods/roads/infrastructure/textures/infrastructure_marker_side_yellow.png new file mode 100644 index 0000000..a3a439d Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_marker_side_yellow.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_marker_top_red_yellow.png b/mods/roads/infrastructure/textures/infrastructure_marker_top_red_yellow.png new file mode 100644 index 0000000..afebd88 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_marker_top_red_yellow.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_marker_top_yellow_yellow.png b/mods/roads/infrastructure/textures/infrastructure_marker_top_yellow_yellow.png new file mode 100644 index 0000000..de9d4d6 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_marker_top_yellow_yellow.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_noise_barrier.png b/mods/roads/infrastructure/textures/infrastructure_noise_barrier.png new file mode 100644 index 0000000..a52a243 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_noise_barrier.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_razor_wire.png b/mods/roads/infrastructure/textures/infrastructure_razor_wire.png new file mode 100644 index 0000000..49309e9 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_razor_wire.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_riffled_sheet.png b/mods/roads/infrastructure/textures/infrastructure_riffled_sheet.png new file mode 100644 index 0000000..072d31c Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_riffled_sheet.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_road_sign_crosswalk_back.png b/mods/roads/infrastructure/textures/infrastructure_road_sign_crosswalk_back.png new file mode 100644 index 0000000..590e65d Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_road_sign_crosswalk_back.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_road_sign_crosswalk_front.png b/mods/roads/infrastructure/textures/infrastructure_road_sign_crosswalk_front.png new file mode 100644 index 0000000..78b5dce Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_road_sign_crosswalk_front.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_road_sign_retroreflective_surface.png b/mods/roads/infrastructure/textures/infrastructure_road_sign_retroreflective_surface.png new file mode 100644 index 0000000..f9c95c1 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_road_sign_retroreflective_surface.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_road_sign_right_of_way_back.png b/mods/roads/infrastructure/textures/infrastructure_road_sign_right_of_way_back.png new file mode 100644 index 0000000..a98467f Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_road_sign_right_of_way_back.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_road_sign_right_of_way_front.png b/mods/roads/infrastructure/textures/infrastructure_road_sign_right_of_way_front.png new file mode 100644 index 0000000..0f52f69 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_road_sign_right_of_way_front.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_road_sign_stop_back.png b/mods/roads/infrastructure/textures/infrastructure_road_sign_stop_back.png new file mode 100644 index 0000000..d87b178 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_road_sign_stop_back.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_road_sign_stop_front.png b/mods/roads/infrastructure/textures/infrastructure_road_sign_stop_front.png new file mode 100644 index 0000000..dcb628d Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_road_sign_stop_front.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_road_sign_yield_back.png b/mods/roads/infrastructure/textures/infrastructure_road_sign_yield_back.png new file mode 100644 index 0000000..d934905 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_road_sign_yield_back.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_road_sign_yield_front.png b/mods/roads/infrastructure/textures/infrastructure_road_sign_yield_front.png new file mode 100644 index 0000000..caad0cc Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_road_sign_yield_front.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_cone.png b/mods/roads/infrastructure/textures/infrastructure_traffic_cone.png new file mode 100644 index 0000000..b4ae9a5 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_cone.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_cone_bottom.png b/mods/roads/infrastructure/textures/infrastructure_traffic_cone_bottom.png new file mode 100644 index 0000000..c9a5137 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_cone_bottom.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_cone_side.png b/mods/roads/infrastructure/textures/infrastructure_traffic_cone_side.png new file mode 100644 index 0000000..ec5a939 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_cone_side.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_cone_top.png b/mods/roads/infrastructure/textures/infrastructure_traffic_cone_top.png new file mode 100644 index 0000000..b744dc1 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_cone_top.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians.png new file mode 100644 index 0000000..9cd1470 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_bottom_back.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_bottom_back.png new file mode 100644 index 0000000..357011d Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_bottom_back.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_bottom_front_1.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_bottom_front_1.png new file mode 100644 index 0000000..a689dc4 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_bottom_front_1.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_bottom_front_2.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_bottom_front_2.png new file mode 100644 index 0000000..a689dc4 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_bottom_front_2.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_bottom_front_3.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_bottom_front_3.png new file mode 100644 index 0000000..7729d96 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_bottom_front_3.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_bottom_front_4.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_bottom_front_4.png new file mode 100644 index 0000000..7729d96 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_bottom_front_4.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_top_back.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_top_back.png new file mode 100644 index 0000000..708d59b Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_top_back.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_top_front_1.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_top_front_1.png new file mode 100644 index 0000000..737c426 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_top_front_1.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_top_front_2.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_top_front_2.png new file mode 100644 index 0000000..737c426 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_top_front_2.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_top_front_3.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_top_front_3.png new file mode 100644 index 0000000..8d22856 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_top_front_3.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_top_front_4.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_top_front_4.png new file mode 100644 index 0000000..8d22856 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_pedestrians_top_front_4.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_side.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_side.png new file mode 100644 index 0000000..01076e3 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_side.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles.png new file mode 100644 index 0000000..393422a Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_bottom_1.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_bottom_1.png new file mode 100644 index 0000000..4cbb75b Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_bottom_1.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_bottom_2.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_bottom_2.png new file mode 100644 index 0000000..c81f500 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_bottom_2.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_bottom_3.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_bottom_3.png new file mode 100644 index 0000000..f55108c Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_bottom_3.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_bottom_4.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_bottom_4.png new file mode 100644 index 0000000..c81f500 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_bottom_4.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_top_1.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_top_1.png new file mode 100644 index 0000000..116ae46 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_top_1.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_top_2.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_top_2.png new file mode 100644 index 0000000..4a57e89 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_top_2.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_top_3.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_top_3.png new file mode 100644 index 0000000..9dab2ea Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_top_3.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_top_4.png b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_top_4.png new file mode 100644 index 0000000..ddc2364 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_traffic_lights_vehicles_top_4.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_truss.png b/mods/roads/infrastructure/textures/infrastructure_truss.png new file mode 100644 index 0000000..ba628f1 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_truss.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_warning_light_back.png b/mods/roads/infrastructure/textures/infrastructure_warning_light_back.png new file mode 100644 index 0000000..0301aee Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_warning_light_back.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_warning_light_bottom.png b/mods/roads/infrastructure/textures/infrastructure_warning_light_bottom.png new file mode 100644 index 0000000..e7090a0 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_warning_light_bottom.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_warning_light_front_anim.png b/mods/roads/infrastructure/textures/infrastructure_warning_light_front_anim.png new file mode 100644 index 0000000..601725b Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_warning_light_front_anim.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_warning_light_left.png b/mods/roads/infrastructure/textures/infrastructure_warning_light_left.png new file mode 100644 index 0000000..e519af4 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_warning_light_left.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_warning_light_right.png b/mods/roads/infrastructure/textures/infrastructure_warning_light_right.png new file mode 100644 index 0000000..4bd42dc Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_warning_light_right.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_warning_light_top.png b/mods/roads/infrastructure/textures/infrastructure_warning_light_top.png new file mode 100644 index 0000000..898ed0f Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_warning_light_top.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_wire_netting.png b/mods/roads/infrastructure/textures/infrastructure_wire_netting.png new file mode 100644 index 0000000..506eda7 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_wire_netting.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_wire_rope_safety_barrier_back.png b/mods/roads/infrastructure/textures/infrastructure_wire_rope_safety_barrier_back.png new file mode 100644 index 0000000..31418f3 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_wire_rope_safety_barrier_back.png differ diff --git a/mods/roads/infrastructure/textures/infrastructure_wire_rope_safety_barrier_front.png b/mods/roads/infrastructure/textures/infrastructure_wire_rope_safety_barrier_front.png new file mode 100644 index 0000000..3e46bd1 Binary files /dev/null and b/mods/roads/infrastructure/textures/infrastructure_wire_rope_safety_barrier_front.png differ diff --git a/mods/roads/license.txt b/mods/roads/license.txt new file mode 100644 index 0000000..fa53ac9 --- /dev/null +++ b/mods/roads/license.txt @@ -0,0 +1,60 @@ +THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. + +BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. + +1. Definitions + + "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License. + "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined below) for the purposes of this License. + "Creative Commons Compatible License" means a license that is listed at http://creativecommons.org/compatiblelicenses that has been approved by Creative Commons as being essentially equivalent to this License, including, at a minimum, because that license: (i) contains terms that have the same purpose, meaning and effect as the License Elements of this License; and, (ii) explicitly permits the relicensing of adaptations of works made available under that license under this License or a Creative Commons jurisdiction license with the same License Elements as this License. + "Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership. + "License Elements" means the following high-level license attributes as selected by Licensor and indicated in the title of this License: Attribution, ShareAlike. + "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License. + "Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast. + "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work. + "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation. + "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images. + "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium. + +2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws. + +3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below: + + to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections; + to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified."; + to Distribute and Publicly Perform the Work including as incorporated in Collections; and, + to Distribute and Publicly Perform Adaptations. + + For the avoidance of doubt: + Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; + Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and, + Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License. + +The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved. + +4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: + + You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(c), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(c), as requested. + You may Distribute or Publicly Perform an Adaptation only under the terms of: (i) this License; (ii) a later version of this License with the same License Elements as this License; (iii) a Creative Commons jurisdiction license (either this or a later license version) that contains the same License Elements as this License (e.g., Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons Compatible License. If you license the Adaptation under one of the licenses mentioned in (iv), you must comply with the terms of that license. If you license the Adaptation under the terms of any of the licenses mentioned in (i), (ii) or (iii) (the "Applicable License"), you must comply with the terms of the Applicable License generally and the following provisions: (I) You must include a copy of, or the URI for, the Applicable License with every copy of each Adaptation You Distribute or Publicly Perform; (II) You may not offer or impose any terms on the Adaptation that restrict the terms of the Applicable License or the ability of the recipient of the Adaptation to exercise the rights granted to that recipient under the terms of the Applicable License; (III) You must keep intact all notices that refer to the Applicable License and to the disclaimer of warranties with every copy of the Work as included in the Adaptation You Distribute or Publicly Perform; (IV) when You Distribute or Publicly Perform the Adaptation, You may not impose any effective technological measures on the Adaptation that restrict the ability of a recipient of the Adaptation from You to exercise the rights granted to that recipient under the terms of the Applicable License. This Section 4(b) applies to the Adaptation as incorporated in a Collection, but this does not require the Collection apart from the Adaptation itself to be made subject to the terms of the Applicable License. + If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Ssection 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4(c) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties. + Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise. + +5. Representations, Warranties and Disclaimer + +UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. + +6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. Termination + + This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. + Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above. + +8. Miscellaneous + + Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License. + Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License. + If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent. + This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You. + The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law. diff --git a/mods/roads/manholes/depends.txt b/mods/roads/manholes/depends.txt new file mode 100644 index 0000000..421a27d --- /dev/null +++ b/mods/roads/manholes/depends.txt @@ -0,0 +1 @@ +streetsmod \ No newline at end of file diff --git a/mods/roads/manholes/init.lua b/mods/roads/manholes/init.lua new file mode 100644 index 0000000..b9a2f40 --- /dev/null +++ b/mods/roads/manholes/init.lua @@ -0,0 +1,88 @@ +--[[ + StreetsMod: Manholes in asphalt +]] +minetest.register_node(":streets:manhole",{ + description = streets.S("Simple manhole"), + tiles = {"streets_asphalt.png^streets_manhole.png","streets_asphalt.png"}, + groups = {cracky=3} +}) + +minetest.register_node(":streets:manhole_adv_closed",{ + description = streets.S("Advanced manhole"), + tiles = {"streets_asphalt.png^streets_manhole_advanced.png","streets_asphalt.png"}, + groups = {cracky=3}, + drawtype = "nodebox", + paramtype = "light", + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = { + --Walls + {-0.5,-0.5,-0.5,-0.3,0.5,0.5}, + {-0.5,-0.5,-0.5,0.5,0.5,-0.3}, + {0.3,-0.5,-0.5,0.5,0.5,0.5}, + {-0.5,-0.5,0.3,0.5,0.5,0.5}, + --Cover + {-0.5,0.4,-0.1,0.5,0.5,0.1}, + {-0.1,0.4,-0.5,0.1,0.5,0.5}, + {-0.2,0.4,-0.2,0.2,0.5,0.2} + } + }, + selection_box = { + type = "regular", + }, + on_rightclick = function(pos,node,clicker) + minetest.set_node(pos,{name="streets:manhole_adv_open"}) + end +}) +minetest.register_node(":streets:manhole_adv_open",{ + description = streets.S("Advanced manhole"), + tiles = {"streets_asphalt.png^streets_manhole_advanced.png","streets_asphalt.png"}, + groups = {cracky=3,not_in_creative_inventory=1}, + drawtype = "nodebox", + paramtype = "light", + drop = "streets:manhole_adv_closed", + climbable = true, + walkable = false, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = { + --Walls + {-0.5,-0.5,-0.5,-0.3,0.5,0.5}, + {-0.5,-0.5,-0.5,0.5,0.5,-0.3}, + {0.3,-0.5,-0.5,0.5,0.5,0.5}, + {-0.5,-0.5,0.3,0.5,0.5,0.5}, + } + }, + selection_box = { + type = "fixed", + fixed = { + --Walls + {-0.5,-0.5,-0.5,-0.3,0.5,0.5}, + {-0.5,-0.5,-0.5,0.5,0.5,-0.3}, + {0.3,-0.5,-0.5,0.5,0.5,0.5}, + {-0.5,-0.5,0.3,0.5,0.5,0.5}, + } + }, + on_rightclick = function(pos,node,clicker) + minetest.set_node(pos,{name="streets:manhole_adv_closed"}) + end +}) + +minetest.register_craft({ + output = "streets:manhole_adv_closed 2", + recipe = { + {"streets:asphalt", "default:steel_ingot", "streets:asphalt"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"streets:asphalt", "default:steel_ingot", "streets:asphalt"} + } +}) +minetest.register_craft({ + output = "streets:manhole 3", + recipe = { + {"streets:asphalt", "streets:asphalt", "streets:asphalt"}, + {"streets:asphalt", "default:steel_ingot", "streets:asphalt"}, + {"streets:asphalt", "streets:asphalt", "streets:asphalt"} + } +}) \ No newline at end of file diff --git a/mods/roads/modpack.conf b/mods/roads/modpack.conf new file mode 100644 index 0000000..33d6a06 --- /dev/null +++ b/mods/roads/modpack.conf @@ -0,0 +1,5 @@ +release = 769 +author = cheapie +name = roads +description = Advanced modern road infastructure (fork) +title = Roads diff --git a/mods/roads/modpack.txt b/mods/roads/modpack.txt new file mode 100644 index 0000000..48abf62 --- /dev/null +++ b/mods/roads/modpack.txt @@ -0,0 +1 @@ +This file indicates that the current folder is a modpack. Please also read readme.txt for more information. \ No newline at end of file diff --git a/mods/roads/readme.txt b/mods/roads/readme.txt new file mode 100644 index 0000000..99cf703 Binary files /dev/null and b/mods/roads/readme.txt differ diff --git a/mods/roads/roadsigns/depends.txt b/mods/roads/roadsigns/depends.txt new file mode 100644 index 0000000..042430d --- /dev/null +++ b/mods/roads/roadsigns/depends.txt @@ -0,0 +1 @@ +streetsmod? diff --git a/mods/roads/roadsigns/init.lua b/mods/roads/roadsigns/init.lua new file mode 100644 index 0000000..5664188 --- /dev/null +++ b/mods/roads/roadsigns/init.lua @@ -0,0 +1,41 @@ +--[[ + StreetsMod: Poles and signs +]] +streets.workshop = {} + +streets.workshop.register_sign = function(nodename, desc, img, rrecipe, rtime) + + minetest.register_node(nodename,{ + description = desc, + tiles = {img}, + inventory_image = img, + wield_image = img, + groups = {snappy = 1,attached_node = 1}, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", desc) + end, + drawtype = "nodebox", + node_box = { + type = "wallmounted", + fixed = { + {-0.4,-0.5,-0.4,0.4,-0.4,0.4} + } + }, + paramtype = "light", + paramtype2 = "wallmounted", + walkable = false, + sunlight_propagates = true, + selection_box = { + type = "wallmounted" + }, + streets = { + signworkshop = { + recipe = rrecipe, + time = rtime + } + } + }) +end + +dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/signs.lua") diff --git a/mods/roads/roadsigns/signs.lua b/mods/roads/roadsigns/signs.lua new file mode 100644 index 0000000..9b8b129 --- /dev/null +++ b/mods/roads/roadsigns/signs.lua @@ -0,0 +1,17 @@ +-- example: streets.workshop.register_sign(nodename, desc, img, recipe, time) +streets.workshop.register_sign(":streets:sign_blank", streets.S("Empty sign"), "streets_sign_back.png", {"default:steel_ingot","","",""}, 3) + +streets.workshop.register_sign(":streets:sign_lava", streets.S("Warning sign (lava)"), "streets_sign_lava.png", {"streets:sign_blank","bucket:bucket_lava","",""}, 5) + +streets.workshop.register_sign(":streets:sign_water", streets.S("Warning sign (water)"), "streets_sign_water.png", {"streets:sign_blank","bucket:bucket_water","",""}, 5) + +streets.workshop.register_sign(":streets:sign_construction", streets.S("Warning sign (Construction area)"), "streets_sign_construction.png", {"streets:sign_blank","default:dirt","",""}, 5) + + +streets.workshop.register_sign(":streets:sign_mine", streets.S("Notice sign (Public Mine Ahead)"), "streets_sign_mine.png", {"streets:sign_blank","default:dirt","",""}, 5) + +streets.workshop.register_sign(":streets:sign_shop", streets.S("Notice sign (Shop/Mall Ahead)"), "streets_sign_shop.png", {"streets:sign_blank","default:dirt","",""}, 5) + +streets.workshop.register_sign(":streets:sign_workshop", streets.S("Notice sign (Public Workshop Ahead)"), "streets_sign_workshop.png", {"streets:sign_blank","default:dirt","",""}, 5) + +streets.workshop.register_sign(":streets:sign_grasswalk", streets.S("Warning sign (No walking on the grass)"), "streets_sign_grasswalk.png", {"streets:sign_blank","default:dirt","",""}, 5) diff --git a/mods/roads/steelsupport/depends.txt b/mods/roads/steelsupport/depends.txt new file mode 100644 index 0000000..33c719f --- /dev/null +++ b/mods/roads/steelsupport/depends.txt @@ -0,0 +1,3 @@ +default? +sounds +streetsmod \ No newline at end of file diff --git a/mods/roads/steelsupport/init.lua b/mods/roads/steelsupport/init.lua new file mode 100644 index 0000000..56cc084 --- /dev/null +++ b/mods/roads/steelsupport/init.lua @@ -0,0 +1,20 @@ +--[[ + StreetsMod: Steel support for hanging signs on highways etc. +]] +minetest.register_node(":streets:steel_support",{ + description = streets.S("Steel support"), + tiles = {"streets_support.png"}, + groups = {cracky = 1}, + drawtype = "glasslike_framed", + climbable = true, + sunlight_propagates = true, + paramtype = "light", +}) +minetest.register_craft({ + output = "streets:steel_support 5", + recipe = { + {"default:steel_ingot","","default:steel_ingot"}, + {"","default:steel_ingot",""}, + {"default:steel_ingot","","default:steel_ingot"} + } +}) \ No newline at end of file diff --git a/mods/roads/streetlamps/depends.txt b/mods/roads/streetlamps/depends.txt new file mode 100644 index 0000000..f507470 --- /dev/null +++ b/mods/roads/streetlamps/depends.txt @@ -0,0 +1,3 @@ +default +streetsmod +mesecons? \ No newline at end of file diff --git a/mods/roads/streetlamps/init.lua b/mods/roads/streetlamps/init.lua new file mode 100644 index 0000000..fa99824 --- /dev/null +++ b/mods/roads/streetlamps/init.lua @@ -0,0 +1,128 @@ +--[[ + StreetsMod: Streetlamps +]] +--[[minetest.register_node(":streets:streetlamp_basic_controller",{ + description = streets.S("Trafficlight"), + tiles = {"streets_lampcontroller_top.png","streets_lampcontroller_bottom.png","streets_lampcontroller_sides.png"}, + groups = {cracky = 1, not_in_creative_inventory = 1}, + drawtype = "nodebox", + paramtype = "light", + node_box = { + type = "fixed", + fixed = { + {-0.5,-0.5,-0.5,0.5,0.5,0.5}, + {-0.05,0.5,-0.05,0.05,1.6,0.05} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5,-0.5,-0.5,0.5,0.5,0.5}, + {-0.3,1.5,-0.3,0.3,4.5,0.3} + } + }, + mesecons = { + effector = { + action_on = function(pos,node) + minetest.set_node({x = pos.x, y = pos.y + 4, z = pos.z},{name = "streets:streetlamp_basic_top_on"}) + end, + action_off = function(pos,node) + minetest.set_node({x = pos.x, y = pos.y + 4, z = pos.z},{name = "streets:streetlamp_basic_top_off"}) + end + } + }, + after_dig_node = function(pos) + minetest.remove_node({x = pos.x, y = pos.y + 2, z = pos.z}) + minetest.remove_node({x = pos.x, y = pos.y + 3, z = pos.z}) + minetest.remove_node({x = pos.x, y = pos.y + 4, z = pos.z}) + minetest.chat_send_all("!!!") + end +})]] + +minetest.register_node(":streets:streetlamp_basic_bottom",{ + drop = "", + description = streets.S("Street lamp"), + tiles = {"streets_lamps_basic_bottom.png"}, + inventory_image = "streets_lamps_basi_inv.png", + groups = {cracky = 1}, + paramtype = "light", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.15,-0.5,-0.15,0.15,0.4,0.15}, + {-0.1,0.4,-0.1,0.1,0.5,0.1} + } + }, + pointable = false, + after_place_node = function(pos,placer,itemstack) + minetest.set_node({x = pos.x, y = pos.y + 1, z = pos.z},{name = "streets:streetlamp_basic_middle"}) + minetest.set_node({x = pos.x, y = pos.y + 2, z = pos.z},{name = "streets:streetlamp_basic_top_on"}) + -- minetest.set_node({x = pos.x, y = pos.y - 2, z = pos.z},{name = "streets:streetlamp_basic_controller"}) + end +}) +minetest.register_node(":streets:streetlamp_basic_middle",{ + drop = "", + description = streets.S("U cheater U"), + groups = {cracky = 1, not_in_creative_inventory = 1}, + tiles = {"streets_lamps_basic_middle.png"}, + paramtype = "light", + drawtype = "nodebox", + pointable = false, + node_box = { + type = "fixed", + fixed = { + {-0.1,-0.5,-0.1,0.1,0.5,0.1} + } + } +}) +--[[minetest.register_node(":streets:streetlamp_basic_top_off",{ + drop = "", + description = streets.S("U cheater U"), + groups = {cracky = 1, not_in_creative_inventory = 1}, + paramtype = "light", + drawtype = "nodebox", + pointable = false, + node_box = { + type = "fixed", + fixed = { + {-0.1,-0.5,-0.1,0.1,-0.4,0.1}, + {-0.3,-0.4,-0.3,0.3,0.5,0.3} + } + } +})]] +minetest.register_node(":streets:streetlamp_basic_top_on",{ + drop = "streets:streetlamp_basic_bottom", + description = streets.S("U cheater U"), + groups = {cracky = 1, not_in_creative_inventory = 1}, + tiles = {"streets_lamps_basic_top_top.png","streets_lamps_basic_top_top.png","streets_lamps_basic_top.png","streets_lamps_basic_top.png","streets_lamps_basic_top.png","streets_lamps_basic_top.png"}, + paramtype = "light", + drawtype = "nodebox", + light_source = 10, + node_box = { + type = "fixed", + fixed = { + {-0.1,-0.5,-0.1,0.1,-0.4,0.1}, + {-0.3,-0.4,-0.3,0.3,0.5,0.3} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.3,0.5,-0.3,0.3,-2.5,0.3}, + } + }, + after_dig_node = function(pos) + minetest.remove_node({x = pos.x, y = pos.y - 1, z = pos.z}) + minetest.remove_node({x = pos.x, y = pos.y - 2, z = pos.z}) + end +}) + +minetest.register_craft({ + output = "streets:streetlamp_basic_bottom", + recipe = { + {"default:glass","default:torch","default:glass"}, + {"","streets:bigpole",""}, + {"","streets:bigpole",""} + } +}) diff --git a/mods/roads/streetsawards/depends.txt b/mods/roads/streetsawards/depends.txt new file mode 100644 index 0000000..42d368b --- /dev/null +++ b/mods/roads/streetsawards/depends.txt @@ -0,0 +1,2 @@ +streetsmod +awards? \ No newline at end of file diff --git a/mods/roads/streetsawards/init.lua b/mods/roads/streetsawards/init.lua new file mode 100644 index 0000000..fedc768 --- /dev/null +++ b/mods/roads/streetsawards/init.lua @@ -0,0 +1,22 @@ +if streets.extendedBy.awards == true then + awards.register_achievement("award_countryroads",{ + title = "Roadbuilder", + description = "You built some quite big roads!", + icon = "novicebuilder.png", + trigger = { + type = "place", + node = "streets:asphalt", + target = 175, + }, + }) + awards.register_achievement("award_underworld",{ + title = "Start your sewers!", + description = "You placed your first manhole! Did you know that you can open it with a right-click?", + icon = "novicebuilder.png", + trigger = { + type = "place", + node = "streets:manhole_adv_closed", + target = 1, + }, + }) +end \ No newline at end of file diff --git a/mods/roads/streetsconcrete/depends.txt b/mods/roads/streetsconcrete/depends.txt new file mode 100644 index 0000000..6e37c8d --- /dev/null +++ b/mods/roads/streetsconcrete/depends.txt @@ -0,0 +1,3 @@ +sounds +streetsmod +basic_materials? diff --git a/mods/roads/streetsconcrete/init.lua b/mods/roads/streetsconcrete/init.lua new file mode 100644 index 0000000..494157c --- /dev/null +++ b/mods/roads/streetsconcrete/init.lua @@ -0,0 +1,50 @@ +--[[ + StreetsMod: Concrete, Concrete wall (flat), Concrete wall (full) +]] + minetest.register_alias("streets:concrete","basic_materials:concrete_block") + -- Use technic's concrete block for the seperating wall + minetest.register_node(":streets:concrete_wall",{ + description = streets.S("Concrete wall"), + tiles = {"basic_materials_concrete_block.png"}, + groups = {cracky=2}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.4, -0.5, -0.5, 0.4, -0.4, 0.5}, + {-0.1, -0.4, -0.5, 0.1, 0.5, 0.5} + } + } + }) + minetest.register_craft({ + output = "streets:concrete_wall 3", + recipe = { + {"","basic_materials:concrete_block",""}, + {"","basic_materials:concrete_block",""}, + {"basic_materials:concrete_block","basic_materials:concrete_block","basic_materials:concrete_block"} + } + }) + minetest.register_node(":streets:concrete_wall_flat",{ + description = streets.S("Concrete wall"), + tiles = {"basic_materials_concrete_block.png"}, + groups = {cracky=2}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.1, -0.5, -0.5, 0.1, 0.5, 0.5} + } + } + }) + minetest.register_craft({ + output = "streets:concrete_wall_flat 3", + recipe = { + {"","basic_materials:concrete_block",""}, + {"","basic_materials:concrete_block",""}, + {"","",""} + } + }) diff --git a/mods/roads/streetshotfix/depends.txt b/mods/roads/streetshotfix/depends.txt new file mode 100644 index 0000000..421a27d --- /dev/null +++ b/mods/roads/streetshotfix/depends.txt @@ -0,0 +1 @@ +streetsmod \ No newline at end of file diff --git a/mods/roads/streetshotfix/init.lua b/mods/roads/streetshotfix/init.lua new file mode 100644 index 0000000..d9511c2 --- /dev/null +++ b/mods/roads/streetshotfix/init.lua @@ -0,0 +1,9 @@ +--[[ + StreetsMod Hotfixes in order of creation, signed with date +]] +-- Hotfix #1; April 14, 2014; https://github.com/webdesigner97/streets/issues/11 +minetest.register_alias("stairs:stair_asphalt","streets:stair_asphalt") + +-- Hotfix #2; June 27, 2014; https://github.com/webdesigner97/streets/issues/25 +minetest.register_alias("streets:asphalt_stair","streets:stair_asphalt") +minetest.register_alias("streets:asphalt_slab","streets:slab_asphalt") \ No newline at end of file diff --git a/mods/roads/streetsmod/forms.lua b/mods/roads/streetsmod/forms.lua new file mode 100644 index 0000000..c636c85 --- /dev/null +++ b/mods/roads/streetsmod/forms.lua @@ -0,0 +1,4 @@ +-- Form for chatcommand /streets + streets.forms.chatcmd = smartfs.create("streets:chatcmd", function(state) + state:load(streets.modpath .. "/forms/cmd_streets.smartfs") + end) \ No newline at end of file diff --git a/mods/roads/streetsmod/forms/cmd_streets.smartfs b/mods/roads/streetsmod/forms/cmd_streets.smartfs new file mode 100644 index 0000000..3dbd29c --- /dev/null +++ b/mods/roads/streetsmod/forms/cmd_streets.smartfs @@ -0,0 +1 @@ +return { ["ele"] = { ["streets:chatcmd_version"] = { ["type"] = "label", ["pos"] = { ["y"] = 1, ["x"] = 6.5 }, ["name"] = "streets:chatcmd_version", ["value"] = "Running version: 1.4.4dev" }, ["streets:chatcmd_guibg"] = { ["type"] = "code", ["name"] = "streets:chatcmd_guibg", ["code"] = "bgcolor[#080808BB;true]background[5,5;1,1;gui_formbg.png;true]" }, ["streets:chatcmd_modlist"] = { ["pos"] = { ["y"] = 1, ["x"] = 0 }, ["size"] = { ["h"] = 5, ["w"] = 6 }, ["type"] = "list", ["name"] = "streets:chatcmd_modlist", ["items"] = { "digilines installed: false", "mesecons installed: false", "moreblocks installed: false", "wool installed: true", "technic installed: false", "prefab installed: false", "awards installed: false" } } }, ["size"] = { ["h"] = 6, ["w"] = 10 } } \ No newline at end of file diff --git a/mods/roads/streetsmod/init.lua b/mods/roads/streetsmod/init.lua new file mode 100644 index 0000000..c9b78b6 --- /dev/null +++ b/mods/roads/streetsmod/init.lua @@ -0,0 +1,89 @@ +--[[ + StreetsMod 1.5 by webdesigner97: + License : CC-BY-SA 3.0 Unported (see license.txt) + Readme : see readme.txt + Forum : http://bit.ly/12cPMeo + Depends : default +]] +streets = {} + +-- Kaeza intllib + -- Boilerplate to support localized strings if intllib mod is installed. + if minetest.get_modpath("intllib") then + streets.S = intllib.Getter() + else + streets.S = function(s) return s end + end + +-- Create variable and tables + print("Streets: " .. streets.S("Creating variables and tables...")) + streets.version = "1.5" + streets.modpath = minetest.get_modpath("streetsmod") + streets.extendedBy = {} + streets.load = { + start = os.clock(), + fin = 0 + } + streets.forms = {} + +-- rubenwardy: smartfs + if not minetest.get_modpath("smartfs") then + dofile(streets.modpath .. "/libs/smartfs/smartfs.lua") + end + +-- Load forms + dofile(streets.modpath .. "/forms.lua") + +-- Check for mods which change this mod's beahaviour + print("Streets: " .. streets.S("Checking installed mods...")) + if minetest.get_modpath("wool") then + streets.extendedBy.wool = true + else + streets.extendedBy.wool = false + end + if minetest.get_modpath("technic") then + streets.extendedBy.technic = true + else + streets.extendedBy.technic = false + end + if minetest.get_modpath("moreblocks") then + streets.extendedBy.moreblocks = true + else + streets.extendedBy.moreblocks = false + end + if minetest.get_modpath("mesecons") then + streets.extendedBy.mesecons = true + else + streets.extendedBy.mesecons = false + end + if minetest.get_modpath("digilines") then + streets.extendedBy.digilines = true + else + streets.extendedBy.digilines = false + end + if minetest.get_modpath("prefab") then + streets.extendedBy.prefab = true + else + streets.extendedBy.prefab = false + end + if minetest.get_modpath("awards") then + streets.extendedBy.awards = true + else + streets.extendedBy.awards = false + end + +-- Streets chatcommand + local function round(num, idp) + local mult = 10^(idp or 0) + return math.floor(num * mult + 0.5) / mult + end + minetest.register_chatcommand("streets",{ + description = streets.S("Check version of your installed StreetsMod and find information"), + func = function(name,param) + streets.forms.chatcmd:show(name); + end + }) + +-- Done + print("Streets: " .. streets.S("Setup completed, have fun with StreetsMod") .. " " .. streets.version .. "!") + streets.load.fin = os.clock() diff --git a/mods/roads/streetsmod/libs/smartfs/.gitattributes b/mods/roads/streetsmod/libs/smartfs/.gitattributes new file mode 100644 index 0000000..412eeda --- /dev/null +++ b/mods/roads/streetsmod/libs/smartfs/.gitattributes @@ -0,0 +1,22 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp +*.sln merge=union +*.csproj merge=union +*.vbproj merge=union +*.fsproj merge=union +*.dbproj merge=union + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/mods/roads/streetsmod/libs/smartfs/.gitignore b/mods/roads/streetsmod/libs/smartfs/.gitignore new file mode 100644 index 0000000..b9d6bd9 --- /dev/null +++ b/mods/roads/streetsmod/libs/smartfs/.gitignore @@ -0,0 +1,215 @@ +################# +## Eclipse +################# + +*.pydevproject +.project +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + + +################# +## Visual Studio +################# + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results + +[Dd]ebug/ +[Rr]elease/ +x64/ +build/ +[Bb]in/ +[Oo]bj/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.log +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml +*.pubxml + +# NuGet Packages Directory +## TODO: If you have NuGet Package Restore enabled, uncomment the next line +#packages/ + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml +*.pfx +*.publishsettings + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +App_Data/*.mdf +App_Data/*.ldf + +############# +## Windows detritus +############# + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Mac crap +.DS_Store + + +############# +## Python +############# + +*.py[co] + +# Packages +*.egg +*.egg-info +dist/ +build/ +eggs/ +parts/ +var/ +sdist/ +develop-eggs/ +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg diff --git a/mods/roads/streetsmod/libs/smartfs/README.md b/mods/roads/streetsmod/libs/smartfs/README.md new file mode 100644 index 0000000..df0e166 --- /dev/null +++ b/mods/roads/streetsmod/libs/smartfs/README.md @@ -0,0 +1,88 @@ +smartfs +======= + +This mod provides a 2nd generation way of creating forms - this means that the modder does not need to worry about complex formspec strings + +* Expandable: you can register your own elements to use on the form. +* Easy event handling: use binding to handle events. +* New elements: Includes a toggle button + +License: WTFPL +To install this library, place the smartfs.lua file in your mod and then include it (dofile). +There is an init.lua file in the download that shows you how to do this. + +#Using Smart Formspec +Smartfs provides 2nd generation Minetest forms to replace clunky formspec strings. Each smartfs form is a container filled with GUI elements. A number of default elements are included with smartfs, but modders can also define their own custom elements. This document describes the basic usage of the smartfs API. + +##Installation +Smartfs can be used as a library or a mod. + +To use smartfs as a library, copy the smartfs.lua file to your mod folder and add + dofile(minetest.get\_modpath(minetest.get\_current\_modname()).."/smartfs.lua") +to the top of any files that use it. + +To use smartfs as a mod, add it to your game's mods folder or to the user mods folder and enable it. + +## Creating and showing forms +A form is a rectangular area of the screen upon which all elements are placed. Use the smartfs.create() function to create a new form. This function takes two arguments and returns a form object. + +The first argument is a unique string that identifies the form. The second argument is a function that should take a single argument called state which is used to set form properties like size and background color. State also has constructors for all form elements and can be used with state:element_name. Below is a quick example. + + myform = smartfs.create("My Form",function(state) + --sets the form's size + -- (width, hieght) + state:size(5,5) + + --creates a label and places it on the form + --(x-pos, y-pos, name, text) + state:label(3,3,"label1", "A label!") + end) + +Forms can be shown to the player by using the show(target) function. The target argument is the name of the player that will see the form. + + myform:show("singleplayer") + +Here is a list of steps the library takes. +* You create a new form using smartfs.create(). +* The form is registered and stored for later use. +* You show a form to a player using the myform:show() +* The state is created and stored. +* The function in smartfs.create runs and creates the elements. +* The form is displayed to the player. + +## Modifying Elements +Elements have functions of the form element:function(args) where you need to have access to the element object. + +You can get the element object by assigning a variable to its creation function like so: + + local button1 = state:button(0,0, 1,4, "btn1", "A button") + --button1 is now a table representing the button + +You can also get the element by using state:get(name). The example below will retrieve a button with the name "btn1": + + button1 = state:get("btn1") + --or + state:get("btn1"):onClick(your\_onclick\_function + +Both of these methods should be used inside the form creation callback function, the function you pass to smartfs.create, or in event callbacks. + +Now that you have located your element you can modify it. + + button1:setPos(4,0) + +## Inventory Support +Smartfs supports adding a button to Inventory+ or Unified Inventory which will open one of your own custom forms. Use the smartfs.add\_to\_inventory(form, icon, title) function where form is the smartfs form linked to by the button, icon is the button image (only for unified inventory), and title is the button text (only for inventory+). + + smartfs.add_to_inventory(form, icon, title) + +## Dynamic forms +Dynamic forms allow you to make a form without having to register it before the game finished loading. + + local state = smartfs.dynamic("smartfs:dyn_form", name) + state:load(minetest.get_modpath("smartfs").."/example.smartfs") + state:get("btn"):click(function(self,state) + print("Button clicked!") + end) + state:show() + +Make sure you call state:show() diff --git a/mods/roads/streetsmod/libs/smartfs/api.md b/mods/roads/streetsmod/libs/smartfs/api.md new file mode 100644 index 0000000..69e3f47 --- /dev/null +++ b/mods/roads/streetsmod/libs/smartfs/api.md @@ -0,0 +1,107 @@ +#Full API +##Smartfs +* smartfs( name ) - returns the form regisered with the name 'name' +* smartfs.create( name,function ) - creates a new form and adds elements to it by running the function. Use before Minetest loads. (like minetest.register_node) +* smartfs.element( name, data ) - creates a new element type. +* smartfs.dynamic( formname, playername ) - creates a dynamic form. Returns state. See example.lua for example. Remember to call state:show() +* smartfs.add\_to\_inventory(form, icon, title) - Adds a form to an installed advanced inventory. Returns true on success. +* smartfs.inventory_mod() - Returns the name of an installed and supported inventory mod that will be used above, or null. +* smartfs.override\_load\_checks() - Allows you to use smartfs.create after the game loads. Not recommended! + +##Form +* form:show( playername [, parameters] ) - shows the form to a player. See state.param. +* form.name - the name of the form. + +##State + +### Methods +* state:size( width,height ) - sets the forms width and height. +* state:get( name ) - gets an element by name. +* state:show() - reshows the form to the player. +* state:close() - closes the form (does not work yet, due to no MT api support). +* state:load( filepath ) - Loads elements from a file. +* state:save( filepath ) - Saves elements to a file. +* state:button( x,y,w,h,name,text [, exit_on_click] ) - create a new button at x,y with name and caption (text) + * ^ optional: exit_on_click - set to true to exit the form when the button is clicked. ( Also see button.setClose() ) +* state:toggle( x,y,w,h,name,list ) - create a new toggle button at x,y with name and possible list of values +* state:label( x,y,name,text ) - create a new label at x,y with name and caption (text) +* state:field( x,y,w,h,name,label ) - create a new field at x,y with label + * state:pwdfield( x,y,w,h,name,label ) - create a password field + * state:textarea( x,y,w,h,name,label ) - create a new textarea +* state:image( x,y,w,h,name,imagepath ) - create an image box. +* state:inventory( x,y,w,h,name ) - create an inventory listing (use 'main' as name for the main player inventory) +* state:checkbox( x,y,name,label,selected ) - create a check box. +* state:element( element_type, data ) - Semi-private, create an element with type and data. + +### Variables +* state.player - The name of the player. +* state.param - The parameters supplied by form:show. +* state.def - The form definition. +* state.is_inv - Boolean which is true if this form is being shown as an inventory. + +##Button +* element:setPosition( x,y ) - change the position +* element:getPosition() - get the current position +* element:setSize( w,h ) - set the size +* element:getSize() - get the size +* element:setText( text ) - set the caption of the button +* element:getText() - get the caption of the button +* element:setImage( filename ) - sets the background of the button +* element:getImage() - get the background filename of the button +* element:click( func(self,state) ) - specify a function to run when the button is clicked + +##Toggle Button +* element:setPosition( x,y ) - change the position +* element:getPosition() - get the current position +* element:setSize( w,h ) - set the size +* element:getSize() - get the size +* element:getText() - get the text of the toggle option +* element:setId( filename ) - sets the selected id +* element:getId() - get the selected id +* element:onToggle( func(self,state) ) - specify a function to run when the value if toggled + +##Label +* element:setPosition( x,y ) - change the position +* element:getPosition() - get the current position +* element:setText( text ) - set the caption of the label +* element:getText() - get the caption of the label + +##Field and Text Area +* element:setPosition( x,y ) - change the position +* element:getPosition() - get the current position +* element:setSize( w,h ) - set the size +* element:getSize() - get the size +* element:setText( text ) - set the caption of the button +* element:getText() - get the caption of the field +* element:setImage( filename ) - sets the background of the field +* element:getImage() - get the background filename of the field + +##List box +* element:onClick( func(self,state,idx) ) - function to run when listbox item idx is clicked +* element:onDoubleClick( func(self,state,idx) ) - function to run when listbox item idx is double clicked +* element:setPosition( x,y ) - set the position +* element:getPosition() - returns {x=x, y=y} +* element:setSize( w,h ) - set the size +* element:getSize() - gets the size {w=w, h=h} +* element:addItem( item ) - appends and item +* element:removeItem( idx ) - remove item +* element:popItem() - removes last item and returns + +##Inventory listing +* element:setPosition( x,y ) - set the position +* element:getPosition() - returns {x=x, y=y} +* element:setSize( w,h ) - set the size +* element:getSize() - gets the size {w=w, h=h} +* element:setLocation( location ) - set a custom inventory location or nil for the default (current_player) + * element:usePosition( position ) - use a node metadata attached inventory of the node at the given positon + * element:useDetached( name ) - use a detached inventory with the given name + * element:usePlayer( name ) - use a player inventory other than the current player +* element:getLocation() - returns the inventory location (default: current_player) +* element:setIndex( index ) - set the inventory starting index +* element:getIndex() - returns the inventory starting index + +##Custom Code +* element:onSubmit( func(self) ) - on form submit +* element:onBuild( func(self) ) - run every time form is shown. You can set code from here +* element:setCode( code ) - set the formspec code +* element:getCode( code ) - get the formspec code diff --git a/mods/roads/streetsmod/libs/smartfs/depends.txt b/mods/roads/streetsmod/libs/smartfs/depends.txt new file mode 100644 index 0000000..4893cdc --- /dev/null +++ b/mods/roads/streetsmod/libs/smartfs/depends.txt @@ -0,0 +1,2 @@ +unified_inventory? +inventory_plus? diff --git a/mods/roads/streetsmod/libs/smartfs/example.lua b/mods/roads/streetsmod/libs/smartfs/example.lua new file mode 100644 index 0000000..935dd70 --- /dev/null +++ b/mods/roads/streetsmod/libs/smartfs/example.lua @@ -0,0 +1,66 @@ +dofile(minetest.get_modpath("smartfs").."/smartfs.lua") + +s = smartfs.create("smartfs:form",function(state) + state:size(10,7) + state:label(2,0,"lbl","SmartFS example formspec!") + state:field(7,1,3,1,"txt","Textbox") + state:image(0,0,2,2,"img","default_stone.png") + state:toggle(0,2,3,1,"tg",{"plenty..","of..","custom..","elements"}) + state:checkbox(2,1,"c","Easy code",true) + local res = "smartfs.create(\"smartfs:form\",function(state)\n" + res = res .. "\tstate:size(10,7)\n" + res = res .. "\tstate:label(2,0,\"lbl\",\"SmartFS example formspec!\")\n" + res = res .. "\tstate:field(7,1,3,1,\"txt\",\"Textbox\")\n" + res = res .. "\tstate:image(0,0,2,2,\"img\",\"default_stone.png\")\n" + res = res .. "\tstate:toggle(0,2,3,1,\"tg\",{\"plenty..\",\"of..\",\"custom..\",\"elements\"})\n" + res = res .. "\tstate:checkbox(2,1,\"c\",\"Easy code\",true)\n" + res = res .. "end)" + state:textarea(1,3.5,9,4,"ta","Code:"):setText(res) + return true +end) + +l = smartfs.create("smartfs:load",function(state) + state:load(minetest.get_modpath("smartfs").."/example.smartfs") + state:get("btn"):click(function(self,state) + print("Button clicked!") + end) + return true +end) + +smartfs.add_to_inventory(l,"icon.png","SmartFS") + +minetest.register_chatcommand("sfs_s", { + params = "", + description = "SmartFS test formspec 1: basics", + func = function(name, param) + s:show(name) + end, +}) +minetest.register_chatcommand("sfs_l", { + params = "", + description = "SmartFS test formspec 2: loading", + func = function(name, param) + l:show(name) + end, +}) + +minetest.register_chatcommand("sfs_d", { + params = "", + description = "SmartFS test formspec 3: dynamic", + func = function(name, param) + local state = smartfs.dynamic("smartfs:dyn_form", name) + state:load(minetest.get_modpath("smartfs").."/example.smartfs") + state:get("btn"):click(function(self,state) + print("Button clicked!") + end) + state:show() + end, +}) + +minetest.register_chatcommand("sfs_lc", { + params = "", + description = "SmartFS test formspec 4: smartfs.create error catching", + func = function(name, param) + smartfs.create("asdinas",function() end) + end +}) diff --git a/mods/roads/streetsmod/libs/smartfs/example.smartfs b/mods/roads/streetsmod/libs/smartfs/example.smartfs new file mode 100644 index 0000000..cbbaabf --- /dev/null +++ b/mods/roads/streetsmod/libs/smartfs/example.smartfs @@ -0,0 +1 @@ +return { ["ele"] = { ["c"] = { ["pos"] = { ["y"] = 1, ["x"] = 1 }, ["label"] = "Check", ["value"] = true, ["type"] = "checkbox", ["name"] = "c" }, ["btn"] = { ["pos"] = { ["y"] = 2, ["x"] = 1 }, ["size"] = { ["h"] = 1, ["w"] = 1 }, ["value"] = "Button", ["type"] = "button", ["name"] = "btn" } }, ["size"] = { ["h"] = 3, ["w"] = 5 } } \ No newline at end of file diff --git a/mods/roads/streetsmod/libs/smartfs/init.lua b/mods/roads/streetsmod/libs/smartfs/init.lua new file mode 100644 index 0000000..b2aaa29 --- /dev/null +++ b/mods/roads/streetsmod/libs/smartfs/init.lua @@ -0,0 +1,2 @@ +dofile(minetest.get_modpath("smartfs").."/smartfs.lua") +--dofile(minetest.get_modpath("smartfs").."/example.lua") diff --git a/mods/roads/streetsmod/libs/smartfs/smartfs.lua b/mods/roads/streetsmod/libs/smartfs/smartfs.lua new file mode 100644 index 0000000..dfa0819 --- /dev/null +++ b/mods/roads/streetsmod/libs/smartfs/smartfs.lua @@ -0,0 +1,760 @@ +--------------------------- +-- SmartFS: Smart Formspecs +-- by Rubenwardy +--------------------------- + +smartfs = { + _fdef = {}, + _edef = {}, + opened = {}, + inv = {} +} + +-- the smartfs() function +function smartfs.__call(self, name) + return smartfs._fdef[name] +end + +-- Register forms and elements +function smartfs.create(name,onload) + if smartfs._fdef[name] then + error("SmartFS - (Error) Form "..name.." already exists!") + end + if smartfs.loaded and not smartfs._loaded_override then + error("SmartFS - (Error) Forms should be declared while the game loads.") + end + + smartfs._fdef[name] = { + _reg = onload, + name = name, + show = smartfs._show_ + } + + return smartfs._fdef[name] +end +function smartfs.override_load_checks() + smartfs._loaded_override = true +end + +minetest.after(0, function() + smartfs.loaded = true +end) +function smartfs.dynamic(name,player) + if not smartfs._dynamic_warned then + smartfs._dynamic_warned = true + print("SmartFS - (Warning) On the fly forms are being used. May cause bad things to happen") + end + local state = smartfs._makeState_({name=name},player,nil,false) + state.show = state._show_ + smartfs.opened[player] = state + return state +end +function smartfs.element(name,data) + if smartfs._edef[name] then + error("SmartFS - (Error) Element type "..name.." already exists!") + end + smartfs._edef[name] = data + return smartfs._edef[name] +end + +function smartfs.inventory_mod() + if unified_inventory then + return "unified_inventory" + elseif inventory_plus then + return "inventory_plus" + else + return nil + end +end + +function smartfs.add_to_inventory(form,icon,title) + if unified_inventory then + unified_inventory.register_button(form.name, { + type = "image", + image = icon, + }) + unified_inventory.register_page(form.name, { + get_formspec = function(player, formspec) + local name = player:get_player_name() + local opened = smartfs._show_(form, name, nil, true) + return {formspec = opened:_getFS_(false)} + end + }) + return true + elseif inventory_plus then + minetest.register_on_joinplayer(function(player) + inventory_plus.register_button(player, form.name, title) + end) + minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname == "" and fields[form.name] then + local name = player:get_player_name() + local opened = smartfs._show_(form, name, nil, true) + inventory_plus.set_inventory_formspec(player, opened:_getFS_(true)) + end + end) + return true + else + return false + end +end + +function smartfs._makeState_(form,player,params,is_inv) + return { + _ele = {}, + def = form, + player = player, + param = params, + is_inv = is_inv, + get = function(self,name) + return self._ele[name] + end, + close = function(self) + self.closed = true + end, + size = function(self,w,h) + self._size = {w=w,h=h} + end, + _getFS_ = function(self,size) + local res = "" + if self._size and size then + res = "size["..self._size.w..","..self._size.h.."]" + end + for key,val in pairs(self._ele) do + res = res .. val:build() + end + return res + end, + _show_ = function(self) + if self.is_inv then + if unified_inventory then + unified_inventory.set_inventory_formspec(minetest.get_player_by_name(self.player), self.def.name) + elseif inventory_plus then + inventory_plus.set_inventory_formspec(minetest.get_player_by_name(self.player), self:_getFS_(true)) + end + else + local res = self:_getFS_(true) + minetest.show_formspec(player,form.name,res) + end + end, + load = function(self,file) + local file = io.open(file, "r") + if file then + local table = minetest.deserialize(file:read("*all")) + if type(table) == "table" then + if table.size then + self._size = table.size + end + for key,val in pairs(table.ele) do + self:element(val.type,val) + end + return true + end + end + return false + end, + save = function(self,file) + local res = {ele={}} + + if self._size then + res.size = self._size + end + + for key,val in pairs(self._ele) do + res.ele[key] = val.data + end + + local file = io.open(file, "w") + if file then + file:write(minetest.serialize(res)) + file:close() + return true + end + return false + end, + button = function(self,x,y,w,h,name,text,exitf) + if exitf == nil then exitf = false end + return self:element("button",{pos={x=x,y=y},size={w=w,h=h},name=name,value=text,closes=exitf}) + end, + label = function(self,x,y,name,text) + return self:element("label",{pos={x=x,y=y},name=name,value=text}) + end, + toggle = function(self,x,y,w,h,name,list) + return self:element("toggle",{pos={x=x,y=y},size={w=w,h=h},name=name,id=1,list=list}) + end, + field = function(self,x,y,w,h,name,label) + return self:element("field",{pos={x=x,y=y},size={w=w,h=h},name=name,value="",label=label}) + end, + pwdfield = function(self,x,y,w,h,name,label) + local res = self:element("field",{pos={x=x,y=y},size={w=w,h=h},name=name,value="",label=label}) + res:isPassword(true) + return res + end, + textarea = function(self,x,y,w,h,name,label) + local res = self:element("field",{pos={x=x,y=y},size={w=w,h=h},name=name,value="",label=label}) + res:isMultiline(true) + return res + end, + image = function(self,x,y,w,h,name,img) + return self:element("image",{pos={x=x,y=y},size={w=w,h=h},name=name,value=img}) + end, + checkbox = function(self,x,y,name,label,selected) + return self:element("checkbox",{pos={x=x,y=y},name=name,value=selected,label=label}) + end, + listbox = function(self,x,y,w,h,name) + return self:element("list", { pos={x=x,y=y}, size={w=w,h=h}, name=name }) + end, + inventory = function(self,x,y,w,h,name) + return self:element("inventory", { pos={x=x,y=y}, size={w=w,h=h}, name=name }) + end, + element = function(self,typen,data) + local type = smartfs._edef[typen] + + if not type then + error("Element type "..typen.." does not exist!") + end + + if self._ele[data.name] then + error("Element "..data.name.." already exists") + end + data.type = typen + + local ele = { + name = data.name, + root = self, + data = data, + remove = function(self) + self.root._ele[self.name] = nil + end + } + + for key,val in pairs(type) do + ele[key] = val + end + + self._ele[data.name] = ele + + return self._ele[data.name] + end + } +end + +-- Show a formspec to a user +function smartfs._show_(form, player, params, is_inv) + local state = smartfs._makeState_(form, player, params, is_inv) + state.show = state._show_ + if form._reg(state)~=false then + if not is_inv then + smartfs.opened[player] = state + state:_show_() + else + smartfs.inv[player] = state + end + end + return state +end + +-- Receive fields from formspec +local function _sfs_recieve_(state,name,fields) + if (fields.quit == "true") then + if not state.is_inv then + smartfs.opened[name] = nil + end + return true + end + + for key,val in pairs(fields) do + if state._ele[key] then + state._ele[key].data.value = val + end + end + for key,val in pairs(state._ele) do + if val.submit then + if (val:submit(fields)==true) then + return true + end + end + end + if state.closed ~= true then + state:_show_() + else + minetest.show_formspec(name,"","size[5,1]label[0,0;Formspec closing not yet created!]") + if not state.is_inv then + smartfs.opened[name] = nil + end + end + return true +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + local name = player:get_player_name() + if smartfs.opened[name] and not smartfs.opened[name].is_inv then + if smartfs.opened[name].def.name == formname then + local state = smartfs.opened[name] + return _sfs_recieve_(state,name,fields) + else + smartfs.opened[name] = nil + end + elseif smartfs.inv[name] and smartfs.inv[name].is_inv then + local state = smartfs.inv[name] + _sfs_recieve_(state,name,fields) + end + return false +end) + + +----------------------------------------------------------------- +------------------------- ELEMENTS ---------------------------- +----------------------------------------------------------------- + +smartfs.element("button",{ + build = function(self) + if self.data.img then + return "image_button[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.data.size.w..","..self.data.size.h.. + ";".. + self.data.img.. + ";".. + self.name.. + ";".. + self.data.value.. + "]" + else + if self.data.closes then + return "button_exit[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.data.size.w..","..self.data.size.h.. + ";".. + self.name.. + ";".. + self.data.value.. + "]" + else + return "button[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.data.size.w..","..self.data.size.h.. + ";".. + self.name.. + ";".. + self.data.value.. + "]" + end + end + end, + submit = function(self,fields,state) + if fields[self.name] and self._click then + self:_click(self.root) + end + + if self.data.closes then + return true + end + end, + setPosition = function(self,x,y) + self.data.pos = {x=x,y=y} + end, + getPosition = function(self,x,y) + return self.data.pos + end, + setSize = function(self,w,h) + self.data.size = {w=w,h=h} + end, + getSize = function(self,x,y) + return self.data.size + end, + onClick = function(self,func) + self._click = func + end, + click = function(self,func) + self._click = func + end, + setText = function(self,text) + self.data.value = text + end, + getText = function(self) + return self.data.value + end, + setImage = function(self,image) + self.data.img = image + end, + getImage = function(self) + return self.data.img + end, + setClose = function(self,bool) + self.data.closes = bool + end +}) + +smartfs.element("toggle",{ + build = function(self) + return "button[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.data.size.w..","..self.data.size.h.. + ";".. + self.name.. + ";".. + self.data.list[self.data.id].. + "]" + end, + submit = function(self,fields) + if fields[self.name] then + self.data.id = self.data.id + 1 + if self.data.id > #self.data.list then + self.data.id = 1 + end + if self._tog then + self:_tog(self.root) + end + end + end, + onToggle = function(self,func) + self._tog = func + end, + setPosition = function(self,x,y) + self.data.pos = {x=x,y=y} + end, + getPosition = function(self,x,y) + return self.data.pos + end, + setSize = function(self,w,h) + self.data.size = {w=w,h=h} + end, + getSize = function(self,x,y) + return self.data.size + end, + setId = function(self,id) + self.data.id = id + end, + getId = function(self) + return self.data.id + end, + getText = function(self) + return self.data.list[self.data.id] + end +}) + +smartfs.element("label",{ + build = function(self) + return "label[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.data.value.. + "]" + end, + setPosition = function(self,x,y) + self.data.pos = {x=x,y=y} + end, + getPosition = function(self,x,y) + return self.data.pos + end, + setText = function(self,text) + self.data.value = text + end, + getText = function(self) + return self.data.value + end +}) + +smartfs.element("field",{ + build = function(self) + if self.data.ml then + return "textarea[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.data.size.w..","..self.data.size.h.. + ";".. + self.name.. + ";".. + self.data.label.. + ";".. + self.data.value.. + "]" + elseif self.data.pwd then + return "pwdfield[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.data.size.w..","..self.data.size.h.. + ";".. + self.name.. + ";".. + self.data.label.. + "]" + else + return "field[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.data.size.w..","..self.data.size.h.. + ";".. + self.name.. + ";".. + self.data.label.. + ";".. + self.data.value.. + "]" + end + end, + setPosition = function(self,x,y) + self.data.pos = {x=x,y=y} + end, + getPosition = function(self,x,y) + return self.data.pos + end, + setSize = function(self,w,h) + self.data.size = {w=w,h=h} + end, + getSize = function(self,x,y) + return self.data.size + end, + setText = function(self,text) + self.data.value = text + end, + getText = function(self) + return self.data.value + end, + isPassword = function(self,bool) + self.data.pwd = bool + end, + isMultiline = function(self,bool) + self.data.ml = bool + end +}) + +smartfs.element("image",{ + build = function(self) + return "image[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.data.size.w..","..self.data.size.h.. + ";".. + self.data.value.. + "]" + end, + setPosition = function(self,x,y) + self.data.pos = {x=x,y=y} + end, + getPosition = function(self,x,y) + return self.data.pos + end, + setSize = function(self,w,h) + self.data.size = {w=w,h=h} + end, + getSize = function(self,x,y) + return self.data.size + end, + setImage = function(self,text) + self.data.value = text + end, + getImage = function(self) + return self.data.value + end +}) + +smartfs.element("checkbox",{ + build = function(self) + if self.data.value then + return "checkbox[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.name.. + ";".. + self.data.label.. + ";true]" + else + return "checkbox[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.name.. + ";".. + self.data.label.. + ";false]" + end + end, + setPosition = function(self,x,y) + self.data.pos = {x=x,y=y} + end, + getPosition = function(self,x,y) + return self.data.pos + end, + setSize = function(self,w,h) + self.data.size = {w=w,h=h} + end, + getSize = function(self,x,y) + return self.data.size + end, + setText = function(self,text) + self.data.value = text + end, + getText = function(self) + return self.data.value + end +}) + +smartfs.element("list",{ + build = function(self) + local listformspec = "textlist[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.data.size.w..","..self.data.size.h.. + ";".. + self.data.name.. + ";" + + --loop through the list's items and add them to the formspec + if not self.data.items then + self.data.items = {" "} + end + for i,value in ipairs(self.data.items) do + listformspec = listformspec..value.."," + end + listformspec = string.sub(listformspec, 0, -2) --removes extra , + --close out the list items section + listformspec = listformspec..";" + + --TODO support selected idx and transparency + + --close formspec definition and return formspec + listformspec = listformspec.."]" + return listformspec + end, + submit = function(self,fields) + if fields[self.name] then + local _type = string.sub(fields[self.data.name],1,3) + local index = string.sub(fields[self.data.name],5) + if _type == "CHG" and self._click then + self:_click(self.root, index) + elseif _type == "DCL" and self._doubleClick then + self:_doubleClick(self.root, index) + end + end + end, + onClick = function(self, func) + self._click = func + end, + click = function(self, func) + self._click = func + end, + onDoubleClick = function(self, func) + self._doubleClick = func + end, + doubleclick = function(self, func) + self._doubleClick = func + end, + setPosition = function(self,x,y) + self.data.pos = {x=x,y=y} + end, + getPosition = function(self,x,y) + return self.data.pos + end, + setSize = function(self,w,h) + self.data.size = {w=w,h=h} + end, + getSize = function(self,x,y) + return self.data.size + end, + addItem = function(self, item) + if not self.data.items then + self.data.items = {" "} + end + table.insert(self.data.items, item) + end, + removeItem = function(self,idx) + if not self.data.items then + self.data.items = {" "} + end + table.remove(self.data.items,idx) + end, + popItem = function(self) + if not self.data.items then + self.data.items = {" "} + end + local item = self.data.items[#self.data.items] + table.remove(self.data.items) + return item + end +}) + +smartfs.element("inventory",{ + build = function(self) + return "list[".. + (self.data.location or "current_player") .. + ";".. + self.name.. + ";".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.data.size.w..","..self.data.size.h.. + ";".. + (self.data.index or "") .. + "]" + end, + setPosition = function(self,x,y) + self.data.pos = {x=x,y=y} + end, + getPosition = function(self,x,y) + return self.data.pos + end, + setSize = function(self,w,h) + self.data.size = {w=w,h=h} + end, + getSize = function(self,x,y) + return self.data.size + end, + -- available inventory locations + -- "current_player": Player to whom the menu is shown + -- "player:": Any player + -- "nodemeta:,,": Any node metadata + -- "detached:": A detached inventory + -- "context" does not apply to smartfs, since there is no node-metadata as context available + setLocation = function(self,location) + self.data.location = location + end, + getLocation = function(self) + return self.data.location or "current_player" + end, + usePosition = function(self, pos) + self.data.location = string.format("nodemeta:%d,%d,%d", pos.x, pos.y, pos.z) + end, + usePlayer = function(self, name) + self.data.location = "player:" .. name + end, + useDetached = function(self, name) + self.data.location = "detached:" .. name + end, + setIndex = function(self,index) + self.data.index = index + end, + getIndex = function(self) + return self.data.index + end +}) + +smartfs.element("code",{ + build = function(self) + if self._build then + self:_build() + end + + return self.data.code + end, + submit = function(self,fields) + if self._sub then + self:_sub(fields) + end + end, + onSubmit = function(self,func) + self._sub = func + end, + onBuild = function(self,func) + self._build = func + end, + setCode = function(self,code) + self.data.code = code + end, + getCode = function(self) + return self.data.code + end +}) diff --git a/mods/roads/streetsmod/locale/de.txt b/mods/roads/streetsmod/locale/de.txt new file mode 100644 index 0000000..57694d3 --- /dev/null +++ b/mods/roads/streetsmod/locale/de.txt @@ -0,0 +1,59 @@ +# Translation file GERMAN +Setup completed, have fun with StreetsMod=Setup abgeschlossen, viel Spass mit StreetsMod +Creating variables and tables...=Erstelle Variablen und Tabellen... +Checking installed mods...=Ueberpruefe installierte Mods... +Check version of your installed StreetsMod and find information=Ueberpruefe die installierte StreetsMod Version und weitere Infos +Asphalt=Asphalt +Asphalt stair=Asphalt Treppe +Asphalt slab=Asphalt Platte +Construction fence=Bauzaun +Delineator=Leitpfosten +Emergency Phone=Notrufsaeule +Asphalt with sideline=Asphalt mit Seitenlinie +Asphalt with solid line=Asphalt mit durchgezogener Linie +Asphalt with dashed line=Asphalt mit unterbrochener Linie +Asphalt with sideline (edge)=Asphalt mit Seitenlinie (Ecke) +Asphalt with parking label=Asphalt mit Parkplatzsymbol +Asphalt with arrow=Asphalt mit Richtungspfeil +Simple manhole=Einfacher Gulli +Advanced manhole=Gulli +Pole=Stange +Empty sign=Leeres Schild +Warning sign (lava)=Gefahrenschild Lava +Warning sign (water)=Gefahrenschild Wasser +Warning sign (Construction area)=Gefahrenschild Baustelle +Warning: Careful of lava=Achtung: Lava +Warning: Water nearby=Achtung: Wasser +Warning: Construction area, possible deep excavations=Achtung Baustelle, eventuell tiefe Graeben +Sign workshop - Create signs for your roads!=Schilderworkshop - Baue Schilder fuer deine Strassen! +Available signs:=Verfuegbare Schilder +Needed stuff:=Benoetigt +Put it here:=Rohstoffe +Selected:=Ausgewaehlt +Output:=Ausgabe +Sign workshop=Schilderworkshop +Sign workshop idle=Schilderworkshop bereit +Sign workshop working=Schilderworkshop arbeitet +Please wait %s seconds... = Bitte warte %s Sekunden... +Solid line (yellow)=Durchgezogene Linie (gelb) +Dashed line (yellow)=Unterbrochene Linie (gelb) +Cross (yellow)=Kreuz (gelb) +Outer edge (yellow)=Ecklinie (gelb) +Parking (yellow)=Parkplatzsymbol (gelb) +Arrow (yellow)=Pfeil (gelb) +Sideline (yellow)=Seitenlinie (gelb) +Steel support=Stahlrahmen +Street lamp=Strassenlampe +Concrete wall=Betonwand +Concrete=Beton +Trafficlight=Ampel +Running version=Version +Cheater=Schummler +Cheater!=Schummler! +Off=Aus +Channel=Kanal +green=Gruen +red=Rot +warn=Warnung +off=Aus +U cheater U=Du Schummler Du diff --git a/mods/roads/streetsmod/locale/pt.txt b/mods/roads/streetsmod/locale/pt.txt new file mode 100644 index 0000000..6ffeeaa --- /dev/null +++ b/mods/roads/streetsmod/locale/pt.txt @@ -0,0 +1,59 @@ +# Translation file for StreetsMod might not be up-to-date. +Setup completed, have fun with StreetsMod=Configuração completa, se divirta com o StreetsMod +Creating variables and tables...=Criando variáveis e tabelas... +Checking installed mods...=Verificando mods instalados... +Check version of your installed StreetsMod and find information=Verifique a versão instalada do StreetsMod e encontre informações +Asphalt=Asfalto +Asphalt stair=Escada de asfalto +Asphalt slab=Placa de asfalto +Construction fence=Cerca de construção +Delineator=Delineador +Emergency Phone=Telefone de Emergência +Asphalt with sideline=Asfalto com linha lateral +Asphalt with solid line=Asfalto com linha contínua +Asphalt with dashed line=Asfalto com linha traçada +Asphalt with sideline (edge)=Asfalto com linha lateral (borda) +Asphalt with parking label=Asfalto com estacionamento +Asphalt with arrow=Asfalto com flecha +Simple manhole=Buraco simples +Advanced manhole=Buraco elaborado +Pole=Poste +Empty sign=Sinal vazio +Warning sign (lava)=Sinal de aviso (lava) +Warning sign (water)=Sinal de aviso (água) +Warning sign (Construction area)=Sinal de aviso (Área de construção) +Warning: Careful of lava=Aviso: Cuidado com a lava +Warning: Water nearby=Aviso: Água nos arredores +Warning: Construction area, possible deep excavations=Aviso: Área de construção, possíveis escavações profundas +Sign workshop - Create signs for your roads!=Oficina de sinais - Crie sinais para suas estradas! +Available signs:=Sinais disponíveis: +Needed stuff:=Materiais necessários: +Put it here:=Coloque aqui: +Selected:=Selecionado: +Output:=Saída: +Sign workshop=Oficina de sinal +Sign workshop idle=Oficina de sinal em espera +Sign workshop working=Oficina de sinal trabalhando +Please wait %s seconds... =Por favor aguarde %s segundos... +Solid line (yellow)=Linha contínua (amarela) +Dashed line (yellow)=Linha traçada (amarela) +Cross (yellow)=Cruzamento (amarelo) +Outer edge (yellow)=Borda externa (amarela) +Parking (yellow)=Estacionamento (amarela) +Arrow (yellow)=Flecha (amarela) +Sideline (yellow)=Linha lateral (amarela) +Steel support=Suporte/apoio de aço +Street lamp=Lâmpada de rua +Concrete wall=Parede de concreto +Concrete=Concreto +Trafficlight=Semáforo +Running version=Versão sendo utilizada +Cheater=Trapaceiro +Cheater!=Trapaceiro! +Off=Desligado +Channel=Canal +green=verde +red=vermelho +warn=aviso +off=desligado +U cheater U=Seu trapaceiro seu diff --git a/mods/roads/streetsmod/locale/pt_br.txt b/mods/roads/streetsmod/locale/pt_br.txt new file mode 100644 index 0000000..6ffeeaa --- /dev/null +++ b/mods/roads/streetsmod/locale/pt_br.txt @@ -0,0 +1,59 @@ +# Translation file for StreetsMod might not be up-to-date. +Setup completed, have fun with StreetsMod=Configuração completa, se divirta com o StreetsMod +Creating variables and tables...=Criando variáveis e tabelas... +Checking installed mods...=Verificando mods instalados... +Check version of your installed StreetsMod and find information=Verifique a versão instalada do StreetsMod e encontre informações +Asphalt=Asfalto +Asphalt stair=Escada de asfalto +Asphalt slab=Placa de asfalto +Construction fence=Cerca de construção +Delineator=Delineador +Emergency Phone=Telefone de Emergência +Asphalt with sideline=Asfalto com linha lateral +Asphalt with solid line=Asfalto com linha contínua +Asphalt with dashed line=Asfalto com linha traçada +Asphalt with sideline (edge)=Asfalto com linha lateral (borda) +Asphalt with parking label=Asfalto com estacionamento +Asphalt with arrow=Asfalto com flecha +Simple manhole=Buraco simples +Advanced manhole=Buraco elaborado +Pole=Poste +Empty sign=Sinal vazio +Warning sign (lava)=Sinal de aviso (lava) +Warning sign (water)=Sinal de aviso (água) +Warning sign (Construction area)=Sinal de aviso (Área de construção) +Warning: Careful of lava=Aviso: Cuidado com a lava +Warning: Water nearby=Aviso: Água nos arredores +Warning: Construction area, possible deep excavations=Aviso: Área de construção, possíveis escavações profundas +Sign workshop - Create signs for your roads!=Oficina de sinais - Crie sinais para suas estradas! +Available signs:=Sinais disponíveis: +Needed stuff:=Materiais necessários: +Put it here:=Coloque aqui: +Selected:=Selecionado: +Output:=Saída: +Sign workshop=Oficina de sinal +Sign workshop idle=Oficina de sinal em espera +Sign workshop working=Oficina de sinal trabalhando +Please wait %s seconds... =Por favor aguarde %s segundos... +Solid line (yellow)=Linha contínua (amarela) +Dashed line (yellow)=Linha traçada (amarela) +Cross (yellow)=Cruzamento (amarelo) +Outer edge (yellow)=Borda externa (amarela) +Parking (yellow)=Estacionamento (amarela) +Arrow (yellow)=Flecha (amarela) +Sideline (yellow)=Linha lateral (amarela) +Steel support=Suporte/apoio de aço +Street lamp=Lâmpada de rua +Concrete wall=Parede de concreto +Concrete=Concreto +Trafficlight=Semáforo +Running version=Versão sendo utilizada +Cheater=Trapaceiro +Cheater!=Trapaceiro! +Off=Desligado +Channel=Canal +green=verde +red=vermelho +warn=aviso +off=desligado +U cheater U=Seu trapaceiro seu diff --git a/mods/roads/streetsmod/locale/template.txt.txt b/mods/roads/streetsmod/locale/template.txt.txt new file mode 100644 index 0000000..179cc7d --- /dev/null +++ b/mods/roads/streetsmod/locale/template.txt.txt @@ -0,0 +1,59 @@ +# Translation file for StreetsMod might not be up-to-date. +Setup completed, have fun with StreetsMod= +Creating variables and tables...= +Checking installed mods...= +Check version of your installed StreetsMod and find information= +Asphalt= +Asphalt stair= +Asphalt slab= +Construction fence= +Delineator= +Emergency Phone= +Asphalt with sideline= +Asphalt with solid line= +Asphalt with dashed line= +Asphalt with sideline (edge)= +Asphalt with parking label= +Asphalt with arrow= +Simple manhole= +Advanced manhole= +Pole= +Empty sign= +Warning sign (lava)= +Warning sign (water)= +Warning sign (Construction area)= +Warning: Careful of lava= +Warning: Water nearby= +Warning: Construction area, possible deep excavations= +Sign workshop - Create signs for your roads!= +Available signs:= +Needed stuff:= +Put it here:= +Selected:= +Output:= +Sign workshop= +Sign workshop idle= +Sign workshop working= +Please wait %s seconds... = +Solid line (yellow)= +Dashed line (yellow)= +Cross (yellow)= +Outer edge (yellow)= +Parking (yellow)= +Arrow (yellow)= +Sideline (yellow)= +Steel support= +Street lamp= +Concrete wall= +Concrete= +Trafficlight= +Running version= +Cheater= +Cheater!= +Off= +Channel= +green= +red= +warn= +off= +U cheater U= diff --git a/mods/roads/streetsmod/nodeboxes/trafficlight.nbe b/mods/roads/streetsmod/nodeboxes/trafficlight.nbe new file mode 100644 index 0000000..189f333 --- /dev/null +++ b/mods/roads/streetsmod/nodeboxes/trafficlight.nbe @@ -0,0 +1,19 @@ +MINETEST NODEBOX EDITOR +PARSER 1 +NAME test + +NODE node1 +POSITION 0 0 0 +NODEBOX nodebox1 -0.1875 -0.5 0.5 0.1875 0.5 0.75 +NODEBOX nodebox2 -0.0625 0.375 0.3125 0.0625 0.4375 0.5 +NODEBOX nodebox3 -0.0625 0.0625 0.3125 0.0625 0.125 0.5 +NODEBOX nodebox4 -0.0625 -0.25 0.3125 0.0625 -0.1875 0.5 +NODEBOX nodebox5 0.0625 0.3125 0.3125 0.125 0.38 0.5 +NODEBOX nodebox6 -0.125 0.3125 0.3125 -0.0625 0.375 0.5 +NODEBOX nodebox7 0.0625 0 0.3125 0.125 0.0625 0.5 +NODEBOX nodebox8 -0.125 0 0.3125 -0.0625 0.0625 0.5 +NODEBOX nodebox9 0.0625 -0.3125 0.3125 0.125 -0.25 0.5 +NODEBOX nodebox10 -0.125 -0.3125 0.3125 -0.0625 -0.25 0.5 +NODEBOX NodeBox11 -0.125 -0.125 0.85 0.125 0.125 0.75 +END NODE + diff --git a/mods/roads/streetsmod/readme.txt b/mods/roads/streetsmod/readme.txt new file mode 100644 index 0000000..a2c9172 --- /dev/null +++ b/mods/roads/streetsmod/readme.txt @@ -0,0 +1 @@ +This is the first loaded mod in this modpack which prepares tables, variables etc. \ No newline at end of file diff --git a/mods/roads/streetsmod/textures/streets_asphalt.png b/mods/roads/streetsmod/textures/streets_asphalt.png new file mode 100644 index 0000000..1920362 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_asphalt.png differ diff --git a/mods/roads/streetsmod/textures/streets_concrete.png b/mods/roads/streetsmod/textures/streets_concrete.png new file mode 100644 index 0000000..cf91587 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_concrete.png differ diff --git a/mods/roads/streetsmod/textures/streets_delineator.png b/mods/roads/streetsmod/textures/streets_delineator.png new file mode 100644 index 0000000..ae69f2e Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_delineator.png differ diff --git a/mods/roads/streetsmod/textures/streets_delineator_top.png b/mods/roads/streetsmod/textures/streets_delineator_top.png new file mode 100644 index 0000000..3551ffe Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_delineator_top.png differ diff --git a/mods/roads/streetsmod/textures/streets_fence_bottom.png b/mods/roads/streetsmod/textures/streets_fence_bottom.png new file mode 100644 index 0000000..c3449d4 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_fence_bottom.png differ diff --git a/mods/roads/streetsmod/textures/streets_fence_fromtop.png b/mods/roads/streetsmod/textures/streets_fence_fromtop.png new file mode 100644 index 0000000..f4c0e23 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_fence_fromtop.png differ diff --git a/mods/roads/streetsmod/textures/streets_fence_inv.png b/mods/roads/streetsmod/textures/streets_fence_inv.png new file mode 100644 index 0000000..0446f12 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_fence_inv.png differ diff --git a/mods/roads/streetsmod/textures/streets_fence_top.png b/mods/roads/streetsmod/textures/streets_fence_top.png new file mode 100644 index 0000000..7d1d9f2 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_fence_top.png differ diff --git a/mods/roads/streetsmod/textures/streets_lampcontroller_bottom.png b/mods/roads/streetsmod/textures/streets_lampcontroller_bottom.png new file mode 100644 index 0000000..cdd5b40 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_lampcontroller_bottom.png differ diff --git a/mods/roads/streetsmod/textures/streets_lampcontroller_sides.png b/mods/roads/streetsmod/textures/streets_lampcontroller_sides.png new file mode 100644 index 0000000..39e9960 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_lampcontroller_sides.png differ diff --git a/mods/roads/streetsmod/textures/streets_lampcontroller_top.png b/mods/roads/streetsmod/textures/streets_lampcontroller_top.png new file mode 100644 index 0000000..00d2e4c Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_lampcontroller_top.png differ diff --git a/mods/roads/streetsmod/textures/streets_lamps_basi_inv.png b/mods/roads/streetsmod/textures/streets_lamps_basi_inv.png new file mode 100644 index 0000000..5c31236 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_lamps_basi_inv.png differ diff --git a/mods/roads/streetsmod/textures/streets_lamps_basic_bottom.png b/mods/roads/streetsmod/textures/streets_lamps_basic_bottom.png new file mode 100644 index 0000000..07d123f Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_lamps_basic_bottom.png differ diff --git a/mods/roads/streetsmod/textures/streets_lamps_basic_middle.png b/mods/roads/streetsmod/textures/streets_lamps_basic_middle.png new file mode 100644 index 0000000..1370765 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_lamps_basic_middle.png differ diff --git a/mods/roads/streetsmod/textures/streets_lamps_basic_top.png b/mods/roads/streetsmod/textures/streets_lamps_basic_top.png new file mode 100644 index 0000000..355f50d Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_lamps_basic_top.png differ diff --git a/mods/roads/streetsmod/textures/streets_lamps_basic_top_top.png b/mods/roads/streetsmod/textures/streets_lamps_basic_top_top.png new file mode 100644 index 0000000..4d6bf22 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_lamps_basic_top_top.png differ diff --git a/mods/roads/streetsmod/textures/streets_manhole.png b/mods/roads/streetsmod/textures/streets_manhole.png new file mode 100644 index 0000000..9752c6f Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_manhole.png differ diff --git a/mods/roads/streetsmod/textures/streets_manhole_advanced.png b/mods/roads/streetsmod/textures/streets_manhole_advanced.png new file mode 100644 index 0000000..d8e5b44 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_manhole_advanced.png differ diff --git a/mods/roads/streetsmod/textures/streets_pole.png b/mods/roads/streetsmod/textures/streets_pole.png new file mode 100644 index 0000000..af4a378 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_pole.png differ diff --git a/mods/roads/streetsmod/textures/streets_pole_inv.png b/mods/roads/streetsmod/textures/streets_pole_inv.png new file mode 100644 index 0000000..fce2292 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_pole_inv.png differ diff --git a/mods/roads/streetsmod/textures/streets_rw_arrow_alldirs.png b/mods/roads/streetsmod/textures/streets_rw_arrow_alldirs.png new file mode 100644 index 0000000..532280e Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_rw_arrow_alldirs.png differ diff --git a/mods/roads/streetsmod/textures/streets_sign_back.png b/mods/roads/streetsmod/textures/streets_sign_back.png new file mode 100644 index 0000000..77d4210 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_sign_back.png differ diff --git a/mods/roads/streetsmod/textures/streets_sign_construction.png b/mods/roads/streetsmod/textures/streets_sign_construction.png new file mode 100644 index 0000000..f2c2455 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_sign_construction.png differ diff --git a/mods/roads/streetsmod/textures/streets_sign_grasswalk.png b/mods/roads/streetsmod/textures/streets_sign_grasswalk.png new file mode 100644 index 0000000..1a72dff Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_sign_grasswalk.png differ diff --git a/mods/roads/streetsmod/textures/streets_sign_lava.png b/mods/roads/streetsmod/textures/streets_sign_lava.png new file mode 100644 index 0000000..e80f8e2 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_sign_lava.png differ diff --git a/mods/roads/streetsmod/textures/streets_sign_mine.png b/mods/roads/streetsmod/textures/streets_sign_mine.png new file mode 100644 index 0000000..92aaf97 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_sign_mine.png differ diff --git a/mods/roads/streetsmod/textures/streets_sign_shop.png b/mods/roads/streetsmod/textures/streets_sign_shop.png new file mode 100644 index 0000000..b30ea8e Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_sign_shop.png differ diff --git a/mods/roads/streetsmod/textures/streets_sign_water.png b/mods/roads/streetsmod/textures/streets_sign_water.png new file mode 100644 index 0000000..b941817 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_sign_water.png differ diff --git a/mods/roads/streetsmod/textures/streets_sign_workshop.png b/mods/roads/streetsmod/textures/streets_sign_workshop.png new file mode 100644 index 0000000..3c399bc Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_sign_workshop.png differ diff --git a/mods/roads/streetsmod/textures/streets_signworkshop_bottom.png b/mods/roads/streetsmod/textures/streets_signworkshop_bottom.png new file mode 100644 index 0000000..022bb2c Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_signworkshop_bottom.png differ diff --git a/mods/roads/streetsmod/textures/streets_signworkshop_front.png b/mods/roads/streetsmod/textures/streets_signworkshop_front.png new file mode 100644 index 0000000..83317b1 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_signworkshop_front.png differ diff --git a/mods/roads/streetsmod/textures/streets_signworkshop_side.png b/mods/roads/streetsmod/textures/streets_signworkshop_side.png new file mode 100644 index 0000000..509a3e3 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_signworkshop_side.png differ diff --git a/mods/roads/streetsmod/textures/streets_signworkshop_top.png b/mods/roads/streetsmod/textures/streets_signworkshop_top.png new file mode 100644 index 0000000..07f4f06 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_signworkshop_top.png differ diff --git a/mods/roads/streetsmod/textures/streets_sos_bottom.png b/mods/roads/streetsmod/textures/streets_sos_bottom.png new file mode 100644 index 0000000..f109fbf Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_sos_bottom.png differ diff --git a/mods/roads/streetsmod/textures/streets_sos_front.png b/mods/roads/streetsmod/textures/streets_sos_front.png new file mode 100644 index 0000000..83828c8 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_sos_front.png differ diff --git a/mods/roads/streetsmod/textures/streets_sos_side.png b/mods/roads/streetsmod/textures/streets_sos_side.png new file mode 100644 index 0000000..0be873f Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_sos_side.png differ diff --git a/mods/roads/streetsmod/textures/streets_sos_top.png b/mods/roads/streetsmod/textures/streets_sos_top.png new file mode 100644 index 0000000..bd4c693 Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_sos_top.png differ diff --git a/mods/roads/streetsmod/textures/streets_support.png b/mods/roads/streetsmod/textures/streets_support.png new file mode 100644 index 0000000..610a38a Binary files /dev/null and b/mods/roads/streetsmod/textures/streets_support.png differ diff --git a/mods/roads/streetspoles/depends.txt b/mods/roads/streetspoles/depends.txt new file mode 100644 index 0000000..421a27d --- /dev/null +++ b/mods/roads/streetspoles/depends.txt @@ -0,0 +1 @@ +streetsmod \ No newline at end of file diff --git a/mods/roads/streetspoles/init.lua b/mods/roads/streetspoles/init.lua new file mode 100644 index 0000000..fe24bf4 --- /dev/null +++ b/mods/roads/streetspoles/init.lua @@ -0,0 +1,191 @@ +--[[ + StreetsMod: Poles +]] + +-- Simple pole +minetest.register_node(":streets:pole_bottom",{ + description = streets.S("Pole"), + tiles = {"streets_pole.png"}, + groups = {cracky=2}, + inventory_image = "streets_pole_inv.png", + wield_image = "streets_pole_inv.png", + paramtype = "light", + paramtype2 = "facedir", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.1,-0.5,-0.5,0.1,0.5,-0.4}, + {-0.125,-0.5,-0.525,0.125,-0.3,-0.375} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.1,-0.5,-0.5,0.1,0.5,-0.4} + } + }, + after_place_node = function(pos,placer,itemstack) + pos.y = pos.y +1 + if minetest.get_node(pos).name == "air" then + minetest.add_node(pos,{name = "streets:pole_top", param2 = minetest.dir_to_facedir(placer:get_look_dir())}) + else + minetest.chat_send_player(placer:get_player_name(),"Not enough free space! A pole has a height of 2 blocks!") + pos.y = pos.y -1 + minetest.remove_node(pos) + end + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + pos.y = pos.y +1 + if minetest.get_node(pos).name == "streets:pole_top" then + minetest.remove_node(pos) + end + end +}) + +minetest.register_node(":streets:pole_top",{ + description = streets.S("Y u no play minetest without cheating?"), + tiles = {"streets_pole.png"}, + groups = {not_in_creative_inventory=1,cracky=2}, + paramtype = "light", + paramtype2 = "facedir", + drawtype = "nodebox", + drop = "", + node_box = { + type = "fixed", + fixed = { + {-0.1,-0.5,-0.5,0.1,0.5,-0.4} + } + } +}) + +minetest.register_craft({ + output = "streets:pole_bottom 3", + recipe = { + {"","default:steel_ingot",""}, + {"","default:steel_ingot",""}, + {"","default:steel_ingot",""} + } +}) + +-- Big pole + +minetest.register_node(":streets:bigpole", { + description = "Pole", + paramtype = "light", + paramtype2 = "facedir", + drawtype = "nodebox", + tiles = {"streets_pole.png"}, + sunlight_propagates = true, + groups = {cracky = 1, level = 2, bigpole = 1}, + node_box = { + type = "fixed", + fixed = { + {-0.15, -0.5, -0.15, 0.15, 0.5, 0.15} + } + }, + on_place = minetest.rotate_node, + digiline = { + wire = { + rules = { + {x= 0, y= 0, z=-1}, + {x= 0, y= 0, z= 1}, + {x= 1, y= 0, z= 0}, + {x=-1, y= 0, z= 0}, + {x= 0, y=-1, z= 0}, + {x= 0, y= 1, z= 0}, + {x= 0, y=-2, z= 0} + } + } + } +}) +minetest.register_node(":streets:bigpole_edge", { + description = "Pole", + drop = "streets:bigpole", + paramtype = "light", + paramtype2 = "facedir", + drawtype = "nodebox", + tiles = {"streets_pole.png"}, + sunlight_propagates = true, + groups = {cracky = 1, level = 2, bigpole = 1}, + node_box = { + type = "fixed", + fixed = { + {-0.15,-0.5,-0.15,0.15,0.15,0.15}, + {-0.15,-0.15,-0.15,0.15,0.15,-0.5} + } + }, + digiline = { + wire = { + rules = { + {x= 0, y= 0, z=-1}, + {x= 0, y= 0, z= 1}, + {x= 1, y= 0, z= 0}, + {x=-1, y= 0, z= 0}, + {x= 0, y=-1, z= 0}, + {x= 0, y= 1, z= 0}, + } + } + } +}) +minetest.register_node(":streets:bigpole_tjunction", { + description = "Pole", + drop = "streets:bigpole", + paramtype = "light", + paramtype2 = "facedir", + drawtype = "nodebox", + tiles = {"streets_pole.png"}, + sunlight_propagates = true, + groups = {cracky = 1, level = 2, bigpole = 1}, + node_box = { + type = "fixed", + fixed = { + {-0.15, -0.5, -0.15, 0.15, 0.15, 0.15}, + {-0.15, -0.15, -0.5, 0.15, 0.15, 0.5} + } + }, + digiline = { + wire = { + rules = { + {x= 0, y= 0, z=-1}, + {x= 0, y= 0, z= 1}, + {x= 1, y= 0, z= 0}, + {x=-1, y= 0, z= 0}, + {x= 0, y=-1, z= 0}, + {x= 0, y= 1, z= 0}, + } + } + } +}) +minetest.register_craft({ + output = "streets:bigpole 3", + recipe = { + {"","",""}, + {"","default:steel_ingot",""}, + {"","default:steel_ingot",""} + } +}) +minetest.register_craft({ + output = "streets:bigpole_edge 3", + recipe = { + {"","",""}, + {"streets:bigpole","streets:bigpole",""}, + {"streets:bigpole","",""} + } +}) +minetest.register_craft({ + output = "streets:bigpole_edge 3", + recipe = { + {"","",""}, + {"streets:bigpole","streets:bigpole",""}, + {"","streets:bigpole",""} + } +}) +minetest.register_craft({ + output = "streets:bigpole_tjunction 2", + recipe = { + {"","",""}, + {"streets:bigpole_edge","streets:bigpole",""}, + {"","",""} + } +}) diff --git a/mods/roads/trafficlight/depends.txt b/mods/roads/trafficlight/depends.txt new file mode 100644 index 0000000..e437ca2 --- /dev/null +++ b/mods/roads/trafficlight/depends.txt @@ -0,0 +1 @@ +streetsmod diff --git a/mods/roads/trafficlight/init.lua b/mods/roads/trafficlight/init.lua new file mode 100644 index 0000000..f099128 --- /dev/null +++ b/mods/roads/trafficlight/init.lua @@ -0,0 +1,1811 @@ +--[[ + StreetsMod: inDev Trafficlights +]] +dofile(streets.modpath .. "/../trafficlight/old2new.lua") + +streets.tlBox = { + {-0.1875,-0.5,0.5,0.1875,0.5,0.75}, --Box + + {-0.125, -0.125, 0.85, 0.125, 0.125, 0.75}, -- Pole Mounting Bracket + + {-0.125,0.3125,0.3125,-0.0625,0.375,0.5}, --Top Visor, Left + {-0.0625,0.375,0.3125,0.0625,0.4375,0.5}, --Top Visor, Center + {0.0625,0.3125,0.3125,0.125,0.38,0.5}, --Top Visor, Right + + {-0.125,0,0.3125,-0.0625,0.0625,0.5}, --Middle Visor, Left + {-0.0625,0.0625,0.3125,0.0625,0.125,0.5}, --Middle Visor, Center + {0.0625,0,0.3125,0.125,0.0625,0.5}, --Middle Visor, Right + + {-0.125,-0.3125,0.3125,-0.0625,-0.25,0.5}, --Bottom Visor, Left + {-0.0625,-0.25,0.3125,0.0625,-0.1875,0.5}, --Bottom Visor, Center + {0.0625,-0.3125,0.3125,0.125,-0.25,0.5}, --Bottom Visor, Right +} + +streets.tleBox = { + {-0.1875,-0.1875,0.5,0.1875,0.5,0.75}, --Box + + {-0.125,0.3125,0.3125,-0.0625,0.375,0.5}, --Top Visor, Left + {-0.0625,0.375,0.3125,0.0625,0.4375,0.5}, --Top Visor, Center + {0.0625,0.3125,0.3125,0.125,0.38,0.5}, --Top Visor, Right + + {-0.125,0,0.3125,-0.0625,0.0625,0.5}, --Middle Visor, Left + {-0.0625,0.0625,0.3125,0.0625,0.125,0.5}, --Middle Visor, Center + {0.0625,0,0.3125,0.125,0.0625,0.5}, --Middle Visor, Right +} + +streets.plBox = { + {-0.1875,-0.5,0.5,0.1875,0.5,0.75}, --Box + + {-0.125, -0.125, 0.85, 0.125, 0.125, 0.75}, -- Pole Mounting Bracket + + {-0.1875,0.0625,0.3125,-0.1375,0.4375,0.5}, --Top Visor, Left + {-0.1375,0.3875,0.3125,0.1375,0.4375,0.5}, --Top Visor, Center + {0.1875,0.0625,0.3125,0.1375,0.4375,0.5}, --Top Visor, Right + + {-0.1875,-0.0625,0.3125,-0.1375,-0.4375,0.5}, --Bottom Visor, Left + {-0.1375,-0.0625,0.3125,0.1375,-0.1125,0.5}, --Bottom Visor, Center + {0.1875,-0.0625,0.3125,0.1375,-0.4375,0.5}, --Bottom Visor, Right +} + +streets.bBox = { + {-0.1875,-0.1875,0.5,0.1875,0.1875,0.75}, --Box + + {-0.125, -0.125, 0.85, 0.125, 0.125, 0.75}, -- Pole Mounting Bracket + + {-0.125,0,0.3125,-0.0625,0.0625,0.5}, --Visor, Left + {-0.0625,0.0625,0.3125,0.0625,0.125,0.5}, --Visor, Center + {0.0625,0,0.3125,0.125,0.0625,0.5}, --Visor, Right +} + +streets.hbBox = { + {-0.375,-0.25,0.5,0.375,0.25,0.75}, --Box + + {-0.125, -0.125, 0.85, 0.125, 0.125, 0.75}, -- Pole Mounting Bracket + + {-0.3,0.0625,0.3125,-0.2375,0.125,0.5}, --Top Left Visor, Left + {-0.2375,0.125,0.3125,-0.1125,0.1875,0.5}, --Top Left Visor, Center + {-0.1125,0.0625,0.3125,-0.05,0.125,0.5}, --Top Left Visor, Right + + {0.1125,0.0625,0.3125,0.05,0.125,0.5}, --Top Right Visor, Left + {0.2375,0.125,0.3125,0.1125,0.1875,0.5}, --Top Right Visor, Center + {0.3,0.0625,0.3125,0.2375,0.125,0.5}, --Top Right Visor, Right + + {-0.125,-0.125,0.3125,-0.0625,-0.0625,0.5}, --Bottom Visor, Left + {-0.0625,-0.0625,0.3125,0.0625,0,0.5}, --Bottom Visor, Center + {0.0625,-0.125,0.3125,0.125,-0.0625,0.5}, --Bottom Visor, Right +} + +streets.rrfbBox = { + {-0.375,0.05,0.5,0.375,0.3,0.75}, --Box + + {-0.125, 0.125, 0.85, 0.125, 0.25, 0.75}, -- Pole Mounting Bracket + + --These usually don't have visors +} + +streets.tlDigilineRules = { + {x= 0, y= 0, z=-1}, + {x= 0, y= 0, z= 1}, + {x= 1, y= 0, z= 0}, + {x=-1, y= 0, z= 0}, + {x= 0, y=-1, z= 0}, + {x= 0, y= 1, z= 0} + } + +local function ped_on_flash_start(pos) + local timer = minetest.get_node_timer(pos) + timer:set(99,0) +end + +local function ped_on_flash_end(pos,record) + local objs = minetest.get_objects_inside_radius(pos,1.5) + for _,obj in pairs(objs) do + if obj:get_luaentity() and obj:get_luaentity().name == "streets:pedcountdown" then + obj:remove() + end + end + local timer = minetest.get_node_timer(pos) + if not record then + timer:stop() + return + end + local meta = minetest.get_meta(pos) + local lastflashtime = meta:get_int("lastflashtime") + local twoflashesago = meta:get_int("twoflashesago") + local flashtime = math.min(timer:get_elapsed(),99) + meta:set_int("twoflashesago",lastflashtime) + meta:set_int("lastflashtime",flashtime) + if math.abs(twoflashesago-lastflashtime) + math.abs(lastflashtime-flashtime) < 3 then + meta:set_int("flashtime",flashtime) + end + timer:stop() +end + +streets.tlSwitch = function(pos,to) + if not pos or not to then + return + end + minetest.swap_node(pos, {name = to, param2 = minetest.get_node(pos).param2}) +end + +streets.on_digiline_receive = function(pos, node, channel, msg) + local setchan = minetest.get_meta(pos):get_string("channel") + if setchan ~= channel then + return + end + -- Tl states + local name = minetest.get_node(pos).name + local althalfhz = minetest.get_node(pos).param2 % 2 == 1 + if msg == "OFF" then + if name:find("pedlight") then + if name == "streets:pedlight_top_flashingdontwalk" then + ped_on_flash_end(pos,false) + end + streets.tlSwitch(pos,"streets:pedlight_top_off") + elseif name:find("extender_left") then + streets.tlSwitch(pos,"streets:trafficlight_top_extender_left_off") + elseif name:find("extender_right") then + streets.tlSwitch(pos,"streets:trafficlight_top_extender_right_off") + elseif name:find("left") then + streets.tlSwitch(pos,"streets:trafficlight_top_left_off") + elseif name:find("right") then + streets.tlSwitch(pos,"streets:trafficlight_top_right_off") + elseif name:find("beacon_hybrid") then + streets.tlSwitch(pos,"streets:beacon_hybrid_off") + elseif name:find("beacon") then + streets.tlSwitch(pos,"streets:beacon_off") + elseif name:find("rrfb") then + streets.tlSwitch(pos,"streets:trafficlight_rrfb_off") + else + streets.tlSwitch(pos,"streets:trafficlight_top_off") + end + elseif msg == "GREEN" then + if name:find("pedlight") then + if name == "streets:pedlight_top_flashingdontwalk" then + ped_on_flash_end(pos,false) + end + streets.tlSwitch(pos,"streets:pedlight_top_walk") + elseif name:find("extender_left") then + streets.tlSwitch(pos,"streets:trafficlight_top_extender_left_green") + elseif name:find("extender_right") then + streets.tlSwitch(pos,"streets:trafficlight_top_extender_right_green") + elseif name:find("left") then + streets.tlSwitch(pos,"streets:trafficlight_top_left_green") + elseif name:find("right") then + streets.tlSwitch(pos,"streets:trafficlight_top_right_green") + elseif name:find("beacon_hybrid") then + --Not Supported + elseif name:find("beacon") then + --Not Supported + elseif name:find("rrfb") then + --Not Supported + else + streets.tlSwitch(pos,"streets:trafficlight_top_green") + end + elseif msg == "FLASHGREEN" then + if name:find("pedlight") then + if name == "streets:pedlight_top_flashingdontwalk" then + ped_on_flash_end(pos,false) + end + streets.tlSwitch(pos,"streets:pedlight_top_flashingwalk") + elseif name:find("extender_left") then + streets.tlSwitch(pos,"streets:trafficlight_top_extender_left_flashgreen") + elseif name:find("extender_right") then + streets.tlSwitch(pos,"streets:trafficlight_top_extender_right_flashgreen") + elseif name:find("left") then + streets.tlSwitch(pos,"streets:trafficlight_top_left_flashgreen") + elseif name:find("right") then + streets.tlSwitch(pos,"streets:trafficlight_top_right_flashgreen") + elseif name:find("beacon_hybrid") then + --Not Supported + elseif name:find("beacon") then + --Not Supported + elseif name:find("rrfb") then + --Not Supported + else + streets.tlSwitch(pos,"streets:trafficlight_top_flashgreen") + end + elseif msg == "RED" then + if name:find("pedlight") then + if name == "streets:pedlight_top_flashingdontwalk" then + ped_on_flash_end(pos,true) + end + streets.tlSwitch(pos,"streets:pedlight_top_dontwalk") + elseif name:find("extender_left") then + streets.tlSwitch(pos,"streets:trafficlight_top_extender_left_off") + elseif name:find("extender_right") then + streets.tlSwitch(pos,"streets:trafficlight_top_extender_right_off") + elseif name:find("left") then + streets.tlSwitch(pos,"streets:trafficlight_top_left_red") + elseif name:find("right") then + streets.tlSwitch(pos,"streets:trafficlight_top_right_red") + elseif name:find("beacon_hybrid") then + streets.tlSwitch(pos,"streets:beacon_hybrid_red") + elseif name:find("beacon") then + streets.tlSwitch(pos,"streets:beacon_red") + elseif name:find("rrfb") then + --Not Supported + else + streets.tlSwitch(pos,"streets:trafficlight_top_red") + end + elseif msg == "WARN" or msg == "FLASHYELLOW" then + if name:find("pedlight") then + if name ~= "streets:pedlight_top_flashingdontwalk" then + ped_on_flash_start(pos) + end + streets.tlSwitch(pos,"streets:pedlight_top_flashingdontwalk") + elseif name:find("extender_left") then + if althalfhz then + streets.tlSwitch(pos,"streets:trafficlight_top_extender_left_flashyellow_alt") + else + streets.tlSwitch(pos,"streets:trafficlight_top_extender_left_flashyellow") + end + elseif name:find("extender_right") then + if althalfhz then + streets.tlSwitch(pos,"streets:trafficlight_top_extender_right_flashyellow_alt") + else + streets.tlSwitch(pos,"streets:trafficlight_top_extender_right_flashyellow") + end + elseif name:find("left") then + if althalfhz then + streets.tlSwitch(pos,"streets:trafficlight_top_left_warn_alt") + else + streets.tlSwitch(pos,"streets:trafficlight_top_left_warn") + end + elseif name:find("right") then + if althalfhz then + streets.tlSwitch(pos,"streets:trafficlight_top_right_warn_alt") + else + streets.tlSwitch(pos,"streets:trafficlight_top_right_warn") + end + elseif name:find("beacon_hybrid") then + streets.tlSwitch(pos,"streets:beacon_hybrid_flashyellow") + elseif name:find("beacon") then + streets.tlSwitch(pos,"streets:beacon_flashyellow") + elseif name:find("rrfb") then + streets.tlSwitch(pos,"streets:trafficlight_rrfb_on") + else + if althalfhz then + streets.tlSwitch(pos,"streets:trafficlight_top_warn_alt") + else + streets.tlSwitch(pos,"streets:trafficlight_top_warn") + end + end + elseif msg == "YELLOW" then + if name:find("pedlight") then + if name ~= "streets:pedlight_top_flashingdontwalk" then + ped_on_flash_start(pos) + end + streets.tlSwitch(pos,"streets:pedlight_top_flashingdontwalk") + elseif name:find("extender_left") then + streets.tlSwitch(pos,"streets:trafficlight_top_extender_left_yellow") + elseif name:find("extender_right") then + streets.tlSwitch(pos,"streets:trafficlight_top_extender_right_yellow") + elseif name:find("left") then + streets.tlSwitch(pos,"streets:trafficlight_top_left_yellow") + elseif name:find("right") then + streets.tlSwitch(pos,"streets:trafficlight_top_right_yellow") + elseif name:find("beacon_hybrid") then + streets.tlSwitch(pos,"streets:beacon_hybrid_yellow") + elseif name:find("beacon") then + streets.tlSwitch(pos,"streets:beacon_yellow") + elseif name:find("rrfb") then + --Not Supported + else + streets.tlSwitch(pos,"streets:trafficlight_top_yellow") + end + elseif msg == "REDYELLOW" then + if name:find("pedlight") then + --Not Supported + elseif name:find("extender_left") then + --Not Supported + elseif name:find("extender_right") then + --Not Supported + elseif name:find("left") then + streets.tlSwitch(pos,"streets:trafficlight_top_left_redyellow") + elseif name:find("right") then + streets.tlSwitch(pos,"streets:trafficlight_top_right_redyellow") + elseif name:find("beacon_hybrid") then + --Not Supported + elseif name:find("beacon") then + --Not Supported + elseif name:find("rrfb") then + --Not Supported + else + streets.tlSwitch(pos,"streets:trafficlight_top_redyellow") + end + elseif msg == "FLASHRED" then + if name:find("pedlight") then + if name ~= "streets:pedlight_top_flashingdontwalk" then + ped_on_flash_start(pos) + end + streets.tlSwitch(pos,"streets:pedlight_top_flashingdontwalk") + elseif name:find("extender_left") then + streets.tlSwitch(pos,"streets:trafficlight_top_extender_left_off") + elseif name:find("extender_right") then + streets.tlSwitch(pos,"streets:trafficlight_top_extender_right_off") + elseif name:find("left") then + if althalfhz then + streets.tlSwitch(pos,"streets:trafficlight_top_left_flashred_alt") + else + streets.tlSwitch(pos,"streets:trafficlight_top_left_flashred") + end + elseif name:find("right") then + if althalfhz then + streets.tlSwitch(pos,"streets:trafficlight_top_right_flashred_alt") + else + streets.tlSwitch(pos,"streets:trafficlight_top_right_flashred") + end + elseif name:find("beacon_hybrid") then + streets.tlSwitch(pos,"streets:beacon_hybrid_flashred") + elseif name:find("beacon") then + streets.tlSwitch(pos,"streets:beacon_flashred") + elseif name:find("rrfb") then + --Not Supported + else + if althalfhz then + streets.tlSwitch(pos,"streets:trafficlight_top_flashred_alt") + else + streets.tlSwitch(pos,"streets:trafficlight_top_flashred") + end + end + end +end + +minetest.register_node(":streets:digiline_distributor",{ + description = streets.S("Digiline distributor"), + tiles = {"streets_lampcontroller_top.png","streets_lampcontroller_bottom.png","streets_lampcontroller_sides.png"}, + groups = {cracky = 1}, + drawtype = "nodebox", + paramtype = "light", + node_box = { + type = "fixed", + fixed = { + {-0.5,-0.5,-0.5,0.5,0.5,0.5}, + {-0.05,0.5,-0.05,0.05,1.6,0.05} + } + }, + digiline = { + wire = { + rules = { + {x= 0, y= 0, z=-1}, + {x= 0, y= 0, z= 1}, + {x= 1, y= 0, z= 0}, + {x=-1, y= 0, z= 0}, + {x= 0, y= 2, z=0} + } + } + } +}) + +minetest.register_node(":streets:beacon_hybrid_off",{ + description = "Hybrid Beacon", + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2}, + inventory_image = "streets_hybrid_beacon_inv.png", + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.hbBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_hb_off.png"}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:beacon_hybrid_yellow",{ + drop = "streets:beacon_hybrid_off", + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2, not_in_creative_inventory = 1}, + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.hbBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_hb_yellow.png"}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:beacon_hybrid_red",{ + drop = "streets:beacon_hybrid_off", + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2, not_in_creative_inventory = 1}, + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.hbBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_hb_red.png"}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:beacon_hybrid_flashyellow",{ + drop = "streets:beacon_hybrid_off", + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2, not_in_creative_inventory = 1}, + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.hbBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png",{ + name="streets_hb_flashyellow.png", + animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.2}, + }}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:beacon_hybrid_flashred",{ + drop = "streets:beacon_hybrid_off", + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2, not_in_creative_inventory = 1}, + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.hbBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png",{ + name="streets_hb_flashred.png", + animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.2}, + }}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:beacon_off",{ + description = "Beacon", + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2}, + inventory_image = "streets_beacon_inv.png", + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.bBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_off.png"}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:beacon_red",{ + drop = "streets:beacon_off", + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2, not_in_creative_inventory = 1}, + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.bBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_b_red.png"}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:beacon_yellow",{ + drop = "streets:beacon_off", + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2, not_in_creative_inventory = 1}, + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.bBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_yellow.png"}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:beacon_flashred",{ + drop = "streets:beacon_off", + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2, not_in_creative_inventory = 1}, + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.bBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png",{ + name="streets_b_flashred.png", + animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.2}, + }}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:beacon_flashyellow",{ + drop = "streets:beacon_off", + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2, not_in_creative_inventory = 1}, + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.bBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png",{ + name="streets_tl_warn.png", + animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.2}, + }}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:trafficlight_top_extender_left_off",{ + description = streets.S("Traffic Light Left-Turn Module"), + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2}, + inventory_image = "streets_trafficlight_inv_extender_left.png", + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.tleBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_left_off.png"}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:trafficlight_top_extender_left_yellow",{ + drop = "streets:trafficlight_top_extender_left_off", + description = streets.S("Traffic Light Left-Turn Module"), + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2, not_in_creative_inventory = 1}, + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.tleBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tle_left_yellow.png"}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:trafficlight_top_extender_left_flashyellow",{ + drop = "streets:trafficlight_top_extender_left_off", + description = streets.S("Traffic Light Left-Turn Module"), + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2, not_in_creative_inventory = 1}, + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.tleBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png",{ + name="streets_tl_left_warn.png", + animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.2}, + }}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:trafficlight_top_extender_left_flashyellow_alt",{ + drop = "streets:trafficlight_top_extender_left_off", + description = streets.S("Traffic Light Left-Turn Module"), + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2, not_in_creative_inventory = 1}, + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.tleBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png",{ + name="streets_tl_left_warn_alt.png", + animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.2}, + }}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:trafficlight_top_extender_left_flashgreen",{ + drop = "streets:trafficlight_top_extender_left_off", + description = streets.S("Traffic Light Left-Turn Module"), + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2, not_in_creative_inventory = 1}, + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.tleBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png",{ + name="streets_tle_left_flashgreen.png", + animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.2}, + }}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:trafficlight_top_extender_left_green",{ + drop = "streets:trafficlight_top_extender_left_off", + description = streets.S("Traffic Light Left-Turn Module"), + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2, not_in_creative_inventory = 1}, + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.tleBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tle_left_green.png"}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:trafficlight_top_extender_right_off",{ + description = streets.S("Traffic Light Right-Turn Module"), + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2}, + inventory_image = "streets_trafficlight_inv_extender_right.png", + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.tleBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_right_off.png"}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:trafficlight_top_extender_right_yellow",{ + drop = "streets:trafficlight_top_extender_right_off", + description = streets.S("Traffic Light Right-Turn Module"), + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2, not_in_creative_inventory = 1}, + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.tleBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tle_right_yellow.png"}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:trafficlight_top_extender_right_flashyellow",{ + drop = "streets:trafficlight_top_extender_right_off", + description = streets.S("Traffic Light Right-Turn Module"), + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2, not_in_creative_inventory = 1}, + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.tleBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png",{ + name="streets_tl_right_warn.png", + animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.2}, + }}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:trafficlight_top_extender_right_flashyellow_alt",{ + drop = "streets:trafficlight_top_extender_right_off", + description = streets.S("Traffic Light Right-Turn Module"), + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2, not_in_creative_inventory = 1}, + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.tleBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png",{ + name="streets_tl_right_warn_alt.png", + animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.2}, + }}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:trafficlight_top_extender_right_flashgreen",{ + drop = "streets:trafficlight_top_extender_right_off", + description = streets.S("Traffic Light Right-Turn Module"), + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2, not_in_creative_inventory = 1}, + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.tleBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png",{ + name="streets_tle_right_flashgreen.png", + animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.2}, + }}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:trafficlight_top_extender_right_green",{ + drop = "streets:trafficlight_top_extender_left_off", + description = streets.S("Traffic Light Right-Turn Module"), + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2, not_in_creative_inventory = 1}, + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.tleBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tle_right_green.png"}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + + + +minetest.register_node(":streets:pedlight_top_off",{ + description = streets.S("Pedestrian Light"), + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2}, + inventory_image = "streets_pedlight_inv.png", + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.plBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_pl_off.png"}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:pedlight_top_dontwalk",{ + drop = "streets:pedlight_top_off", + groups = {cracky = 1, not_in_creative_inventory = 1}, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + drawtype = "nodebox", + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_pl_dontwalk.png"}, + node_box = { + type = "fixed", + fixed = streets.plBox + }, + light_source = 6, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, +}) + +minetest.register_node(":streets:pedlight_top_walk",{ + drop = "streets:pedlight_top_off", + groups = {cracky = 1, not_in_creative_inventory = 1}, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + drawtype = "nodebox", + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_pl_walk.png"}, + node_box = { + type = "fixed", + fixed = streets.plBox + }, + light_source = 6, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, +}) + +minetest.register_node(":streets:pedlight_top_flashingdontwalk",{ + drop = "streets:pedlight_top_off", + groups = {cracky = 1, not_in_creative_inventory = 1}, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + drawtype = "nodebox", + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png",{ + name="streets_pl_flashingdontwalk.png", + animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.2}, + }}, + node_box = { + type = "fixed", + fixed = streets.plBox + }, + light_source = 6, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, +}) + +minetest.register_node(":streets:pedlight_top_flashingwalk",{ + drop = "streets:pedlight_top_off", + groups = {cracky = 1, not_in_creative_inventory = 1}, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + drawtype = "nodebox", + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png",{ + name="streets_pl_flashingwalk.png", + animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.2}, + }}, + node_box = { + type = "fixed", + fixed = streets.plBox + }, + light_source = 6, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, +}) + +minetest.register_entity(":streets:pedcountdown",{ + physical = false, + collisionbox = {0,0,0,0,0,0}, + visual = "upright_sprite", + textures = {"streets_pl_number_0l.png"} +}) + +minetest.register_abm({ + label = "Update pedestrian countdown time display", + nodenames = {"streets:pedlight_top_flashingdontwalk"}, + interval = 1, + chance = 1, + catch_up = false, + action = function(pos,node) + local meta = minetest.get_meta(pos) + local timer = minetest.get_node_timer(pos) + local totaltime = meta:get_int("flashtime") + local timesofar = timer:get_elapsed() + local timeleft = math.max(0,totaltime-timesofar) + local objs = minetest.get_objects_inside_radius(pos,1.5) + for _,obj in pairs(objs) do + if obj:get_luaentity() and obj:get_luaentity().name == "streets:pedcountdown" then + obj:remove() + end + end + local backdir = minetest.facedir_to_dir(node.param2) + local frontdir = vector.multiply(backdir,-1) + local entpos = vector.add(vector.multiply(frontdir,-0.495),pos) + local entity = minetest.add_entity(entpos,"streets:pedcountdown") + local yaw = 0 + if backdir.z == -1 then + yaw = math.pi + elseif backdir.x == 1 then + yaw = math.pi / 2 + elseif backdir.x == -1 then + yaw = math.pi / -2 + end + --Circles are hard... + entity:setyaw(yaw) + + local ldigit = math.floor(timeleft/10) + local rdigit = timeleft % 10 + local tex = string.format("streets_pl_number_%01dl.png^streets_pl_number_%01dr.png",ldigit,rdigit) + entity:set_properties({textures={tex}}) + end +}) + + +for _,i in pairs({"","_left","_right"}) do + minetest.register_node(":streets:trafficlight_top"..i.."_off",{ + description = streets.S((i == "" and "Traffic Light") or (i == "_left" and "Traffic Light (Left Turn)") or (i == "_right" and "Traffic Light (Right Turn)")), + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2}, + inventory_image = ((i == "") and "streets_trafficlight_inv_straight.png") or ((i == "_left") and "streets_trafficlight_inv_left.png") or ((i == "_right") and "streets_trafficlight_inv_right.png"), + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.tlBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl"..i.."_off.png"}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, + }) + + minetest.register_node(":streets:trafficlight_top"..i.."_red",{ + drop = "streets:trafficlight_top"..i.."_off", + groups = {cracky = 1, not_in_creative_inventory = 1}, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + drawtype = "nodebox", + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl"..i.."_red.png"}, + node_box = { + type = "fixed", + fixed = streets.tlBox + }, + light_source = 6, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + }) + + minetest.register_node(":streets:trafficlight_top"..i.."_yellow",{ + drop = "streets:trafficlight_top"..i.."_off", + groups = {cracky = 1, not_in_creative_inventory = 1}, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + drawtype = "nodebox", + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl"..i.."_yellow.png"}, + node_box = { + type = "fixed", + fixed = streets.tlBox + }, + light_source = 6, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + }) + + minetest.register_node(":streets:trafficlight_top"..i.."_redyellow",{ + drop = "streets:trafficlight_top"..i.."_off", + groups = {cracky = 1, not_in_creative_inventory = 1}, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + drawtype = "nodebox", + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl"..i.."_redyellow.png"}, + node_box = { + type = "fixed", + fixed = streets.tlBox + }, + light_source = 6, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + }) + + minetest.register_node(":streets:trafficlight_top"..i.."_green",{ + drop = "streets:trafficlight_top"..i.."_off", + groups = {cracky = 1, not_in_creative_inventory = 1}, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + drawtype = "nodebox", + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl"..i.."_green.png"}, + node_box = { + type = "fixed", + fixed = streets.tlBox + }, + light_source = 6, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + }) + + minetest.register_node(":streets:trafficlight_top"..i.."_warn",{ + drop = "streets:trafficlight_top"..i.."_off", + groups = {cracky = 1, not_in_creative_inventory = 1}, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + drawtype = "nodebox", + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png",{ + name="streets_tl"..i.."_warn.png", + animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.2}, + }}, + node_box = { + type = "fixed", + fixed = streets.tlBox + }, + light_source = 6, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + }) + + minetest.register_node(":streets:trafficlight_top"..i.."_flashred",{ + drop = "streets:trafficlight_top"..i.."_off", + groups = {cracky = 1, not_in_creative_inventory = 1}, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + drawtype = "nodebox", + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png",{ + name="streets_tl"..i.."_flashred.png", + animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.2}, + }}, + node_box = { + type = "fixed", + fixed = streets.tlBox + }, + light_source = 6, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + }) + + minetest.register_node(":streets:trafficlight_top"..i.."_warn_alt",{ + drop = "streets:trafficlight_top"..i.."_off", + groups = {cracky = 1, not_in_creative_inventory = 1}, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + drawtype = "nodebox", + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png",{ + name="streets_tl"..i.."_warn_alt.png", + animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.2}, + }}, + node_box = { + type = "fixed", + fixed = streets.tlBox + }, + light_source = 6, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + }) + + minetest.register_node(":streets:trafficlight_top"..i.."_flashred_alt",{ + drop = "streets:trafficlight_top"..i.."_off", + groups = {cracky = 1, not_in_creative_inventory = 1}, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + drawtype = "nodebox", + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png",{ + name="streets_tl"..i.."_flashred_alt.png", + animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.2}, + }}, + node_box = { + type = "fixed", + fixed = streets.tlBox + }, + light_source = 6, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + }) + + minetest.register_node(":streets:trafficlight_top"..i.."_flashgreen",{ + drop = "streets:trafficlight_top"..i.."_off", + groups = {cracky = 1, not_in_creative_inventory = 1}, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + drawtype = "nodebox", + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png",{ + name="streets_tl"..i.."_flashgreen.png", + animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.2}, + }}, + node_box = { + type = "fixed", + fixed = streets.tlBox + }, + light_source = 6, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + }) +end + +minetest.register_node(":streets:trafficlight_rrfb_off",{ + description = streets.S("Rectangular Rapid Flashing Beacon"), + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2}, + inventory_image = "streets_rrfb_inv.png", + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.rrfbBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_rrfb_off.png"}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:trafficlight_rrfb_on",{ + drop = "streets:trafficlight_rrfb_off", + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2, not_in_creative_inventory = 1}, + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.rrfbBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png",{ + name="streets_rrfb_on.png", + animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=0.75}, + }}, + digiline = { + receptor = {}, + wire = {rules=streets.tlDigilineRules}, + effector = { + action = function(pos, node, channel, msg) + streets.on_digiline_receive(pos, node, channel, msg) + end + } + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + if (fields.channel) then + minetest.get_meta(pos):set_string("channel", fields.channel) + minetest.get_meta(pos):set_string("state", "Off") + end + end, +}) + +minetest.register_node(":streets:green_arrow",{ + description = "Straight-through green arrow", + drawtype="nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1, level = 2}, + inventory_image = "streets_trafficlight_inv_greenarrow.png", + light_source = 11, + sunlight_propagates = true, + node_box = { + type = "fixed", + fixed = streets.bBox + }, + tiles = {"streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_bg.png","streets_tl_straight_green.png"} +}) + +minetest.register_craft({ + output = "streets:trafficlight_top_off", + recipe = { + {"default:steel_ingot", "dye:red", "default:steel_ingot"}, + {"default:steel_ingot", "dye:yellow", "default:steel_ingot"}, + {"default:steel_ingot", "dye:green", "default:steel_ingot"} + } +}) + +minetest.register_craft({ + output = "streets:trafficlight_top_left_off", + recipe = { + {"dye:red", "default:steel_ingot", "default:steel_ingot"}, + {"dye:yellow", "default:steel_ingot", "default:steel_ingot"}, + {"dye:green", "default:steel_ingot", "default:steel_ingot"} + } +}) + +minetest.register_craft({ + output = "streets:trafficlight_top_right_off", + recipe = { + {"default:steel_ingot", "default:steel_ingot", "dye:red"}, + {"default:steel_ingot", "default:steel_ingot", "dye:yellow"}, + {"default:steel_ingot", "default:steel_ingot", "dye:green"} + } +}) + +minetest.register_craft({ + output = "streets:pedlight_top_off", + recipe = { + {"default:steel_ingot", "dye:orange", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"default:steel_ingot", "dye:white", "default:steel_ingot"} + } +}) + +minetest.register_craft({ + output = "streets:trafficlight_top_extender_left_off", + recipe = { + {"dye:yellow", "default:steel_ingot", "default:steel_ingot"}, + {"dye:green", "default:steel_ingot", "default:steel_ingot"} + } +}) + +minetest.register_craft({ + output = "streets:trafficlight_top_extender_right_off", + recipe = { + {"default:steel_ingot", "default:steel_ingot", "dye:yellow"}, + {"default:steel_ingot", "default:steel_ingot", "dye:green"} + } +}) + +minetest.register_craft({ + output = "streets:beacon_off", + recipe = { + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"default:steel_ingot", "dye:red", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"} + } +}) + +minetest.register_craft({ + output = "streets:beacon_hybrid_off", + recipe = { + {"dye:red", "default:steel_ingot", "dye:red"}, + {"default:steel_ingot", "dye:yellow", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"} + } +}) + +minetest.register_craft({ + output = "streets:trafficlight_rrfb_off", + recipe = { + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"dye:yellow", "default:steel_ingot", "dye:yellow"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"} + } +}) + +minetest.register_craft({ + output = "streets:green_arrow", + recipe = { + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"default:steel_ingot", "dye:green", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"} + } +}) + +minetest.register_craft({ + output = "streets:digiline_distributor", + recipe = { + {"", "digilines:wire_std_00000000", ""}, + {"digilines:wire_std_00000000", "mesecons_luacontroller:luacontroller0000", "digilines:wire_std_00000000"}, + {"", "digilines:wire_std_00000000", ""} + } +}) diff --git a/mods/roads/trafficlight/old2new.lua b/mods/roads/trafficlight/old2new.lua new file mode 100644 index 0000000..51ba9f3 --- /dev/null +++ b/mods/roads/trafficlight/old2new.lua @@ -0,0 +1,58 @@ +--[[ + StreetsMod: Convert old trafficlights +]] +minetest.register_node(":streets:trafficlight_bottom", { + diggable = false, + pointable = false, + drawtype = "airlike", + description = "I'm an old node, please drop me", + groups = {not_in_creative_inventory = 1} +}) +minetest.register_abm({ + nodenames = {"streets:trafficlight_bottom"}, + interval = 1, + chance = 1, + action = function(pos, node) + minetest.log("action", "Converting trafficlight at position " .. minetest.pos_to_string(pos)) + -- Replace controller with distributor + pos.y = pos.y - 2 + minetest.set_node(pos, {name = "streets:digiline_distributor"}) + -- Change bottom pole + pos.y = pos.y + 2 + minetest.set_node(pos, {name = "streets:bigpole", param2 = 2}) + -- Change middle pole + pos.y = pos.y + 1 + minetest.set_node(pos, {name = "streets:bigpole", param2 = 2}) + -- Change the top + pos.y = pos.y + 1 + local fd = minetest.get_node(pos).param2 + local ch = minetest.get_meta(pos):get_string("channel") + minetest.set_node(pos, {name = "streets:bigpole", param2 = 2}) + -- Place new top + if fd == 1 then + minetest.set_node({x = pos.x - 1, y = pos.y, z = pos.z}, {name = "streets:trafficlight_top_warn", param2 = fd}) + local meta = minetest.get_meta({x = pos.x - 1, y = pos.y, z = pos.z}) + meta:set_string("channel", ch) + meta:set_string("state", "warn") + meta:set_string("formspec", "field[channel;Channel;${channel}]") + elseif fd == 2 then + minetest.set_node({x = pos.x, y = pos.y, z = pos.z + 1}, {name = "streets:trafficlight_top_warn", param2 = fd}) + local meta = minetest.get_meta({x = pos.x, y = pos.y, z = pos.z + 1}) + meta:set_string("channel", ch) + meta:set_string("state", "warn") + meta:set_string("formspec", "field[channel;Channel;${channel}]") + elseif fd == 3 then + minetest.set_node({x = pos.x + 1, y = pos.y, z = pos.z}, {name = "streets:trafficlight_top_warn", param2 = fd}) + local meta = minetest.get_meta({x = pos.x + 1, y = pos.y, z = pos.z}) + meta:set_string("channel", ch) + meta:set_string("state", "warn") + meta:set_string("formspec", "field[channel;Channel;${channel}]") + elseif fd == 0 then + minetest.set_node({x = pos.x, y = pos.y, z = pos.z - 1}, {name = "streets:trafficlight_top_warn", param2 = fd}) + local meta = minetest.get_meta({x = pos.x, y = pos.y, z = pos.z - 1}) + meta:set_string("channel", ch) + meta:set_string("state", "warn") + meta:set_string("formspec", "field[channel;Channel;${channel}]") + end + end +}) \ No newline at end of file diff --git a/mods/roads/trafficlight/textures/streets_b_flashred.png b/mods/roads/trafficlight/textures/streets_b_flashred.png new file mode 100644 index 0000000..8f20032 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_b_flashred.png differ diff --git a/mods/roads/trafficlight/textures/streets_b_red.png b/mods/roads/trafficlight/textures/streets_b_red.png new file mode 100644 index 0000000..7419027 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_b_red.png differ diff --git a/mods/roads/trafficlight/textures/streets_beacon_inv.png b/mods/roads/trafficlight/textures/streets_beacon_inv.png new file mode 100644 index 0000000..bd9a700 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_beacon_inv.png differ diff --git a/mods/roads/trafficlight/textures/streets_hb_flashred.png b/mods/roads/trafficlight/textures/streets_hb_flashred.png new file mode 100644 index 0000000..7b0afa2 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_hb_flashred.png differ diff --git a/mods/roads/trafficlight/textures/streets_hb_flashyellow.png b/mods/roads/trafficlight/textures/streets_hb_flashyellow.png new file mode 100644 index 0000000..3e97632 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_hb_flashyellow.png differ diff --git a/mods/roads/trafficlight/textures/streets_hb_off.png b/mods/roads/trafficlight/textures/streets_hb_off.png new file mode 100644 index 0000000..999e1a4 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_hb_off.png differ diff --git a/mods/roads/trafficlight/textures/streets_hb_red.png b/mods/roads/trafficlight/textures/streets_hb_red.png new file mode 100644 index 0000000..4dc175e Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_hb_red.png differ diff --git a/mods/roads/trafficlight/textures/streets_hb_yellow.png b/mods/roads/trafficlight/textures/streets_hb_yellow.png new file mode 100644 index 0000000..27f97dd Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_hb_yellow.png differ diff --git a/mods/roads/trafficlight/textures/streets_hybrid_beacon_inv.png b/mods/roads/trafficlight/textures/streets_hybrid_beacon_inv.png new file mode 100644 index 0000000..f368555 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_hybrid_beacon_inv.png differ diff --git a/mods/roads/trafficlight/textures/streets_pedlight_inv.png b/mods/roads/trafficlight/textures/streets_pedlight_inv.png new file mode 100644 index 0000000..c4520f1 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pedlight_inv.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_dontwalk.png b/mods/roads/trafficlight/textures/streets_pl_dontwalk.png new file mode 100644 index 0000000..3abc776 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_dontwalk.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_flashingdontwalk.png b/mods/roads/trafficlight/textures/streets_pl_flashingdontwalk.png new file mode 100644 index 0000000..4fbed1e Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_flashingdontwalk.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_flashingwalk.png b/mods/roads/trafficlight/textures/streets_pl_flashingwalk.png new file mode 100644 index 0000000..55986d0 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_flashingwalk.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_0l.png b/mods/roads/trafficlight/textures/streets_pl_number_0l.png new file mode 100644 index 0000000..99fc263 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_0l.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_0r.png b/mods/roads/trafficlight/textures/streets_pl_number_0r.png new file mode 100644 index 0000000..6f9b143 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_0r.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_1l.png b/mods/roads/trafficlight/textures/streets_pl_number_1l.png new file mode 100644 index 0000000..e35735a Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_1l.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_1r.png b/mods/roads/trafficlight/textures/streets_pl_number_1r.png new file mode 100644 index 0000000..b878ae6 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_1r.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_2l.png b/mods/roads/trafficlight/textures/streets_pl_number_2l.png new file mode 100644 index 0000000..d439aa9 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_2l.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_2r.png b/mods/roads/trafficlight/textures/streets_pl_number_2r.png new file mode 100644 index 0000000..dd9b4be Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_2r.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_3l.png b/mods/roads/trafficlight/textures/streets_pl_number_3l.png new file mode 100644 index 0000000..bdab896 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_3l.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_3r.png b/mods/roads/trafficlight/textures/streets_pl_number_3r.png new file mode 100644 index 0000000..da7de9a Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_3r.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_4l.png b/mods/roads/trafficlight/textures/streets_pl_number_4l.png new file mode 100644 index 0000000..91d1ff4 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_4l.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_4r.png b/mods/roads/trafficlight/textures/streets_pl_number_4r.png new file mode 100644 index 0000000..5468b00 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_4r.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_5l.png b/mods/roads/trafficlight/textures/streets_pl_number_5l.png new file mode 100644 index 0000000..4d21bbd Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_5l.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_5r.png b/mods/roads/trafficlight/textures/streets_pl_number_5r.png new file mode 100644 index 0000000..9992ed9 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_5r.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_6l.png b/mods/roads/trafficlight/textures/streets_pl_number_6l.png new file mode 100644 index 0000000..92f64be Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_6l.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_6r.png b/mods/roads/trafficlight/textures/streets_pl_number_6r.png new file mode 100644 index 0000000..ba84f54 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_6r.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_7l.png b/mods/roads/trafficlight/textures/streets_pl_number_7l.png new file mode 100644 index 0000000..9328d86 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_7l.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_7r.png b/mods/roads/trafficlight/textures/streets_pl_number_7r.png new file mode 100644 index 0000000..444ce49 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_7r.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_8l.png b/mods/roads/trafficlight/textures/streets_pl_number_8l.png new file mode 100644 index 0000000..9a78cd8 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_8l.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_8r.png b/mods/roads/trafficlight/textures/streets_pl_number_8r.png new file mode 100644 index 0000000..727afad Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_8r.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_9l.png b/mods/roads/trafficlight/textures/streets_pl_number_9l.png new file mode 100644 index 0000000..4830e0f Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_9l.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_9r.png b/mods/roads/trafficlight/textures/streets_pl_number_9r.png new file mode 100644 index 0000000..dabea2a Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_9r.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_number_template.png b/mods/roads/trafficlight/textures/streets_pl_number_template.png new file mode 100644 index 0000000..41ae2f1 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_number_template.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_off.png b/mods/roads/trafficlight/textures/streets_pl_off.png new file mode 100644 index 0000000..1b41b40 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_off.png differ diff --git a/mods/roads/trafficlight/textures/streets_pl_walk.png b/mods/roads/trafficlight/textures/streets_pl_walk.png new file mode 100644 index 0000000..4a79e54 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_pl_walk.png differ diff --git a/mods/roads/trafficlight/textures/streets_rrfb_inv.png b/mods/roads/trafficlight/textures/streets_rrfb_inv.png new file mode 100644 index 0000000..8977926 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_rrfb_inv.png differ diff --git a/mods/roads/trafficlight/textures/streets_rrfb_off.png b/mods/roads/trafficlight/textures/streets_rrfb_off.png new file mode 100644 index 0000000..0d1ba1a Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_rrfb_off.png differ diff --git a/mods/roads/trafficlight/textures/streets_rrfb_on.png b/mods/roads/trafficlight/textures/streets_rrfb_on.png new file mode 100644 index 0000000..4b28c81 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_rrfb_on.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_bg.png b/mods/roads/trafficlight/textures/streets_tl_bg.png new file mode 100644 index 0000000..e4213db Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_bg.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_flashgreen.png b/mods/roads/trafficlight/textures/streets_tl_flashgreen.png new file mode 100644 index 0000000..dd9cb78 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_flashgreen.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_flashred.png b/mods/roads/trafficlight/textures/streets_tl_flashred.png new file mode 100644 index 0000000..82c118c Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_flashred.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_flashred_alt.png b/mods/roads/trafficlight/textures/streets_tl_flashred_alt.png new file mode 100644 index 0000000..5fc8371 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_flashred_alt.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_green.png b/mods/roads/trafficlight/textures/streets_tl_green.png new file mode 100644 index 0000000..7d7ba80 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_green.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_left_flashgreen.png b/mods/roads/trafficlight/textures/streets_tl_left_flashgreen.png new file mode 100644 index 0000000..9cb8b60 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_left_flashgreen.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_left_flashred.png b/mods/roads/trafficlight/textures/streets_tl_left_flashred.png new file mode 100644 index 0000000..f0378a4 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_left_flashred.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_left_flashred_alt.png b/mods/roads/trafficlight/textures/streets_tl_left_flashred_alt.png new file mode 100644 index 0000000..2b11eeb Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_left_flashred_alt.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_left_green.png b/mods/roads/trafficlight/textures/streets_tl_left_green.png new file mode 100644 index 0000000..b6cb996 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_left_green.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_left_off.png b/mods/roads/trafficlight/textures/streets_tl_left_off.png new file mode 100644 index 0000000..e43c0e4 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_left_off.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_left_red.png b/mods/roads/trafficlight/textures/streets_tl_left_red.png new file mode 100644 index 0000000..cc4e18a Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_left_red.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_left_redyellow.png b/mods/roads/trafficlight/textures/streets_tl_left_redyellow.png new file mode 100644 index 0000000..4b58d78 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_left_redyellow.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_left_warn.png b/mods/roads/trafficlight/textures/streets_tl_left_warn.png new file mode 100644 index 0000000..ac3268a Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_left_warn.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_left_warn_alt.png b/mods/roads/trafficlight/textures/streets_tl_left_warn_alt.png new file mode 100644 index 0000000..4e36822 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_left_warn_alt.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_left_yellow.png b/mods/roads/trafficlight/textures/streets_tl_left_yellow.png new file mode 100644 index 0000000..ca704df Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_left_yellow.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_off.png b/mods/roads/trafficlight/textures/streets_tl_off.png new file mode 100644 index 0000000..fb7dfaa Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_off.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_red.png b/mods/roads/trafficlight/textures/streets_tl_red.png new file mode 100644 index 0000000..4560199 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_red.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_redyellow.png b/mods/roads/trafficlight/textures/streets_tl_redyellow.png new file mode 100644 index 0000000..234d987 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_redyellow.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_right_flashgreen.png b/mods/roads/trafficlight/textures/streets_tl_right_flashgreen.png new file mode 100644 index 0000000..8d21ac9 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_right_flashgreen.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_right_flashred.png b/mods/roads/trafficlight/textures/streets_tl_right_flashred.png new file mode 100644 index 0000000..3f5e1d9 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_right_flashred.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_right_flashred_alt.png b/mods/roads/trafficlight/textures/streets_tl_right_flashred_alt.png new file mode 100644 index 0000000..3a82b10 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_right_flashred_alt.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_right_green.png b/mods/roads/trafficlight/textures/streets_tl_right_green.png new file mode 100644 index 0000000..bde7d6e Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_right_green.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_right_off.png b/mods/roads/trafficlight/textures/streets_tl_right_off.png new file mode 100644 index 0000000..68d02bf Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_right_off.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_right_red.png b/mods/roads/trafficlight/textures/streets_tl_right_red.png new file mode 100644 index 0000000..6e4b737 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_right_red.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_right_redyellow.png b/mods/roads/trafficlight/textures/streets_tl_right_redyellow.png new file mode 100644 index 0000000..e0fb8fa Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_right_redyellow.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_right_warn.png b/mods/roads/trafficlight/textures/streets_tl_right_warn.png new file mode 100644 index 0000000..2fa3e6c Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_right_warn.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_right_warn_alt.png b/mods/roads/trafficlight/textures/streets_tl_right_warn_alt.png new file mode 100644 index 0000000..7cadbc4 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_right_warn_alt.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_right_yellow.png b/mods/roads/trafficlight/textures/streets_tl_right_yellow.png new file mode 100644 index 0000000..ab37ca0 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_right_yellow.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_straight_green.png b/mods/roads/trafficlight/textures/streets_tl_straight_green.png new file mode 100644 index 0000000..afbd506 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_straight_green.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_warn.png b/mods/roads/trafficlight/textures/streets_tl_warn.png new file mode 100644 index 0000000..349fa84 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_warn.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_warn_alt.png b/mods/roads/trafficlight/textures/streets_tl_warn_alt.png new file mode 100644 index 0000000..26b1387 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_warn_alt.png differ diff --git a/mods/roads/trafficlight/textures/streets_tl_yellow.png b/mods/roads/trafficlight/textures/streets_tl_yellow.png new file mode 100644 index 0000000..42b4803 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tl_yellow.png differ diff --git a/mods/roads/trafficlight/textures/streets_tle_left_flashgreen.png b/mods/roads/trafficlight/textures/streets_tle_left_flashgreen.png new file mode 100644 index 0000000..8462064 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tle_left_flashgreen.png differ diff --git a/mods/roads/trafficlight/textures/streets_tle_left_green.png b/mods/roads/trafficlight/textures/streets_tle_left_green.png new file mode 100644 index 0000000..9747c0a Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tle_left_green.png differ diff --git a/mods/roads/trafficlight/textures/streets_tle_left_yellow.png b/mods/roads/trafficlight/textures/streets_tle_left_yellow.png new file mode 100644 index 0000000..2868038 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tle_left_yellow.png differ diff --git a/mods/roads/trafficlight/textures/streets_tle_right_flashgreen.png b/mods/roads/trafficlight/textures/streets_tle_right_flashgreen.png new file mode 100644 index 0000000..59402e0 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tle_right_flashgreen.png differ diff --git a/mods/roads/trafficlight/textures/streets_tle_right_green.png b/mods/roads/trafficlight/textures/streets_tle_right_green.png new file mode 100644 index 0000000..509325f Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tle_right_green.png differ diff --git a/mods/roads/trafficlight/textures/streets_tle_right_yellow.png b/mods/roads/trafficlight/textures/streets_tle_right_yellow.png new file mode 100644 index 0000000..da16275 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_tle_right_yellow.png differ diff --git a/mods/roads/trafficlight/textures/streets_trafficlight_inv.png b/mods/roads/trafficlight/textures/streets_trafficlight_inv.png new file mode 100644 index 0000000..fb76b72 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_trafficlight_inv.png differ diff --git a/mods/roads/trafficlight/textures/streets_trafficlight_inv_extender_left.png b/mods/roads/trafficlight/textures/streets_trafficlight_inv_extender_left.png new file mode 100644 index 0000000..d28a437 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_trafficlight_inv_extender_left.png differ diff --git a/mods/roads/trafficlight/textures/streets_trafficlight_inv_extender_right.png b/mods/roads/trafficlight/textures/streets_trafficlight_inv_extender_right.png new file mode 100644 index 0000000..bf4cdb6 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_trafficlight_inv_extender_right.png differ diff --git a/mods/roads/trafficlight/textures/streets_trafficlight_inv_greenarrow.png b/mods/roads/trafficlight/textures/streets_trafficlight_inv_greenarrow.png new file mode 100644 index 0000000..530a9b9 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_trafficlight_inv_greenarrow.png differ diff --git a/mods/roads/trafficlight/textures/streets_trafficlight_inv_left.png b/mods/roads/trafficlight/textures/streets_trafficlight_inv_left.png new file mode 100644 index 0000000..04530aa Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_trafficlight_inv_left.png differ diff --git a/mods/roads/trafficlight/textures/streets_trafficlight_inv_right.png b/mods/roads/trafficlight/textures/streets_trafficlight_inv_right.png new file mode 100644 index 0000000..5a73942 Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_trafficlight_inv_right.png differ diff --git a/mods/roads/trafficlight/textures/streets_trafficlight_inv_straight.png b/mods/roads/trafficlight/textures/streets_trafficlight_inv_straight.png new file mode 100644 index 0000000..ac3e7aa Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_trafficlight_inv_straight.png differ diff --git a/mods/roads/trafficlight/textures/streets_trafficlight_template.png b/mods/roads/trafficlight/textures/streets_trafficlight_template.png new file mode 100644 index 0000000..f987c9b Binary files /dev/null and b/mods/roads/trafficlight/textures/streets_trafficlight_template.png differ diff --git a/mods/screwdriver/README.txt b/mods/screwdriver/README.txt new file mode 100644 index 0000000..14c073e --- /dev/null +++ b/mods/screwdriver/README.txt @@ -0,0 +1,13 @@ +Minetest Game mod: screwdriver +============================== +See license.txt for license information. + +License of source code +---------------------- +Originally by RealBadAngel, Maciej Kasatkin (LGPLv2.1+) +Various Minetest developers and contributors (LGPLv2.1+) + +License of media (textures) +--------------------------- +Created by Gambit (CC BY-SA 3.0): + screwdriver.png diff --git a/mods/screwdriver/init.lua b/mods/screwdriver/init.lua new file mode 100644 index 0000000..48684cf --- /dev/null +++ b/mods/screwdriver/init.lua @@ -0,0 +1,177 @@ +-- screwdriver/init.lua + +screwdriver = {} + +-- Load support for MT game translation. +local S = minetest.get_translator("screwdriver") + + +screwdriver.ROTATE_FACE = 1 +screwdriver.ROTATE_AXIS = 2 +screwdriver.disallow = function(pos, node, user, mode, new_param2) + return false +end +screwdriver.rotate_simple = function(pos, node, user, mode, new_param2) + if mode ~= screwdriver.ROTATE_FACE then + return false + end +end + +-- For attached wallmounted nodes: returns true if rotation is valid +-- simplified version of minetest:builtin/game/falling.lua#L148. +local function check_attached_node(pos, rotation) + local d = minetest.wallmounted_to_dir(rotation) + local p2 = vector.add(pos, d) + local n = minetest.get_node(p2).name + local def2 = minetest.registered_nodes[n] + if def2 and not def2.walkable then + return false + end + return true +end + +screwdriver.rotate = {} + +local facedir_tbl = { + [screwdriver.ROTATE_FACE] = { + [0] = 1, [1] = 2, [2] = 3, [3] = 0, + [4] = 5, [5] = 6, [6] = 7, [7] = 4, + [8] = 9, [9] = 10, [10] = 11, [11] = 8, + [12] = 13, [13] = 14, [14] = 15, [15] = 12, + [16] = 17, [17] = 18, [18] = 19, [19] = 16, + [20] = 21, [21] = 22, [22] = 23, [23] = 20, + }, + [screwdriver.ROTATE_AXIS] = { + [0] = 4, [1] = 4, [2] = 4, [3] = 4, + [4] = 8, [5] = 8, [6] = 8, [7] = 8, + [8] = 12, [9] = 12, [10] = 12, [11] = 12, + [12] = 16, [13] = 16, [14] = 16, [15] = 16, + [16] = 20, [17] = 20, [18] = 20, [19] = 20, + [20] = 0, [21] = 0, [22] = 0, [23] = 0, + }, +} + +screwdriver.rotate.facedir = function(pos, node, mode) + local rotation = node.param2 % 32 -- get first 5 bits + local other = node.param2 - rotation + rotation = facedir_tbl[mode][rotation] or 0 + return rotation + other +end + +screwdriver.rotate.colorfacedir = screwdriver.rotate.facedir + +local wallmounted_tbl = { + [screwdriver.ROTATE_FACE] = {[2] = 5, [3] = 4, [4] = 2, [5] = 3, [1] = 0, [0] = 1}, + [screwdriver.ROTATE_AXIS] = {[2] = 5, [3] = 4, [4] = 2, [5] = 1, [1] = 0, [0] = 3} +} + +screwdriver.rotate.wallmounted = function(pos, node, mode) + local rotation = node.param2 % 8 -- get first 3 bits + local other = node.param2 - rotation + rotation = wallmounted_tbl[mode][rotation] or 0 + if minetest.get_item_group(node.name, "attached_node") ~= 0 then + -- find an acceptable orientation + for i = 1, 5 do + if not check_attached_node(pos, rotation) then + rotation = wallmounted_tbl[mode][rotation] or 0 + else + break + end + end + end + return rotation + other +end + +screwdriver.rotate.colorwallmounted = screwdriver.rotate.wallmounted + +-- Handles rotation +screwdriver.handler = function(itemstack, user, pointed_thing, mode, uses) + if pointed_thing.type ~= "node" then + return + end + + local pos = pointed_thing.under + local player_name = user and user:get_player_name() or "" + + if minetest.is_protected(pos, player_name) then + minetest.record_protection_violation(pos, player_name) + return + end + + local node = minetest.get_node(pos) + local ndef = minetest.registered_nodes[node.name] + if not ndef then + return itemstack + end + -- can we rotate this paramtype2? + local fn = screwdriver.rotate[ndef.paramtype2] + if not fn and not ndef.on_rotate then + return itemstack + end + + local should_rotate = true + local new_param2 + if fn then + new_param2 = fn(pos, node, mode) + else + new_param2 = node.param2 + end + + -- Node provides a handler, so let the handler decide instead if the node can be rotated + if ndef.on_rotate then + -- Copy pos and node because callback can modify it + local result = ndef.on_rotate(vector.new(pos), + {name = node.name, param1 = node.param1, param2 = node.param2}, + user, mode, new_param2) + if result == false then -- Disallow rotation + return itemstack + elseif result == true then + should_rotate = false + end + elseif ndef.on_rotate == false then + return itemstack + elseif ndef.can_dig and not ndef.can_dig(pos, user) then + return itemstack + end + + if should_rotate and new_param2 ~= node.param2 then + node.param2 = new_param2 + minetest.swap_node(pos, node) + minetest.check_for_falling(pos) + end + + if not minetest.is_creative_enabled(player_name) then + itemstack:add_wear_by_uses(uses or 200) + end + + return itemstack +end + +-- Screwdriver +minetest.register_tool("screwdriver:screwdriver", { + description = S("Screwdriver") .. "\n" .. S("(left-click rotates face, right-click rotates axis)"), + inventory_image = "screwdriver.png", + groups = {tool = 1}, + on_use = function(itemstack, user, pointed_thing) + screwdriver.handler(itemstack, user, pointed_thing, screwdriver.ROTATE_FACE, 200) + return itemstack + end, + on_place = function(itemstack, user, pointed_thing) + screwdriver.handler(itemstack, user, pointed_thing, screwdriver.ROTATE_AXIS, 200) + return itemstack + end, +}) + + +minetest.register_craft({ + output = "screwdriver:screwdriver", + recipe = { + {"default:steel_ingot"}, + {"group:stick"} + } +}) + +minetest.register_alias("screwdriver:screwdriver1", "screwdriver:screwdriver") +minetest.register_alias("screwdriver:screwdriver2", "screwdriver:screwdriver") +minetest.register_alias("screwdriver:screwdriver3", "screwdriver:screwdriver") +minetest.register_alias("screwdriver:screwdriver4", "screwdriver:screwdriver") diff --git a/mods/screwdriver/license.txt b/mods/screwdriver/license.txt new file mode 100644 index 0000000..d9b721b --- /dev/null +++ b/mods/screwdriver/license.txt @@ -0,0 +1,50 @@ +License of source code +---------------------- + +GNU Lesser General Public License, version 2.1 +Copyright (C) 2013-2016 RealBadAngel, Maciej Kasatkin +Copyright (C) 2013-2016 Various Minetest developers and contributors + +This program is free software; you can redistribute it and/or modify it under the terms +of the GNU Lesser General Public License as published by the Free Software Foundation; +either version 2.1 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU Lesser General Public License for more details: +https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html + + +Licenses of media (textures) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2013-2016 Gambit + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/mods/screwdriver/locale/screwdriver.de.tr b/mods/screwdriver/locale/screwdriver.de.tr new file mode 100644 index 0000000..3c48ab4 --- /dev/null +++ b/mods/screwdriver/locale/screwdriver.de.tr @@ -0,0 +1,3 @@ +# textdomain: screwdriver +Screwdriver=Schraubendreher +(left-click rotates face, right-click rotates axis)=(Linksklick dreht Seite, Rechtsklick dreht Achse) diff --git a/mods/screwdriver/locale/screwdriver.eo.tr b/mods/screwdriver/locale/screwdriver.eo.tr new file mode 100644 index 0000000..7f8fedf --- /dev/null +++ b/mods/screwdriver/locale/screwdriver.eo.tr @@ -0,0 +1,3 @@ +# textdomain: screwdriver +Screwdriver=Ŝraŭbturnilo +(left-click rotates face, right-click rotates axis)=(maldekstra-klako turnas supraĵon, dekstra-klako turnas akson) diff --git a/mods/screwdriver/locale/screwdriver.es.tr b/mods/screwdriver/locale/screwdriver.es.tr new file mode 100644 index 0000000..868ffc3 --- /dev/null +++ b/mods/screwdriver/locale/screwdriver.es.tr @@ -0,0 +1,3 @@ +# textdomain: screwdriver +Screwdriver=Destornillador +(left-click rotates face, right-click rotates axis)=(clic-izquierdo gira la cara, clic-derecho rota el eje) diff --git a/mods/screwdriver/locale/screwdriver.fr.tr b/mods/screwdriver/locale/screwdriver.fr.tr new file mode 100644 index 0000000..fe34a9b --- /dev/null +++ b/mods/screwdriver/locale/screwdriver.fr.tr @@ -0,0 +1,3 @@ +# textdomain: screwdriver +Screwdriver=Tournevis +(left-click rotates face, right-click rotates axis)=(clic gauche pour changer de face, clic droit pour changer d'axe) diff --git a/mods/screwdriver/locale/screwdriver.id.tr b/mods/screwdriver/locale/screwdriver.id.tr new file mode 100644 index 0000000..ec83c79 --- /dev/null +++ b/mods/screwdriver/locale/screwdriver.id.tr @@ -0,0 +1,3 @@ +# textdomain: screwdriver +Screwdriver=Obeng +(left-click rotates face, right-click rotates axis)=(klik kiri putar sisi, klik kanan putar sumbu) diff --git a/mods/screwdriver/locale/screwdriver.it.tr b/mods/screwdriver/locale/screwdriver.it.tr new file mode 100644 index 0000000..ff44b89 --- /dev/null +++ b/mods/screwdriver/locale/screwdriver.it.tr @@ -0,0 +1,3 @@ +# textdomain: screwdriver +Screwdriver=Cacciavite +(left-click rotates face, right-click rotates axis)=(click sinistro ruota la faccia, click destro ruota l'asse) diff --git a/mods/screwdriver/locale/screwdriver.ja.tr b/mods/screwdriver/locale/screwdriver.ja.tr new file mode 100644 index 0000000..55690f2 --- /dev/null +++ b/mods/screwdriver/locale/screwdriver.ja.tr @@ -0,0 +1,3 @@ +# textdomain: screwdriver +Screwdriver=ドライバー +(left-click rotates face, right-click rotates axis)=(左クリックで面が回転。右クリックで軸が回転) diff --git a/mods/screwdriver/locale/screwdriver.jbo.tr b/mods/screwdriver/locale/screwdriver.jbo.tr new file mode 100644 index 0000000..1a85bb6 --- /dev/null +++ b/mods/screwdriver/locale/screwdriver.jbo.tr @@ -0,0 +1,3 @@ +# textdomain: screwdriver +Screwdriver=lo lupcartci +(left-click rotates face, right-click rotates axis)=.i tu'a le zulselpevysmacu cu rinka lo nu le sefta cu carna@n.i tu'a le prityselpevysmacu cu rinka lo nu le jendu cu carna diff --git a/mods/screwdriver/locale/screwdriver.ms.tr b/mods/screwdriver/locale/screwdriver.ms.tr new file mode 100644 index 0000000..f296fc5 --- /dev/null +++ b/mods/screwdriver/locale/screwdriver.ms.tr @@ -0,0 +1,3 @@ +# textdomain: screwdriver +Screwdriver=Pemutar Skru +(left-click rotates face, right-click rotates axis)=(klik-kiri putar muka, klik-kanan putar paksi) diff --git a/mods/screwdriver/locale/screwdriver.pl.tr b/mods/screwdriver/locale/screwdriver.pl.tr new file mode 100644 index 0000000..3b4bfd6 --- /dev/null +++ b/mods/screwdriver/locale/screwdriver.pl.tr @@ -0,0 +1,3 @@ +# textdomain: screwdriver +Screwdriver=Śrubokręt +(left-click rotates face, right-click rotates axis)=(lewy przycisk myszy obraca powierzchnię, prawy przycisk myszy obraca oś) diff --git a/mods/screwdriver/locale/screwdriver.pt_BR.tr b/mods/screwdriver/locale/screwdriver.pt_BR.tr new file mode 100644 index 0000000..3e89f40 --- /dev/null +++ b/mods/screwdriver/locale/screwdriver.pt_BR.tr @@ -0,0 +1,3 @@ +# textdomain: screwdriver +Screwdriver=Chave de fenda +(left-click rotates face, right-click rotates axis)=(Clique esquerdo rotaciona a face, clique direito rotaciona o eixo) diff --git a/mods/screwdriver/locale/screwdriver.ru.tr b/mods/screwdriver/locale/screwdriver.ru.tr new file mode 100644 index 0000000..bbab330 --- /dev/null +++ b/mods/screwdriver/locale/screwdriver.ru.tr @@ -0,0 +1,3 @@ +# textdomain: screwdriver +Screwdriver=Отвёртка +(left-click rotates face, right-click rotates axis)=(клик левой кнопкой мыши вращает грань, клик правой кнопкой мыши вращает ось) diff --git a/mods/screwdriver/locale/screwdriver.sk.tr b/mods/screwdriver/locale/screwdriver.sk.tr new file mode 100644 index 0000000..74cb417 --- /dev/null +++ b/mods/screwdriver/locale/screwdriver.sk.tr @@ -0,0 +1,3 @@ +# textdomain: screwdriver +Screwdriver=Skrutkovač +(left-click rotates face, right-click rotates axis)=(Ľavý klik otáča stranu, pravý klik otáča os) diff --git a/mods/screwdriver/locale/screwdriver.sv.tr b/mods/screwdriver/locale/screwdriver.sv.tr new file mode 100644 index 0000000..be440a7 --- /dev/null +++ b/mods/screwdriver/locale/screwdriver.sv.tr @@ -0,0 +1,3 @@ +# textdomain: screwdriver +Screwdriver=Skruvmejsel +(left-click rotates face, right-click rotates axis)=(vänster-klick roterar ansikte, höger-klick roterar axeln) diff --git a/mods/screwdriver/locale/screwdriver.uk.tr b/mods/screwdriver/locale/screwdriver.uk.tr new file mode 100644 index 0000000..363e4c4 --- /dev/null +++ b/mods/screwdriver/locale/screwdriver.uk.tr @@ -0,0 +1,3 @@ +# textdomain: screwdriver +Screwdriver=Викрутка +(left-click rotates face, right-click rotates axis)=(клік лівою кнопкою миші повертає край, клік правою кнопкою миші - вісь) diff --git a/mods/screwdriver/locale/screwdriver.zh_CN.tr b/mods/screwdriver/locale/screwdriver.zh_CN.tr new file mode 100644 index 0000000..caddf79 --- /dev/null +++ b/mods/screwdriver/locale/screwdriver.zh_CN.tr @@ -0,0 +1,3 @@ +# textdomain: screwdriver +Screwdriver=螺丝刀 +(left-click rotates face, right-click rotates axis)=(左键单击旋转面,右键单击旋转轴) diff --git a/mods/screwdriver/locale/screwdriver.zh_TW.tr b/mods/screwdriver/locale/screwdriver.zh_TW.tr new file mode 100644 index 0000000..e638bfa --- /dev/null +++ b/mods/screwdriver/locale/screwdriver.zh_TW.tr @@ -0,0 +1,3 @@ +# textdomain: screwdriver +Screwdriver=螺絲刀 +(left-click rotates face, right-click rotates axis)=(左鍵單擊旋轉面,右鍵單擊旋轉軸) diff --git a/mods/screwdriver/locale/template.txt b/mods/screwdriver/locale/template.txt new file mode 100644 index 0000000..4cc8e2a --- /dev/null +++ b/mods/screwdriver/locale/template.txt @@ -0,0 +1,3 @@ +# textdomain: screwdriver +Screwdriver= +(left-click rotates face, right-click rotates axis)= diff --git a/mods/screwdriver/mod.conf b/mods/screwdriver/mod.conf new file mode 100644 index 0000000..306c52b --- /dev/null +++ b/mods/screwdriver/mod.conf @@ -0,0 +1,2 @@ +name = screwdriver +description = Minetest Game mod: screwdriver diff --git a/mods/screwdriver/textures/screwdriver.png b/mods/screwdriver/textures/screwdriver.png new file mode 100644 index 0000000..b2a56d5 Binary files /dev/null and b/mods/screwdriver/textures/screwdriver.png differ diff --git a/mods/sethome/README.txt b/mods/sethome/README.txt new file mode 100644 index 0000000..6f0a282 --- /dev/null +++ b/mods/sethome/README.txt @@ -0,0 +1,7 @@ +Minetest Game mod: sethome +========================== +See license.txt for license information. + +Authors of source code +---------------------- +sfan5 (MIT) diff --git a/mods/sethome/init.lua b/mods/sethome/init.lua new file mode 100644 index 0000000..9fc8e6a --- /dev/null +++ b/mods/sethome/init.lua @@ -0,0 +1,107 @@ +-- sethome/init.lua + +sethome = {} + +-- Load support for MT game translation. +local S = minetest.get_translator("sethome") + + +local homes_file = minetest.get_worldpath() .. "/homes" +local homepos = {} + +local function loadhomes() + local input = io.open(homes_file, "r") + if not input then + return -- no longer an error + end + + -- Iterate over all stored positions in the format "x y z player" for each line + for pos, name in input:read("*a"):gmatch("(%S+ %S+ %S+)%s([%w_-]+)[\r\n]") do + homepos[name] = minetest.string_to_pos(pos) + end + input:close() +end + +loadhomes() + +sethome.set = function(name, pos) + local player = minetest.get_player_by_name(name) + if not player or not pos then + return false + end + local player_meta = player:get_meta() + player_meta:set_string("sethome:home", minetest.pos_to_string(pos)) + + -- remove `name` from the old storage file + if not homepos[name] then + return true + end + local data = {} + local output = io.open(homes_file, "w") + if output then + homepos[name] = nil + for i, v in pairs(homepos) do + table.insert(data, string.format("%.1f %.1f %.1f %s\n", v.x, v.y, v.z, i)) + end + output:write(table.concat(data)) + io.close(output) + return true + end + return true -- if the file doesn't exist - don't return an error. +end + +sethome.get = function(name) + local player = minetest.get_player_by_name(name) + local player_meta = player:get_meta() + local pos = minetest.string_to_pos(player_meta:get_string("sethome:home")) + if pos then + return pos + end + + -- fetch old entry from storage table + pos = homepos[name] + if pos then + return vector.new(pos) + else + return nil + end +end + +sethome.go = function(name) + local pos = sethome.get(name) + local player = minetest.get_player_by_name(name) + if player and pos then + player:set_pos(pos) + return true + end + return false +end + +minetest.register_privilege("home", { + description = S("Can use /sethome and /home"), + give_to_singleplayer = false +}) + +minetest.register_chatcommand("home", { + description = S("Teleport you to your home point"), + privs = {home = true}, + func = function(name) + if sethome.go(name) then + return true, S("Teleported to home!") + end + return false, S("Set a home using /sethome") + end, +}) + +minetest.register_chatcommand("sethome", { + description = S("Set your home point"), + privs = {home = true}, + func = function(name) + name = name or "" -- fallback to blank name if nil + local player = minetest.get_player_by_name(name) + if player and sethome.set(name, player:get_pos()) then + return true, S("Home set!") + end + return false, S("Player not found!") + end, +}) diff --git a/mods/sethome/license.txt b/mods/sethome/license.txt new file mode 100644 index 0000000..09f03b0 --- /dev/null +++ b/mods/sethome/license.txt @@ -0,0 +1,24 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2014-2016 sfan5 + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT diff --git a/mods/sethome/locale/sethome.de.tr b/mods/sethome/locale/sethome.de.tr new file mode 100644 index 0000000..46279dd --- /dev/null +++ b/mods/sethome/locale/sethome.de.tr @@ -0,0 +1,8 @@ +# textdomain: sethome +Can use /sethome and /home=Kann /sethome und /home benutzen +Teleport you to your home point=Teleportieren Sie sich zu Ihrem Zuhause-Punkt +Teleported to home!=Nach Hause teleportiert! +Set a home using /sethome=Ein Zuhause mit /sethome setzen +Set your home point=Ihren Zuhause-Punkt setzen +Home set!=Zuhause gesetzt! +Player not found!=Spieler nicht gefunden! diff --git a/mods/sethome/locale/sethome.eo.tr b/mods/sethome/locale/sethome.eo.tr new file mode 100644 index 0000000..eb8f0a6 --- /dev/null +++ b/mods/sethome/locale/sethome.eo.tr @@ -0,0 +1,8 @@ +# textdomain: sethome +Can use /sethome and /home=Povas uzi /sethome kaj /home +Teleport you to your home point=Teletransporti vin al via hejmo +Teleported to home!=Teletransportita al hejmo! +Set a home using /sethome=Fiksi hejmon per /sethome +Set your home point=Fiksi vian hejman punkton +Home set!=Fiksita hejmo! +Player not found!=Ludanto ne troveblas! diff --git a/mods/sethome/locale/sethome.es.tr b/mods/sethome/locale/sethome.es.tr new file mode 100644 index 0000000..7c04ee3 --- /dev/null +++ b/mods/sethome/locale/sethome.es.tr @@ -0,0 +1,8 @@ +# textdomain: sethome +Can use /sethome and /home=Puedes usar /sethome y /home +Teleport you to your home point=Teletranspórtate a tu hogar +Teleported to home!=¡Teletransportado a tu hogar! +Set a home using /sethome=Establece tu hogar usando /sethome +Set your home point=Establece el sitio de tu hogar +Home set!=¡Hogar establecido! +Player not found!=¡Jugador no encontrado! diff --git a/mods/sethome/locale/sethome.fr.tr b/mods/sethome/locale/sethome.fr.tr new file mode 100644 index 0000000..852621d --- /dev/null +++ b/mods/sethome/locale/sethome.fr.tr @@ -0,0 +1,8 @@ +# textdomain: sethome +Can use /sethome and /home=Peut utiliser /sethome et /home +Teleport you to your home point=Vous téléporter à votre domicile +Teleported to home!=Téléporté à votre domicile ! +Set a home using /sethome=Définir un domicile en utilisant /sethome +Set your home point=Définir votre domicile +Home set!=Domicile défini ! +Player not found!=Joueur non trouvé ! diff --git a/mods/sethome/locale/sethome.id.tr b/mods/sethome/locale/sethome.id.tr new file mode 100644 index 0000000..1966978 --- /dev/null +++ b/mods/sethome/locale/sethome.id.tr @@ -0,0 +1,8 @@ +# textdomain: sethome +Can use /sethome and /home=Boleh pakai /sethome dan /home +Teleport you to your home point=Teleportasi ke rumah Anda +Teleported to home!=Teleportasi ke rumah! +Set a home using /sethome=Atur letak rumah dengan /sethome +Set your home point=Atur letak rumah +Home set!=Letak rumah diatur! +Player not found!=Pemain tidak ditemukan! diff --git a/mods/sethome/locale/sethome.it.tr b/mods/sethome/locale/sethome.it.tr new file mode 100644 index 0000000..6bdf11c --- /dev/null +++ b/mods/sethome/locale/sethome.it.tr @@ -0,0 +1,8 @@ +# textdomain: sethome +Can use /sethome and /home=Può usare /sethome e /home +Teleport you to your home point=Ti teletrasporta al tuo punto di domicilio +Teleported to home!=Teletrasportato a casa! +Set a home using /sethome=Imposta un domicilio usando /sethome +Set your home point=Imposta il tuo punto di domicilio +Home set!=Domicilio impostato! +Player not found!=Giocatore non trovato! diff --git a/mods/sethome/locale/sethome.ja.tr b/mods/sethome/locale/sethome.ja.tr new file mode 100644 index 0000000..3d636b5 --- /dev/null +++ b/mods/sethome/locale/sethome.ja.tr @@ -0,0 +1,8 @@ +# textdomain: sethome +Can use /sethome and /home=/sethomeと/homeが使えます +Teleport you to your home point=ホーム地点にテレポートします +Teleported to home!=ホームにテレポート! +Set a home using /sethome=/sethomeを使ってホームを設定します +Set your home point=ホーム地点を設定します +Home set!=ホーム地点をセット! +Player not found!=プレーヤーが見つかりません! diff --git a/mods/sethome/locale/sethome.jbo.tr b/mods/sethome/locale/sethome.jbo.tr new file mode 100644 index 0000000..90ac1a3 --- /dev/null +++ b/mods/sethome/locale/sethome.jbo.tr @@ -0,0 +1,8 @@ +# textdomain: sethome +Can use /sethome and /home=kakne lo nu pilno lo me zoi gy./sethome.gy. ku .e lo me zoi gy./home.gy. +Teleport you to your home point=sukmu'u lo do zdani mokca +Teleported to home!=puba'o sukmu'u lo zdani +Set a home using /sethome=ko tcimi'e fi lo zdani sepi'o lo me zoi gy./sethome.gy. +Set your home point=tcimi'e fi lo do zdani mokca +Home set!=puba'o tcimi'e fi lo zdani +Player not found!=lo kelci na te facki diff --git a/mods/sethome/locale/sethome.ms.tr b/mods/sethome/locale/sethome.ms.tr new file mode 100644 index 0000000..7e9ec76 --- /dev/null +++ b/mods/sethome/locale/sethome.ms.tr @@ -0,0 +1,8 @@ +# textdomain: sethome +Can use /sethome and /home=Boleh guna /sethome dan /home +Teleport you to your home point=Teleportasikan anda ke titik rumah anda +Teleported to home!=Diteleportasikan ke rumah! +Set a home using /sethome=Tetapkan rumah menggunakan /sethome +Set your home point=Tetapkan titik rumah anda +Home set!=Rumah ditetapkan! +Player not found!=Pemain tidak dijumpai! diff --git a/mods/sethome/locale/sethome.pl.tr b/mods/sethome/locale/sethome.pl.tr new file mode 100644 index 0000000..981a8c4 --- /dev/null +++ b/mods/sethome/locale/sethome.pl.tr @@ -0,0 +1,8 @@ +# textdomain: sethome +Can use /sethome and /home=Może używać /sethome i /home +Teleport you to your home point=Teleportuj się do swojego punktu domowego +Teleported to home!=Teleportowano do punktu domowego +Set a home using /sethome=Ustaw punkt domowy używając /sethome +Set your home point=Ustaw swój punkt domowy +Home set!=Punkt domowy ustawiony! +Player not found!=Gracz nie odnaleziony! diff --git a/mods/sethome/locale/sethome.pt_BR.tr b/mods/sethome/locale/sethome.pt_BR.tr new file mode 100644 index 0000000..fe2c35c --- /dev/null +++ b/mods/sethome/locale/sethome.pt_BR.tr @@ -0,0 +1,8 @@ +# textdomain: sethome +Can use /sethome and /home=Pode usar /sethome e /home +Teleport you to your home point=Teletransportá-lo para seu ponto de origem +Teleported to home!=Teletransportado para o ponto de origem! +Set a home using /sethome=Defina um ponto de origem usando /sethome +Set your home point=Define seu ponto de origem +Home set!=Ponto de origem definido! +Player not found!=Jogador não encontrado! diff --git a/mods/sethome/locale/sethome.ru.tr b/mods/sethome/locale/sethome.ru.tr new file mode 100644 index 0000000..6738824 --- /dev/null +++ b/mods/sethome/locale/sethome.ru.tr @@ -0,0 +1,8 @@ +# textdomain: sethome +Can use /sethome and /home=Возможность использовать /sethome и /home +Teleport you to your home point=Вы телепортируетесь в свою домашнюю точку +Teleported to home!=Вы телепортировались домой! +Set a home using /sethome=Установите домашнюю точку, используя /sethome +Set your home point=Установите вашу домашнюю точку +Home set!=Домашняя точка установлена! +Player not found!=Игрок не обнаружен! diff --git a/mods/sethome/locale/sethome.sk.tr b/mods/sethome/locale/sethome.sk.tr new file mode 100644 index 0000000..be5233e --- /dev/null +++ b/mods/sethome/locale/sethome.sk.tr @@ -0,0 +1,8 @@ +# textdomain: sethome +Can use /sethome and /home=Môžeš použivať /sethome a /home +Teleport you to your home point=Teleportuj sa domov +Teleported to home!=Teleportovaný domov! +Set a home using /sethome=Nastav si domov použitím /sethome +Set your home point=Nastaviť si domov +Home set!=Domov nastavený! +Player not found!=Hráč nenájdený! diff --git a/mods/sethome/locale/sethome.sv.tr b/mods/sethome/locale/sethome.sv.tr new file mode 100644 index 0000000..60673ae --- /dev/null +++ b/mods/sethome/locale/sethome.sv.tr @@ -0,0 +1,8 @@ +# textdomain: sethome +Can use /sethome and /home=Kan använda /sethome och /home +Teleport you to your home point=Teleportera dig till din hempunkt +Teleported to home!=Teleporterad hem! +Set a home using /sethome=Ställ in ett hem med /sethome +Set your home point=Ställ in din hempunkt +Home set!=Hem inställt! +Player not found!=Spelare finns inte! diff --git a/mods/sethome/locale/sethome.uk.tr b/mods/sethome/locale/sethome.uk.tr new file mode 100644 index 0000000..d8d4a8f --- /dev/null +++ b/mods/sethome/locale/sethome.uk.tr @@ -0,0 +1,8 @@ +# textdomain: sethome +Can use /sethome and /home=Можливість використання /sethome та /home +Teleport you to your home point=Ви телепортуєтесь у свою домашню точку +Teleported to home!=Ви телепортувались додому! +Set a home using /sethome=Встановіть домашню точку, використовуючи /sethome +Set your home point=Встановіть домашню точку +Home set!=Домашня точка встановлена! +Player not found!=Гравець не визначений! diff --git a/mods/sethome/locale/sethome.zh_CN.tr b/mods/sethome/locale/sethome.zh_CN.tr new file mode 100644 index 0000000..0af54ce --- /dev/null +++ b/mods/sethome/locale/sethome.zh_CN.tr @@ -0,0 +1,8 @@ +# textdomain: sethome +Can use /sethome and /home=可以使用/sethome和/home +Teleport you to your home point=将您传送到家 +Teleported to home!=已传送到家! +Set a home using /sethome=使用/sethome设定家 +Set your home point=设定您家的地点 +Home set!=已设定家! +Player not found!=未找到玩家! diff --git a/mods/sethome/locale/sethome.zh_TW.tr b/mods/sethome/locale/sethome.zh_TW.tr new file mode 100644 index 0000000..43e14aa --- /dev/null +++ b/mods/sethome/locale/sethome.zh_TW.tr @@ -0,0 +1,8 @@ +# textdomain: sethome +Can use /sethome and /home=可以使用/sethome和/home +Teleport you to your home point=傳送您到您家的地點 +Teleported to home!=已傳送到家! +Set a home using /sethome=使用/sethome設定家 +Set your home point=設定您家的地點 +Home set!=已設定家! +Player not found!=未找到玩家! diff --git a/mods/sethome/locale/template.txt b/mods/sethome/locale/template.txt new file mode 100644 index 0000000..d04bd50 --- /dev/null +++ b/mods/sethome/locale/template.txt @@ -0,0 +1,8 @@ +# textdomain: sethome +Can use /sethome and /home= +Teleport you to your home point= +Teleported to home!= +Set a home using /sethome= +Set your home point= +Home set!= +Player not found!= diff --git a/mods/sethome/mod.conf b/mods/sethome/mod.conf new file mode 100644 index 0000000..0079925 --- /dev/null +++ b/mods/sethome/mod.conf @@ -0,0 +1,2 @@ +name = sethome +description = Minetest Game mod: sethome diff --git a/mods/sounds/LICENSE.txt b/mods/sounds/LICENSE.txt new file mode 100644 index 0000000..357bcd0 --- /dev/null +++ b/mods/sounds/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright © 2021 Jordan Irwin (AntumDeluge) + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/mods/sounds/README.md b/mods/sounds/README.md new file mode 100644 index 0000000..f125b7b --- /dev/null +++ b/mods/sounds/README.md @@ -0,0 +1,218 @@ +## Sound Pack for Minetest + +### Description: + +A [Minetest][] mod that provides a set of free sounds & methods. + +What is the purpose of this mod? There are four ideas behind `sounds`: + +1. It is intended as a more universal method for adding sounds to games rather than depending on [MTG & default][default] for sounds only. It is completely compatible with default sounds. The same methods called in `default` to set node sounds, like `default.node_sound_stone_defaults`, are implemented & it can be installed in parallel. *Section: [Replacement for default](#replacement-for-default)* +2. It is simply a well of sounds. Many sound files are provided & can be used with [minetest.sound_play](https://minetest.gitlab.io/minetest/minetest-namespace-reference/#sounds) just as normal. There is also a wrapper function, [sounds:play](https://antummt.github.io/mod-sounds/reference/latest/topics/api.html#sounds:play), that does its best to verify that a sound played successfully. If so, it will return a sound handle ID. Otherwise it will return `nil`. A random sound can be played from a list with [sounds:play_random](https://antummt.github.io/mod-sounds/reference/latest/topics/api.html#sounds:play_random). It also caches all loaded mod sounds after server startup in `sounds.cache` table. So sound files can easily be checked for existence. *Section: [Checking for Existing Sounds](#checking-for-existing-sounds)* +3. It adds callable sound groups that can be used to play specified individual sounds, or a random sound in the group. The benefit to this is that the file naming convention is irrelivent. The only thing that matters is that the sound file is registered with the group. *Section: [Playing Sounds Manually](#playing-sounds-manually)* +4. Adds an API for setting biome ambiance sounds. + +Note that most included sounds have been set with a peak amplitude of -6.0db. + + +icon + +### Licensing: + +- Code: [MIT](LICENSE.txt) +- Icon/Screenshot: [CC0](https://openclipart.org/detail/260975) +- Media: see following table + +#### Sound file sources & licensing: + +See [sources.md](sources.md) + +### Usage: + +#### Replacement for default: + +If your mod depends on *default* for node sounds only, then you can easily switch to *sounds*. Simply add *default* & *sounds* as optional dependencies in your *mod.conf*. *sounds* overrides methods used by *default* to its own. For example *default.node_sound_dirt_defaults*. + +Example of overidden method: +```lua +function sounds.node_dirt(tbl) + tbl = tbl or {} + + tbl.footstep = tbl.footstep or {name="sounds_dirt_step", gain=0.4} + tbl.dug = tbl.dug or {name="sounds_dirt_step", gain=1.0} + tbl.place = tbl.place or {name="sounds_node_place_soft", gain=1.0} + + sounds.node(tbl) + return tbl +end + +default.node_sound_dirt_defaults = sounds.node_dirt +``` + +Example of setting node sounds: +```lua +minetest.register_node("foo:bar", { + description = "Foo Node", + -- this is the same as calling `sounds.node_stone()` + sounds = default.node_sound_stone_defaults() + ... +}) +``` + +#### Playing Sounds Manually: + +`SoundGroup` instances are objects for storing & playing sounds. These objects can be called to play a sound from their group. An index can be specified when called to determine which sound to play. If the index parameter is omitted, a random sound will be picked. A table of arguments can also be passed. This is compatible with [SimpleSoundSpec](https://minetest.gitlab.io/minetest/sounds/#simplesoundspec). + +Creating `SoundGroup` objects: +```lua +local s_group1 = SoundGroup({"sound1", "sound2"}) +local s_group2 = SoundGroup({"sound3", "sound4", "sound5"}) + +-- SoundGroup objects can be concatenated with the arithmetic operator +local s_group3 = s_group1 + s_group2 + +-- strings can also be concatenated to group with arithmetic operator +s_group3 = s_group3 + "sound6" + +-- by setting the `prepend` attribute `true`, sound file names will be prepended +-- with "sounds_" when played or accessed +s_group1(2) -- plays "sound2" + +s_group1.prepend = true +s_group1(2) -- plays "sounds_sound2" +``` + +There are many [pre-defined sound groups](https://antummt.github.io/mod-sounds/reference/latest/topics/groups.html). + +Calling a `SoundGroup` object: +```lua +-- play random sound from group +sounds.horse_neigh() + +-- play specific sound from group +sounds.horse_neigh(2) + +-- play random sound from group with parameters +sounds.horse_neigh({gain=1.0}) + +-- play specific sound from group with parameters +sounds.horse_neigh(2, {gain=1.0}) + +-- the `play` method is the same as calling the object directly +sounds.horse_neigh:play(2, {gain=1.0}) +``` + +#### Node Sounds: + +`SoundGroup` objects can also be used in node registration: +```lua +minetest.register_node("foo:bar", { + description = "Foo Node", + sounds = { + -- a random sound from the `sounds.cow_moo` group will be played when digging this node + dig = sounds.cow_moo, + }, + ... +``` + +Currently using `SoundGroup` for node sounds only works for "dig", "dug", & "place". + +`SoundGroup` objects are tables & are indexed by integer. But using the `get` method is more reliable as it will return the string name with "sounds_" prefix if `prepend` is set: +```lua +local s_group1 = SoundGroup({"sound1", "sound2"}) +local s1 = s_group1:get(1) -- returns "sound1" +local s2 = s_group1[2] -- returns "sound2" + +local s_group2 = SoundGroup({"sound3", "sound4", prepend=true}) +local s3 = s_group2:get(1) -- returns "sounds_sound3" +local s4 = s_group2[2] -- returns "sound4" +``` + +The built-in `type` function can be used to check for a `SoundGroup` instance: +```lua +if type(s_group1) == "SoundGroup" then + s_group1() +end +``` + +#### Checking for Existing Sounds: + +All mod sound files are stored in the global table `sounds.cache` after server startup. Checking if a file exists for playing is simple: + +```lua +if sounds.cache["default_dig_crumbly"] then + core.sound_play("default_dig_crumbly") +end +``` + +#### Testing Sounds: + +If setting `sounds.enable_tests` is enabled, the chat command `/sounds_tests` can be used to show a formspec for playing & testing sounds. + +To test *any* sound, input the sound name in the "Manual play" field & press the corresponding "Play" button. If the sound file exists, it will play & some info will be filled in the "Last played" field. + +To test sounds cached in sound groups, select a group in the left column of the "Group play" field. Then select a sound in the right column & press the corresponding "Play" button. + +Sounds can be looped by checking the "Loop" box. + +#### Biome Ambiance: + +A sound group can be registered for playing sounds randomly in a biome with the `sounds:register_biome_sounds` method (`sounds.enable_biome_sounds` must be enabled): + +``` +sounds:register_biome_sounds(biome, snds, params) +- Registers a sound group to be played in a biome. +- parameters: + - biome: Biome name. + - snds: string, table, or SoundGroup of sounds registered with biome. + - params: SimpleSoundSpec parameters (optional). +``` + +Example usage: +```lua +sounds:register_biome_sounds("grassland", sounds.bird, {gain=0.25}) +``` + +#### Settings: + +``` +sounds.disabled_groups +- Disables individual built-in sound groups categories. "all" disables all categories. +- type: string (comma-separated list) +- default: empty + +sounds.enable_tests +- Enables sounds testing with sounds_tests chat command. +- type: bool +- default: false + +sounds.enable_biome_sounds +- Enables/Disables ambiance sounds for biomes. +- type: bool +- default: false + +sounds.biome_interval +- Interval between playing biome sounds. +- type: int +- min: 5 +- default: 30 + +sounds.biome_chance +- Chance that sound will be played at interval. +- type: int +- min: 0 +- max: 100 +- default: 20 +``` + +### Links: + +- [![ContentDB](https://content.minetest.net/packages/AntumDeluge/sounds/shields/title/)](https://content.minetest.net/packages/AntumDeluge/sounds/) +- [Forum](https://forum.minetest.net/viewtopic.php?t=26868) +- [Git repo](https://github.com/AntumMT/mod-sounds) +- [Reference](https://antummt.github.io/mod-sounds/reference/) +- [Changelog](changelog.txt) +- [TODO](TODO.txt) + + +[Minetest]: http://minetest.net/ +[default]: https://github.com/minetest/minetest_game/tree/master/mods/default diff --git a/mods/sounds/TODO.txt b/mods/sounds/TODO.txt new file mode 100644 index 0000000..d5da57f --- /dev/null +++ b/mods/sounds/TODO.txt @@ -0,0 +1,10 @@ + +TODO: +- allow setting explicit parameters for individual sounds in SoundGroup instances +- tests: + - fix wrong sound selected when changing groups (example: select #2, switch to group with one sound, switch to group with two sounds, press play) +- set interval & chance for individual biomes +- allow individual biomes sound groups to be configured in settings +- add chat commands for playing sounds: + - /sounds me (individuals) + - /sounds all (server admins/plays for all players) diff --git a/mods/sounds/api.lua b/mods/sounds/api.lua new file mode 100644 index 0000000..0f231a3 --- /dev/null +++ b/mods/sounds/api.lua @@ -0,0 +1,340 @@ + +--- Sounds API +-- +-- @topic api + + +local failed = {} + + +-- initialize random number generator +local rand = PcgRandom(os.time()) + + +--- Functions +-- +-- @section functions + + +--- Plays a sound. +-- +-- +-- @function sounds:play +-- @tparam string name Sound file without .ogg suffix. +-- @tparam[opt] SoundParams sp Sound parameters. +-- @treturn list (`int`) Sound handle or `nil` and (`string`) sound file name. +-- @usage +-- local handle = sounds:play("sound1", {gain=1.0}) +-- if handle then +-- print("Sound handle: " .. handle) +-- end +sounds.play = function(self, name, sp) + local s_type = type(name) + if s_type ~= "string" then + sounds.log("error", "cannot play non-string type: " .. s_type) + return + end + + if not sounds.cache[name] then + if not failed[name] then + failed[name] = true + sounds.log("error", "\"" .. name .. "\" not available for playing") + end + + return + end + + local s_handle = core.sound_play(name, sp) + + -- TODO: register check to see if sound is still playing & remove from "playing" list + --playing[s_handle] = name + + return s_handle, name +end + +--- Plays a random sound from a list. +-- +-- @function sounds:play_random +-- @tparam table snds List of sound names. +-- @tparam[opt] SoundParams sp Sound parameters. +sounds.play_random = function(self, snds, sp) + if #snds == 0 then + return + end + + local play_group = table.copy(snds) + if type(snds) == "SoundGroup" and snds.prepend == true then + for idx, snd in ipairs(play_group) do + play_group[idx] = "sounds_" .. snd + end + end + + return sounds:play(play_group[rand:next(1, #play_group)], sp) +end + +--- Wrapper for core.sound_stop. +-- +-- @function sounds:stop +-- @tparam int handle +sounds.stop = function(self, handle) + core.sound_stop(handle) +end + + +--- Objects +-- +-- @section objects + +--- Sound Group. +-- +-- @table SoundGroup +-- @tfield SoundGroup:count count Retrieves number of available sounds. +-- @tfield SoundGroup:play play Plays indexed or random sound. +-- @tfield bool prepend If set to `true`, prepends "sounds_" to sound filenames when played or accessed. +SoundGroup = { + --- Constructor. + -- + -- @function SoundGroup + -- @tparam table def Sound definition. + -- @treturn SoundGroup Sound group definition table. + -- @usage + -- -- create new sound groups + -- local s_group1 = SoundGroup({"sound1", "sound2", prepend=true}) + -- local s_group2 = SoundGroup({"modname_sound1", "modname_sound2"}) + -- + -- -- play sound at index + -- s_group1:play(2) + -- + -- -- play random sound from group + -- s_group1:play() + -- + -- -- play sound at index with parameters + -- s_group1:play(1, {gain=1.0, max_hear_distance=100}) + -- + -- -- play random sound with parameters + -- s_group1:play({gain=1.0, max_hear_distance=100}) + -- + -- -- calling a SoundGroup instance directly is the same as executing the "play" method + -- s_group(1, {gain=1.0, max_hear_distance=100}) + __init = { + __call = function(self, def) + def = def or {} + if type(def) == "string" then + def = {def} + end + + for k, v in pairs(self) do + if k ~= "new" and k ~= "__init" and def[k] == nil then + def[k] = v + end + end + + def.__type = "SoundGroup" + + def.__init = { + -- execute "play" method when called directly + __call = self.play, + + -- allow arithmetic operation to join groups + __add = function(self, g1) + local new_group = {} + for _, snd in ipairs(self) do + table.insert(new_group, snd) + end + if type(g1) == "string" then + table.insert(new_group, g1) + else + for _, snd in ipairs(g1) do + table.insert(new_group, snd) + end + end + + new_group.prepend = self.prepend + return SoundGroup(new_group) + end, + } + setmetatable(def, def.__init) + + return def + end, + }, + + --- Retrieves number of sounds in group. + -- + -- @function SoundGroup:count + -- @treturn int + count = function(self) + local s_count = 0 + for _, idx in ipairs(self) do + s_count = s_count + 1 + end + + return s_count + end, + + --- Plays a sound from the group. + -- + -- If ***idx*** is not specified, an available sound will be selected + -- randomly from the group. + -- + -- @function SoundGroup:play + -- @tparam[opt] int idx Sound index. + -- @tparam[opt] SoundParams sp Sound parameters. + -- @treturn int Sound handle or `nil`. + -- @note idx & sp parameters positions can be switched. + -- @usage + -- local handle = SoundGroup:play(2, {gain=1.0}) + -- if handle then + -- print("Sound handle: " .. handle) + -- end + play = function(self, idx, sp) + local s_count = self:count() + if s_count < 1 then + sounds.log("error", "no sounds to play") + return + end + + -- allow second parameter to be sound parameters table + if type(idx) == "table" then + local sp_old = sp + sp = table.copy(idx) + idx = sp_old + sp_old = nil + end + + -- play random + if not idx then + if s_count == 1 then + idx = 1 + else + return sounds:play_random(self, sp) + end + end + + if type(idx) ~= "number" then + print("idx must be a number") + return + end + + if idx > s_count then + sounds.log("error", "sound index " .. idx .. " out of range: max " .. s_count) + return + end + + local selected = self[idx] + if type(selected) == "string" and self.prepend == true then + selected = "sounds_" .. selected + end + + return sounds:play(selected, sp) + end, + + --- Retrieves random name from group. + -- + -- @function SoundGroup:get_random + -- @treturn string + get_random = function(self) + local name + local s_count = self:count() + if s_count > 0 then + if s_count == 1 then + name = self[1] + else + name = self[rand:next(1, s_count)] + end + + if self.prepend == true then + name = "sounds_" .. name + end + end + + return name + end, + + --- Retrieves sounds names in group. + -- + -- If `idx` is supplied, a `string` or `nil` is returned. If + -- there is only one sound in the group, the `string` name of + -- that sound is returned. Otherwise, a table is returned with + -- all sound file names. + -- + -- @function SoundGroup:get + -- @tparam[opt] int idx Sound index. + -- @return `string` or `table` containing sound file names. + get = function(self, idx) + local count = self:count() + if count == 0 then return end + + local retval + if type(idx) == "number" then + retval = self[idx] + elseif count == 1 then + retval = self[1] + else + retval = {} + for _, snd in ipairs(self) do + table.insert(retval, snd) + end + end + + if self.prepend == true then + local rtype = type(retval) + if rtype == "string" then + retval = "sounds_" .. retval + elseif rtype == "table" then + for idx, snd in ipairs(retval) do + retval[idx] = "sounds_" .. snd + end + end + end + + return retval + end, +} +setmetatable(SoundGroup, SoundGroup.__init) + + +--- Internal Sound Group. +-- +-- Same as `SoundGroup` but with "prepend" set to "true" by default. Meant for +-- use with sound files prefixed with "sounds_" only. +-- +-- @table iSoundGroup +iSoundGroup = table.copy(SoundGroup) +setmetatable(iSoundGroup, SoundGroup.__init) +iSoundGroup.prepend = true + + +--- Functions +-- +-- @section functions + +local biome_sounds = {} + +--- Registers sounds to play randomly in biome. +-- +-- @function sounds:register_biome_sounds +-- @tparam string biome Biome name. +-- @param snds Sounds registered with biome. Can be `string`, `table`, or `SoundGroup`. +-- @tparam[opt] table params Sound parameter table. +sounds.register_biome_sounds = function(self, biome, snds, params) + if not sounds.enable_biome_sounds then + sounds.log("warning", "sounds:register_biome_sounds: biome sounds disabled, sounds will not play") + end + + biome_sounds[biome] = {group=SoundGroup(snds), params=params} +end + +--- Retrieves sounds for biome. +-- +-- @function sounds:get_biome_sounds +-- @tparam[opt] string biome Biome name. +-- @return `SoundGroup` or `nil`. If biome parameter is `nil`, then all registered biome +-- sound groups are returned. +sounds.get_biome_sounds = function(self, biome) + if not biome then + return biome_sounds + end + + return biome_sounds[biome] +end diff --git a/mods/sounds/changelog.txt b/mods/sounds/changelog.txt new file mode 100644 index 0000000..c5d3bb6 --- /dev/null +++ b/mods/sounds/changelog.txt @@ -0,0 +1,279 @@ + +v1.12 +---- +- fixed cache value check +- added sounds: + - duck_quack + - loon + - mermaid_song + - robot + - toy_squeak + - trumpeter_swan + + +v1.11 +----- +- added setting to enable/disable built-in sound groups +- added setting to disable individual sound groups categories +- fixed caching random sounds count +- SoundGroup can be constructed with string parameter +- biome sounds can be registered with sounds.register_biome_sounds +- shortened sounds rain_light, rain_medium, & wind +- added sounds: + - church_bells + + +v1.10.1 +------- +- deleted sounds: + - melee_hit_04 + - melee_hit_07 + - melee_hit_08 + - melee_hit_09 + - melee_hit_10 + - melee_hit_11 + - melee_hit_12 + - melee_hit_13 + - melee_hit_14 + - melee_hit_16 +- renamed sounds: + - melee_hit_05 to melee_hit_04 + - melee_hit_06 to melee_hit_05 + - melee_hit_15 to melee_hit_06 + + +v1.10 +----- +- added method "sounds:play_random" +- added "random" play button to tests +- changed to require "prepend" to prefix sound files with "sounds_" +- fixed inheriting "prepend" attribute when concatenating SoundGroup instances with arithmetic operator +- added iSoundGroup object meant for use with sounds prefixed with "sounds_" only +- fixed length of clock_tick so loops +- deleted "node_place_metal" sounds duplicates of "node_dug_metal" +- deleted some of the less useful compound groups +- renamed sounds: + - some "ar_fire sounds" to "ar_burst" +- added sounds: + - ar_burst + - cicada + - explosion + - explosion_distant + - explosion_scifi + - fireworks + - fireworks_pop + - fuse_short + - ghost + - ghost_damage + - ghost_death + - helicopter + - melee_hit + - plasma_shot + - scrape + - shears + - zombie_damage + - zombie_growl + + +v1.9 +---- +- "sounds:play" now returns handle & sound file name string +- added "sounds:stop" wrapper function for "core:sound_stop" +- added setting "sounds.enable_tests" +- added sounds testing formspec shown with "/sounds_tests" chat command +- added localization support for sounds testing formspec +- added Spanish translation for sounds testing formspec +- added sounds: + - ar_fire + - fireball + - laser + - pistol_cock + - pistol_fire + - pistol_fire_dry + - pistol_reload + - ricochet + - rifle_cock + - rifle_fire + - rifle_fire_cock + - rifle_fire_dry + - rifle_small_fire + - shotgun_fire_pump + - shotgun_pump + + +v1.8 +---- +- strings can be added to SoundGroup via arithmetic operator +- added sounds: + - chalk_screech + - chalk_write + - compressor_motor + - motorbike_idle + - tree_creak + - vehicle_horn + + +v1.7 +---- +- added sounds: + - airplane_prop + - car_motor + - jet_ambience + - jet_flyby + - jet_land + - train_whistle + - zombie_death + + +v1.6 +---- +- added sounds: + - door_close_02 + - door_close_03 + - door_knock + - door_open + - doorbell + - fire_crackle + - leaves + - match_ignite + - tool_break + - vehicle_motor_idle + - vomit + - woodpecker_peck + - woosh + + +v1.5 +---- +- added sounds: + - balloon_inflate + - balloon_pop + - bicycle_bell + - bicycle_horn + - bicycle_spokes + - cobra + - dolphin_chirp + - dolphin_click + - door_close + - door_creak + - goose + - lamb + - laugh_evil + - lava_cool + - leopard (many) + - raccoon_chatter + - rain_heavy + - rain_light + - rain_medium + - sea_lion + - seagull + - seagulls + - snake_rattle + - squirrel + - thunder + - whale + - wind +- renamed sounds: + - sheep -> sheep_baa + + +v1.4 +---- +- added sounds: + - bat + - bear + - camel + - canary + - cricket + - giraffe_hum + - gorilla_grunt + - gorilla_roar + - gorilla_snarl + - monkey + - parrot + - parrot_chirp + - parrot_whistle + - peacock_02 + - penguin + - pig_snort + - pig_squeal + - puppy_bark + - toucan + - turkey_gobble +- renamed sounds: + - elephant -> elephant_trumpet + + +v1.3 +---- +- pencil sounds split into "pencil_erase" & "pencil_write" groups +- fixed arithmetic operations on SoundGroup +- renamed node sound files +- SoundGroup:play returns handle or nil only +- using built-in type function on SoundGroup instance will return "SoundGroup" +- added sounds: + - bee + - bees + - bumble_bee + - chicken + - clock_tick + - coyote_howl + - crow_caw + - duck_quack + - goat_bleat + - grasshopper + - hyena + - jaguar_saw + - lion + - mouse + - owl + - peacock + - piano + - pigeon + - tiger_roar + - tiger_snarl + - undead_moan + - vulture + - watch_tick + - whistle + - wolf + - yak + - zebra + - zipper + + +v1.2 +---- +- added API object "SoundGroup" for creating & playing sound groups +- added sounds: + - apple_bite + - bird + - bounce + - cat_meow + - coins + - cow_moo + - dog_bark + - elephant + - explosion + - frog + - fuse + - gallop + - horse_neigh + - horse_snort + - pencil + - quail + - rooster + - sheep + - skeleton_bones + + +v1.1 +---- +- added entity hit sound from default mod + + +v1.0 +---- +- initial release +- added node sounds from default mod +- added methods for setting node sounds diff --git a/mods/sounds/groups/animal.lua b/mods/sounds/groups/animal.lua new file mode 100644 index 0000000..98b02a8 --- /dev/null +++ b/mods/sounds/groups/animal.lua @@ -0,0 +1,801 @@ + +--- Pre-defined Animal Sound Groups +-- +-- @topic animal_groups + + + +--- Amphibian +-- +-- @section amphibian + + +--- @sndgroup sounds.frog +-- @snd frog +sounds.frog = iSoundGroup({ + "frog", +}) + + + +--- Bat +-- +-- @section bat + + +--- @sndgroup sounds.bat +-- @snd bat_01 +-- @snd bat_02 +-- @snd bat_03 +sounds.bat = iSoundGroup({ + "bat_01", + "bat_02", + "bat_03", +}) + + + +--- Bear +-- +-- @section bear + + +--- @sndgroup sounds.bear +-- @snd bear_01 +-- @snd bear_02 +sounds.bear = iSoundGroup({ + "bear_01", + "bear_02", +}) + + + +--- Bovine +-- +-- @section bovine + + +--- @sndgroup sounds.cow_moo +-- @snd cow_moo_01 +-- @snd cow_moo_02 +sounds.cow_moo = iSoundGroup({ + "cow_moo_01", + "cow_moo_02", +}) + +--- @sndgroup sounds.yak +-- @snd yak (imitation) +sounds.yak = iSoundGroup({ + "yak", +}) + + + +--- Camelid +-- +-- @section camelid + + +--- @sndgroup sounds.camel +-- @snd camel_01 +-- @snd camel_02 +sounds.camel = iSoundGroup({ + "camel_01", + "camel_02", +}) + + + +--- Canine +-- +-- @section canine + + +--- @sndgroup sounds.coyote_howl +-- @snd coyote_howl +sounds.coyote_howl = iSoundGroup({ + "coyote_howl", +}) + +--- @sndgroup sounds.dog_bark +-- @snd dog_bark +sounds.dog_bark = iSoundGroup({ + "dog_bark", +}) + +--- @sndgroup sounds.puppy_bark +-- @snd puppy_bark +sounds.puppy_bark = iSoundGroup({ + "puppy_bark", +}) + +---
+-- +-- Includes: +-- +-- - `sounds.dog_bark` +-- - `sounds.puppy_bark` +-- +-- @sndgroup sounds.dog +sounds.dog = sounds.dog_bark + sounds.puppy_bark + +--- @sndgroup sounds.hyena +-- @snd hyena_01 +-- @snd hyena_02 +-- @snd hyena_03 +sounds.hyena = iSoundGroup({ + "hyena_01", + "hyena_02", + "hyena_03", +}) + +--- @sndgroup sounds.wolf_howl +-- @snd wolf_howl +sounds.wolf_howl = iSoundGroup({ + "wolf_howl", +}) + +--- @sndgroup sounds.wolf_snarl +-- @snd wolf_snarl +sounds.wolf_snarl = iSoundGroup({ + "wolf_snarl", +}) + + + +--- Caprine +-- +-- @section caprine + + +--- @sndgroup sounds.goat_bleat +-- @snd goat_bleat_01 +-- @snd goat_bleat_02 +-- @snd goat_bleat_03 +sounds.goat_bleat = iSoundGroup({ + "goat_bleat_01", + "goat_bleat_02", + "goat_bleat_03", +}) + +--- @sndgroup sounds.lamb +-- @snd lamb +sounds.lamb = iSoundGroup({ + "lamb", +}) + +--- @sndgroup sounds.sheep_baa +-- @snd sheep_baa +sounds.sheep_baa = iSoundGroup({ + "sheep_baa", +}) + +---
+-- +-- Includes: +-- +-- - `sounds.lamb` +-- - `sounds.sheep_baa` +-- +-- @sndgroup sounds.sheep +sounds.sheep = sounds.lamb + sounds.sheep_baa + + + +--- Cetacean +-- +-- @section cetacean + + +--- @sndgroup sounds.dolphin_chirp +-- @snd dolphin_chirp +sounds.dolphin_chirp = iSoundGroup({ + "dolphin_chirp", +}) + +--- @sndgroup sounds.dolphin_click +-- @snd dolphin_click +sounds.dolphin_click = iSoundGroup({ + "dolphin_click", +}) + +---
+-- +-- Includes: +-- +-- - `sounds.dolphin_chirp` +-- - `sounds.dolphin_click` +-- +-- @sndgroup sounds.dolphin +sounds.dolphin = sounds.dolphin_chirp + sounds.dolphin_click + +--- @sndgroup sounds.whale +-- @snd whale +sounds.whale = iSoundGroup({ + "whale", +}) + + + +--- Elephant +-- +-- @section elephant + + +--- @sndgroup sounds.elephant_trumpet +-- @snd elephant_trumpet +sounds.elephant_trumpet = iSoundGroup({ + "elephant_trumpet", +}) + + + +--- Equine +-- +-- @section equine + + +--- @sndgroup sounds.horse_neigh +-- @snd horse_neigh_01 +-- @snd horse_neigh_02 +sounds.horse_neigh = iSoundGroup({ + "horse_neigh_01", + "horse_neigh_02", +}) + +--- @sndgroup sounds.horse_snort +-- @snd horse_snort_01 +-- @snd horse_snort_02 +sounds.horse_snort = iSoundGroup({ + "horse_snort_01", + "horse_snort_02", +}) + +---
+-- +-- Includes: +-- +-- - `sounds.horse_neigh` +-- - `sounds.horse_snort` +-- +-- @sndgroup sounds.horse +sounds.horse = sounds.horse_neigh + sounds.horse_snort + +--- @sndgroup sounds.zebra +-- @snd zebra +sounds.zebra = iSoundGroup({ + "zebra", +}) + + + +--- Feline +-- +-- @section feline + + +--- @sndgroup sounds.cat_meow +-- @snd cat_meow +sounds.cat_meow = iSoundGroup({ + "cat_meow", +}) + +--- @sndgroup sounds.jaguar +-- @snd jaguar_saw +sounds.jaguar = iSoundGroup({ + "jaguar_saw", +}) + +--- @sndgroup sounds.leopard_growl +-- @snd leopard_growl_01 +-- @snd leopard_growl_02 +-- @snd leopard_growl_03 +sounds.leopard_growl = iSoundGroup({ + "leopard_growl_01", + "leopard_growl_02", + "leopard_growl_03", +}) + +--- @sndgroup sounds.leopard_roar +-- @snd leopard_roar_01 +-- @snd leopard_roar_02 +-- @snd leopard_roar_03 +-- @snd leopard_roar_04 +-- @snd leopard_roar_05 +sounds.leopard_roar = iSoundGroup({ + "leopard_roar_01", + "leopard_roar_02", + "leopard_roar_03", + "leopard_roar_04", + "leopard_roar_05", +}) + +--- @sndgroup sounds.leopard_saw +-- @snd leopard_saw_01 +-- @snd leopard_saw_02 +-- @snd leopard_saw_03 +sounds.leopard_saw = iSoundGroup({ + "leopard_saw_01", + "leopard_saw_02", + "leopard_saw_03", +}) + +--- @sndgroup sounds.leopard_snarl +-- @snd leopard_snarl_01 +-- @snd leopard_snarl_02 +sounds.leopard_snarl = iSoundGroup({ + "leopard_snarl_01", + "leopard_snarl_02", +}) + +--- @sndgroup sounds.leopard_snort +-- @snd leopard_snort +sounds.leopard_snort = iSoundGroup({ + "leopard_snort", +}) + +---
+-- +-- Includes: +-- +-- - `sounds.leopard_growl` +-- - `sounds.leopard_roar` +-- - `sounds.leopard_saw` +-- - `sounds.leopard_snarl` +-- - `sounds.leopard_snort` +-- +-- @sndgroup sounds.leopard +sounds.leopard = sounds.leopard_growl + sounds.leopard_roar + sounds.leopard_saw + + sounds.leopard_snarl + sounds.leopard_snort + +--- @sndgroup sounds.lion +-- @snd lion_bellow +sounds.lion = iSoundGroup({ + "lion_bellow", +}) + +--- @sndgroup sounds.tiger_roar +-- @snd tiger_roar_01 +sounds.tiger_roar = iSoundGroup({ + "tiger_roar_01", +}) + +--- @sndgroup sounds.tiger_snarl +-- @snd tiger_snarl_01 +-- @snd tiger_snarl_02 +-- @snd tiger_snarl_03 +-- @snd tiger_snarl_04 +sounds.tiger_snarl = iSoundGroup({ + "tiger_snarl_01", + "tiger_snarl_02", + "tiger_snarl_03", + "tiger_snarl_04", +}) + +---
+-- +-- Includes: +-- +-- - `sounds.tiger_roar` +-- - `sounds.tiger_snarl` +-- +-- @sndgroup sounds.tiger +sounds.tiger = sounds.tiger_roar + sounds.tiger_snarl + + + +--- Fowl +-- +-- @section fowl + + +--- @sndgroup sounds.canary +-- @snd canary_01 +-- @snd canary_02 +-- @snd canary_03 +sounds.canary = iSoundGroup({ + "canary_01", + "canary_02", + "canary_03", +}) + +---
+-- +-- Includes: +-- +-- - `sounds.canary` +-- +-- @sndgroup sounds.bird +-- @snd bird_01 +-- @snd bird_02 +-- @snd bird_03 +sounds.bird = iSoundGroup({ + "bird_01", + "bird_02", + "bird_03", +}) + sounds.canary + +--- @sndgroup sounds.chicken +-- @snd chicken_01 +-- @snd chicken_02 +sounds.chicken = iSoundGroup({ + "chicken_01", + "chicken_02", +}) + +--- @sndgroup sounds.crow_caw +-- @snd crow_caw +sounds.crow_caw = iSoundGroup({ + "crow_caw", +}) + +--- @sndgroup sounds.duck_quack +-- @snd duck_quack_01 +-- @snd duck_quack_02 +-- @snd duck_quack_03 +sounds.duck_quack = iSoundGroup({ + "duck_quack_01", + "duck_quack_02", + "duck_quack_03", +}) + +--- @sndgroup sounds.goose +-- @snd goose +sounds.goose = iSoundGroup({ + "goose", +}) + +--- @sndgroup sounds.loon +-- @snd loon_01 +-- @snd loon_02 +-- @snd loon_03 +sounds.loon = iSoundGroup({ + "loon_01", + "loon_02", + "loon_03", +}) + +--- @sndgroup sounds.owl +-- @snd owl_hoot +sounds.owl = iSoundGroup({ + "owl_hoot", +}) + +--- @sndgroup sounds.parrot_chirp +-- @snd parrot_chirp +sounds.parrot_chirp = iSoundGroup({ + "parrot_chirp", +}) + +--- @sndgroup sounds.parrot_whistle +-- @snd parrot_whistle +sounds.parrot_whistle = iSoundGroup({ + "parrot_whistle", +}) + +---
+-- +-- Includes: +-- +-- - `sounds.parrot_chirp` +-- - `sounds.parrot_whistle` +-- +-- @sndgroup sounds.parrot +-- @snd parrot_01 +-- @snd parrot_02 +-- @snd parrot_03 +sounds.parrot = iSoundGroup({ + "parrot_01", + "parrot_02", + "parrot_03", +}) + sounds.parrot_chirp + sounds.parrot_whistle + +--- @sndgroup sounds.peacock +-- @snd peacock_01 +-- @snd peacock_02 +sounds.peacock = iSoundGroup({ + "peacock_01", + "peacock_02", +}) + +--- @sndgroup sounds.penguin +-- @snd penguin_01 +-- @snd penguin_02 +sounds.penguin = iSoundGroup({ + "penguin_01", + "penguin_02", +}) + +--- @sndgroup sounds.pigeon +-- @snd pigeon +sounds.pigeon = iSoundGroup({ + "pigeon", +}) + +--- @sndgroup sounds.quail +-- @snd quail +sounds.quail = iSoundGroup({ + "quail", +}) + +--- @sndgroup sounds.rooster +-- @snd rooster +sounds.rooster = iSoundGroup({ + "rooster", +}) + +--- @sndgroup sounds.seagull +-- @snd seagull_01 +-- @snd seagull_02 +-- @snd seagulls +sounds.seagull = iSoundGroup({ + "seagull_01", + "seagull_02", + "seagulls", +}) + +--- @sndgroup sounds.toucan +-- @snd toucan_01 +-- @snd toucan_02 +-- @snd toucan_03 +sounds.toucan = iSoundGroup({ + "toucan_01", + "toucan_02", + "toucan_03", +}) + +--- @sndgroup sounds.trumpeter_swan +-- @snd trumpeter_swan +sounds.trumpeter_swan = iSoundGroup({ + "trumpeter_swan", +}) + +--- @sndgroup sounds.turkey_gobble +-- @snd turkey_gobble +sounds.turkey_gobble = iSoundGroup({ + "turkey_gobble", +}) + +--- @sndgroup sounds.vulture +-- @snd vulture (imitation) +sounds.vulture = iSoundGroup({ + "vulture", +}) + +--- @sndgroup sounds.woodpecker +-- @snd woodpecker_peck +sounds.woodpecker = iSoundGroup({ + "woodpecker_peck", +}) + + + +--- Giraffe +-- +-- @section giraffe + + +--- @sndgroup sounds.giraffe_hum +-- @snd giraffe_hum +sounds.giraffe_hum = iSoundGroup({ + "giraffe_hum", +}) + + + +--- Insect +-- +-- @section insect + + +--- @sndgroup sounds.bee +-- @snd bee (loopable) +-- @snd bumble_bee_01 (loopable) +-- @snd bumble_bee_02 +-- @snd bees (loopable) +sounds.bee = iSoundGroup({ + "bee", + "bumble_bee_01", + "bumble_bee_02", + "bees", +}) + +--- @sndgroup sounds.cicada +-- @snd cicada_01 (loopable) +-- @snd cicada_02 (loopable) +-- @snd cicada_03 (loopable) +-- @snd cicada_04 (loopable) +-- @snd cicada_05 (loopable) +-- @snd cicada_06 (loopable) +-- @snd cicada_07 (loopable) +-- @snd cicada_08 (loopable) +sounds.cicada = iSoundGroup({ + "cicada_01", + "cicada_02", + "cicada_03", + "cicada_04", + "cicada_05", + "cicada_06", + "cicada_07", + "cicada_08", +}) + +--- @sndgroup sounds.cricket +-- @snd cricket (loopable) +sounds.cricket = iSoundGroup({ + "cricket", +}) + +--- @sndgroup sounds.grasshopper +-- @snd grasshopper +sounds.grasshopper = iSoundGroup({ + "grasshopper", +}) + + + +--- Pinniped +-- +-- @section pinniped + + +--- @sndgroup sounds.sea_lion +-- @snd sea_lion_01 +-- @snd sea_lion_02 +-- @snd sea_lion_03 +sounds.sea_lion = iSoundGroup({ + "sea_lion_01", + "sea_lion_02", + "sea_lion_03", +}) + + + +--- Primate +-- +-- @section primate + + +--- @sndgroup sounds.gorilla_grunt +-- @snd gorilla_grunt +sounds.gorilla_grunt = iSoundGroup({ + "gorilla_grunt", +}) + +--- @sndgroup sounds.gorilla_roar +-- @snd gorilla_roar +sounds.gorilla_roar = iSoundGroup({ + "gorilla_roar", +}) + +--- @sndgroup sounds.gorilla_snarl +-- @snd gorilla_snarl_01 +-- @snd gorilla_snarl_02 +-- @snd gorilla_snarl_03 +-- @snd gorilla_snarl_04 +sounds.gorilla_snarl = iSoundGroup({ + "gorilla_snarl_01", + "gorilla_snarl_02", + "gorilla_snarl_03", + "gorilla_snarl_04", +}) + +---
+-- +-- Includes: +-- +-- - `sounds.gorilla_grunt` +-- - `sounds.gorilla_roar` +-- - `sounds.gorilla_snarl` +-- +-- @sndgroup sounds.gorilla +sounds.gorilla = sounds.gorilla_grunt + sounds.gorilla_roar + sounds.gorilla_snarl + +--- @sndgroup sounds.monkey +-- @snd monkey_01 (imitation) +-- @snd monkey_02 (imitation) +-- @snd monkey_03 (imitation) +sounds.monkey = iSoundGroup({ + "monkey_01", + "monkey_02", + "monkey_03", +}) + + + +--- Raccoon +-- +-- @section raccoon + + +--- @sndgroup sounds.raccoon +-- @snd raccoon_chatter +-- @snd raccoon_chatter_baby_01 +-- @snd raccoon_chatter_baby_02 +sounds.raccoon = iSoundGroup({ + "raccoon_chatter", + "raccoon_chatter_baby_01", + "raccoon_chatter_baby_02", +}) + + +--- Rodent +-- +-- @section rodent + + +--- @sndgroup sounds.mouse +-- @snd mouse (imitation) +sounds.mouse = iSoundGroup({ + "mouse", +}) + +--- @sndgroup sounds.squirrel +-- @snd squirrel_01 +-- @snd squirrel_02 +-- @snd squirrel_03 +sounds.squirrel = iSoundGroup({ + "squirrel_01", + "squirrel_02", + "squirrel_03", +}) + + + +--- Snake +-- +-- @section snake + + +--- @sndgroup sounds.cobra +-- @snd cobra_01 +-- @snd cobra_02 +sounds.cobra = iSoundGroup({ + "cobra_01", + "cobra_02", +}) + +--- @sndgroup sounds.snake_rattle +-- @snd snake_rattle +sounds.snake_rattle = iSoundGroup({ + "snake_rattle", +}) + +---
+-- +-- Includes: +-- +-- - `sounds.cobra` +-- - `sounds.snake_rattle` +-- +-- @sndgroup sounds.snake +sounds.snake = sounds.cobra + sounds.snake_rattle + + + +--- Swine +-- +-- @section swine + + +--- @sndgroup sounds.pig_snort +-- @snd pig_snort +sounds.pig_snort = iSoundGroup({ + "pig_snort", +}) + +--- @sndgroup sounds.pig_squeal +-- @snd pig_squeal +sounds.pig_squeal = iSoundGroup({ + "pig_squeal", +}) + +---
+-- +-- Includes: +-- +-- - `sounds.pig_snort` +-- - `sounds.pig_squeal` +-- +-- @sndgroup sounds.pig +sounds.pig = sounds.pig_snort + sounds.pig_squeal diff --git a/mods/sounds/groups/creature.lua b/mods/sounds/groups/creature.lua new file mode 100644 index 0000000..8c24c92 --- /dev/null +++ b/mods/sounds/groups/creature.lua @@ -0,0 +1,129 @@ + +--- Pre-defined Creature Sound Groups +-- +-- @topic creature_groups + + + +--- Ghost +-- +-- @section ghost + + +--- @sndgroup sounds.ghost +-- @snd ghost_01 +-- @snd ghost_02 +sounds.ghost = iSoundGroup({ + "ghost_01", + "ghost_02", +}) + +--- @sndgroup sounds.ghost_damage +-- @snd ghost_damage +sounds.ghost_damage = iSoundGroup({ + "ghost_damage", +}) + +--- @sndgroup sounds.ghost +-- @snd ghost_death +sounds.ghost_death = iSoundGroup({ + "ghost_death", +}) + + + +--- Mermaid +-- +-- @section mermaid + + +--- @sndgroup sounds.mermaid_song +-- @snd mermaid_song_01 +-- @snd mermaid_song_02 +-- @snd mermaid_song_03 +-- @snd mermaid_song_04 +-- @snd mermaid_song_05 +sounds.mermaid_song = iSoundGroup({ + "mermaid_song_01", + "mermaid_song_02", + "mermaid_song_03", + "mermaid_song_04", + "mermaid_song_05", +}) + + + +--- Robot +-- +-- @section robot + + +--- @sndgroup sounds.robot +-- @snd robot_01 +-- @snd robot_02 +sounds.robot = iSoundGroup({ + "robot_01", + "robot_02", +}) + + + +--- Undead +-- +-- @section undead + + +--- @sndgroup sounds.skeleton +-- @snd skeleton_bones +sounds.skeleton = iSoundGroup({ + "skeleton_bones", +}) + +--- @sndgroup sounds.undead_moan +-- @snd undead_moan_01 +-- @snd undead_moan_02 +-- @snd undead_moan_03 +-- @snd undead_moan_04 +sounds.undead_moan = iSoundGroup({ + "undead_moan_01", + "undead_moan_02", + "undead_moan_03", + "undead_moan_04", +}) + +--- @sndgroup sounds.zombie_damage +-- @snd zombie_damage +sounds.zombie_damage = iSoundGroup({ + "zombie_damage", +}) + +--- @sndgroup sounds.zombie_death +-- @snd zombie_death +sounds.zombie_death = iSoundGroup({ + "zombie_death", +}) + +--- @sndgroup sounds.zombie_growl +-- @snd zombie_growl_01 +-- @snd zombie_growl_02 +-- @snd zombie_growl_03 +sounds.zombie_growl = iSoundGroup({ + "zombie_growl_01", + "zombie_growl_02", + "zombie_growl_03", +}) + + + +--- Misc. +-- +-- @section misc + + +--- @sndgroup sounds.laugh_evil +-- @snd laugh_evil_01 +-- @snd laugh_evil_02 +sounds.laugh_evil = iSoundGroup({ + "laugh_evil_01", + "laugh_evil_02", +}) diff --git a/mods/sounds/groups/firearm.lua b/mods/sounds/groups/firearm.lua new file mode 100644 index 0000000..a7efba9 --- /dev/null +++ b/mods/sounds/groups/firearm.lua @@ -0,0 +1,151 @@ + +--- Pre-defined Firearm Sound Groups +-- +-- @topic firearm_groups + + + +--- Assualt Rifle +-- +-- @section ar + + +--- @sndgroup sounds.ar_burst +-- @snd ar_burst_01 +-- @snd ar_burst_02 +-- @snd ar_burst_03 +sounds.ar_burst = iSoundGroup({ + "ar_burst_01", + "ar_burst_02", + "ar_burst_03", +}) + +---
+-- +-- Includes: +-- +-- - `sounds.ar_burst` +-- +-- @sndgroup sounds.ar_fire +-- @snd ar_fire_01 +-- @snd ar_fire_02 +sounds.ar_fire = iSoundGroup({ + "ar_fire_01", + "ar_fire_02", +}) + sounds.ar_burst + + + +--- Pistol +-- +-- @section pistol + + +--- @sndgroup sounds.pistol_cock +-- @snd pistol_cock_01 +-- @snd pistol_cock_02 +-- @snd pistol_cock_03 +sounds.pistol_cock = iSoundGroup({ + "pistol_cock_01", + "pistol_cock_02", + "pistol_cock_03", +}) + +--- @sndgroup sounds.pistol_fire +-- @snd pistol_fire_01 +-- @snd pistol_fire_02 +-- @snd pistol_fire_03 +sounds.pistol_fire = iSoundGroup({ + "pistol_fire_01", + "pistol_fire_02", + "pistol_fire_03", +}) + +--- @sndgroup sounds.pistol_fire_dry +-- @snd pistol_fire_dry +sounds.pistol_fire_dry = iSoundGroup({ + "pistol_fire_dry", +}) + +--- @sndgroup sounds.pistol_reload +-- @snd pistol_reload +sounds.pistol_reload = iSoundGroup({ + "pistol_reload", +}) + + + +--- Ricochet +-- +-- @section ricochet + + +--- @sndgroup = sounds.ricochet +-- @snd ricochet +sounds.ricochet = iSoundGroup({ + "ricochet", +}) + + + +--- Rifle +-- +-- @section rifle + + +--- @sndgroup sounds.rifle_cock +-- @snd rifle_cock_01 +-- @snd rifle_cock_02 +-- @snd rifle_cock_03 +sounds.rifle_cock = iSoundGroup({ + "rifle_cock_01", + "rifle_cock_02", + "rifle_cock_03", +}) + +--- @sndgroup sounds.rifle_fire +-- @snd rifle_fire_01 +-- @snd rifle_fire_02 +-- @snd rifle_fire_03 +-- @snd rifle_fire_04 +-- @snd rifle_fire_cock +sounds.rifle_fire = iSoundGroup({ + "rifle_fire_01", + "rifle_fire_02", + "rifle_fire_03", + "rifle_fire_04", + "rifle_fire_cock", +}) + +--- @sndgroup sounds.rifle_fire_dry +-- @snd rifle_fire_dry +sounds.rifle_fire_dry = iSoundGroup({ + "rifle_fire_dry", +}) + +--- @sndgroup sounds.rifle_small_fire +-- @snd rifle_small_fire_01 +-- @snd rifle_small_fire_02 +sounds.rifle_small_fire = iSoundGroup({ + "rifle_small_fire_01", + "rifle_small_fire_02", +}) + + + +--- Shotgun +-- +-- @section shotgun + + +--- @sndgroup sounds.shotgun_fire +-- @snd shotgun_fire_pump +sounds.shotgun_fire = iSoundGroup({ + "shotgun_fire_pump", +}) + +--- @sndgroup sounds.shotgun_pump +-- @snd shotgun_pump +sounds.shotgun_pump = iSoundGroup({ + "shotgun_pump", +}) diff --git a/mods/sounds/groups/main.lua b/mods/sounds/groups/main.lua new file mode 100644 index 0000000..9035bac --- /dev/null +++ b/mods/sounds/groups/main.lua @@ -0,0 +1,540 @@ + +--- Pre-defined General Sound Groups +-- +-- @topic groups + + + +--- Balloon +-- +-- @section balloon + + +--- @sndgroup sounds.balloon_inflate +-- @snd balloon_inflate +sounds.balloon_inflate = iSoundGroup({ + "balloon_inflate", +}) + +--- @sndgroup sounds.balloon_pop +-- @snd balloon_pop +sounds.balloon_pop = iSoundGroup({ + "balloon_pop", +}) + + + +--- Bite +-- +-- @section bite + + +--- @sndgroup sounds.bite +-- @snd apple_bite +sounds.bite = iSoundGroup({ + "apple_bite", +}) + + + +--- Bounce +-- +-- @section bounce + + +--- @sndgroup sounds.bounce +-- @snd boing +sounds.bounce = iSoundGroup({ + "boing", +}) + + + +--- Chalk +-- +-- @section chalk + + +--- @sndgroup sounds.chalk_screech +-- @snd chalk_screech_01 +-- @snd chalk_screech_02 +-- @snd chalk_screech_03 +sounds.chalk_screech = iSoundGroup({ + "chalk_screech_01", + "chalk_screech_02", + "chalk_screech_03", +}) + +--- @sndgroup sounds.chalk_write +-- @snd chalk_write_01 +-- @snd chalk_write_02 +-- @snd chalk_write_03 +sounds.chalk_write = iSoundGroup({ + "chalk_write_01", + "chalk_write_02", + "chalk_write_03", +}) + + + +--- Church Bells +-- +-- @section church_bells + + +--- @sndgroup sounds.church_bells +-- @snd church_bells_01 (loopable) +-- @snd church_bells_02 (loopable) +sounds.church_bells = iSoundGroup({ + "church_bells_01", + "church_bells_02", +}) + + + +--- Clock +-- +-- @section clock + + +--- @sndgroup sounds.clock +-- @snd clock_tick (loopable) +sounds.clock = iSoundGroup({ + "clock_tick", +}) + + + +--- Coin +-- +-- @section coin + + +--- @sndgroup sounds.coin +-- @snd coin +sounds.coin = iSoundGroup({ + "coin", +}) + + + +--- Combat +-- +-- @section combat + + +--- @sndgroup sounds.entity_hit +-- @snd entity_hit +sounds.entity_hit = iSoundGroup({ + "entity_hit", +}) + +--- @sndgroup sounds.melee_hit +-- @snd melee_hit_01 +-- @snd melee_hit_02 +-- @snd melee_hit_03 +-- @snd melee_hit_04 +-- @snd melee_hit_05 +-- @snd melee_hit_06 +sounds.melee_hit = iSoundGroup({ + "melee_hit_01", + "melee_hit_02", + "melee_hit_03", + "melee_hit_04", + "melee_hit_05", + "melee_hit_06", +}) + + + +--- Compressor +-- +-- @section compressor + + +--- @sndgroup sounds.compressor +-- @snd compressor_motor_01 (loopable) +-- @snd compressor_motor_02 (loopable) +sounds.compressor = iSoundGroup({ + "compressor_motor_01", + "compressor_motor_02", +}) + + + +--- Door +-- +-- @section door + + +--- @sndgroup sounds.door_close +-- @snd door_close_01 +-- @snd door_close_02 +-- @snd door_close_03 +sounds.door_close = iSoundGroup({ + "door_close_01", + "door_close_02", + "door_close_03", +}) + +--- @sndgroup sounds.door_creak +-- @snd door_creak +sounds.door_creak = iSoundGroup({ + "door_creak", +}) + +--- @sndgroup sounds.door_knock +-- @snd door_knock_01 +-- @snd door_knock_02 +sounds.door_knock = iSoundGroup({ + "door_knock_01", + "door_knock_02", +}) + +--- @sndgroup sounds.door_open +-- @snd door_open +sounds.door_open = iSoundGroup({ + "door_open", +}) + +--- @sndgroup sounds.doorbell +-- @snd doorbell_01 +-- @snd doorbell_02 +-- @snd doorbell_03 +sounds.doorbell = iSoundGroup({ + "doorbell_01", + "doorbell_02", + "doorbell_03", +}) + + + +--- Explosion +-- +-- @section explosion + + +--- @sndgroup sounds.explosion +-- @snd explosion_01 +-- @snd explosion_02 +-- @snd explosion_03 +sounds.explosion = iSoundGroup({ + "explosion_01", + "explosion_02", + "explosion_03", +}) + +--- @sndgroup sounds.explosion_distant +-- @snd explosion_distant_01 +-- @snd explosion_distant_02 +-- @snd explosion_distant_03 +-- @snd explosion_distant_04 +sounds.explosion_distant = iSoundGroup({ + "explosion_distant_01", + "explosion_distant_02", + "explosion_distant_03", + "explosion_distant_04", +}) + + + +--- Fire +-- +-- @section fire + + +--- @sndgroup sounds.fire +-- @snd fire_crackle (loopable) +sounds.fire = iSoundGroup({ + "fire_crackle", +}) + + + +--- Fireworks +-- +-- @section fireworks + + +--- @sndgroup sounds.fireworks +-- @snd fireworks_01 +-- @snd fireworks_02 +sounds.fireworks = iSoundGroup({ + "fireworks_01", + "fireworks_02", +}) + +--- @sndgroup sounds.fireworks_pop +-- @snd fireworks_pop_01 +-- @snd fireworks_pop_02 +-- @snd fireworks_pop_03 +sounds.fireworks_pop = iSoundGroup({ + "fireworks_pop_01", + "fireworks_pop_02", + "fireworks_pop_03", +}) + + + +--- Fuse +-- +-- @section fuse + + +--- @sndgroup sounds.fuse +-- @snd fuse +-- @snd fuse_short +sounds.fuse = iSoundGroup({ + "fuse", + "fuse_short", +}) + + + +--- Gallop +-- +-- @section gallop + + +--- @sndgroup sounds.gallop +-- @snd gallop_01 (loopable) +-- @snd gallop_02 (loopable) +sounds.gallop = iSoundGroup({ + "gallop_01", + "gallop_02", +}) + + + +--- Lava +-- +-- @section lava + + +--- @sndgroup sounds.lava_cool +-- @snd[r3] lava_cool +sounds.lava_cool = iSoundGroup({ + "lava_cool", +}) + + + +--- Leaves +-- +-- @section leaves + + +--- @sndgroup sounds.leaves +-- @snd leaves_01 +-- @snd leaves_02 +sounds.leaves = iSoundGroup({ + "leaves_01", + "leaves_02", +}) + + + +--- Match +-- +-- @section match + + +--- @sndgroup sounds.match +-- @snd match_ignite +sounds.match = iSoundGroup({ + "match_ignite", +}) + + + +--- Pencil +-- +-- @section pencil + + +--- @sndgroup sounds.pencil_erase +-- @snd pencil_erase +sounds.pencil_erase = iSoundGroup({ + "pencil_erase", +}) + +--- @sndgroup sounds.pencil_write +-- @snd pencil_write +sounds.pencil_write = iSoundGroup({ + "pencil_write", +}) + + + +--- Piano +-- +-- @section piano + + +--- @sndgroup sounds.piano +-- @snd piano +sounds.piano = iSoundGroup({ + "piano", +}) + + + +--- Scrape +-- +-- @section scrape + + +--- @sndgroup sounds.scrape +-- @snd scrape_01 +-- @snd scrape_02 +-- @snd scrape_03 +-- @snd scrape_04 +-- @snd scrape_05 +-- @snd scrape_06 +-- @snd scrape_07 +-- @snd scrape_08 +sounds.scrape = iSoundGroup({ + "scrape_01", + "scrape_02", + "scrape_03", + "scrape_04", + "scrape_05", + "scrape_06", + "scrape_07", + "scrape_08", +}) + + + +--- Shears +-- +-- @section shears + + +--- @sndgroup sounds.shears +-- @snd shears_01 +-- @snd shears_02 +sounds.shears = iSoundGroup({ + "shears_01", + "shears_02", +}) + + + +--- Tool +-- +-- @section tool + + +--- @sndgroup sounds.tool_break +-- @snd[r3] tool_break +sounds.tool_break = iSoundGroup({ + "tool_break", +}) + + + +--- Toy +-- +-- @section toy + + +--- @sndgroup sounds.toy_squeak +-- @snd toy_squeak_01 +-- @snd toy_squeak_02 +sounds.toy_squeak = iSoundGroup({ + "toy_squeak_01", + "toy_squeak_02", +}) + + + +--- Tree +-- +-- @section tree + + +--- @sndgroup sounds.tree +-- @snd tree_creak +sounds.tree = iSoundGroup({ + "tree_creak", +}) + + + +--- Vomit +-- +-- @section vomit + + +--- @sndgroup sounds.vomit +-- @snd vomit_01 +-- @snd vomit_02 +-- @snd vomit_03 +-- @snd vomit_04 +-- @snd vomit_05 +sounds.vomit = iSoundGroup({ + "vomit_01", + "vomit_02", + "vomit_03", + "vomit_04", + "vomit_05", +}) + + + +--- Watch +-- +-- @section watch + + +--- @sndgroup sounds.watch +-- @snd watch_tick (loopable) +sounds.watch = iSoundGroup({ + "watch_tick", +}) + + + +--- Whistle +-- +-- @section whistle + + +--- @sndgroup sounds.whistle +-- @snd whistle +sounds.whistle = iSoundGroup({ + "whistle", +}) + + + +--- Woosh +-- +-- @section woosh + + +--- @sndgroup sounds.woosh +-- @snd woosh_01 +-- @snd woosh_02 +-- @snd woosh_03 +-- @snd woosh_04 +sounds.woosh = iSoundGroup({ + "woosh_01", + "woosh_02", + "woosh_03", + "woosh_04", +}) + + + +--- Zipper +-- +-- @section zipper + + +--- @sndgroup sounds.zipper +-- @snd zipper +sounds.zipper = iSoundGroup({ + "zipper", +}) diff --git a/mods/sounds/groups/node.lua b/mods/sounds/groups/node.lua new file mode 100644 index 0000000..447e233 --- /dev/null +++ b/mods/sounds/groups/node.lua @@ -0,0 +1,115 @@ + +--- Pre-defined Node Sound Groups +-- +-- @topic node_groups + + +sounds.node = { + dig = { + --- @sndgroup sounds.node.dig.choppy + -- @snd[r3] node_dig_choppy + -- @see node sounds.node_choppy + choppy = iSoundGroup({"node_dig_choppy"}), + --- @sndgroup sounds.node.dig.cracky + -- @snd[r3] node_dig_cracky + -- @see node sounds.node_cracky + cracky = iSoundGroup({"node_dig_cracky"}), + --- @sndgroup sounds.node.dig.crumbly + -- @snd node_dig_crumbly + -- @see node sounds.node_crumbly + crumbly = iSoundGroup({"node_dig_crumbly"}), + --- @sndgroup sounds.node.dig.snappy + -- @snd node_dig_snappy + -- @see node sounds.node_snappy + snappy = iSoundGroup({"node_dig_snappy"}), + --- @sndgroup sounds.node.dig.gravel + -- @snd[r2] node_dig_gravel + -- @see node sounds.node_gravel + gravel = iSoundGroup({"node_dig_gravel"}), + --- @sndgroup sounds.node.dig.ice + -- @snd[r3] node_dig_ice + -- @see node sounds.node_ice + ice = iSoundGroup({"node_dig_ice"}), + --- @sndgroup sounds.node.dig.metal + -- @snd node_dig_metal + -- @see node sounds.node_metal + metal = iSoundGroup({"node_dig_metal"}), + }, + --- @sndgroup sounds.node.dug + -- @snd[r2] node_dug + -- @see node sounds.node + dug = iSoundGroup({"node_dug", + --- @sndgroup sounds.node.dug.glass + -- @snd[r3] node_dug_glass + -- @see node sounds.node_glass + glass = iSoundGroup({"node_dug_glass"}), + --- @sndgroup sounds.node.dug.gravel + -- @snd[r3] node_dug_gravel + gravel = iSoundGroup({"node_dug_gravel"}), + --- @sndgroup sounds.node.dug.ice + -- @snd node_dug_ice + -- @see node sounds.node_ice + ice = iSoundGroup({"node_dug_ice"}), + --- @sndgroup sounds.node.dug.metal + -- @snd[r2] node_dug_metal + -- @see node sounds.node_metal + metal = iSoundGroup({"node_dug_metal"}), + }), + --- @sndgroup sounds.node.place + -- @snd[r2] node_place + -- @see node sounds.node + place = iSoundGroup({"node_place", + --- @sndgroup sounds.node.place.metal + -- @snd[r2] node_dug_metal + -- @see node sounds.node_metal + metal = iSoundGroup({"node_dug_metal"}), + --- @sndgroup sounds.node.place.soft + -- @snd[r3] node_place_soft + soft = iSoundGroup({"node_place_soft"}), + }), + step = { + --- @sndgroup sounds.node.step.dirt + -- @snd[r2] node_step_dirt + -- @see node sounds.node_dirt + dirt = iSoundGroup({"node_step_dirt"}), + --- @sndgroup sounds.node.step.glass + -- @snd node_step_glass + -- @see node sounds.node_glass + glass = iSoundGroup({"node_step_glass"}), + --- @sndgroup sounds.node.step.grass + -- @snd[r3] node_step_grass + -- @see node sounds.node_grass + grass = iSoundGroup({"node_step_grass"}), + --- @sndgroup sounds.node.step.gravel + -- @snd[r4] node_step_gravel + -- @see node sounds.node_gravel + gravel = iSoundGroup({"node_step_gravel"}), + --- @sndgroup sounds.node.step.hard + -- @snd[r3] node_step_hard + hard = iSoundGroup({"node_step_hard"}), + --- @sndgroup sounds.node.step.ice + -- @snd[r3] node_step_ice + -- @see node sounds.node_ice + ice = iSoundGroup({"node_step_ice"}), + --- @sndgroup sounds.node.step.metal + -- @snd[r3] node_step_metal + -- @see node sounds.node_metal + metal = iSoundGroup({"node_step_metal"}), + --- @sndgroup sounds.node.step.sand + -- @snd[r3] node_step_sand + -- @see node sounds.node_sand + sand = iSoundGroup({"node_step_sand"}), + --- @sndgroup sounds.node.step.snow + -- @snd[r5] node_step_snow + -- @see node sounds.node_snow + snow = iSoundGroup({"node_step_snow"}), + --- @sndgroup sounds.node.step.water + -- @snd[r4] node_step_water (**Note:** node\_step\_water.4 is silent) + -- @see node sounds.node_water + water = iSoundGroup({"node_step_water"}), + --- @sndgroup sounds.node.step.wood + -- @snd[r2] node_step_wood + -- @see node sounds.node_wood + wood = iSoundGroup({"node_step_wood"}), + }, +} diff --git a/mods/sounds/groups/projectile.lua b/mods/sounds/groups/projectile.lua new file mode 100644 index 0000000..1e0b52a --- /dev/null +++ b/mods/sounds/groups/projectile.lua @@ -0,0 +1,46 @@ + +--- Pre-defined Projectile Sound Groups +-- +-- @topic projectile_groups + + + +--- Fireball +-- +-- @section fireball + + +--- @sndgroup sounds.fireball +-- @snd fireball_01 +-- @snd fireball_02 +-- @snd fireball_03 +sounds.fireball = iSoundGroup({ + "fireball_01", + "fireball_02", + "fireball_03", +}) + + + +--- Laser +-- +-- @section laser + + +--- @sndgroup sounds.laser +-- @snd laser_01 +-- @snd laser_02 +-- @snd laser_03 +-- @snd laser_04 +-- @snd laser_05 +-- @snd laser_06 +-- @snd laser_07 +sounds.laser = iSoundGroup({ + "laser_01", + "laser_02", + "laser_03", + "laser_04", + "laser_05", + "laser_06", + "laser_07", +}) diff --git a/mods/sounds/groups/scifi.lua b/mods/sounds/groups/scifi.lua new file mode 100644 index 0000000..dc00713 --- /dev/null +++ b/mods/sounds/groups/scifi.lua @@ -0,0 +1,18 @@ + +--- Pre-defined Sci-Fi Sound Groups +-- +-- @topic scifi_groups + + + +--- @sndgroup sounds.explosion_scifi +-- @snd explosion_scifi +sounds.explosion_scifi = iSoundGroup({ + "explosion_scifi", +}) + +--- @sndgroup sounds.plasma_shot +-- @snd plasma_shot +sounds.plasma_shot = iSoundGroup({ + "plasma_shot", +}) diff --git a/mods/sounds/groups/vehicle.lua b/mods/sounds/groups/vehicle.lua new file mode 100644 index 0000000..ee3cede --- /dev/null +++ b/mods/sounds/groups/vehicle.lua @@ -0,0 +1,114 @@ + +--- Pre-defined Vehicle Sound Groups +-- +-- @topic vehicle_groups + + + +--- Airplane +-- +-- @section airplane + + +--- @sndgroup sounds.airplane +-- @snd airplane_prop (loopable) +sounds.airplane = iSoundGroup({ + "airplane_prop", +}) + +--- @sndgroup sounds.jet +-- @snd jet_ambience (loopable) +-- @snd jet_flyby +-- @snd jet_land +sounds.jet = iSoundGroup({ + "jet_ambience", + "jet_flyby", + "jet_land", +}) + + + +--- Bicycle +-- +-- @section bicycle + + +--- @sndgroup sounds.bicycle_bell +-- @snd bicycle_bell +sounds.bicycle_bell = iSoundGroup({ + "bicycle_bell", +}) + +--- @sndgroup sounds.bicycle_horn +-- @snd bicycle_horn +sounds.bicycle_horn = iSoundGroup({ + "bicycle_horn", +}) + +--- @sndgroup sounds.bicycle_spokes +-- @snd bicycle_spokes +sounds.bicycle_spokes = iSoundGroup({ + "bicycle_spokes", +}) + + + +--- Helicopter +-- +-- @section helicopter + + +--- @sndgroup sounds.helicopter +-- @snd helicopter (loopable) +sounds.helicopter = iSoundGroup({ + "helicopter", +}) + + + +--- Motorbike +-- +-- @section motorbike + + +--- @sndgroup sounds.motorbike +-- @snd motorbike_idle (loopable) +sounds.motorbike = iSoundGroup({ + "motorbike_idle", +}) + + + +--- Train +-- +-- @section train + + +--- @sndgroup sounds.train_whistle +-- @snd train_whistle +sounds.train_whistle = iSoundGroup({ + "train_whistle", +}) + + + +--- Vehicle +-- +-- @section vehicle + + +--- @sndgroup sounds.vehicle_horn +-- @snd vehicle_horn_01 +-- @snd vehicle_horn_02 +sounds.vehicle_horn = iSoundGroup({ + "vehicle_horn_01", + "vehicle_horn_02", +}) + +--- @sndgroup sounds.vehicle_motor +-- @snd car_motor (loopable) +-- @snd vehicle_motor_idle (loopable) +sounds.vehicle_motor = iSoundGroup({ + "car_motor", + "vehicle_motor_idle", +}) diff --git a/mods/sounds/groups/weather.lua b/mods/sounds/groups/weather.lua new file mode 100644 index 0000000..00b02b8 --- /dev/null +++ b/mods/sounds/groups/weather.lua @@ -0,0 +1,53 @@ + +--- Pre-defined Weather Sound Groups +-- +-- @topic weather_groups + + + +--- Rain +-- +-- @section rain + + +--- @sndgroup sounds.rain +-- @snd rain_light (loopable) +-- @snd rain_medium (loopable) +-- @snd rain_heavy_01 (loopable) +-- @snd rain_heavy_02 (loopable) +sounds.rain = iSoundGroup({ + "rain_light", + "rain_medium", + "rain_heavy_01", + "rain_heavy_02", +}) + + + +--- Thunder +-- +-- @section thunder + + +--- @sndgroup sounds.thunder +-- @snd thunder_01 +-- @snd thunder_02 +-- @snd thunder_03 +sounds.thunder = iSoundGroup({ + "thunder_01", + "thunder_02", + "thunder_03", +}) + + + +--- Wind +-- +-- @section wind + + +--- @sndgroup sounds.wind +-- @snd wind (loopable) +sounds.wind = iSoundGroup({ + "wind", +}) diff --git a/mods/sounds/init.lua b/mods/sounds/init.lua new file mode 100644 index 0000000..3e789ad --- /dev/null +++ b/mods/sounds/init.lua @@ -0,0 +1,134 @@ + +sounds = {} +sounds.modname = core.get_current_modname() +sounds.modpath = core.get_modpath(sounds.modname) + +local debugging = core.settings:get_bool("debug_mods", false) + +sounds.log = function(lvl, msg) + if not msg then + msg = lvl + lvl = nil + end + + if not debugging and lvl == "debug" then return end + + msg = "[" .. sounds.modname .. "] " .. msg + + if lvl == "debug" then + msg = "[DEBUG] " .. msg + lvl = "action" + end + + if not lvl then + core.log(msg) + else + core.log(lvl, msg) + end +end + + +dofile(sounds.modpath .. "/settings.lua") + +local scripts = { + "override", + "api", +} + +if not sounds.disabled_groups["all"] then + local dir_groups = sounds.modpath .. "/groups" + for _, lua in ipairs(core.get_dir_list(dir_groups, false)) do + if lua:find("%.lua$") then + local sg = lua:gsub("%.lua$", "") + if not sounds.disabled_groups[sg] then + sounds.log("debug", "sounds groups \"" .. sg .. "\" loading") + table.insert(scripts, "groups/" .. sg) + else + sounds.log("debug", "sounds groups \"" .. sg .. "\" disabled") + end + end + end +else + sounds.log("debug", "built-in sounds groups disabled") +end + +-- ensure that node.lua is loaded after groups/node.lua +table.insert(scripts, "node") + +for _, s in ipairs(scripts) do + dofile(sounds.modpath .. "/" .. s .. ".lua") +end + +if sounds.enable_tests then + dofile(sounds.modpath .. "/tests.lua") +end + + +-- cache available sound files +sounds.cache = {} +core.register_on_mods_loaded(function() + sounds.log("action", "caching sound files ...") + + for _, modname in ipairs(core.get_modnames()) do + local s_dir = core.get_modpath(modname) .. "/sounds" + for _, ogg in ipairs(core.get_dir_list(s_dir, false)) do + if ogg:find("%.ogg$") then + local basename = ogg:gsub("%.ogg$", "") + local cache_value = true + + -- files for playing randomly by core must have suffix trimmed + if basename:find("%.[0-9]$") then + basename = basename:gsub("%.[0-9]$", "") + cache_value = sounds.cache[basename] + if type(cache_value) ~= "number" then + cache_value = 1 + else + cache_value = cache_value + 1 + end + end + + sounds.cache[basename] = cache_value + end + end + end +end) + + +if sounds.enable_biome_sounds then + local timer = 0 + local interval = tonumber(core.settings:get("sounds.biome_interval")) or 30 + local chance = tonumber(core.settings:get("sounds.biome_chance")) or 20 + + interval = interval >= 5 and interval or 5 + chance = chance >= 0 and chance or 0 + chance = chance <= 100 and chance or 100 + + core.register_globalstep(function(dtime) + timer = timer + dtime + if timer < interval then + return + end + timer = 0 + + if math.random(100) <= chance then + for _, player in ipairs(core.get_connected_players()) do + local p_name = player:get_player_name() + local b_id = core.get_biome_data(player:get_pos()).biome + + if b_id then + local b_sounds = sounds:get_biome_sounds(core.get_biome_name(b_id)) + + if b_sounds and type(b_sounds.group) == "SoundGroup" then + local b_params = {} + if b_sounds.params then + b_params = table.copy(b_sounds.params) + end + b_params.to_player = p_name + + b_sounds.group(b_params) + end + end + end + end + end) +end diff --git a/mods/sounds/locale/sounds.es.tr b/mods/sounds/locale/sounds.es.tr new file mode 100644 index 0000000..ed43526 --- /dev/null +++ b/mods/sounds/locale/sounds.es.tr @@ -0,0 +1,18 @@ +# textdomain:sounds + +# Translators: Jordan Irwin (AntumDeluge) + + +Displays sounds tests formspec.=Mostrar formspec de pruebas de sonidos. +Sounds Tests=Pruebas de Sonidos +Name: @1=Nombre: @1 +Cached: @1=En caché: @1 +Played: @1=Reproducido: @1 +Manual play:=Reproducir manual: +Group play:=Reproducir grupo: +Play=Reproducir +Stop=Parar +Loop=Bucle +Random=Al azar +yes=sí +no= diff --git a/mods/sounds/locale/template.txt b/mods/sounds/locale/template.txt new file mode 100644 index 0000000..5edbf6c --- /dev/null +++ b/mods/sounds/locale/template.txt @@ -0,0 +1,18 @@ +# textdomain:sounds + +# Translators: + + +Displays sounds tests formspec.= +Sounds Tests= +Name: @1= +Cached: @1= +Played: @1= +Manual play:= +Group play:= +Play= +Stop= +Loop= +Random= +yes= +no= diff --git a/mods/sounds/mod.conf b/mods/sounds/mod.conf new file mode 100644 index 0000000..60a4b09 --- /dev/null +++ b/mods/sounds/mod.conf @@ -0,0 +1,8 @@ +name = sounds +version = 1.12 +title = Sounds +description = A set of free sounds & API. +license = MIT +author = Jordan Irwin (AntumDeluge) +min_minetest_version = 5.0 +optional_depends = default diff --git a/mods/sounds/node.lua b/mods/sounds/node.lua new file mode 100644 index 0000000..2a20c9d --- /dev/null +++ b/mods/sounds/node.lua @@ -0,0 +1,303 @@ + +--- Node Sounds +-- +-- @topic node + + +--- General sounds. +-- +-- Aliased or overridden methods: +-- +-- - `default.node_sound_defaults` +-- +-- @function sounds.node +-- @tparam[opt] table tbl Sound table to update. +local node_sounds = { + __call = function(self, tbl) + tbl = tbl or {} + + tbl.footstep = tbl.footstep or {name="", gain=1.0} + tbl.dug = tbl.dug or {name="sounds_node_dug", gain=0.25} + tbl.place = tbl.place or {name="sounds_node_place", gain=1.0} + + return tbl + end, +} + +sounds.node = sounds.node or {} -- in case groups/node.lua was not loaded +setmetatable(sounds.node, node_sounds) + +--- Sounds for "choppy" objects & tools. +-- +-- @tparam[opt] table tbl Sound table to update. +function sounds.node_choppy(tbl) + tbl = tbl or {} + + tbl.dig = tbl.dig or {name="sounds_node_dig_choppy", gain=0.5} + + sounds.node(tbl) + return tbl +end + +--- Sounds for "cracky" objects & tools. +-- +-- @tparam[opt] table tbl Sound table to update. +function sounds.node_cracky(tbl) + tbl = tbl or {} + + tbl.dig = tbl.dig or {name="sounds_node_dig_cracky", gain=0.5} + + sounds.node(tbl) + return tbl +end + +--- Sounds for "crumbly" objects & tools. +-- +-- @tparam[opt] table tbl Sound table to update. +function sounds.node_crumbly(tbl) + tbl = tbl or {} + + tbl.dig = tbl.dig or {name="sounds_node_dig_crumbly", gain=0.5} + + sounds.node(tbl) + return tbl +end + +--- Sounds for "snappy" objects & tools. +-- +-- @tparam[opt] table tbl Sound table to update. +function sounds.node_snappy(tbl) + tbl = tbl or {} + + tbl.dig = tbl.dig or {name="sounds_node_dig_snappy", gain=0.5} + + sounds.node(tbl) + return tbl +end + +--- Sounds for dirt-like nodes. +-- +-- Aliased or overridden methods: +-- +-- - `default.node_sound_dirt_defaults` +-- +-- @tparam[opt] table tbl Sound table to update. +function sounds.node_dirt(tbl) + tbl = tbl or {} + + tbl.footstep = tbl.footstep or {name="sounds_node_step_dirt", gain=0.4} + tbl.dug = tbl.dug or {name="sounds_node_step_dirt", gain=1.0} + tbl.place = tbl.place or {name="sounds_node_place_soft", gain=1.0} + + sounds.node(tbl) + return tbl +end + +--- Sounds for glass-like nodes. +-- +-- Aliased or overridden methods: +-- +-- - `default.node_sound_glass_defaults` +-- +-- @tparam[opt] table tbl Sound table to update. +function sounds.node_glass(tbl) + tbl = tbl or {} + + tbl.footstep = tbl.footstep or {name="sounds_node_step_glass", gain=0.3} + tbl.dig = tbl.dig or {name="sounds_node_step_glass", gain=0.5} + tbl.dug = tbl.dug or {name="sounds_node_dug_glass", gain=1.0} + + sounds.node(tbl) + return tbl +end + +--- Sounds for grass-like nodes. +-- +-- @tparam[opt] table tbl Sound table to update. +function sounds.node_grass(tbl) + tbl = tbl or {} + + tbl.footstep = tbl.footstep or {name="sounds_node_step_grass", gain=0.25} + + return sounds.node_dirt(tbl) +end + +--- Sounds for gravel-like nodes. +-- +-- Aliased or overridden methods: +-- +-- - `default.node_sound_gravel_defaults` +-- +-- @tparam[opt] table tbl Sound table to update. +function sounds.node_gravel(tbl) + tbl = tbl or {} + + tbl.footstep = tbl.footstep or {name="sounds_node_step_gravel", gain=0.1} + tbl.dig = tbl.dig or {name="sounds_node_dig_gravel", gain=0.35} + tbl.dug = tbl.dug or {name="sounds_node_dug_gravel", gain=1.0} + tbl.place = tbl.place or {name="sounds_node_place_soft", gain=1.0} + + sounds.node(tbl) + return tbl +end + +--- Sounds for ice-like nodes. +-- +-- Aliased or overridden methods: +-- +-- - `default.node_sound_ice_defaults` +-- +-- @tparam[opt] table tbl Sound table to update. +function sounds.node_ice(tbl) + tbl = tbl or {} + + tbl.footstep = tbl.footstep or {name="sounds_node_step_ice", gain=0.3} + tbl.dig = tbl.dig or {name="sounds_node_dig_ice", gain=0.5} + tbl.dug = tbl.dug or {name="sounds_node_dug_ice", gain=0.5} + + sounds.node(tbl) + return tbl +end + +--- Sounds for leaf-like nodes. +-- +-- Aliased or overridden methods: +-- +-- - `default.node_sound_leaves_defaults` +-- +-- @tparam[opt] table tbl Sound table to update. +function sounds.node_leaves(tbl) + tbl = tbl or {} + + tbl.footstep = tbl.footstep or {name="sounds_node_step_grass", gain=0.45} + tbl.dug = tbl.dug or {name="sounds_node_step_grass", gain=0.7} + tbl.place = tbl.place or {name="sounds_node_place_soft", gain=1.0} + + sounds.node(tbl) + return tbl +end + +--- Sounds for metal-like nodes. +-- +-- Aliased or overridden methods: +-- +-- - `default.node_sound_metal_defaults` +-- +-- @tparam[opt] table tbl Sound table to update. +function sounds.node_metal(tbl) + tbl = tbl or {} + + tbl.footstep = tbl.footstep or {name="sounds_node_step_metal", gain=0.4} + tbl.dig = tbl.dig or {name="sounds_node_dig_metal", gain=0.5} + tbl.dug = tbl.dug or {name="sounds_node_dug_metal", gain=0.5} + tbl.place = tbl.place or {name="sounds_node_dug_metal", gain=0.5} + + sounds.node(tbl) + return tbl +end + +--- Sounds for sand-like nodes. +-- +-- Aliased or overridden methods: +-- +-- - `default.node_sound_sand_defaults` +-- +-- @tparam[opt] table tbl Sound table to update. +function sounds.node_sand(tbl) + tbl = tbl or {} + + tbl.footstep = tbl.footstep or {name="sounds_node_step_sand", gain=0.05} + tbl.dug = tbl.dug or {name="sounds_node_step_sand", gain=0.15} + tbl.place = tbl.place or {name="sounds_node_place_soft", gain=1.0} + + sounds.node(tbl) + return tbl +end + +--- Sounds for snow-like nodes. +-- +-- Aliased or overridden methods: +-- +-- - `default.node_sound_snow_defaults` +-- +-- @tparam[opt] table tbl Sound table to update. +function sounds.node_snow(tbl) + tbl = tbl or {} + + tbl.footstep = tbl.footstep or {name="sounds_node_step_snow", gain=0.2} + tbl.dig = tbl.dig or {name="sounds_node_step_snow", gain=0.3} + tbl.dug = tbl.dug or {name="sounds_node_step_snow", gain=0.3} + tbl.place = tbl.place or {name="sounds_node_place_soft", gain=1.0} + + sounds.node(tbl) + return tbl +end + +--- Sounds for stone-like nodes. +-- +-- Aliased or overridden methods: +-- +-- - `default.node_sound_stone_defaults` +-- +-- @tparam[opt] table tbl Sound table to update. +function sounds.node_stone(tbl) + tbl = tbl or {} + + tbl.footstep = tbl.footstep or {name="sounds_node_step_hard", gain=0.3} + tbl.dug = tbl.dug or {name="sounds_node_step_hard", gain=1.0} + + sounds.node(tbl) + return tbl +end + +--- Sounds for water-like nodes. +-- +-- Aliased or overridden methods: +-- +-- - `default.node_sound_water_defaults` +-- +-- @tparam[opt] table tbl Sound table to update. +function sounds.node_water(tbl) + tbl = tbl or {} + + tbl.footstep = tbl.footstep or {name="sounds_node_step_water", gain=0.2} + + sounds.node(tbl) + return tbl +end + +--- Sounds for wood-like nodes. +-- +-- Aliased or overridden methods: +-- +-- - `default.node_sound_wood_defaults` +-- +-- @tparam[opt] table tbl Sound table to update. +function sounds.node_wood(tbl) + tbl = tbl or {} + + tbl.footstep = tbl.footstep or {name="sounds_node_step_wood", gain=0.3} + tbl.dug = tbl.dug or {name="sounds_node_step_wood", gain=1.0} + + sounds.node(tbl) + return tbl +end + + +-- compatibility with default mod function +if not core.global_exists("default") then + default = {} +end + +default.node_sound_defaults = sounds.node +default.node_sound_dirt_defaults = sounds.node_dirt +default.node_sound_glass_defaults = sounds.node_glass +default.node_sound_gravel_defaults = sounds.node_gravel +default.node_sound_ice_defaults = sounds.node_ice +default.node_sound_leaves_defaults = sounds.node_leaves +default.node_sound_metal_defaults = sounds.node_metal +default.node_sound_sand_defaults = sounds.node_sand +default.node_sound_snow_defaults = sounds.node_snow +default.node_sound_stone_defaults = sounds.node_stone +default.node_sound_water_defaults = sounds.node_water +default.node_sound_wood_defaults = sounds.node_wood diff --git a/mods/sounds/override.lua b/mods/sounds/override.lua new file mode 100644 index 0000000..1855fe6 --- /dev/null +++ b/mods/sounds/override.lua @@ -0,0 +1,82 @@ + +-- override built-in type function +local otype = type +type = function(obj) + local base_type = otype(obj) + if base_type == "table" then + local meta_type = otype(obj.__type) + if meta_type == "string" then + return obj.__type + elseif meta_type == "function" then + return obj:__type() + end + end + + return base_type +end + +-- override node registration +local register_node_orig = core.register_node +core.register_node = function(name, def) + if type(def.sounds) == "table" then + if type(def.sounds.dig) == "SoundGroup" then + local on_punch_orig = def.on_punch + local s_group = SoundGroup(def.sounds.dig) + def.sounds.dig = "" -- override default sound + def.on_punch = function(...) + s_group() -- FIXME: should retrieve built-in sound spec + + if type(on_punch_orig) == "function" then + return on_punch_orig(...) + end + end + end + + if type(def.sounds.dug) == "SoundGroup" then + local on_dig_orig = def.on_dig + local s_group = SoundGroup(def.sounds.dug) + def.sounds.dug = nil + def.on_dig = function(...) + s_group() + + if type(on_dig_orig) == "function" then + return on_dig_orig(...) + end + + core.node_dig(...) + end + end + + if type(def.sounds.footstep) == "SoundGroup" then + + end + + -- FIXME: should be overridden in register_craftitem + if type(def.sounds.place) == "SoundGroup" then + local on_place_orig = def.on_place + local s_group = SoundGroup(def.sounds.place) + def.sounds.place = nil + def.on_place = function(stack, ...) + s_group() + + if type(on_place_orig) == "function" then + return on_place_orig(stack, ...) + end + + return core.item_place(stack, ...) + end + end + + if type(def.sounds.place_failed) == "SoundGroup" then + -- FIXME: which callback to override + def.sounds.place_failed = def.sounds.place_failed:get_random() + end + + if type(def.sounds.fall) == "SoundGroup" then + -- FIXME: which callback to override + def.sounds.fall = def.sounds.fall:get_random() + end + end + + return register_node_orig(name, def) +end diff --git a/mods/sounds/screenshot.png b/mods/sounds/screenshot.png new file mode 100644 index 0000000..eda795f Binary files /dev/null and b/mods/sounds/screenshot.png differ diff --git a/mods/sounds/settings.lua b/mods/sounds/settings.lua new file mode 100644 index 0000000..480f59b --- /dev/null +++ b/mods/sounds/settings.lua @@ -0,0 +1,53 @@ + +--- Sounds Settings +-- +-- @topic settings + + +--- Disables individual built-in sound groups categories. +-- +-- Category names that can be disabled are the filenames in the +-- "groups" directory without the ".lua" suffix. Use "all" to +-- disable all built-in groups. +-- +-- @setting sounds.disabled_groups +-- @settype string (comma-separated list) +-- @default Empty string. +-- @usage # disable animal & weather sound groups +-- sounds.disabled_groups = animal,weather +sounds.disabled_groups = {} +for _, d in ipairs(string.split(core.settings:get("sounds.disabled_groups") or "", ",")) do + d = d:trim() + if d ~= "" then + sounds.disabled_groups[d] = true + end +end + +--- Enables/Disables ambiance sounds for biomes. +-- +-- @setting sounds.enable_biome_sounds +-- @settype bool +-- @default false +sounds.enable_biome_sounds = core.settings:get_bool("sounds.enable_biome_sounds", false) + +--- Interval between playing biome sounds. +-- +-- @setting sounds.biome_interval +-- @settype int +-- @min 5 +-- @default 30 + +--- Chance that sound will be played at interval. +-- +-- @setting sounds.biome_chance +-- @settype int +-- @min 0 +-- @max 100 +-- @default 20 + +--- Enables sounds testing with [sounds_tests](tests.html#sounds_tests) chat command. +-- +-- @setting sounds.enable_tests +-- @settype bool +-- @default false +sounds.enable_tests = core.settings:get_bool("sounds.enable_tests", false) diff --git a/mods/sounds/settingtypes.txt b/mods/sounds/settingtypes.txt new file mode 100644 index 0000000..1a4168f --- /dev/null +++ b/mods/sounds/settingtypes.txt @@ -0,0 +1,20 @@ + +# Disables individual built-in sound groups categories (comma- +# separated list). +# +# Category names that can be disabled are the filenames in the +# "groups" directory without the ".lua" suffix. Use "all" to +# disable all built-in groups. +sounds.disabled_groups (Disabled sound groups) string + +# Enables/Disables ambiance sounds for biomes. +sounds.enable_biome_sounds (Enable biome sounds) bool false + +# Interval between playing biome sounds. +sounds.biome_interval (Biome sound interval) int 30 5 + +# Chance that sound will be played at interval. +sounds.biome_chance (Biome sound chance) int 20 0 100 + +# Enables sounds testing with /sounds_tests chat command. +sounds.enable_tests (Sounds tests) bool false diff --git a/mods/sounds/sounds/sounds_airplane_prop.ogg b/mods/sounds/sounds/sounds_airplane_prop.ogg new file mode 100644 index 0000000..ba6389b Binary files /dev/null and b/mods/sounds/sounds/sounds_airplane_prop.ogg differ diff --git a/mods/sounds/sounds/sounds_apple_bite.ogg b/mods/sounds/sounds/sounds_apple_bite.ogg new file mode 100644 index 0000000..327a37e Binary files /dev/null and b/mods/sounds/sounds/sounds_apple_bite.ogg differ diff --git a/mods/sounds/sounds/sounds_ar_burst_01.ogg b/mods/sounds/sounds/sounds_ar_burst_01.ogg new file mode 100644 index 0000000..d6e6409 Binary files /dev/null and b/mods/sounds/sounds/sounds_ar_burst_01.ogg differ diff --git a/mods/sounds/sounds/sounds_ar_burst_02.ogg b/mods/sounds/sounds/sounds_ar_burst_02.ogg new file mode 100644 index 0000000..9a98f97 Binary files /dev/null and b/mods/sounds/sounds/sounds_ar_burst_02.ogg differ diff --git a/mods/sounds/sounds/sounds_ar_burst_03.ogg b/mods/sounds/sounds/sounds_ar_burst_03.ogg new file mode 100644 index 0000000..e6946d4 Binary files /dev/null and b/mods/sounds/sounds/sounds_ar_burst_03.ogg differ diff --git a/mods/sounds/sounds/sounds_ar_fire_01.ogg b/mods/sounds/sounds/sounds_ar_fire_01.ogg new file mode 100644 index 0000000..0af5e73 Binary files /dev/null and b/mods/sounds/sounds/sounds_ar_fire_01.ogg differ diff --git a/mods/sounds/sounds/sounds_ar_fire_02.ogg b/mods/sounds/sounds/sounds_ar_fire_02.ogg new file mode 100644 index 0000000..fd4f653 Binary files /dev/null and b/mods/sounds/sounds/sounds_ar_fire_02.ogg differ diff --git a/mods/sounds/sounds/sounds_balloon_inflate.ogg b/mods/sounds/sounds/sounds_balloon_inflate.ogg new file mode 100644 index 0000000..7c5f64c Binary files /dev/null and b/mods/sounds/sounds/sounds_balloon_inflate.ogg differ diff --git a/mods/sounds/sounds/sounds_balloon_pop.ogg b/mods/sounds/sounds/sounds_balloon_pop.ogg new file mode 100644 index 0000000..28f42a0 Binary files /dev/null and b/mods/sounds/sounds/sounds_balloon_pop.ogg differ diff --git a/mods/sounds/sounds/sounds_bat_01.ogg b/mods/sounds/sounds/sounds_bat_01.ogg new file mode 100644 index 0000000..e121a8f Binary files /dev/null and b/mods/sounds/sounds/sounds_bat_01.ogg differ diff --git a/mods/sounds/sounds/sounds_bat_02.ogg b/mods/sounds/sounds/sounds_bat_02.ogg new file mode 100644 index 0000000..fb0d9e6 Binary files /dev/null and b/mods/sounds/sounds/sounds_bat_02.ogg differ diff --git a/mods/sounds/sounds/sounds_bat_03.ogg b/mods/sounds/sounds/sounds_bat_03.ogg new file mode 100644 index 0000000..8bc116a Binary files /dev/null and b/mods/sounds/sounds/sounds_bat_03.ogg differ diff --git a/mods/sounds/sounds/sounds_bear_01.ogg b/mods/sounds/sounds/sounds_bear_01.ogg new file mode 100644 index 0000000..a119e5a Binary files /dev/null and b/mods/sounds/sounds/sounds_bear_01.ogg differ diff --git a/mods/sounds/sounds/sounds_bear_02.ogg b/mods/sounds/sounds/sounds_bear_02.ogg new file mode 100644 index 0000000..5fe98b0 Binary files /dev/null and b/mods/sounds/sounds/sounds_bear_02.ogg differ diff --git a/mods/sounds/sounds/sounds_bee.ogg b/mods/sounds/sounds/sounds_bee.ogg new file mode 100644 index 0000000..b54cf77 Binary files /dev/null and b/mods/sounds/sounds/sounds_bee.ogg differ diff --git a/mods/sounds/sounds/sounds_bees.ogg b/mods/sounds/sounds/sounds_bees.ogg new file mode 100644 index 0000000..33a555f Binary files /dev/null and b/mods/sounds/sounds/sounds_bees.ogg differ diff --git a/mods/sounds/sounds/sounds_bicycle_bell.ogg b/mods/sounds/sounds/sounds_bicycle_bell.ogg new file mode 100644 index 0000000..d6732ef Binary files /dev/null and b/mods/sounds/sounds/sounds_bicycle_bell.ogg differ diff --git a/mods/sounds/sounds/sounds_bicycle_horn.ogg b/mods/sounds/sounds/sounds_bicycle_horn.ogg new file mode 100644 index 0000000..c4557d4 Binary files /dev/null and b/mods/sounds/sounds/sounds_bicycle_horn.ogg differ diff --git a/mods/sounds/sounds/sounds_bicycle_spokes.ogg b/mods/sounds/sounds/sounds_bicycle_spokes.ogg new file mode 100644 index 0000000..9d2a0b1 Binary files /dev/null and b/mods/sounds/sounds/sounds_bicycle_spokes.ogg differ diff --git a/mods/sounds/sounds/sounds_bird_01.ogg b/mods/sounds/sounds/sounds_bird_01.ogg new file mode 100644 index 0000000..d7cd0dd Binary files /dev/null and b/mods/sounds/sounds/sounds_bird_01.ogg differ diff --git a/mods/sounds/sounds/sounds_bird_02.ogg b/mods/sounds/sounds/sounds_bird_02.ogg new file mode 100644 index 0000000..dc69821 Binary files /dev/null and b/mods/sounds/sounds/sounds_bird_02.ogg differ diff --git a/mods/sounds/sounds/sounds_bird_03.ogg b/mods/sounds/sounds/sounds_bird_03.ogg new file mode 100644 index 0000000..f062eeb Binary files /dev/null and b/mods/sounds/sounds/sounds_bird_03.ogg differ diff --git a/mods/sounds/sounds/sounds_boing.ogg b/mods/sounds/sounds/sounds_boing.ogg new file mode 100644 index 0000000..f5e09a4 Binary files /dev/null and b/mods/sounds/sounds/sounds_boing.ogg differ diff --git a/mods/sounds/sounds/sounds_bumble_bee_01.ogg b/mods/sounds/sounds/sounds_bumble_bee_01.ogg new file mode 100644 index 0000000..9231832 Binary files /dev/null and b/mods/sounds/sounds/sounds_bumble_bee_01.ogg differ diff --git a/mods/sounds/sounds/sounds_bumble_bee_02.ogg b/mods/sounds/sounds/sounds_bumble_bee_02.ogg new file mode 100644 index 0000000..0dc0bd4 Binary files /dev/null and b/mods/sounds/sounds/sounds_bumble_bee_02.ogg differ diff --git a/mods/sounds/sounds/sounds_camel_01.ogg b/mods/sounds/sounds/sounds_camel_01.ogg new file mode 100644 index 0000000..624e6d4 Binary files /dev/null and b/mods/sounds/sounds/sounds_camel_01.ogg differ diff --git a/mods/sounds/sounds/sounds_camel_02.ogg b/mods/sounds/sounds/sounds_camel_02.ogg new file mode 100644 index 0000000..58232aa Binary files /dev/null and b/mods/sounds/sounds/sounds_camel_02.ogg differ diff --git a/mods/sounds/sounds/sounds_canary_01.ogg b/mods/sounds/sounds/sounds_canary_01.ogg new file mode 100644 index 0000000..d269421 Binary files /dev/null and b/mods/sounds/sounds/sounds_canary_01.ogg differ diff --git a/mods/sounds/sounds/sounds_canary_02.ogg b/mods/sounds/sounds/sounds_canary_02.ogg new file mode 100644 index 0000000..9d311a3 Binary files /dev/null and b/mods/sounds/sounds/sounds_canary_02.ogg differ diff --git a/mods/sounds/sounds/sounds_canary_03.ogg b/mods/sounds/sounds/sounds_canary_03.ogg new file mode 100644 index 0000000..0abd376 Binary files /dev/null and b/mods/sounds/sounds/sounds_canary_03.ogg differ diff --git a/mods/sounds/sounds/sounds_car_motor.ogg b/mods/sounds/sounds/sounds_car_motor.ogg new file mode 100644 index 0000000..8af0ab6 Binary files /dev/null and b/mods/sounds/sounds/sounds_car_motor.ogg differ diff --git a/mods/sounds/sounds/sounds_cat_meow.ogg b/mods/sounds/sounds/sounds_cat_meow.ogg new file mode 100644 index 0000000..29ddae8 Binary files /dev/null and b/mods/sounds/sounds/sounds_cat_meow.ogg differ diff --git a/mods/sounds/sounds/sounds_chalk_screech_01.ogg b/mods/sounds/sounds/sounds_chalk_screech_01.ogg new file mode 100644 index 0000000..fa55efb Binary files /dev/null and b/mods/sounds/sounds/sounds_chalk_screech_01.ogg differ diff --git a/mods/sounds/sounds/sounds_chalk_screech_02.ogg b/mods/sounds/sounds/sounds_chalk_screech_02.ogg new file mode 100644 index 0000000..9dd2d2c Binary files /dev/null and b/mods/sounds/sounds/sounds_chalk_screech_02.ogg differ diff --git a/mods/sounds/sounds/sounds_chalk_screech_03.ogg b/mods/sounds/sounds/sounds_chalk_screech_03.ogg new file mode 100644 index 0000000..3577ef6 Binary files /dev/null and b/mods/sounds/sounds/sounds_chalk_screech_03.ogg differ diff --git a/mods/sounds/sounds/sounds_chalk_write_01.ogg b/mods/sounds/sounds/sounds_chalk_write_01.ogg new file mode 100644 index 0000000..23df0e2 Binary files /dev/null and b/mods/sounds/sounds/sounds_chalk_write_01.ogg differ diff --git a/mods/sounds/sounds/sounds_chalk_write_02.ogg b/mods/sounds/sounds/sounds_chalk_write_02.ogg new file mode 100644 index 0000000..348ccff Binary files /dev/null and b/mods/sounds/sounds/sounds_chalk_write_02.ogg differ diff --git a/mods/sounds/sounds/sounds_chalk_write_03.ogg b/mods/sounds/sounds/sounds_chalk_write_03.ogg new file mode 100644 index 0000000..262b172 Binary files /dev/null and b/mods/sounds/sounds/sounds_chalk_write_03.ogg differ diff --git a/mods/sounds/sounds/sounds_chicken_01.ogg b/mods/sounds/sounds/sounds_chicken_01.ogg new file mode 100644 index 0000000..3a5e274 Binary files /dev/null and b/mods/sounds/sounds/sounds_chicken_01.ogg differ diff --git a/mods/sounds/sounds/sounds_chicken_02.ogg b/mods/sounds/sounds/sounds_chicken_02.ogg new file mode 100644 index 0000000..2d3be8a Binary files /dev/null and b/mods/sounds/sounds/sounds_chicken_02.ogg differ diff --git a/mods/sounds/sounds/sounds_church_bells_01.ogg b/mods/sounds/sounds/sounds_church_bells_01.ogg new file mode 100644 index 0000000..e9e3a47 Binary files /dev/null and b/mods/sounds/sounds/sounds_church_bells_01.ogg differ diff --git a/mods/sounds/sounds/sounds_church_bells_02.ogg b/mods/sounds/sounds/sounds_church_bells_02.ogg new file mode 100644 index 0000000..9f0cb65 Binary files /dev/null and b/mods/sounds/sounds/sounds_church_bells_02.ogg differ diff --git a/mods/sounds/sounds/sounds_cicada_01.ogg b/mods/sounds/sounds/sounds_cicada_01.ogg new file mode 100644 index 0000000..a0956f3 Binary files /dev/null and b/mods/sounds/sounds/sounds_cicada_01.ogg differ diff --git a/mods/sounds/sounds/sounds_cicada_02.ogg b/mods/sounds/sounds/sounds_cicada_02.ogg new file mode 100644 index 0000000..edb4fbc Binary files /dev/null and b/mods/sounds/sounds/sounds_cicada_02.ogg differ diff --git a/mods/sounds/sounds/sounds_cicada_03.ogg b/mods/sounds/sounds/sounds_cicada_03.ogg new file mode 100644 index 0000000..3908c01 Binary files /dev/null and b/mods/sounds/sounds/sounds_cicada_03.ogg differ diff --git a/mods/sounds/sounds/sounds_cicada_04.ogg b/mods/sounds/sounds/sounds_cicada_04.ogg new file mode 100644 index 0000000..15f16c5 Binary files /dev/null and b/mods/sounds/sounds/sounds_cicada_04.ogg differ diff --git a/mods/sounds/sounds/sounds_cicada_05.ogg b/mods/sounds/sounds/sounds_cicada_05.ogg new file mode 100644 index 0000000..56e32a3 Binary files /dev/null and b/mods/sounds/sounds/sounds_cicada_05.ogg differ diff --git a/mods/sounds/sounds/sounds_cicada_06.ogg b/mods/sounds/sounds/sounds_cicada_06.ogg new file mode 100644 index 0000000..1d7c76c Binary files /dev/null and b/mods/sounds/sounds/sounds_cicada_06.ogg differ diff --git a/mods/sounds/sounds/sounds_cicada_07.ogg b/mods/sounds/sounds/sounds_cicada_07.ogg new file mode 100644 index 0000000..8a214b9 Binary files /dev/null and b/mods/sounds/sounds/sounds_cicada_07.ogg differ diff --git a/mods/sounds/sounds/sounds_cicada_08.ogg b/mods/sounds/sounds/sounds_cicada_08.ogg new file mode 100644 index 0000000..ae39aa8 Binary files /dev/null and b/mods/sounds/sounds/sounds_cicada_08.ogg differ diff --git a/mods/sounds/sounds/sounds_clock_tick.ogg b/mods/sounds/sounds/sounds_clock_tick.ogg new file mode 100644 index 0000000..8fda52e Binary files /dev/null and b/mods/sounds/sounds/sounds_clock_tick.ogg differ diff --git a/mods/sounds/sounds/sounds_cobra_01.ogg b/mods/sounds/sounds/sounds_cobra_01.ogg new file mode 100644 index 0000000..39bf215 Binary files /dev/null and b/mods/sounds/sounds/sounds_cobra_01.ogg differ diff --git a/mods/sounds/sounds/sounds_cobra_02.ogg b/mods/sounds/sounds/sounds_cobra_02.ogg new file mode 100644 index 0000000..7168e94 Binary files /dev/null and b/mods/sounds/sounds/sounds_cobra_02.ogg differ diff --git a/mods/sounds/sounds/sounds_coin.ogg b/mods/sounds/sounds/sounds_coin.ogg new file mode 100644 index 0000000..6ff8b99 Binary files /dev/null and b/mods/sounds/sounds/sounds_coin.ogg differ diff --git a/mods/sounds/sounds/sounds_compressor_motor_01.ogg b/mods/sounds/sounds/sounds_compressor_motor_01.ogg new file mode 100644 index 0000000..8f5a1e7 Binary files /dev/null and b/mods/sounds/sounds/sounds_compressor_motor_01.ogg differ diff --git a/mods/sounds/sounds/sounds_compressor_motor_02.ogg b/mods/sounds/sounds/sounds_compressor_motor_02.ogg new file mode 100644 index 0000000..e08b75b Binary files /dev/null and b/mods/sounds/sounds/sounds_compressor_motor_02.ogg differ diff --git a/mods/sounds/sounds/sounds_cow_moo_01.ogg b/mods/sounds/sounds/sounds_cow_moo_01.ogg new file mode 100644 index 0000000..66d960a Binary files /dev/null and b/mods/sounds/sounds/sounds_cow_moo_01.ogg differ diff --git a/mods/sounds/sounds/sounds_cow_moo_02.ogg b/mods/sounds/sounds/sounds_cow_moo_02.ogg new file mode 100644 index 0000000..ac97c45 Binary files /dev/null and b/mods/sounds/sounds/sounds_cow_moo_02.ogg differ diff --git a/mods/sounds/sounds/sounds_coyote_howl.ogg b/mods/sounds/sounds/sounds_coyote_howl.ogg new file mode 100644 index 0000000..1dd537f Binary files /dev/null and b/mods/sounds/sounds/sounds_coyote_howl.ogg differ diff --git a/mods/sounds/sounds/sounds_cricket.ogg b/mods/sounds/sounds/sounds_cricket.ogg new file mode 100644 index 0000000..c49a75f Binary files /dev/null and b/mods/sounds/sounds/sounds_cricket.ogg differ diff --git a/mods/sounds/sounds/sounds_crow_caw.ogg b/mods/sounds/sounds/sounds_crow_caw.ogg new file mode 100644 index 0000000..004443f Binary files /dev/null and b/mods/sounds/sounds/sounds_crow_caw.ogg differ diff --git a/mods/sounds/sounds/sounds_dog_bark.ogg b/mods/sounds/sounds/sounds_dog_bark.ogg new file mode 100644 index 0000000..2289246 Binary files /dev/null and b/mods/sounds/sounds/sounds_dog_bark.ogg differ diff --git a/mods/sounds/sounds/sounds_dolphin_chirp.ogg b/mods/sounds/sounds/sounds_dolphin_chirp.ogg new file mode 100644 index 0000000..200fb89 Binary files /dev/null and b/mods/sounds/sounds/sounds_dolphin_chirp.ogg differ diff --git a/mods/sounds/sounds/sounds_dolphin_click.ogg b/mods/sounds/sounds/sounds_dolphin_click.ogg new file mode 100644 index 0000000..dbe98b0 Binary files /dev/null and b/mods/sounds/sounds/sounds_dolphin_click.ogg differ diff --git a/mods/sounds/sounds/sounds_door_close_01.ogg b/mods/sounds/sounds/sounds_door_close_01.ogg new file mode 100644 index 0000000..2387592 Binary files /dev/null and b/mods/sounds/sounds/sounds_door_close_01.ogg differ diff --git a/mods/sounds/sounds/sounds_door_close_02.ogg b/mods/sounds/sounds/sounds_door_close_02.ogg new file mode 100644 index 0000000..5810f13 Binary files /dev/null and b/mods/sounds/sounds/sounds_door_close_02.ogg differ diff --git a/mods/sounds/sounds/sounds_door_close_03.ogg b/mods/sounds/sounds/sounds_door_close_03.ogg new file mode 100644 index 0000000..e0f2578 Binary files /dev/null and b/mods/sounds/sounds/sounds_door_close_03.ogg differ diff --git a/mods/sounds/sounds/sounds_door_creak.ogg b/mods/sounds/sounds/sounds_door_creak.ogg new file mode 100644 index 0000000..31926ea Binary files /dev/null and b/mods/sounds/sounds/sounds_door_creak.ogg differ diff --git a/mods/sounds/sounds/sounds_door_knock_01.ogg b/mods/sounds/sounds/sounds_door_knock_01.ogg new file mode 100644 index 0000000..b1c7d55 Binary files /dev/null and b/mods/sounds/sounds/sounds_door_knock_01.ogg differ diff --git a/mods/sounds/sounds/sounds_door_knock_02.ogg b/mods/sounds/sounds/sounds_door_knock_02.ogg new file mode 100644 index 0000000..4113996 Binary files /dev/null and b/mods/sounds/sounds/sounds_door_knock_02.ogg differ diff --git a/mods/sounds/sounds/sounds_door_open.ogg b/mods/sounds/sounds/sounds_door_open.ogg new file mode 100644 index 0000000..1d855a5 Binary files /dev/null and b/mods/sounds/sounds/sounds_door_open.ogg differ diff --git a/mods/sounds/sounds/sounds_doorbell_01.ogg b/mods/sounds/sounds/sounds_doorbell_01.ogg new file mode 100644 index 0000000..bb005ab Binary files /dev/null and b/mods/sounds/sounds/sounds_doorbell_01.ogg differ diff --git a/mods/sounds/sounds/sounds_doorbell_02.ogg b/mods/sounds/sounds/sounds_doorbell_02.ogg new file mode 100644 index 0000000..93c9048 Binary files /dev/null and b/mods/sounds/sounds/sounds_doorbell_02.ogg differ diff --git a/mods/sounds/sounds/sounds_doorbell_03.ogg b/mods/sounds/sounds/sounds_doorbell_03.ogg new file mode 100644 index 0000000..fd9dd57 Binary files /dev/null and b/mods/sounds/sounds/sounds_doorbell_03.ogg differ diff --git a/mods/sounds/sounds/sounds_duck_quack_01.ogg b/mods/sounds/sounds/sounds_duck_quack_01.ogg new file mode 100644 index 0000000..6bb058c Binary files /dev/null and b/mods/sounds/sounds/sounds_duck_quack_01.ogg differ diff --git a/mods/sounds/sounds/sounds_duck_quack_02.ogg b/mods/sounds/sounds/sounds_duck_quack_02.ogg new file mode 100644 index 0000000..2606683 Binary files /dev/null and b/mods/sounds/sounds/sounds_duck_quack_02.ogg differ diff --git a/mods/sounds/sounds/sounds_duck_quack_03.ogg b/mods/sounds/sounds/sounds_duck_quack_03.ogg new file mode 100644 index 0000000..0075cf8 Binary files /dev/null and b/mods/sounds/sounds/sounds_duck_quack_03.ogg differ diff --git a/mods/sounds/sounds/sounds_elephant_trumpet.ogg b/mods/sounds/sounds/sounds_elephant_trumpet.ogg new file mode 100644 index 0000000..afb7672 Binary files /dev/null and b/mods/sounds/sounds/sounds_elephant_trumpet.ogg differ diff --git a/mods/sounds/sounds/sounds_entity_hit.ogg b/mods/sounds/sounds/sounds_entity_hit.ogg new file mode 100644 index 0000000..7888087 Binary files /dev/null and b/mods/sounds/sounds/sounds_entity_hit.ogg differ diff --git a/mods/sounds/sounds/sounds_explosion_01.ogg b/mods/sounds/sounds/sounds_explosion_01.ogg new file mode 100644 index 0000000..c219fb6 Binary files /dev/null and b/mods/sounds/sounds/sounds_explosion_01.ogg differ diff --git a/mods/sounds/sounds/sounds_explosion_02.ogg b/mods/sounds/sounds/sounds_explosion_02.ogg new file mode 100644 index 0000000..75f0c10 Binary files /dev/null and b/mods/sounds/sounds/sounds_explosion_02.ogg differ diff --git a/mods/sounds/sounds/sounds_explosion_03.ogg b/mods/sounds/sounds/sounds_explosion_03.ogg new file mode 100644 index 0000000..83198d4 Binary files /dev/null and b/mods/sounds/sounds/sounds_explosion_03.ogg differ diff --git a/mods/sounds/sounds/sounds_explosion_distant_01.ogg b/mods/sounds/sounds/sounds_explosion_distant_01.ogg new file mode 100644 index 0000000..332ed47 Binary files /dev/null and b/mods/sounds/sounds/sounds_explosion_distant_01.ogg differ diff --git a/mods/sounds/sounds/sounds_explosion_distant_02.ogg b/mods/sounds/sounds/sounds_explosion_distant_02.ogg new file mode 100644 index 0000000..8ba9eee Binary files /dev/null and b/mods/sounds/sounds/sounds_explosion_distant_02.ogg differ diff --git a/mods/sounds/sounds/sounds_explosion_distant_03.ogg b/mods/sounds/sounds/sounds_explosion_distant_03.ogg new file mode 100644 index 0000000..118b76d Binary files /dev/null and b/mods/sounds/sounds/sounds_explosion_distant_03.ogg differ diff --git a/mods/sounds/sounds/sounds_explosion_distant_04.ogg b/mods/sounds/sounds/sounds_explosion_distant_04.ogg new file mode 100644 index 0000000..9e0fded Binary files /dev/null and b/mods/sounds/sounds/sounds_explosion_distant_04.ogg differ diff --git a/mods/sounds/sounds/sounds_explosion_scifi.ogg b/mods/sounds/sounds/sounds_explosion_scifi.ogg new file mode 100644 index 0000000..d69098a Binary files /dev/null and b/mods/sounds/sounds/sounds_explosion_scifi.ogg differ diff --git a/mods/sounds/sounds/sounds_fire_crackle.ogg b/mods/sounds/sounds/sounds_fire_crackle.ogg new file mode 100644 index 0000000..a14a69b Binary files /dev/null and b/mods/sounds/sounds/sounds_fire_crackle.ogg differ diff --git a/mods/sounds/sounds/sounds_fireball_01.ogg b/mods/sounds/sounds/sounds_fireball_01.ogg new file mode 100644 index 0000000..a98f6a6 Binary files /dev/null and b/mods/sounds/sounds/sounds_fireball_01.ogg differ diff --git a/mods/sounds/sounds/sounds_fireball_02.ogg b/mods/sounds/sounds/sounds_fireball_02.ogg new file mode 100644 index 0000000..3aa9985 Binary files /dev/null and b/mods/sounds/sounds/sounds_fireball_02.ogg differ diff --git a/mods/sounds/sounds/sounds_fireball_03.ogg b/mods/sounds/sounds/sounds_fireball_03.ogg new file mode 100644 index 0000000..6488f44 Binary files /dev/null and b/mods/sounds/sounds/sounds_fireball_03.ogg differ diff --git a/mods/sounds/sounds/sounds_fireworks_01.ogg b/mods/sounds/sounds/sounds_fireworks_01.ogg new file mode 100644 index 0000000..0ee7eb0 Binary files /dev/null and b/mods/sounds/sounds/sounds_fireworks_01.ogg differ diff --git a/mods/sounds/sounds/sounds_fireworks_02.ogg b/mods/sounds/sounds/sounds_fireworks_02.ogg new file mode 100644 index 0000000..cf19660 Binary files /dev/null and b/mods/sounds/sounds/sounds_fireworks_02.ogg differ diff --git a/mods/sounds/sounds/sounds_fireworks_pop_01.ogg b/mods/sounds/sounds/sounds_fireworks_pop_01.ogg new file mode 100644 index 0000000..336b21b Binary files /dev/null and b/mods/sounds/sounds/sounds_fireworks_pop_01.ogg differ diff --git a/mods/sounds/sounds/sounds_fireworks_pop_02.ogg b/mods/sounds/sounds/sounds_fireworks_pop_02.ogg new file mode 100644 index 0000000..b14ceb5 Binary files /dev/null and b/mods/sounds/sounds/sounds_fireworks_pop_02.ogg differ diff --git a/mods/sounds/sounds/sounds_fireworks_pop_03.ogg b/mods/sounds/sounds/sounds_fireworks_pop_03.ogg new file mode 100644 index 0000000..65a246e Binary files /dev/null and b/mods/sounds/sounds/sounds_fireworks_pop_03.ogg differ diff --git a/mods/sounds/sounds/sounds_frog.ogg b/mods/sounds/sounds/sounds_frog.ogg new file mode 100644 index 0000000..27f7b0d Binary files /dev/null and b/mods/sounds/sounds/sounds_frog.ogg differ diff --git a/mods/sounds/sounds/sounds_fuse.ogg b/mods/sounds/sounds/sounds_fuse.ogg new file mode 100644 index 0000000..2ce2d92 Binary files /dev/null and b/mods/sounds/sounds/sounds_fuse.ogg differ diff --git a/mods/sounds/sounds/sounds_fuse_short.ogg b/mods/sounds/sounds/sounds_fuse_short.ogg new file mode 100644 index 0000000..1736d80 Binary files /dev/null and b/mods/sounds/sounds/sounds_fuse_short.ogg differ diff --git a/mods/sounds/sounds/sounds_gallop_01.ogg b/mods/sounds/sounds/sounds_gallop_01.ogg new file mode 100644 index 0000000..22a01e1 Binary files /dev/null and b/mods/sounds/sounds/sounds_gallop_01.ogg differ diff --git a/mods/sounds/sounds/sounds_gallop_02.ogg b/mods/sounds/sounds/sounds_gallop_02.ogg new file mode 100644 index 0000000..a48b930 Binary files /dev/null and b/mods/sounds/sounds/sounds_gallop_02.ogg differ diff --git a/mods/sounds/sounds/sounds_ghost_01.ogg b/mods/sounds/sounds/sounds_ghost_01.ogg new file mode 100644 index 0000000..18a0734 Binary files /dev/null and b/mods/sounds/sounds/sounds_ghost_01.ogg differ diff --git a/mods/sounds/sounds/sounds_ghost_02.ogg b/mods/sounds/sounds/sounds_ghost_02.ogg new file mode 100644 index 0000000..21a0be0 Binary files /dev/null and b/mods/sounds/sounds/sounds_ghost_02.ogg differ diff --git a/mods/sounds/sounds/sounds_ghost_damage.ogg b/mods/sounds/sounds/sounds_ghost_damage.ogg new file mode 100644 index 0000000..078bf04 Binary files /dev/null and b/mods/sounds/sounds/sounds_ghost_damage.ogg differ diff --git a/mods/sounds/sounds/sounds_ghost_death.ogg b/mods/sounds/sounds/sounds_ghost_death.ogg new file mode 100644 index 0000000..aa2d0c7 Binary files /dev/null and b/mods/sounds/sounds/sounds_ghost_death.ogg differ diff --git a/mods/sounds/sounds/sounds_giraffe_hum.ogg b/mods/sounds/sounds/sounds_giraffe_hum.ogg new file mode 100644 index 0000000..e7b319c Binary files /dev/null and b/mods/sounds/sounds/sounds_giraffe_hum.ogg differ diff --git a/mods/sounds/sounds/sounds_goat_bleat_01.ogg b/mods/sounds/sounds/sounds_goat_bleat_01.ogg new file mode 100644 index 0000000..56c5a57 Binary files /dev/null and b/mods/sounds/sounds/sounds_goat_bleat_01.ogg differ diff --git a/mods/sounds/sounds/sounds_goat_bleat_02.ogg b/mods/sounds/sounds/sounds_goat_bleat_02.ogg new file mode 100644 index 0000000..f4548c6 Binary files /dev/null and b/mods/sounds/sounds/sounds_goat_bleat_02.ogg differ diff --git a/mods/sounds/sounds/sounds_goat_bleat_03.ogg b/mods/sounds/sounds/sounds_goat_bleat_03.ogg new file mode 100644 index 0000000..3fc80bd Binary files /dev/null and b/mods/sounds/sounds/sounds_goat_bleat_03.ogg differ diff --git a/mods/sounds/sounds/sounds_goose.ogg b/mods/sounds/sounds/sounds_goose.ogg new file mode 100644 index 0000000..803855e Binary files /dev/null and b/mods/sounds/sounds/sounds_goose.ogg differ diff --git a/mods/sounds/sounds/sounds_gorilla_grunt.ogg b/mods/sounds/sounds/sounds_gorilla_grunt.ogg new file mode 100644 index 0000000..3226e92 Binary files /dev/null and b/mods/sounds/sounds/sounds_gorilla_grunt.ogg differ diff --git a/mods/sounds/sounds/sounds_gorilla_roar.ogg b/mods/sounds/sounds/sounds_gorilla_roar.ogg new file mode 100644 index 0000000..9d82580 Binary files /dev/null and b/mods/sounds/sounds/sounds_gorilla_roar.ogg differ diff --git a/mods/sounds/sounds/sounds_gorilla_snarl_01.ogg b/mods/sounds/sounds/sounds_gorilla_snarl_01.ogg new file mode 100644 index 0000000..b41806b Binary files /dev/null and b/mods/sounds/sounds/sounds_gorilla_snarl_01.ogg differ diff --git a/mods/sounds/sounds/sounds_gorilla_snarl_02.ogg b/mods/sounds/sounds/sounds_gorilla_snarl_02.ogg new file mode 100644 index 0000000..d4f53c4 Binary files /dev/null and b/mods/sounds/sounds/sounds_gorilla_snarl_02.ogg differ diff --git a/mods/sounds/sounds/sounds_gorilla_snarl_03.ogg b/mods/sounds/sounds/sounds_gorilla_snarl_03.ogg new file mode 100644 index 0000000..c56f049 Binary files /dev/null and b/mods/sounds/sounds/sounds_gorilla_snarl_03.ogg differ diff --git a/mods/sounds/sounds/sounds_gorilla_snarl_04.ogg b/mods/sounds/sounds/sounds_gorilla_snarl_04.ogg new file mode 100644 index 0000000..2ecbee2 Binary files /dev/null and b/mods/sounds/sounds/sounds_gorilla_snarl_04.ogg differ diff --git a/mods/sounds/sounds/sounds_grasshopper.ogg b/mods/sounds/sounds/sounds_grasshopper.ogg new file mode 100644 index 0000000..8761fbb Binary files /dev/null and b/mods/sounds/sounds/sounds_grasshopper.ogg differ diff --git a/mods/sounds/sounds/sounds_helicopter.ogg b/mods/sounds/sounds/sounds_helicopter.ogg new file mode 100644 index 0000000..f93edaf Binary files /dev/null and b/mods/sounds/sounds/sounds_helicopter.ogg differ diff --git a/mods/sounds/sounds/sounds_horse_neigh_01.ogg b/mods/sounds/sounds/sounds_horse_neigh_01.ogg new file mode 100644 index 0000000..3b2b791 Binary files /dev/null and b/mods/sounds/sounds/sounds_horse_neigh_01.ogg differ diff --git a/mods/sounds/sounds/sounds_horse_neigh_02.ogg b/mods/sounds/sounds/sounds_horse_neigh_02.ogg new file mode 100644 index 0000000..fe2c3a2 Binary files /dev/null and b/mods/sounds/sounds/sounds_horse_neigh_02.ogg differ diff --git a/mods/sounds/sounds/sounds_horse_snort_01.ogg b/mods/sounds/sounds/sounds_horse_snort_01.ogg new file mode 100644 index 0000000..c876874 Binary files /dev/null and b/mods/sounds/sounds/sounds_horse_snort_01.ogg differ diff --git a/mods/sounds/sounds/sounds_horse_snort_02.ogg b/mods/sounds/sounds/sounds_horse_snort_02.ogg new file mode 100644 index 0000000..763cb73 Binary files /dev/null and b/mods/sounds/sounds/sounds_horse_snort_02.ogg differ diff --git a/mods/sounds/sounds/sounds_hyena_01.ogg b/mods/sounds/sounds/sounds_hyena_01.ogg new file mode 100644 index 0000000..cab1ae0 Binary files /dev/null and b/mods/sounds/sounds/sounds_hyena_01.ogg differ diff --git a/mods/sounds/sounds/sounds_hyena_02.ogg b/mods/sounds/sounds/sounds_hyena_02.ogg new file mode 100644 index 0000000..209ef8d Binary files /dev/null and b/mods/sounds/sounds/sounds_hyena_02.ogg differ diff --git a/mods/sounds/sounds/sounds_hyena_03.ogg b/mods/sounds/sounds/sounds_hyena_03.ogg new file mode 100644 index 0000000..f934607 Binary files /dev/null and b/mods/sounds/sounds/sounds_hyena_03.ogg differ diff --git a/mods/sounds/sounds/sounds_jaguar_saw.ogg b/mods/sounds/sounds/sounds_jaguar_saw.ogg new file mode 100644 index 0000000..03732b4 Binary files /dev/null and b/mods/sounds/sounds/sounds_jaguar_saw.ogg differ diff --git a/mods/sounds/sounds/sounds_jet_ambience.ogg b/mods/sounds/sounds/sounds_jet_ambience.ogg new file mode 100644 index 0000000..73166eb Binary files /dev/null and b/mods/sounds/sounds/sounds_jet_ambience.ogg differ diff --git a/mods/sounds/sounds/sounds_jet_flyby.ogg b/mods/sounds/sounds/sounds_jet_flyby.ogg new file mode 100644 index 0000000..e28dc59 Binary files /dev/null and b/mods/sounds/sounds/sounds_jet_flyby.ogg differ diff --git a/mods/sounds/sounds/sounds_jet_land.ogg b/mods/sounds/sounds/sounds_jet_land.ogg new file mode 100644 index 0000000..582980d Binary files /dev/null and b/mods/sounds/sounds/sounds_jet_land.ogg differ diff --git a/mods/sounds/sounds/sounds_lamb.ogg b/mods/sounds/sounds/sounds_lamb.ogg new file mode 100644 index 0000000..7ac1480 Binary files /dev/null and b/mods/sounds/sounds/sounds_lamb.ogg differ diff --git a/mods/sounds/sounds/sounds_laser_01.ogg b/mods/sounds/sounds/sounds_laser_01.ogg new file mode 100644 index 0000000..f48c226 Binary files /dev/null and b/mods/sounds/sounds/sounds_laser_01.ogg differ diff --git a/mods/sounds/sounds/sounds_laser_02.ogg b/mods/sounds/sounds/sounds_laser_02.ogg new file mode 100644 index 0000000..45596af Binary files /dev/null and b/mods/sounds/sounds/sounds_laser_02.ogg differ diff --git a/mods/sounds/sounds/sounds_laser_03.ogg b/mods/sounds/sounds/sounds_laser_03.ogg new file mode 100644 index 0000000..c8237b3 Binary files /dev/null and b/mods/sounds/sounds/sounds_laser_03.ogg differ diff --git a/mods/sounds/sounds/sounds_laser_04.ogg b/mods/sounds/sounds/sounds_laser_04.ogg new file mode 100644 index 0000000..54cdfa6 Binary files /dev/null and b/mods/sounds/sounds/sounds_laser_04.ogg differ diff --git a/mods/sounds/sounds/sounds_laser_05.ogg b/mods/sounds/sounds/sounds_laser_05.ogg new file mode 100644 index 0000000..8ab6cdb Binary files /dev/null and b/mods/sounds/sounds/sounds_laser_05.ogg differ diff --git a/mods/sounds/sounds/sounds_laser_06.ogg b/mods/sounds/sounds/sounds_laser_06.ogg new file mode 100644 index 0000000..4072cf0 Binary files /dev/null and b/mods/sounds/sounds/sounds_laser_06.ogg differ diff --git a/mods/sounds/sounds/sounds_laser_07.ogg b/mods/sounds/sounds/sounds_laser_07.ogg new file mode 100644 index 0000000..7cefec9 Binary files /dev/null and b/mods/sounds/sounds/sounds_laser_07.ogg differ diff --git a/mods/sounds/sounds/sounds_laugh_evil_01.ogg b/mods/sounds/sounds/sounds_laugh_evil_01.ogg new file mode 100644 index 0000000..ace21ab Binary files /dev/null and b/mods/sounds/sounds/sounds_laugh_evil_01.ogg differ diff --git a/mods/sounds/sounds/sounds_laugh_evil_02.ogg b/mods/sounds/sounds/sounds_laugh_evil_02.ogg new file mode 100644 index 0000000..51f7e45 Binary files /dev/null and b/mods/sounds/sounds/sounds_laugh_evil_02.ogg differ diff --git a/mods/sounds/sounds/sounds_lava_cool.1.ogg b/mods/sounds/sounds/sounds_lava_cool.1.ogg new file mode 100644 index 0000000..85cdcb3 Binary files /dev/null and b/mods/sounds/sounds/sounds_lava_cool.1.ogg differ diff --git a/mods/sounds/sounds/sounds_lava_cool.2.ogg b/mods/sounds/sounds/sounds_lava_cool.2.ogg new file mode 100644 index 0000000..7af8e09 Binary files /dev/null and b/mods/sounds/sounds/sounds_lava_cool.2.ogg differ diff --git a/mods/sounds/sounds/sounds_lava_cool.3.ogg b/mods/sounds/sounds/sounds_lava_cool.3.ogg new file mode 100644 index 0000000..455625a Binary files /dev/null and b/mods/sounds/sounds/sounds_lava_cool.3.ogg differ diff --git a/mods/sounds/sounds/sounds_leaves_01.ogg b/mods/sounds/sounds/sounds_leaves_01.ogg new file mode 100644 index 0000000..8d1e354 Binary files /dev/null and b/mods/sounds/sounds/sounds_leaves_01.ogg differ diff --git a/mods/sounds/sounds/sounds_leaves_02.ogg b/mods/sounds/sounds/sounds_leaves_02.ogg new file mode 100644 index 0000000..1f413f7 Binary files /dev/null and b/mods/sounds/sounds/sounds_leaves_02.ogg differ diff --git a/mods/sounds/sounds/sounds_leopard_growl_01.ogg b/mods/sounds/sounds/sounds_leopard_growl_01.ogg new file mode 100644 index 0000000..6a78618 Binary files /dev/null and b/mods/sounds/sounds/sounds_leopard_growl_01.ogg differ diff --git a/mods/sounds/sounds/sounds_leopard_growl_02.ogg b/mods/sounds/sounds/sounds_leopard_growl_02.ogg new file mode 100644 index 0000000..f66bce5 Binary files /dev/null and b/mods/sounds/sounds/sounds_leopard_growl_02.ogg differ diff --git a/mods/sounds/sounds/sounds_leopard_growl_03.ogg b/mods/sounds/sounds/sounds_leopard_growl_03.ogg new file mode 100644 index 0000000..2f6d86d Binary files /dev/null and b/mods/sounds/sounds/sounds_leopard_growl_03.ogg differ diff --git a/mods/sounds/sounds/sounds_leopard_roar_01.ogg b/mods/sounds/sounds/sounds_leopard_roar_01.ogg new file mode 100644 index 0000000..c32abda Binary files /dev/null and b/mods/sounds/sounds/sounds_leopard_roar_01.ogg differ diff --git a/mods/sounds/sounds/sounds_leopard_roar_02.ogg b/mods/sounds/sounds/sounds_leopard_roar_02.ogg new file mode 100644 index 0000000..37bd1ed Binary files /dev/null and b/mods/sounds/sounds/sounds_leopard_roar_02.ogg differ diff --git a/mods/sounds/sounds/sounds_leopard_roar_03.ogg b/mods/sounds/sounds/sounds_leopard_roar_03.ogg new file mode 100644 index 0000000..2c24e5f Binary files /dev/null and b/mods/sounds/sounds/sounds_leopard_roar_03.ogg differ diff --git a/mods/sounds/sounds/sounds_leopard_roar_04.ogg b/mods/sounds/sounds/sounds_leopard_roar_04.ogg new file mode 100644 index 0000000..852d3d6 Binary files /dev/null and b/mods/sounds/sounds/sounds_leopard_roar_04.ogg differ diff --git a/mods/sounds/sounds/sounds_leopard_roar_05.ogg b/mods/sounds/sounds/sounds_leopard_roar_05.ogg new file mode 100644 index 0000000..7c02635 Binary files /dev/null and b/mods/sounds/sounds/sounds_leopard_roar_05.ogg differ diff --git a/mods/sounds/sounds/sounds_leopard_saw_01.ogg b/mods/sounds/sounds/sounds_leopard_saw_01.ogg new file mode 100644 index 0000000..64e4e42 Binary files /dev/null and b/mods/sounds/sounds/sounds_leopard_saw_01.ogg differ diff --git a/mods/sounds/sounds/sounds_leopard_saw_02.ogg b/mods/sounds/sounds/sounds_leopard_saw_02.ogg new file mode 100644 index 0000000..9327802 Binary files /dev/null and b/mods/sounds/sounds/sounds_leopard_saw_02.ogg differ diff --git a/mods/sounds/sounds/sounds_leopard_saw_03.ogg b/mods/sounds/sounds/sounds_leopard_saw_03.ogg new file mode 100644 index 0000000..865a696 Binary files /dev/null and b/mods/sounds/sounds/sounds_leopard_saw_03.ogg differ diff --git a/mods/sounds/sounds/sounds_leopard_snarl_01.ogg b/mods/sounds/sounds/sounds_leopard_snarl_01.ogg new file mode 100644 index 0000000..88e1c53 Binary files /dev/null and b/mods/sounds/sounds/sounds_leopard_snarl_01.ogg differ diff --git a/mods/sounds/sounds/sounds_leopard_snarl_02.ogg b/mods/sounds/sounds/sounds_leopard_snarl_02.ogg new file mode 100644 index 0000000..65bb4cc Binary files /dev/null and b/mods/sounds/sounds/sounds_leopard_snarl_02.ogg differ diff --git a/mods/sounds/sounds/sounds_leopard_snort.ogg b/mods/sounds/sounds/sounds_leopard_snort.ogg new file mode 100644 index 0000000..d092615 Binary files /dev/null and b/mods/sounds/sounds/sounds_leopard_snort.ogg differ diff --git a/mods/sounds/sounds/sounds_lion_bellow.ogg b/mods/sounds/sounds/sounds_lion_bellow.ogg new file mode 100644 index 0000000..eb9ee0a Binary files /dev/null and b/mods/sounds/sounds/sounds_lion_bellow.ogg differ diff --git a/mods/sounds/sounds/sounds_loon_01.ogg b/mods/sounds/sounds/sounds_loon_01.ogg new file mode 100644 index 0000000..280cb62 Binary files /dev/null and b/mods/sounds/sounds/sounds_loon_01.ogg differ diff --git a/mods/sounds/sounds/sounds_loon_02.ogg b/mods/sounds/sounds/sounds_loon_02.ogg new file mode 100644 index 0000000..1872ba9 Binary files /dev/null and b/mods/sounds/sounds/sounds_loon_02.ogg differ diff --git a/mods/sounds/sounds/sounds_loon_03.ogg b/mods/sounds/sounds/sounds_loon_03.ogg new file mode 100644 index 0000000..368e994 Binary files /dev/null and b/mods/sounds/sounds/sounds_loon_03.ogg differ diff --git a/mods/sounds/sounds/sounds_match_ignite.ogg b/mods/sounds/sounds/sounds_match_ignite.ogg new file mode 100644 index 0000000..188216a Binary files /dev/null and b/mods/sounds/sounds/sounds_match_ignite.ogg differ diff --git a/mods/sounds/sounds/sounds_melee_hit_01.ogg b/mods/sounds/sounds/sounds_melee_hit_01.ogg new file mode 100644 index 0000000..76ff230 Binary files /dev/null and b/mods/sounds/sounds/sounds_melee_hit_01.ogg differ diff --git a/mods/sounds/sounds/sounds_melee_hit_02.ogg b/mods/sounds/sounds/sounds_melee_hit_02.ogg new file mode 100644 index 0000000..11659d1 Binary files /dev/null and b/mods/sounds/sounds/sounds_melee_hit_02.ogg differ diff --git a/mods/sounds/sounds/sounds_melee_hit_03.ogg b/mods/sounds/sounds/sounds_melee_hit_03.ogg new file mode 100644 index 0000000..932b74c Binary files /dev/null and b/mods/sounds/sounds/sounds_melee_hit_03.ogg differ diff --git a/mods/sounds/sounds/sounds_melee_hit_04.ogg b/mods/sounds/sounds/sounds_melee_hit_04.ogg new file mode 100644 index 0000000..83a6ca7 Binary files /dev/null and b/mods/sounds/sounds/sounds_melee_hit_04.ogg differ diff --git a/mods/sounds/sounds/sounds_melee_hit_05.ogg b/mods/sounds/sounds/sounds_melee_hit_05.ogg new file mode 100644 index 0000000..9dc0494 Binary files /dev/null and b/mods/sounds/sounds/sounds_melee_hit_05.ogg differ diff --git a/mods/sounds/sounds/sounds_melee_hit_06.ogg b/mods/sounds/sounds/sounds_melee_hit_06.ogg new file mode 100644 index 0000000..df0ad97 Binary files /dev/null and b/mods/sounds/sounds/sounds_melee_hit_06.ogg differ diff --git a/mods/sounds/sounds/sounds_mermaid_song_01.ogg b/mods/sounds/sounds/sounds_mermaid_song_01.ogg new file mode 100644 index 0000000..0aea12e Binary files /dev/null and b/mods/sounds/sounds/sounds_mermaid_song_01.ogg differ diff --git a/mods/sounds/sounds/sounds_mermaid_song_02.ogg b/mods/sounds/sounds/sounds_mermaid_song_02.ogg new file mode 100644 index 0000000..be27ee4 Binary files /dev/null and b/mods/sounds/sounds/sounds_mermaid_song_02.ogg differ diff --git a/mods/sounds/sounds/sounds_mermaid_song_03.ogg b/mods/sounds/sounds/sounds_mermaid_song_03.ogg new file mode 100644 index 0000000..50b4d73 Binary files /dev/null and b/mods/sounds/sounds/sounds_mermaid_song_03.ogg differ diff --git a/mods/sounds/sounds/sounds_mermaid_song_04.ogg b/mods/sounds/sounds/sounds_mermaid_song_04.ogg new file mode 100644 index 0000000..45a22f7 Binary files /dev/null and b/mods/sounds/sounds/sounds_mermaid_song_04.ogg differ diff --git a/mods/sounds/sounds/sounds_mermaid_song_05.ogg b/mods/sounds/sounds/sounds_mermaid_song_05.ogg new file mode 100644 index 0000000..b6c0683 Binary files /dev/null and b/mods/sounds/sounds/sounds_mermaid_song_05.ogg differ diff --git a/mods/sounds/sounds/sounds_monkey_01.ogg b/mods/sounds/sounds/sounds_monkey_01.ogg new file mode 100644 index 0000000..3b202f4 Binary files /dev/null and b/mods/sounds/sounds/sounds_monkey_01.ogg differ diff --git a/mods/sounds/sounds/sounds_monkey_02.ogg b/mods/sounds/sounds/sounds_monkey_02.ogg new file mode 100644 index 0000000..c3017cb Binary files /dev/null and b/mods/sounds/sounds/sounds_monkey_02.ogg differ diff --git a/mods/sounds/sounds/sounds_monkey_03.ogg b/mods/sounds/sounds/sounds_monkey_03.ogg new file mode 100644 index 0000000..952516f Binary files /dev/null and b/mods/sounds/sounds/sounds_monkey_03.ogg differ diff --git a/mods/sounds/sounds/sounds_motorbike_idle.ogg b/mods/sounds/sounds/sounds_motorbike_idle.ogg new file mode 100644 index 0000000..ad9c1b5 Binary files /dev/null and b/mods/sounds/sounds/sounds_motorbike_idle.ogg differ diff --git a/mods/sounds/sounds/sounds_mouse.ogg b/mods/sounds/sounds/sounds_mouse.ogg new file mode 100644 index 0000000..6dd508c Binary files /dev/null and b/mods/sounds/sounds/sounds_mouse.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dig_choppy.1.ogg b/mods/sounds/sounds/sounds_node_dig_choppy.1.ogg new file mode 100644 index 0000000..95fa6d4 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dig_choppy.1.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dig_choppy.2.ogg b/mods/sounds/sounds/sounds_node_dig_choppy.2.ogg new file mode 100644 index 0000000..5d3a044 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dig_choppy.2.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dig_choppy.3.ogg b/mods/sounds/sounds/sounds_node_dig_choppy.3.ogg new file mode 100644 index 0000000..2bb0ace Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dig_choppy.3.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dig_cracky.1.ogg b/mods/sounds/sounds/sounds_node_dig_cracky.1.ogg new file mode 100644 index 0000000..ffced27 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dig_cracky.1.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dig_cracky.2.ogg b/mods/sounds/sounds/sounds_node_dig_cracky.2.ogg new file mode 100644 index 0000000..d9e8010 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dig_cracky.2.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dig_cracky.3.ogg b/mods/sounds/sounds/sounds_node_dig_cracky.3.ogg new file mode 100644 index 0000000..7d19d40 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dig_cracky.3.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dig_crumbly.ogg b/mods/sounds/sounds/sounds_node_dig_crumbly.ogg new file mode 100644 index 0000000..a0b2a1f Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dig_crumbly.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dig_gravel.1.ogg b/mods/sounds/sounds/sounds_node_dig_gravel.1.ogg new file mode 100644 index 0000000..baf8fca Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dig_gravel.1.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dig_gravel.2.ogg b/mods/sounds/sounds/sounds_node_dig_gravel.2.ogg new file mode 100644 index 0000000..e0c0c50 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dig_gravel.2.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dig_ice.1.ogg b/mods/sounds/sounds/sounds_node_dig_ice.1.ogg new file mode 100644 index 0000000..97399c8 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dig_ice.1.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dig_ice.2.ogg b/mods/sounds/sounds/sounds_node_dig_ice.2.ogg new file mode 100644 index 0000000..8a5da11 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dig_ice.2.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dig_ice.3.ogg b/mods/sounds/sounds/sounds_node_dig_ice.3.ogg new file mode 100644 index 0000000..765fb9b Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dig_ice.3.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dig_metal.ogg b/mods/sounds/sounds/sounds_node_dig_metal.ogg new file mode 100644 index 0000000..0b58509 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dig_metal.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dig_snappy.ogg b/mods/sounds/sounds/sounds_node_dig_snappy.ogg new file mode 100644 index 0000000..3686fcd Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dig_snappy.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dug.1.ogg b/mods/sounds/sounds/sounds_node_dug.1.ogg new file mode 100644 index 0000000..c04975d Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dug.1.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dug.2.ogg b/mods/sounds/sounds/sounds_node_dug.2.ogg new file mode 100644 index 0000000..9f20926 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dug.2.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dug_glass.1.ogg b/mods/sounds/sounds/sounds_node_dug_glass.1.ogg new file mode 100644 index 0000000..b1ccc5f Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dug_glass.1.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dug_glass.2.ogg b/mods/sounds/sounds/sounds_node_dug_glass.2.ogg new file mode 100644 index 0000000..b6cc9e8 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dug_glass.2.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dug_glass.3.ogg b/mods/sounds/sounds/sounds_node_dug_glass.3.ogg new file mode 100644 index 0000000..ae6a6bf Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dug_glass.3.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dug_gravel.1.ogg b/mods/sounds/sounds/sounds_node_dug_gravel.1.ogg new file mode 100644 index 0000000..1303433 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dug_gravel.1.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dug_gravel.2.ogg b/mods/sounds/sounds/sounds_node_dug_gravel.2.ogg new file mode 100644 index 0000000..ee5ed33 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dug_gravel.2.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dug_gravel.3.ogg b/mods/sounds/sounds/sounds_node_dug_gravel.3.ogg new file mode 100644 index 0000000..add4c54 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dug_gravel.3.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dug_ice.ogg b/mods/sounds/sounds/sounds_node_dug_ice.ogg new file mode 100644 index 0000000..ae37673 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dug_ice.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dug_metal.1.ogg b/mods/sounds/sounds/sounds_node_dug_metal.1.ogg new file mode 100644 index 0000000..5d6cb5b Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dug_metal.1.ogg differ diff --git a/mods/sounds/sounds/sounds_node_dug_metal.2.ogg b/mods/sounds/sounds/sounds_node_dug_metal.2.ogg new file mode 100644 index 0000000..63567fc Binary files /dev/null and b/mods/sounds/sounds/sounds_node_dug_metal.2.ogg differ diff --git a/mods/sounds/sounds/sounds_node_place.1.ogg b/mods/sounds/sounds/sounds_node_place.1.ogg new file mode 100644 index 0000000..9f97fac Binary files /dev/null and b/mods/sounds/sounds/sounds_node_place.1.ogg differ diff --git a/mods/sounds/sounds/sounds_node_place.2.ogg b/mods/sounds/sounds/sounds_node_place.2.ogg new file mode 100644 index 0000000..1d3b3de Binary files /dev/null and b/mods/sounds/sounds/sounds_node_place.2.ogg differ diff --git a/mods/sounds/sounds/sounds_node_place_soft.1.ogg b/mods/sounds/sounds/sounds_node_place_soft.1.ogg new file mode 100644 index 0000000..46b9756 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_place_soft.1.ogg differ diff --git a/mods/sounds/sounds/sounds_node_place_soft.2.ogg b/mods/sounds/sounds/sounds_node_place_soft.2.ogg new file mode 100644 index 0000000..d34c01a Binary files /dev/null and b/mods/sounds/sounds/sounds_node_place_soft.2.ogg differ diff --git a/mods/sounds/sounds/sounds_node_place_soft.3.ogg b/mods/sounds/sounds/sounds_node_place_soft.3.ogg new file mode 100644 index 0000000..fc29365 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_place_soft.3.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_dirt.1.ogg b/mods/sounds/sounds/sounds_node_step_dirt.1.ogg new file mode 100644 index 0000000..201aa3b Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_dirt.1.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_dirt.2.ogg b/mods/sounds/sounds/sounds_node_step_dirt.2.ogg new file mode 100644 index 0000000..2667dbc Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_dirt.2.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_glass.ogg b/mods/sounds/sounds/sounds_node_step_glass.ogg new file mode 100644 index 0000000..191287a Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_glass.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_grass.1.ogg b/mods/sounds/sounds/sounds_node_step_grass.1.ogg new file mode 100644 index 0000000..a04cdb4 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_grass.1.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_grass.2.ogg b/mods/sounds/sounds/sounds_node_step_grass.2.ogg new file mode 100644 index 0000000..d193068 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_grass.2.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_grass.3.ogg b/mods/sounds/sounds/sounds_node_step_grass.3.ogg new file mode 100644 index 0000000..e1897ea Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_grass.3.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_gravel.1.ogg b/mods/sounds/sounds/sounds_node_step_gravel.1.ogg new file mode 100644 index 0000000..8d260ce Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_gravel.1.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_gravel.2.ogg b/mods/sounds/sounds/sounds_node_step_gravel.2.ogg new file mode 100644 index 0000000..2aba2c6 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_gravel.2.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_gravel.3.ogg b/mods/sounds/sounds/sounds_node_step_gravel.3.ogg new file mode 100644 index 0000000..1bcd8a1 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_gravel.3.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_gravel.4.ogg b/mods/sounds/sounds/sounds_node_step_gravel.4.ogg new file mode 100644 index 0000000..696c9ff Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_gravel.4.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_hard.1.ogg b/mods/sounds/sounds/sounds_node_step_hard.1.ogg new file mode 100644 index 0000000..0a08efa Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_hard.1.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_hard.2.ogg b/mods/sounds/sounds/sounds_node_step_hard.2.ogg new file mode 100644 index 0000000..be52a87 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_hard.2.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_hard.3.ogg b/mods/sounds/sounds/sounds_node_step_hard.3.ogg new file mode 100644 index 0000000..a342787 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_hard.3.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_ice.1.ogg b/mods/sounds/sounds/sounds_node_step_ice.1.ogg new file mode 100644 index 0000000..c235f1e Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_ice.1.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_ice.2.ogg b/mods/sounds/sounds/sounds_node_step_ice.2.ogg new file mode 100644 index 0000000..61d2c99 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_ice.2.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_ice.3.ogg b/mods/sounds/sounds/sounds_node_step_ice.3.ogg new file mode 100644 index 0000000..2ecbb43 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_ice.3.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_metal.1.ogg b/mods/sounds/sounds/sounds_node_step_metal.1.ogg new file mode 100644 index 0000000..49fe89b Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_metal.1.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_metal.2.ogg b/mods/sounds/sounds/sounds_node_step_metal.2.ogg new file mode 100644 index 0000000..878711d Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_metal.2.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_metal.3.ogg b/mods/sounds/sounds/sounds_node_step_metal.3.ogg new file mode 100644 index 0000000..2a566a8 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_metal.3.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_sand.1.ogg b/mods/sounds/sounds/sounds_node_step_sand.1.ogg new file mode 100644 index 0000000..b92feab Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_sand.1.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_sand.2.ogg b/mods/sounds/sounds/sounds_node_step_sand.2.ogg new file mode 100644 index 0000000..6bc5da3 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_sand.2.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_sand.3.ogg b/mods/sounds/sounds/sounds_node_step_sand.3.ogg new file mode 100644 index 0000000..880306f Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_sand.3.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_snow.1.ogg b/mods/sounds/sounds/sounds_node_step_snow.1.ogg new file mode 100644 index 0000000..97cc825 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_snow.1.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_snow.2.ogg b/mods/sounds/sounds/sounds_node_step_snow.2.ogg new file mode 100644 index 0000000..97a6baa Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_snow.2.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_snow.3.ogg b/mods/sounds/sounds/sounds_node_step_snow.3.ogg new file mode 100644 index 0000000..bde1f21 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_snow.3.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_snow.4.ogg b/mods/sounds/sounds/sounds_node_step_snow.4.ogg new file mode 100644 index 0000000..8ca6a59 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_snow.4.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_snow.5.ogg b/mods/sounds/sounds/sounds_node_step_snow.5.ogg new file mode 100644 index 0000000..220d60c Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_snow.5.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_water.1.ogg b/mods/sounds/sounds/sounds_node_step_water.1.ogg new file mode 100644 index 0000000..63b9744 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_water.1.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_water.2.ogg b/mods/sounds/sounds/sounds_node_step_water.2.ogg new file mode 100644 index 0000000..8d79c1f Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_water.2.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_water.3.ogg b/mods/sounds/sounds/sounds_node_step_water.3.ogg new file mode 100644 index 0000000..f889150 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_water.3.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_water.4.ogg b/mods/sounds/sounds/sounds_node_step_water.4.ogg new file mode 100644 index 0000000..05780aa Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_water.4.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_wood.1.ogg b/mods/sounds/sounds/sounds_node_step_wood.1.ogg new file mode 100644 index 0000000..34f63a1 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_wood.1.ogg differ diff --git a/mods/sounds/sounds/sounds_node_step_wood.2.ogg b/mods/sounds/sounds/sounds_node_step_wood.2.ogg new file mode 100644 index 0000000..124fc29 Binary files /dev/null and b/mods/sounds/sounds/sounds_node_step_wood.2.ogg differ diff --git a/mods/sounds/sounds/sounds_owl_hoot.ogg b/mods/sounds/sounds/sounds_owl_hoot.ogg new file mode 100644 index 0000000..7000ef4 Binary files /dev/null and b/mods/sounds/sounds/sounds_owl_hoot.ogg differ diff --git a/mods/sounds/sounds/sounds_parrot_01.ogg b/mods/sounds/sounds/sounds_parrot_01.ogg new file mode 100644 index 0000000..a35b85c Binary files /dev/null and b/mods/sounds/sounds/sounds_parrot_01.ogg differ diff --git a/mods/sounds/sounds/sounds_parrot_02.ogg b/mods/sounds/sounds/sounds_parrot_02.ogg new file mode 100644 index 0000000..d77470d Binary files /dev/null and b/mods/sounds/sounds/sounds_parrot_02.ogg differ diff --git a/mods/sounds/sounds/sounds_parrot_03.ogg b/mods/sounds/sounds/sounds_parrot_03.ogg new file mode 100644 index 0000000..c507935 Binary files /dev/null and b/mods/sounds/sounds/sounds_parrot_03.ogg differ diff --git a/mods/sounds/sounds/sounds_parrot_chirp.ogg b/mods/sounds/sounds/sounds_parrot_chirp.ogg new file mode 100644 index 0000000..a557636 Binary files /dev/null and b/mods/sounds/sounds/sounds_parrot_chirp.ogg differ diff --git a/mods/sounds/sounds/sounds_parrot_whistle.ogg b/mods/sounds/sounds/sounds_parrot_whistle.ogg new file mode 100644 index 0000000..7b20ca0 Binary files /dev/null and b/mods/sounds/sounds/sounds_parrot_whistle.ogg differ diff --git a/mods/sounds/sounds/sounds_peacock_01.ogg b/mods/sounds/sounds/sounds_peacock_01.ogg new file mode 100644 index 0000000..b001bed Binary files /dev/null and b/mods/sounds/sounds/sounds_peacock_01.ogg differ diff --git a/mods/sounds/sounds/sounds_peacock_02.ogg b/mods/sounds/sounds/sounds_peacock_02.ogg new file mode 100644 index 0000000..1230cdb Binary files /dev/null and b/mods/sounds/sounds/sounds_peacock_02.ogg differ diff --git a/mods/sounds/sounds/sounds_pencil_erase.ogg b/mods/sounds/sounds/sounds_pencil_erase.ogg new file mode 100644 index 0000000..1fe5245 Binary files /dev/null and b/mods/sounds/sounds/sounds_pencil_erase.ogg differ diff --git a/mods/sounds/sounds/sounds_pencil_write.ogg b/mods/sounds/sounds/sounds_pencil_write.ogg new file mode 100644 index 0000000..3afa8aa Binary files /dev/null and b/mods/sounds/sounds/sounds_pencil_write.ogg differ diff --git a/mods/sounds/sounds/sounds_penguin_01.ogg b/mods/sounds/sounds/sounds_penguin_01.ogg new file mode 100644 index 0000000..5bad620 Binary files /dev/null and b/mods/sounds/sounds/sounds_penguin_01.ogg differ diff --git a/mods/sounds/sounds/sounds_penguin_02.ogg b/mods/sounds/sounds/sounds_penguin_02.ogg new file mode 100644 index 0000000..f06b92d Binary files /dev/null and b/mods/sounds/sounds/sounds_penguin_02.ogg differ diff --git a/mods/sounds/sounds/sounds_piano.ogg b/mods/sounds/sounds/sounds_piano.ogg new file mode 100644 index 0000000..92668f2 Binary files /dev/null and b/mods/sounds/sounds/sounds_piano.ogg differ diff --git a/mods/sounds/sounds/sounds_pig_snort.ogg b/mods/sounds/sounds/sounds_pig_snort.ogg new file mode 100644 index 0000000..5ea53d9 Binary files /dev/null and b/mods/sounds/sounds/sounds_pig_snort.ogg differ diff --git a/mods/sounds/sounds/sounds_pig_squeal.ogg b/mods/sounds/sounds/sounds_pig_squeal.ogg new file mode 100644 index 0000000..71f25e6 Binary files /dev/null and b/mods/sounds/sounds/sounds_pig_squeal.ogg differ diff --git a/mods/sounds/sounds/sounds_pigeon.ogg b/mods/sounds/sounds/sounds_pigeon.ogg new file mode 100644 index 0000000..29b8102 Binary files /dev/null and b/mods/sounds/sounds/sounds_pigeon.ogg differ diff --git a/mods/sounds/sounds/sounds_pistol_cock_01.ogg b/mods/sounds/sounds/sounds_pistol_cock_01.ogg new file mode 100644 index 0000000..bea730b Binary files /dev/null and b/mods/sounds/sounds/sounds_pistol_cock_01.ogg differ diff --git a/mods/sounds/sounds/sounds_pistol_cock_02.ogg b/mods/sounds/sounds/sounds_pistol_cock_02.ogg new file mode 100644 index 0000000..6bdbf6e Binary files /dev/null and b/mods/sounds/sounds/sounds_pistol_cock_02.ogg differ diff --git a/mods/sounds/sounds/sounds_pistol_cock_03.ogg b/mods/sounds/sounds/sounds_pistol_cock_03.ogg new file mode 100644 index 0000000..13f39ac Binary files /dev/null and b/mods/sounds/sounds/sounds_pistol_cock_03.ogg differ diff --git a/mods/sounds/sounds/sounds_pistol_fire_01.ogg b/mods/sounds/sounds/sounds_pistol_fire_01.ogg new file mode 100644 index 0000000..9ab82c0 Binary files /dev/null and b/mods/sounds/sounds/sounds_pistol_fire_01.ogg differ diff --git a/mods/sounds/sounds/sounds_pistol_fire_02.ogg b/mods/sounds/sounds/sounds_pistol_fire_02.ogg new file mode 100644 index 0000000..97b0f7d Binary files /dev/null and b/mods/sounds/sounds/sounds_pistol_fire_02.ogg differ diff --git a/mods/sounds/sounds/sounds_pistol_fire_03.ogg b/mods/sounds/sounds/sounds_pistol_fire_03.ogg new file mode 100644 index 0000000..1f2bc2c Binary files /dev/null and b/mods/sounds/sounds/sounds_pistol_fire_03.ogg differ diff --git a/mods/sounds/sounds/sounds_pistol_fire_dry.ogg b/mods/sounds/sounds/sounds_pistol_fire_dry.ogg new file mode 100644 index 0000000..ff6bb26 Binary files /dev/null and b/mods/sounds/sounds/sounds_pistol_fire_dry.ogg differ diff --git a/mods/sounds/sounds/sounds_pistol_reload.ogg b/mods/sounds/sounds/sounds_pistol_reload.ogg new file mode 100644 index 0000000..573aec5 Binary files /dev/null and b/mods/sounds/sounds/sounds_pistol_reload.ogg differ diff --git a/mods/sounds/sounds/sounds_plasma_shot.ogg b/mods/sounds/sounds/sounds_plasma_shot.ogg new file mode 100644 index 0000000..6484737 Binary files /dev/null and b/mods/sounds/sounds/sounds_plasma_shot.ogg differ diff --git a/mods/sounds/sounds/sounds_puppy_bark.ogg b/mods/sounds/sounds/sounds_puppy_bark.ogg new file mode 100644 index 0000000..25b2155 Binary files /dev/null and b/mods/sounds/sounds/sounds_puppy_bark.ogg differ diff --git a/mods/sounds/sounds/sounds_quail.ogg b/mods/sounds/sounds/sounds_quail.ogg new file mode 100644 index 0000000..cad62c0 Binary files /dev/null and b/mods/sounds/sounds/sounds_quail.ogg differ diff --git a/mods/sounds/sounds/sounds_raccoon_chatter.ogg b/mods/sounds/sounds/sounds_raccoon_chatter.ogg new file mode 100644 index 0000000..7e1baab Binary files /dev/null and b/mods/sounds/sounds/sounds_raccoon_chatter.ogg differ diff --git a/mods/sounds/sounds/sounds_raccoon_chatter_baby_01.ogg b/mods/sounds/sounds/sounds_raccoon_chatter_baby_01.ogg new file mode 100644 index 0000000..d4da315 Binary files /dev/null and b/mods/sounds/sounds/sounds_raccoon_chatter_baby_01.ogg differ diff --git a/mods/sounds/sounds/sounds_raccoon_chatter_baby_02.ogg b/mods/sounds/sounds/sounds_raccoon_chatter_baby_02.ogg new file mode 100644 index 0000000..cefc533 Binary files /dev/null and b/mods/sounds/sounds/sounds_raccoon_chatter_baby_02.ogg differ diff --git a/mods/sounds/sounds/sounds_rain_heavy_01.ogg b/mods/sounds/sounds/sounds_rain_heavy_01.ogg new file mode 100644 index 0000000..c19cb14 Binary files /dev/null and b/mods/sounds/sounds/sounds_rain_heavy_01.ogg differ diff --git a/mods/sounds/sounds/sounds_rain_heavy_02.ogg b/mods/sounds/sounds/sounds_rain_heavy_02.ogg new file mode 100644 index 0000000..9c294d9 Binary files /dev/null and b/mods/sounds/sounds/sounds_rain_heavy_02.ogg differ diff --git a/mods/sounds/sounds/sounds_rain_light.ogg b/mods/sounds/sounds/sounds_rain_light.ogg new file mode 100644 index 0000000..cc21c45 Binary files /dev/null and b/mods/sounds/sounds/sounds_rain_light.ogg differ diff --git a/mods/sounds/sounds/sounds_rain_medium.ogg b/mods/sounds/sounds/sounds_rain_medium.ogg new file mode 100644 index 0000000..d47ede2 Binary files /dev/null and b/mods/sounds/sounds/sounds_rain_medium.ogg differ diff --git a/mods/sounds/sounds/sounds_ricochet.ogg b/mods/sounds/sounds/sounds_ricochet.ogg new file mode 100644 index 0000000..326b96f Binary files /dev/null and b/mods/sounds/sounds/sounds_ricochet.ogg differ diff --git a/mods/sounds/sounds/sounds_rifle_cock_01.ogg b/mods/sounds/sounds/sounds_rifle_cock_01.ogg new file mode 100644 index 0000000..8379978 Binary files /dev/null and b/mods/sounds/sounds/sounds_rifle_cock_01.ogg differ diff --git a/mods/sounds/sounds/sounds_rifle_cock_02.ogg b/mods/sounds/sounds/sounds_rifle_cock_02.ogg new file mode 100644 index 0000000..85deba0 Binary files /dev/null and b/mods/sounds/sounds/sounds_rifle_cock_02.ogg differ diff --git a/mods/sounds/sounds/sounds_rifle_cock_03.ogg b/mods/sounds/sounds/sounds_rifle_cock_03.ogg new file mode 100644 index 0000000..74c28b7 Binary files /dev/null and b/mods/sounds/sounds/sounds_rifle_cock_03.ogg differ diff --git a/mods/sounds/sounds/sounds_rifle_fire_01.ogg b/mods/sounds/sounds/sounds_rifle_fire_01.ogg new file mode 100644 index 0000000..57071e9 Binary files /dev/null and b/mods/sounds/sounds/sounds_rifle_fire_01.ogg differ diff --git a/mods/sounds/sounds/sounds_rifle_fire_02.ogg b/mods/sounds/sounds/sounds_rifle_fire_02.ogg new file mode 100644 index 0000000..cae512a Binary files /dev/null and b/mods/sounds/sounds/sounds_rifle_fire_02.ogg differ diff --git a/mods/sounds/sounds/sounds_rifle_fire_03.ogg b/mods/sounds/sounds/sounds_rifle_fire_03.ogg new file mode 100644 index 0000000..b95fc49 Binary files /dev/null and b/mods/sounds/sounds/sounds_rifle_fire_03.ogg differ diff --git a/mods/sounds/sounds/sounds_rifle_fire_04.ogg b/mods/sounds/sounds/sounds_rifle_fire_04.ogg new file mode 100644 index 0000000..6eb3ac7 Binary files /dev/null and b/mods/sounds/sounds/sounds_rifle_fire_04.ogg differ diff --git a/mods/sounds/sounds/sounds_rifle_fire_cock.ogg b/mods/sounds/sounds/sounds_rifle_fire_cock.ogg new file mode 100644 index 0000000..a790293 Binary files /dev/null and b/mods/sounds/sounds/sounds_rifle_fire_cock.ogg differ diff --git a/mods/sounds/sounds/sounds_rifle_fire_dry.ogg b/mods/sounds/sounds/sounds_rifle_fire_dry.ogg new file mode 100644 index 0000000..a165903 Binary files /dev/null and b/mods/sounds/sounds/sounds_rifle_fire_dry.ogg differ diff --git a/mods/sounds/sounds/sounds_rifle_small_fire_01.ogg b/mods/sounds/sounds/sounds_rifle_small_fire_01.ogg new file mode 100644 index 0000000..b55501c Binary files /dev/null and b/mods/sounds/sounds/sounds_rifle_small_fire_01.ogg differ diff --git a/mods/sounds/sounds/sounds_rifle_small_fire_02.ogg b/mods/sounds/sounds/sounds_rifle_small_fire_02.ogg new file mode 100644 index 0000000..0571edc Binary files /dev/null and b/mods/sounds/sounds/sounds_rifle_small_fire_02.ogg differ diff --git a/mods/sounds/sounds/sounds_robot_01.ogg b/mods/sounds/sounds/sounds_robot_01.ogg new file mode 100644 index 0000000..4c52a7d Binary files /dev/null and b/mods/sounds/sounds/sounds_robot_01.ogg differ diff --git a/mods/sounds/sounds/sounds_robot_02.ogg b/mods/sounds/sounds/sounds_robot_02.ogg new file mode 100644 index 0000000..c843e75 Binary files /dev/null and b/mods/sounds/sounds/sounds_robot_02.ogg differ diff --git a/mods/sounds/sounds/sounds_rooster.ogg b/mods/sounds/sounds/sounds_rooster.ogg new file mode 100644 index 0000000..d3a1cd4 Binary files /dev/null and b/mods/sounds/sounds/sounds_rooster.ogg differ diff --git a/mods/sounds/sounds/sounds_scrape_01.ogg b/mods/sounds/sounds/sounds_scrape_01.ogg new file mode 100644 index 0000000..ed8c4b8 Binary files /dev/null and b/mods/sounds/sounds/sounds_scrape_01.ogg differ diff --git a/mods/sounds/sounds/sounds_scrape_02.ogg b/mods/sounds/sounds/sounds_scrape_02.ogg new file mode 100644 index 0000000..4f90264 Binary files /dev/null and b/mods/sounds/sounds/sounds_scrape_02.ogg differ diff --git a/mods/sounds/sounds/sounds_scrape_03.ogg b/mods/sounds/sounds/sounds_scrape_03.ogg new file mode 100644 index 0000000..5665ed0 Binary files /dev/null and b/mods/sounds/sounds/sounds_scrape_03.ogg differ diff --git a/mods/sounds/sounds/sounds_scrape_04.ogg b/mods/sounds/sounds/sounds_scrape_04.ogg new file mode 100644 index 0000000..4c49894 Binary files /dev/null and b/mods/sounds/sounds/sounds_scrape_04.ogg differ diff --git a/mods/sounds/sounds/sounds_scrape_05.ogg b/mods/sounds/sounds/sounds_scrape_05.ogg new file mode 100644 index 0000000..3d2ccb8 Binary files /dev/null and b/mods/sounds/sounds/sounds_scrape_05.ogg differ diff --git a/mods/sounds/sounds/sounds_scrape_06.ogg b/mods/sounds/sounds/sounds_scrape_06.ogg new file mode 100644 index 0000000..63baf9a Binary files /dev/null and b/mods/sounds/sounds/sounds_scrape_06.ogg differ diff --git a/mods/sounds/sounds/sounds_scrape_07.ogg b/mods/sounds/sounds/sounds_scrape_07.ogg new file mode 100644 index 0000000..851abe3 Binary files /dev/null and b/mods/sounds/sounds/sounds_scrape_07.ogg differ diff --git a/mods/sounds/sounds/sounds_scrape_08.ogg b/mods/sounds/sounds/sounds_scrape_08.ogg new file mode 100644 index 0000000..26062e2 Binary files /dev/null and b/mods/sounds/sounds/sounds_scrape_08.ogg differ diff --git a/mods/sounds/sounds/sounds_sea_lion_01.ogg b/mods/sounds/sounds/sounds_sea_lion_01.ogg new file mode 100644 index 0000000..0f32c47 Binary files /dev/null and b/mods/sounds/sounds/sounds_sea_lion_01.ogg differ diff --git a/mods/sounds/sounds/sounds_sea_lion_02.ogg b/mods/sounds/sounds/sounds_sea_lion_02.ogg new file mode 100644 index 0000000..984a3a3 Binary files /dev/null and b/mods/sounds/sounds/sounds_sea_lion_02.ogg differ diff --git a/mods/sounds/sounds/sounds_sea_lion_03.ogg b/mods/sounds/sounds/sounds_sea_lion_03.ogg new file mode 100644 index 0000000..7730a16 Binary files /dev/null and b/mods/sounds/sounds/sounds_sea_lion_03.ogg differ diff --git a/mods/sounds/sounds/sounds_seagull_01.ogg b/mods/sounds/sounds/sounds_seagull_01.ogg new file mode 100644 index 0000000..3e765d4 Binary files /dev/null and b/mods/sounds/sounds/sounds_seagull_01.ogg differ diff --git a/mods/sounds/sounds/sounds_seagull_02.ogg b/mods/sounds/sounds/sounds_seagull_02.ogg new file mode 100644 index 0000000..9e9e9c8 Binary files /dev/null and b/mods/sounds/sounds/sounds_seagull_02.ogg differ diff --git a/mods/sounds/sounds/sounds_seagulls.ogg b/mods/sounds/sounds/sounds_seagulls.ogg new file mode 100644 index 0000000..d098abb Binary files /dev/null and b/mods/sounds/sounds/sounds_seagulls.ogg differ diff --git a/mods/sounds/sounds/sounds_shears_01.ogg b/mods/sounds/sounds/sounds_shears_01.ogg new file mode 100644 index 0000000..122012a Binary files /dev/null and b/mods/sounds/sounds/sounds_shears_01.ogg differ diff --git a/mods/sounds/sounds/sounds_shears_02.ogg b/mods/sounds/sounds/sounds_shears_02.ogg new file mode 100644 index 0000000..b862cb2 Binary files /dev/null and b/mods/sounds/sounds/sounds_shears_02.ogg differ diff --git a/mods/sounds/sounds/sounds_sheep_baa.ogg b/mods/sounds/sounds/sounds_sheep_baa.ogg new file mode 100644 index 0000000..0b64b67 Binary files /dev/null and b/mods/sounds/sounds/sounds_sheep_baa.ogg differ diff --git a/mods/sounds/sounds/sounds_shotgun_fire_pump.ogg b/mods/sounds/sounds/sounds_shotgun_fire_pump.ogg new file mode 100644 index 0000000..98b6f58 Binary files /dev/null and b/mods/sounds/sounds/sounds_shotgun_fire_pump.ogg differ diff --git a/mods/sounds/sounds/sounds_shotgun_pump.ogg b/mods/sounds/sounds/sounds_shotgun_pump.ogg new file mode 100644 index 0000000..c88b99f Binary files /dev/null and b/mods/sounds/sounds/sounds_shotgun_pump.ogg differ diff --git a/mods/sounds/sounds/sounds_skeleton_bones.ogg b/mods/sounds/sounds/sounds_skeleton_bones.ogg new file mode 100644 index 0000000..90cdc98 Binary files /dev/null and b/mods/sounds/sounds/sounds_skeleton_bones.ogg differ diff --git a/mods/sounds/sounds/sounds_snake_rattle.ogg b/mods/sounds/sounds/sounds_snake_rattle.ogg new file mode 100644 index 0000000..8f2dba6 Binary files /dev/null and b/mods/sounds/sounds/sounds_snake_rattle.ogg differ diff --git a/mods/sounds/sounds/sounds_squirrel_01.ogg b/mods/sounds/sounds/sounds_squirrel_01.ogg new file mode 100644 index 0000000..40698d1 Binary files /dev/null and b/mods/sounds/sounds/sounds_squirrel_01.ogg differ diff --git a/mods/sounds/sounds/sounds_squirrel_02.ogg b/mods/sounds/sounds/sounds_squirrel_02.ogg new file mode 100644 index 0000000..d406a5b Binary files /dev/null and b/mods/sounds/sounds/sounds_squirrel_02.ogg differ diff --git a/mods/sounds/sounds/sounds_squirrel_03.ogg b/mods/sounds/sounds/sounds_squirrel_03.ogg new file mode 100644 index 0000000..d65fef8 Binary files /dev/null and b/mods/sounds/sounds/sounds_squirrel_03.ogg differ diff --git a/mods/sounds/sounds/sounds_thunder_01.ogg b/mods/sounds/sounds/sounds_thunder_01.ogg new file mode 100644 index 0000000..9306b05 Binary files /dev/null and b/mods/sounds/sounds/sounds_thunder_01.ogg differ diff --git a/mods/sounds/sounds/sounds_thunder_02.ogg b/mods/sounds/sounds/sounds_thunder_02.ogg new file mode 100644 index 0000000..56d5f0a Binary files /dev/null and b/mods/sounds/sounds/sounds_thunder_02.ogg differ diff --git a/mods/sounds/sounds/sounds_thunder_03.ogg b/mods/sounds/sounds/sounds_thunder_03.ogg new file mode 100644 index 0000000..67acf5d Binary files /dev/null and b/mods/sounds/sounds/sounds_thunder_03.ogg differ diff --git a/mods/sounds/sounds/sounds_tiger_roar_01.ogg b/mods/sounds/sounds/sounds_tiger_roar_01.ogg new file mode 100644 index 0000000..883fa3e Binary files /dev/null and b/mods/sounds/sounds/sounds_tiger_roar_01.ogg differ diff --git a/mods/sounds/sounds/sounds_tiger_snarl_01.ogg b/mods/sounds/sounds/sounds_tiger_snarl_01.ogg new file mode 100644 index 0000000..a270bc7 Binary files /dev/null and b/mods/sounds/sounds/sounds_tiger_snarl_01.ogg differ diff --git a/mods/sounds/sounds/sounds_tiger_snarl_02.ogg b/mods/sounds/sounds/sounds_tiger_snarl_02.ogg new file mode 100644 index 0000000..c667ef0 Binary files /dev/null and b/mods/sounds/sounds/sounds_tiger_snarl_02.ogg differ diff --git a/mods/sounds/sounds/sounds_tiger_snarl_03.ogg b/mods/sounds/sounds/sounds_tiger_snarl_03.ogg new file mode 100644 index 0000000..d44626b Binary files /dev/null and b/mods/sounds/sounds/sounds_tiger_snarl_03.ogg differ diff --git a/mods/sounds/sounds/sounds_tiger_snarl_04.ogg b/mods/sounds/sounds/sounds_tiger_snarl_04.ogg new file mode 100644 index 0000000..0aea43a Binary files /dev/null and b/mods/sounds/sounds/sounds_tiger_snarl_04.ogg differ diff --git a/mods/sounds/sounds/sounds_tool_break.1.ogg b/mods/sounds/sounds/sounds_tool_break.1.ogg new file mode 100644 index 0000000..2a571ae Binary files /dev/null and b/mods/sounds/sounds/sounds_tool_break.1.ogg differ diff --git a/mods/sounds/sounds/sounds_tool_break.2.ogg b/mods/sounds/sounds/sounds_tool_break.2.ogg new file mode 100644 index 0000000..1789352 Binary files /dev/null and b/mods/sounds/sounds/sounds_tool_break.2.ogg differ diff --git a/mods/sounds/sounds/sounds_tool_break.3.ogg b/mods/sounds/sounds/sounds_tool_break.3.ogg new file mode 100644 index 0000000..a99c4b7 Binary files /dev/null and b/mods/sounds/sounds/sounds_tool_break.3.ogg differ diff --git a/mods/sounds/sounds/sounds_toucan_01.ogg b/mods/sounds/sounds/sounds_toucan_01.ogg new file mode 100644 index 0000000..26afc43 Binary files /dev/null and b/mods/sounds/sounds/sounds_toucan_01.ogg differ diff --git a/mods/sounds/sounds/sounds_toucan_02.ogg b/mods/sounds/sounds/sounds_toucan_02.ogg new file mode 100644 index 0000000..2dbcc44 Binary files /dev/null and b/mods/sounds/sounds/sounds_toucan_02.ogg differ diff --git a/mods/sounds/sounds/sounds_toucan_03.ogg b/mods/sounds/sounds/sounds_toucan_03.ogg new file mode 100644 index 0000000..a4c9747 Binary files /dev/null and b/mods/sounds/sounds/sounds_toucan_03.ogg differ diff --git a/mods/sounds/sounds/sounds_toy_squeak_01.ogg b/mods/sounds/sounds/sounds_toy_squeak_01.ogg new file mode 100644 index 0000000..24209d9 Binary files /dev/null and b/mods/sounds/sounds/sounds_toy_squeak_01.ogg differ diff --git a/mods/sounds/sounds/sounds_toy_squeak_02.ogg b/mods/sounds/sounds/sounds_toy_squeak_02.ogg new file mode 100644 index 0000000..02765c2 Binary files /dev/null and b/mods/sounds/sounds/sounds_toy_squeak_02.ogg differ diff --git a/mods/sounds/sounds/sounds_train_whistle.ogg b/mods/sounds/sounds/sounds_train_whistle.ogg new file mode 100644 index 0000000..f2a8f29 Binary files /dev/null and b/mods/sounds/sounds/sounds_train_whistle.ogg differ diff --git a/mods/sounds/sounds/sounds_tree_creak.ogg b/mods/sounds/sounds/sounds_tree_creak.ogg new file mode 100644 index 0000000..c16f12b Binary files /dev/null and b/mods/sounds/sounds/sounds_tree_creak.ogg differ diff --git a/mods/sounds/sounds/sounds_trumpeter_swan.ogg b/mods/sounds/sounds/sounds_trumpeter_swan.ogg new file mode 100644 index 0000000..36e8f72 Binary files /dev/null and b/mods/sounds/sounds/sounds_trumpeter_swan.ogg differ diff --git a/mods/sounds/sounds/sounds_turkey_gobble.ogg b/mods/sounds/sounds/sounds_turkey_gobble.ogg new file mode 100644 index 0000000..3fc6424 Binary files /dev/null and b/mods/sounds/sounds/sounds_turkey_gobble.ogg differ diff --git a/mods/sounds/sounds/sounds_undead_moan_01.ogg b/mods/sounds/sounds/sounds_undead_moan_01.ogg new file mode 100644 index 0000000..e04ad1f Binary files /dev/null and b/mods/sounds/sounds/sounds_undead_moan_01.ogg differ diff --git a/mods/sounds/sounds/sounds_undead_moan_02.ogg b/mods/sounds/sounds/sounds_undead_moan_02.ogg new file mode 100644 index 0000000..519607d Binary files /dev/null and b/mods/sounds/sounds/sounds_undead_moan_02.ogg differ diff --git a/mods/sounds/sounds/sounds_undead_moan_03.ogg b/mods/sounds/sounds/sounds_undead_moan_03.ogg new file mode 100644 index 0000000..7240095 Binary files /dev/null and b/mods/sounds/sounds/sounds_undead_moan_03.ogg differ diff --git a/mods/sounds/sounds/sounds_undead_moan_04.ogg b/mods/sounds/sounds/sounds_undead_moan_04.ogg new file mode 100644 index 0000000..d03f5b7 Binary files /dev/null and b/mods/sounds/sounds/sounds_undead_moan_04.ogg differ diff --git a/mods/sounds/sounds/sounds_vehicle_horn_01.ogg b/mods/sounds/sounds/sounds_vehicle_horn_01.ogg new file mode 100644 index 0000000..0f6e81a Binary files /dev/null and b/mods/sounds/sounds/sounds_vehicle_horn_01.ogg differ diff --git a/mods/sounds/sounds/sounds_vehicle_horn_02.ogg b/mods/sounds/sounds/sounds_vehicle_horn_02.ogg new file mode 100644 index 0000000..af7d898 Binary files /dev/null and b/mods/sounds/sounds/sounds_vehicle_horn_02.ogg differ diff --git a/mods/sounds/sounds/sounds_vehicle_motor_idle.ogg b/mods/sounds/sounds/sounds_vehicle_motor_idle.ogg new file mode 100644 index 0000000..b1bee5b Binary files /dev/null and b/mods/sounds/sounds/sounds_vehicle_motor_idle.ogg differ diff --git a/mods/sounds/sounds/sounds_vomit_01.ogg b/mods/sounds/sounds/sounds_vomit_01.ogg new file mode 100644 index 0000000..a933b34 Binary files /dev/null and b/mods/sounds/sounds/sounds_vomit_01.ogg differ diff --git a/mods/sounds/sounds/sounds_vomit_02.ogg b/mods/sounds/sounds/sounds_vomit_02.ogg new file mode 100644 index 0000000..0b3a9f5 Binary files /dev/null and b/mods/sounds/sounds/sounds_vomit_02.ogg differ diff --git a/mods/sounds/sounds/sounds_vomit_03.ogg b/mods/sounds/sounds/sounds_vomit_03.ogg new file mode 100644 index 0000000..2777ecd Binary files /dev/null and b/mods/sounds/sounds/sounds_vomit_03.ogg differ diff --git a/mods/sounds/sounds/sounds_vomit_04.ogg b/mods/sounds/sounds/sounds_vomit_04.ogg new file mode 100644 index 0000000..85f82be Binary files /dev/null and b/mods/sounds/sounds/sounds_vomit_04.ogg differ diff --git a/mods/sounds/sounds/sounds_vomit_05.ogg b/mods/sounds/sounds/sounds_vomit_05.ogg new file mode 100644 index 0000000..544edfd Binary files /dev/null and b/mods/sounds/sounds/sounds_vomit_05.ogg differ diff --git a/mods/sounds/sounds/sounds_vulture.ogg b/mods/sounds/sounds/sounds_vulture.ogg new file mode 100644 index 0000000..533d055 Binary files /dev/null and b/mods/sounds/sounds/sounds_vulture.ogg differ diff --git a/mods/sounds/sounds/sounds_watch_tick.ogg b/mods/sounds/sounds/sounds_watch_tick.ogg new file mode 100644 index 0000000..8dce058 Binary files /dev/null and b/mods/sounds/sounds/sounds_watch_tick.ogg differ diff --git a/mods/sounds/sounds/sounds_whale.ogg b/mods/sounds/sounds/sounds_whale.ogg new file mode 100644 index 0000000..34b5ecf Binary files /dev/null and b/mods/sounds/sounds/sounds_whale.ogg differ diff --git a/mods/sounds/sounds/sounds_whistle.ogg b/mods/sounds/sounds/sounds_whistle.ogg new file mode 100644 index 0000000..c4588fc Binary files /dev/null and b/mods/sounds/sounds/sounds_whistle.ogg differ diff --git a/mods/sounds/sounds/sounds_wind.ogg b/mods/sounds/sounds/sounds_wind.ogg new file mode 100644 index 0000000..77b95ea Binary files /dev/null and b/mods/sounds/sounds/sounds_wind.ogg differ diff --git a/mods/sounds/sounds/sounds_wolf_howl.ogg b/mods/sounds/sounds/sounds_wolf_howl.ogg new file mode 100644 index 0000000..787dfde Binary files /dev/null and b/mods/sounds/sounds/sounds_wolf_howl.ogg differ diff --git a/mods/sounds/sounds/sounds_wolf_snarl.ogg b/mods/sounds/sounds/sounds_wolf_snarl.ogg new file mode 100644 index 0000000..b96b55a Binary files /dev/null and b/mods/sounds/sounds/sounds_wolf_snarl.ogg differ diff --git a/mods/sounds/sounds/sounds_woodpecker_peck.ogg b/mods/sounds/sounds/sounds_woodpecker_peck.ogg new file mode 100644 index 0000000..f3c1885 Binary files /dev/null and b/mods/sounds/sounds/sounds_woodpecker_peck.ogg differ diff --git a/mods/sounds/sounds/sounds_woosh_01.ogg b/mods/sounds/sounds/sounds_woosh_01.ogg new file mode 100644 index 0000000..a997406 Binary files /dev/null and b/mods/sounds/sounds/sounds_woosh_01.ogg differ diff --git a/mods/sounds/sounds/sounds_woosh_02.ogg b/mods/sounds/sounds/sounds_woosh_02.ogg new file mode 100644 index 0000000..73af133 Binary files /dev/null and b/mods/sounds/sounds/sounds_woosh_02.ogg differ diff --git a/mods/sounds/sounds/sounds_woosh_03.ogg b/mods/sounds/sounds/sounds_woosh_03.ogg new file mode 100644 index 0000000..150f74b Binary files /dev/null and b/mods/sounds/sounds/sounds_woosh_03.ogg differ diff --git a/mods/sounds/sounds/sounds_woosh_04.ogg b/mods/sounds/sounds/sounds_woosh_04.ogg new file mode 100644 index 0000000..1db1080 Binary files /dev/null and b/mods/sounds/sounds/sounds_woosh_04.ogg differ diff --git a/mods/sounds/sounds/sounds_yak.ogg b/mods/sounds/sounds/sounds_yak.ogg new file mode 100644 index 0000000..7252a0c Binary files /dev/null and b/mods/sounds/sounds/sounds_yak.ogg differ diff --git a/mods/sounds/sounds/sounds_zebra.ogg b/mods/sounds/sounds/sounds_zebra.ogg new file mode 100644 index 0000000..7b3aee7 Binary files /dev/null and b/mods/sounds/sounds/sounds_zebra.ogg differ diff --git a/mods/sounds/sounds/sounds_zipper.ogg b/mods/sounds/sounds/sounds_zipper.ogg new file mode 100644 index 0000000..a74632e Binary files /dev/null and b/mods/sounds/sounds/sounds_zipper.ogg differ diff --git a/mods/sounds/sounds/sounds_zombie_damage.ogg b/mods/sounds/sounds/sounds_zombie_damage.ogg new file mode 100644 index 0000000..aeefca8 Binary files /dev/null and b/mods/sounds/sounds/sounds_zombie_damage.ogg differ diff --git a/mods/sounds/sounds/sounds_zombie_death.ogg b/mods/sounds/sounds/sounds_zombie_death.ogg new file mode 100644 index 0000000..ded4ddc Binary files /dev/null and b/mods/sounds/sounds/sounds_zombie_death.ogg differ diff --git a/mods/sounds/sounds/sounds_zombie_growl_01.ogg b/mods/sounds/sounds/sounds_zombie_growl_01.ogg new file mode 100644 index 0000000..00ba8f7 Binary files /dev/null and b/mods/sounds/sounds/sounds_zombie_growl_01.ogg differ diff --git a/mods/sounds/sounds/sounds_zombie_growl_02.ogg b/mods/sounds/sounds/sounds_zombie_growl_02.ogg new file mode 100644 index 0000000..c26c5e4 Binary files /dev/null and b/mods/sounds/sounds/sounds_zombie_growl_02.ogg differ diff --git a/mods/sounds/sounds/sounds_zombie_growl_03.ogg b/mods/sounds/sounds/sounds_zombie_growl_03.ogg new file mode 100644 index 0000000..aebe5b4 Binary files /dev/null and b/mods/sounds/sounds/sounds_zombie_growl_03.ogg differ diff --git a/mods/sounds/sources.md b/mods/sounds/sources.md new file mode 100644 index 0000000..6c2a396 --- /dev/null +++ b/mods/sounds/sources.md @@ -0,0 +1,487 @@ + +#### General Sounds: + +| Filename (sounds_) / Source | Author | License | Notes | +| --------------------------------- | ---------------------------- | ------------ | ------------------------ | +| [airplane_prop][] | jakobthiesen | CC BY 3.0 | loopable | +| [apple_bite][] | sonicmariobrotha | CC0 | | +| [ar_burst_0[1-2]][ar_fire] | Wyatt Dilley (dwightsabeast) | CC BY 3.0 | | +| [ar_burst_03][] | qubodup | CC0 | | +| [ar_fire*][ar_fire] | Wyatt Dilley (dwightsabeast) | CC BY 3.0 | | +| [balloon_inflate][] | d.n.audio.uk | CC0 | | +| [balloon_pop][] | Gniffelbaf | CC0 | | +| [bat*][bat] | polymorpheva | CC0 | | +| [bear*][fws] | U.S. Fish & Wildlife Service | CC0 | | +| [bee][] | DrDufus | CC0 | loopable | +| [bees][] | tom_woysky | CC0 | loopable | +| [bicycle_bell][bicycle] | AntumDeluge | CC0 | | +| [bicycle_horn][bicycle] | AntumDeluge | CC0 | | +| [bicycle_spokes][bicycle] | AntumDeluge | CC0 | | +| [bird*][bird] | Jc Guan | CC0 | | +| [boing][] | reelworldstudio | CC0 | | +| [bumble_bee_01][] | Iain McCurdy | CC BY 3.0 | loopable | +| [bumble_bee_02][] | CGEffex | CC BY 3.0 | | +| [camel*][camel] | craigsmith | CC0 | | +| [canary*][canary] | MediaCollege.com | CC0 | | +| [car_motor][] | jackthemurray | CC0 | loopable | +| [cat_meow][] | blimp66 | CC BY 3.0 | | +| [chalk_screech_01][] | Sirderf | CC BY 3.0 | | +| [chalk_screech_02][] | Sirderf | CC BY 3.0 | | +| [chalk_screech_03][] | Sirderf | CC BY 3.0 | | +| [chalk_write*][chalk_write] | thavis360 | CC0 | | +| [chicken*][chicken] | www.bonson.ca | CC BY 3.0 | | +| [church_bells_01][] | Jonathan Shaw (InspectorJ) | CC BY 3.0 | loopable | +| [church_bells_02][] | Jonathan Shaw (InspectorJ) | CC BY 3.0 | loopable | +| [cicada_01][] | Jonathan Shaw (InspectorJ) | CC BY 3.0 | loopable | +| [cicada_02][] | Exomène | CC BY 3.0 | loopable | +| [cicada_03][] | beau_rl | CC0 | loopable | +| [cicada_04][] | macdaddyno1 | CC0 | loopable | +| [cicada_05][] | sinewave1kHz | CC0 | loopable | +| [cicada_06][] | Ian Davies | CC0 | loopable | +| [cicada_07][] | Jedo | CC0 | loopable | +| [cicada_08][] | OroborosNZ | CC BY 3.0 | loopable | +| [clock_tick][] | AntumDeluge | CC0 | loopable | +| [cobra*][cobra] | N/A | CC0 | | +| [coin][] | greenvwbeetle | CC0 | | +| [compressor_motor_01][] | ivolipa | CC0 | loopable | +| [compressor_motor_02][] | Cell31 Sound Productions | CC BY 3.0 | loopable | +| [cow_moo*][cow_moo] | JosephSardin | CC0 | | +| [coyote_howl][] | rogerforeman | CC BY 3.0 | | +| [cricket][] | GB01 | CC0 | loopable | +| [crow_caw][] | Morris Gevirtz | CC BY 4.0 | | +| [dog_bark][] | ivolipa | CC0 | | +| [dolphin*][dolphin] | Nagaty Studio | CC BY | | +| [door_close_01][] | LampEight | CC0 | | +| [door_close_02][] | Jonathan Shaw (InspectorJ) | CC BY 3.0 | | +| [door_close_03][] | bennstir | CC BY 3.0 | | +| [door_creak][] | Jonathan Shaw (InspectorJ) | CC BY 3.0 | | +| [door_knock_01][] | LPHypeR | CC BY 3.0 | | +| [door_knock_02][] | Patrick Hunt | CC0 | | +| [door_open][] | skyumori | CC0 | | +| [doorbell_01][] | kwahmah_02 | CC BY 3.0 | | +| [doorbell_02][] | bennstir | CC BY 3.0 | | +| [doorbell_03][] | jorickhoofd | CC BY 3.0 | | +| [duck_quack_01][] | Jonathon Jongsma | CC BY-SA 3.0 | | +| [duck_quack_02][] | DrMaysta | CC0 | | +| [duck_quack_03][] | dobroide / qubodup | CC BY 3.0 | | +| [elephant_trumpet][] | vataaa | CC0 | | +| [entity_hit][] | sonictechtonic | CC BY 3.0 | | +| [explosion_01][] | JuveriSetila | CC0 | | +| [explosion_02][] | studiomandragore | CC0 | | +| [explosion_03][] | FlashTrauma | CC0 | | +| [explosion_distant][]* | Tobiasz 'unfa' Karoń | CC0 | | +| [explosion_scifi][] | Anomaex | CC0 | | +| [frog][] | kayceemixer | CC0 | | +| [fire_crackle][] | 16FThumaF | CC0 | loopable | +| [fireball_01][] | Julien Matthey | CC0 | | +| [fireball_02][] | Julien Matthey | CC0 | | +| [fireball_03][] | Julien Matthey | CC0 | | +| [fireworks_01][] | Florian Reichelt | CC0 | | +| [fireworks_02][] | Jonathan Shaw (InspectorJ) | CC BY 3.0 | | +| [fireworks_pop][]* | Jonathan Shaw (InspectorJ) | CC BY 3.0 | | +| [fuse][] | Ned Bouhalassa | CC0 | | +| [fuse_short][fuse] | Ned Bouhalassa | CC0 | | +| [gallop_01][] | Alan McKinney (alanmcki) | CC BY 3.0 | | +| [gallop_02][] | Alan McKinney (alanmcki) | CC BY 3.0 | | +| [ghost][]* | BlockMen | CC BY-SA 3.0 | | +| [giraffe_hum][] | [↓](#authors) | CC BY-SA 4.0 | | +| [goat_bleat*][goat_bleat] | Stephan | CC0 | | +| [goose][] | Glaneur de sons | CC BY 3.0 | | +| [gorilla_grunt][] | [↓](#authors) | CC0 | | +| [gorilla_roar][] | J0ck0 | CC0 | | +| [gorilla_snarl*][gorilla_grunt] | [↓](#authors) | CC0 | | +| [grasshopper][] | straget | CC0 | | +| [helicopter][] | Thomas Ryder Payne | CC0 | loopable | +| [horse_neigh_01][] | GoodListener | CC BY 3.0 | | +| [horse_neigh_02][] | foxen10 | CC0 | | +| [horse_snort_01][] | madklown | CC0 | | +| [horse_snort_02][] | 0_ciz | CC0 | | +| [hyena_01][] | [↓](#authors) | CC BY 2.0 | | +| [hyena_02][] | [↓](#authors) | CC BY 2.0 | | +| [hyena_03][] | [↓](#authors) | CC BY 2.0 | | +| [jaguar_saw][] | About Zoos | CC BY | | +| [jet_ambience][] | habbis92 | CC0 | loopable | +| [jet_flyby][] | Zerono1 | CC0 | | +| [jet_land][] | bigpickle51 | CC0 | | +| [lamb][] | swiftoid | CC0 | | +| [laser_01][] | Julien Matthey | CC0 | | +| [laser_02][] | Julien Matthey | CC0 | | +| [laser_03][] | Julien Matthey | CC0 | | +| [laser_04][] | Julien Matthey | CC0 | | +| [laser_05][] | Julien Matthey | CC0 | | +| [laser_06][] | Julien Matthey | CC0 | | +| [laser_07][] | Julien Matthey | CC0 | | +| [laugh_evil_01][] | AntumDeluge | CC0 | | +| [laugh_evil_02][] | AntumDeluge | CC0 | | +| [lava_cool][default] | Perttu Ahola (celeron55) | CC BY-SA 3.0 | 3 random sounds | +| [leaves*][leaves] | DSOADigital | CC0 | | +| [leopard*][leopard] | Ian Fairley | CC BY | | +| [lion_bellow][] | felix.blume | CC0 | | +| [loon_01][] | Jonathon Jongsma | CC BY-SA 3.0 | | +| [loon_[02-03]][loon_02] | Jonathon Jongsma | CC BY-SA 3.0 | | +| [match_ignite][] | Jonathan Shaw (InspectorJ) | CC BY 3.0 | | +| [melee_hit][]* | CGEffex | CC BY 3.0 | [OpenGameArt][oga.29445] | +| [mermaid_song][]* | poots | CC BY 3.0 | | +| [monkey*][monkey] | AntumDeluge | CC0 | imitation | +| [motorbike_idle][] | m1rk0 | CC BY 3.0 | loopable | +| [mouse][] | AntumDeluge | CC0 | imitation | +| [owl_hoot][] | Anthousai | CC0 | | +| [parrot*][parrot] | Mings | CC BY 3.0 | | +| [peacock_01][] | dobroide | CC BY 3.0 | | +| [peacock_02][] | MediaCollege.com | CC0 | | +| [pencil_erase][] | damsur | CC0 | | +| [pencil_write][] | NachtmahrTV | CC0 | | +| [penguin*][penguin] | Bidone | CC0 | | +| [piano][] | [↓](#authors) | CC0 | | +| [pig_snort][] | yottasounds | CC BY 3.0 | | +| [pig_squeal][] | MediaCollege.com | CC0 | | +| [pigeon][] | JavierSerrat | CC0 | | +| [pistol_cock*][pistol_cock] | J.Anthracite | CC0 | | +| [pistol_fire_01][] | DrinkingWindGames | CC BY 3.0 | | +| [pistol_fire_02][] | magnuswaker | CC0 | | +| [pistol_fire_03][] | Morgan Purkis | CC0 | | +| [pistol_fire_dry][] | Sophia Caldwell | CC BY 3.0 | | +| [pistol_reload][] | Bunny_Clark | CC BY 3.0 | | +| [plasma_shot][] | Tobiasz 'unfa' Karoń | CC0 | | +| [puppy_bark][] | moffet | CC0 | | +| [quail][] | PrincessGrace | CC0 | | +| [raccoon*][raccoon] | jnargus | CC BY | | +| [rain_heavy_01][] | Inu Etc | CC0 | loopable | +| [rain_heavy_02][] | TRP | CC0 | loopable | +| [rain_light][] | Zepp2010 | CC0 | loopable | +| [rain_medium][] | klangfabrik | CC0 | loopable | +| [ricochet][] | Benboncan | CC BY 3.0 | | +| [rifle_cock_01][] | freemusicpromo | CC0 | | +| [rifle_cock_02][] | Bunny_Clark | CC BY 3.0 | | +| [rifle_cock_03][] | SpliceSound | CC0 | | +| [rifle_fire_01][] | bananplyte | CC0 | | +| [rifle_fire_02][] | [↓](#authors) | CC BY 3.0 | | +| [rifle_fire_03][] | Rob Marion | CC0 | | +| [rifle_fire_04][] | Morgan Purkis | CC0 | | +| [rifle_fire_cock][] | EFlexMusic | CC BY 3.0 | | +| [rifle_fire_dry][] | michorvath | CC0 | | +| [rifle_small_fire][] | Tito Lahaye | CC0 | | +| [robot_01][] | AntumDeluge | OGA BY 3.0 | | +| [robot_02][] | Loge the 60th | CC0 | | +| [rooster][] | poorenglishjuggler | CC0 | | +| [scrape*][scrape] | AntumDeluge | CC0 | | +| [sea_lion*][sea_lion] | felix.blume | CC0 | | +| [seagull*][seagull] | squashy555 | CC0 | | +| [seagulls][] | Soojay | CC0 | | +| [shears][]* | SmartWentCody | CC BY 3.0 | | +| [sheep_baa][] | mikewest | CC0 | | +| [skeleton_bones][] | AntumDeluge | CC0 | | +| [snake_rattle][fws] | U.S. Fish & Wildlife Service | CC0 | | +| [squirrel*][squirrel] | bmccoy2 | CC BY 3.0 | | +| [shotgun_fire_pump][] | Deganoth | CC BY 3.0 | | +| [shotgun_pump][] | dasBUTCHER84 | CC0 | | +| [thunder_01][] | bajko | CC0 | | +| [thunder_02][] | Josh74000MC | CC0 | | +| [thunder_03][] | juskiddink | CC BY 3.0 | | +| [tiger_roar_01][] | videog | CC BY 3.0 | | +| [tiger_snarl_01][tiger_roar_01] | videog | CC BY 3.0 | | +| [tiger_snarl_0[2-4]][tiger_snarl] | schots | CC0 | | +| [tool_break*][tool_break] | HerbertBoland | CC BY 3.0 | | +| [toucan][] | Niels Krabbe | CC BY-SA 4.0 | | +| [toy_squeak_01][] | LamaMakesMusic | CC0 | | +| [toy_squeak_02][] | Iamgiorgio | CC0 | | +| [train_whistle][] | Daniel Simion | CC BY 3.0 | | +| [tree_creak][] | Department64 | CC0 | | +| [trumpeter_swan][] | Jonathon Jongsma | CC BY-SA 4.0 | | +| [turkey_gobble][] | JarredGibb | CC0 | | +| [undead_moan_*][undead_moan] | AntumDeluge | CC0 | | +| [vehicle_horn_01][] | dj997 | CC BY 3.0 | | +| [vehicle_horn_02][] | 15HPanska_Ruttner_Jan | CC0 | | +| [vehicle_motor_idle][] | 238310 | CC0 | loopable | +| [vomit*][vomit] | Anko6 | CC0 | | +| [vulture][] | AntumDeluge | CC0 | imitation | +| [watch_tick][] | Nicolas4677 | CC0 | loopable | +| [whale][] | Ian Fairley | CC BY | | +| [whistle][] | pawsound | CC0 | | +| [wind][] | Jonathan Shaw (InspectorJ) | CC BY 3.0 | loopable | +| [wolf_howl][] | killyourpepe | CC0 | | +| [wolf_snarl][] | newagesoup | CC BY 3.0 | | +| [woodpecker_peck][] | Benboncan | CC BY 3.0 | | +| [woosh_01][] | denao270 | CC0 | | +| [woosh_02][] | mrickey13 | CC0 | | +| [woosh_03][] | BranndyBottle | CC0 | | +| [woosh_04][] | JuanD20 | CC0 | | +| [yak][] | AntumDeluge | CC0 | imitation | +| [zebra][] | Peet J van Eeden | CC BY | | +| [zipper][] | AntumDeluge | CC0 | | +| [zombie_damage][] | Under7dude | CC0 | | +| [zombie_death][] | Under7dude | CC0 | from cmer zombie mod | +| [zombie_growl_01][] | Under7dude | CC0 | | +| [zombie_growl_02][] | Under7dude | CC0 | | +| [zombie_growl_03][] | Under7dude | CC0 | | + +#### Node Sounds: + +| Filename (sounds_node_) / Source | Author | License | Notes | +| --------------------------------- | -------------------------- | ------------ | ----------------------- | +| [dig_choppy.*][dig_choppy] | Sheyvan | CC0 | | +| [dig_cracky.*][dig_cracky] | Benboncan | CC BY 3.0 | | +| [dig_crumbly][default] | Mito551 | CC BY-SA 3.0 | | +| [dig_gravel.*][dig_gravel] | lolamadeus | CC0 | | +| [dig_ice.*][dig_ice] | dheming | CC BY 3.0 | | +| [dig_metal][] | yadronoff | CC BY 3.0 | | +| [dig_snappy][] | blukotek | CC0 | | +| [dug.*][default] | Mito551 | CC BY-SA 3.0 | | +| [dug_glass.1][] | cmusounddesign | CC BY 3.0 | | +| [dug_glass.2][] | Tomlija | CC BY 3.0 | | +| [dug_glass.3][] | lsprice | CC BY 3.0 | | +| [dug_gravel.*][dig_gravel] | lolamadeus | CC0 | | +| [dug_ice][] | Angel_Perez_Grandi | CC BY 3.0 | | +| [dug_metal][]* | qubodup | CC0 | | +| [place*][default] | Mito551 | CC BY-SA 3.0 | | +| [step_dirt.*][default] | Mito551 | CC BY-SA 3.0 | | +| [step_glass][default] | Mito551 | CC BY-SA 3.0 | | +| [step_grass.*][default] | Mito551 | CC BY-SA 3.0 | | +| [step_gravel][default] | Mito551 | CC BY-SA 3.0 | | +| [step_hard.*][step_hard] | Erdie | CC BY 3.0 | | +| [step_ice.*][step_ice] | Jonathan Shaw (InspectorJ) | CC BY 3.0 | | +| [step_metal.*][step_metal] | mypantsfelldown | CC0 | | +| [step_sand.*][step_sand] | worthahep88 | CC0 | | +| [step_snow.*][step_snow] | Ryding | CC0 | | +| [step_water.1][] | AGFX | CC BY 3.0 | | +| [step_water.2][] | AGFX | CC BY 3.0 | | +| [step_water.3][] | AGFX | CC BY 3.0 | | +| step_water.4 | AntumDeluge | CC0 | generated with Audacity | +| [step_wood.*][default] | Mito551 | CC BY-SA 3.0 | | + +
**Authors Continued:** + +- Anton Baotic, Florian Sicks, & Angela S. Stoeger: + - **giraffe_hum** + - **gorilla_grunt** + - **gorilla_snarl** +- **hyena:** Mathevon N, Koralek A, Weldele M, Glickman S, & Theunissen F +- **piano:** Scott Joplin & Tim Starling +- **rifle_fire_02:** Cameron DeDore (DrinkingWindGames) + + +[default]: https://github.com/minetest/minetest_game/tree/master/mods/default +[fws]: https://www.fws.gov/video/sound.htm +[oga.29445]: https://opengameart.org/node/29445 + +[airplane_prop]: https://freesound.org/s/188423/ +[apple_bite]: https://freesound.org/s/333825/ +[ar_burst_03]: https://freesound.org/s/482120/ +[ar_fire]: https://freesound.org/s/553848/ +[balloon_inflate]: https://freesound.org/s/263809/ +[balloon_pop]: https://freesound.org/s/82119/ +[bat]: https://freesound.org/s/104205/ +[bee]: https://freesound.org/s/462875/ +[bees]: https://freesound.org/s/243011/ +[bicycle]: https://opengameart.org/node/16321 +[bird]: https://soundbible.com/340-Bird-Song.html +[boing]: https://freesound.org/s/161122/ +[bumble_bee_01]: https://freesound.org/s/498412/ +[bumble_bee_02]: https://freesound.org/s/99955/ +[camel]: https://freesound.org/s/437937/ +[canary]: https://www.mediacollege.com/downloads/sound-effects/animals/bird/ +[car_motor]: https://freesound.org/s/433584/ +[cat_meow]: https://freesound.org/s/397661/ +[chalk_screech_01]: https://freesound.org/s/332290/ +[chalk_screech_02]: https://freesound.org/s/332289/ +[chalk_screech_03]: https://freesound.org/s/332288/ +[chalk_write]: https://freesound.org/s/178433/ +[chicken]: https://freesound.org/s/24967/ +[church_bells_01]: https://freesound.org/s/371267/ +[church_bells_02]: https://freesound.org/s/417769/ +[cicada_01]: https://freesound.org/s/400331/ +[cicada_02]: https://freesound.org/s/317472/ +[cicada_03]: https://freesound.org/s/554120/ +[cicada_04]: https://freesound.org/s/321591/ +[cicada_05]: https://freesound.org/s/207374/ +[cicada_06]: https://freesound.org/s/434330/ +[cicada_07]: https://freesound.org/s/396809/ +[cicada_08]: https://freesound.org/s/179565/ +[clock_tick]: https://opengameart.org/node/16323 +[cobra]: https://archive.org/details/unknowncobracobrabitewmv +[coin]: https://freesound.org/s/423332/ +[compressor_motor_01]: https://freesound.org/s/337447/ +[compressor_motor_02]: https://freesound.org/s/376927/ +[cow_moo]: https://freesound.org/s/177253/ +[coyote_howl]: https://freesound.org/s/68067/ +[cricket]: https://freesound.org/s/530477/ +[crow_caw]: https://www.xeno-canto.org/617630 +[dig_choppy]: https://freesound.org/s/476113/ +[dig_cracky]: https://freesound.org/s/71823/ +[dig_gravel]: https://freesound.org/s/179341/ +[dig_ice]: https://freesound.org/s/268023/ +[dig_metal]: https://freesound.org/s/320397/ +[dig_snappy]: https://freesound.org/s/251660/ +[dog_bark]: https://freesound.org/s/328730/ +[dolphin]: https://www.youtube.com/watch?v=AZuzadlAGL0 +[door_close_01]: https://freesound.org/s/402465/ +[door_close_02]: https://freesound.org/s/411791/ +[door_close_03]: https://freesound.org/s/80928/ +[door_creak]: https://freesound.org/s/346212/ +[door_knock_01]: https://freesound.org/s/500994/ +[door_knock_02]: https://freesound.org/s/256513/ +[door_open]: https://freesound.org/s/104533/ +[doorbell_01]: https://freesound.org/sounds/275072/ +[doorbell_02]: https://freesound.org/s/81072/ +[doorbell_03]: https://freesound.org/s/177875/ +[duck_quack_01]: https://www.xeno-canto.org/62258 +[duck_quack_02]: https://freesound.org/s/418509/ +[duck_quack_03]: https://freesound.org/s/442820/ +[dug_glass.1]: https://freesound.org/s/71947/ +[dug_glass.2]: https://freesound.org/s/97669/ +[dug_glass.3]: https://freesound.org/s/88808/ +[dug_ice]: https://freesound.org/s/49190/ +[dug_metal]: https://opengameart.org/node/18150 +[elephant_trumpet]: https://freesound.org/s/148873/ +[entity_hit]: https://freesound.org/s/241872/ +[explosion_01]: https://freesound.org/s/514133/ +[explosion_02]: https://freesound.org/s/401628/ +[explosion_03]: https://freesound.org/s/398283/ +[explosion_distant]: https://freesound.org/s/352143/ +[explosion_scifi]: https://freesound.org/s/490253/ +[fire_crackle]: https://freesound.org/s/499032/ +[fireball_01]: https://freesound.org/s/105016/ +[fireball_02]: https://freesound.org/s/346917/ +[fireball_03]: https://freesound.org/s/346916/ +[fireworks_01]: https://freesound.org/s/459973/ +[fireworks_02]: https://freesound.org/s/328861/ +[fireworks_pop]: https://freesound.org/s/410350/ +[frog]: https://freesound.org/s/251495/ +[fuse]: https://freesound.org/s/8320/ +[gallop_01]: https://freesound.org/s/403026/ +[gallop_02]: https://freesound.org/s/403025/ +[ghost]: https://github.com/BlockMen/cme +[giraffe_hum]: https://bmcresnotes.biomedcentral.com/articles/10.1186/s13104-015-1394-3#Sec10 +[goat_bleat]: https://pdsounds.org/pdsounds_files/files/audio/ziegengatter.mp3 +[goose]: https://freesound.org/s/104959/ +[gorilla_grunt]: https://www.mediacollege.com/downloads/sound-effects/animals/primates/ +[gorilla_roar]: https://freesound.org/s/397054/ +[grasshopper]: https://freesound.org/s/401939/ +[helicopter]: https://freesound.org/s/573170/ +[horse_neigh_01]: https://freesound.org/s/322443/ +[horse_neigh_02]: https://freesound.org/s/149024/ +[horse_snort_01]: https://freesound.org/s/184503/ +[horse_snort_02]: https://freesound.org/s/475480/ +[hyena_01]: https://commons.wikimedia.org/wiki/File:Giggling_call_of_a_spotted_hyena_(Crocuta_crocuta)_-_1472-6785-10-9-S1.oga +[hyena_02]: https://commons.wikimedia.org/wiki/File:Giggling_call_of_a_spotted_hyena_(Crocuta_crocuta)_-_1472-6785-10-9-S3.oga +[hyena_03]: https://commons.wikimedia.org/wiki/File:Giggling_call_of_a_spotted_hyena_(Crocuta_crocuta)_-_1472-6785-10-9-S5.oga +[jaguar_saw]: https://www.youtube.com/watch?v=VJ0RCZXu0v4 +[jet_ambience]: https://freesound.org/s/204510/ +[jet_flyby]: https://freesound.org/s/568128/ +[jet_land]: https://freesound.org/s/262755/ +[lamb]: https://freesound.org/s/182509/ +[laser_01]: https://freesound.org/s/268344/ +[laser_02]: https://freesound.org/s/268343/ +[laser_03]: https://freesound.org/s/346919/ +[laser_04]: https://freesound.org/s/346918/ +[laser_05]: https://freesound.org/s/470934/ +[laser_06]: https://freesound.org/s/470933/ +[laser_07]: https://freesound.org/s/470932/ +[laugh_evil_01]: https://opengameart.org/node/81237 +[laugh_evil_02]: https://opengameart.org/node/129475 +[leaves]: https://freesound.org/s/362253/ +[leopard]: https://www.youtube.com/watch?v=VFsHjBbrebk +[lion_bellow]: https://freesound.org/s/405211/ +[loon_01]: https://www.xeno-canto.org/139388 +[loon_02]: https://www.xeno-canto.org/139387 +[match_ignite]: https://freesound.org/s/484266/ +[melee_hit]: https://freesound.org/s/98341/ +[mermaid_song]: https://freesound.org/s/123092/ +[monkey]: https://opengameart.org/node/81240 +[motorbike_idle]: https://freesound.org/s/23212/ +[mouse]: https://opengameart.org/node/16331 +[owl_hoot]: https://freesound.org/s/398734/ +[parrot]: https://freesound.org/s/160381/ +[peacock_01]: https://freesound.org/s/59186/ +[peacock_02]: https://www.mediacollege.com/downloads/sound-effects/animals/bird/ +[pencil_erase]: https://freesound.org/s/443241/ +[pencil_write]: https://freesound.org/s/571800/ +[penguin]: https://freesound.org/s/66150/ +[piano]: https://commons.wikimedia.org/wiki/File:Maple_leaf_rag.ogg +[pig_snort]: https://freesound.org/s/174615/ +[pig_squeal]: https://www.mediacollege.com/downloads/sound-effects/animals/pig/ +[pigeon]: https://freesound.org/s/524345/ +[pistol_cock]: https://freesound.org/s/465488/ +[pistol_fire_01]: https://freesound.org/s/476240/ +[pistol_fire_02]: https://freesound.org/s/522085/ +[pistol_fire_03]: https://freesound.org/s/385812/ +[pistol_fire_dry]: https://freesound.org/s/467183/ +[pistol_reload]: https://freesound.org/s/377549/ +[plasma_shot]: https://freesound.org/s/584198/ +[puppy_bark]: https://freesound.org/s/583142/ +[quail]: https://freesound.org/s/329371/ +[raccoon]: https://www.youtube.com/watch?v=BGjFP1CP7E0 +[rain_heavy_01]: https://freesound.org/s/507902/ +[rain_heavy_02]: https://freesound.org/s/573622/ +[rain_light]: https://freesound.org/s/163264/ +[rain_medium]: https://freesound.org/s/157149/ +[ricochet]: https://freesound.org/s/78091/ +[rifle_cock_01]: https://freesound.org/s/513746/ +[rifle_cock_02]: https://freesound.org/s/377550/ +[rifle_cock_03]: https://freesound.org/s/153560/ +[rifle_fire_01]: https://freesound.org/s/452154/ +[rifle_fire_02]: https://freesound.org/s/410262/ +[rifle_fire_03]: https://freesound.org/s/542046/ +[rifle_fire_04]: https://freesound.org/s/391725/ +[rifle_fire_cock]: https://freesound.org/s/398348/ +[rifle_fire_dry]: https://freesound.org/s/427603/ +[rifle_small_fire]: https://freesound.org/s/319400/ +[robot_01]: https://opengameart.org/node/132704 +[robot_02]: https://soundbible.com/1758-Door-Entry-Notification.html +[rooster]: https://freesound.org/s/269496/ +[scrape]: https://opengameart.org/node/81247 +[sea_lion]: https://freesound.org/s/499564/ +[seagull]: https://freesound.org/s/353416/ +[seagulls]: https://freesound.org/s/462462/ +[shears]: https://freesound.org/s/179015/ +[shotgun_fire_pump]: https://freesound.org/s/348671/ +[shotgun_pump]: https://freesound.org/s/449613/ +[squirrel]: https://freesound.org/s/342105/ +[step_hard]: https://freesound.org/s/41579/ +[step_ice]: https://freesound.org/s/416967/ +[step_metal]: https://freesound.org/s/398937/ +[step_sand]: https://freesound.org/s/319224/ +[step_snow]: https://freesound.org/s/94337/ +[step_water.1]: https://freesound.org/s/20432/ +[step_water.2]: https://freesound.org/s/20434/ +[step_water.3]: https://freesound.org/s/20437/ +[sheep_baa]: https://freesound.org/s/414342/ +[skeleton_bones]: https://opengameart.org/node/16324 +[thunder_01]: https://freesound.org/s/399656/ +[thunder_02]: https://freesound.org/s/475094/ +[thunder_03]: https://freesound.org/s/101948/ +[tiger_roar_01]: https://freesound.org/s/149190/ +[tiger_snarl]: https://freesound.org/s/439280/ +[tool_break]: https://freesound.org/s/33206/ +[toucan]: https://www.xeno-canto.org/250531 +[toy_squeak_01]: https://freesound.org/s/403507/ +[toy_squeak_02]: https://freesound.org/s/371305/ +[train_whistle]: https://soundbible.com/2177-Steam-Train-Whistle.html +[tree_creak]: https://freesound.org/s/95262/ +[trumpeter_swan]: https://www.xeno-canto.org/413784 +[turkey_gobble]: https://freesound.org/s/233125/ +[undead_moan]: https://opengameart.org/node/81246 +[vehicle_horn_01]: https://freesound.org/s/493751/ +[vehicle_horn_02]: https://freesound.org/s/461679/ +[vehicle_motor_idle]: https://freesound.org/s/370189/ +[vomit]: https://freesound.org/s/388525/ +[vulture]: https://opengameart.org/node/16329 +[watch_tick]: https://freesound.org/s/446611/ +[whale]: https://www.youtube.com/watch?v=VIElj_SLxfc +[whistle]: https://freesound.org/s/154873/ +[wind]: https://opengameart.org/node/101110 +[wolf_howl]: https://freesound.org/s/395192/ +[wolf_snarl]: https://freesound.org/s/338674/ +[woodpecker_peck]: https://freesound.org/s/66955/ +[woosh_01]: https://freesound.org/s/346373/ +[woosh_02]: https://freesound.org/s/515625/ +[woosh_03]: https://freesound.org/s/464697/ +[woosh_04]: https://freesound.org/s/392591/ +[yak]: https://opengameart.org/node/98682 +[zebra]: https://www.youtube.com/watch?v=xjGJ_XMVTRE +[zipper]: https://opengameart.org/node/16332 +[zombie_damage]: https://freesound.org/s/163447/ +[zombie_death]: https://freesound.org/s/163442/ +[zombie_growl_01]: https://freesound.org/s/163440/ +[zombie_growl_02]: https://freesound.org/s/163444/ +[zombie_growl_03]: https://freesound.org/s/163445/ diff --git a/mods/sounds/tests.lua b/mods/sounds/tests.lua new file mode 100644 index 0000000..8ede223 --- /dev/null +++ b/mods/sounds/tests.lua @@ -0,0 +1,280 @@ + +--- Sounds Tests +-- +-- Enabled with [sounds.enable_tests](settings.html#sounds.enable_tests). +-- +-- @topic tests + + +local S = core.get_translator(sounds.modname) + +local player_cache = {} +local groups_list = {} +local s_handle + +local fs_w = 16 +local fs_h = 12 + +local get_tests_fs = function(pname) + local p_cache = player_cache[pname] or {} + + local fs = "formspec_version[2]" + .. "size[" .. fs_w .. "," .. fs_h .. "]" + .. "label[0.25,0.5;" .. S("Sounds Tests") .. "]" + .. "button_exit[" .. fs_w-0.75 .. ",0.25;0.5,0.5;btn_close;X]" + .. "label[0.25,1.75;Last played:]" + .. "textlist[3.25,1.5;" .. fs_w-5.5 .. ",1.5;played_status;" + .. S("Name: @1", (p_cache.name or "")) + .. "," .. S("Cached: @1", (p_cache.cached or "")) + .. "," .. S("Played: @1", (p_cache.played or "")) + .. "]" + .. "label[0.25,3.5;" .. S("Manual play:") .. "]" + .. "field[3.25,3.25;" .. fs_w-5.5 .. ",0.5;input_name;;" .. (p_cache.manual_play or "") .. "]" + .. "field_close_on_enter[input_name;false]" + .. "button[" .. fs_w-1.75 .. ",3.25;1.5,0.5;btn_play_man;" .. S("Play") .. "]" + .. "label[0.25,4.25;" .. S("Group play:") .. "]" + .. "textlist[3.25,4;" .. fs_w-(5.5*2) .. "," .. fs_h-4.25 .. ";groups;" + + if #groups_list == 0 then -- cache groups + for k in pairs(sounds) do + if type(sounds[k]) == "SoundGroup" then + table.insert(groups_list, k) + end + end + + for nk in pairs(sounds.node) do + if type(sounds.node[nk]) == "SoundGroup" then + table.insert(groups_list, "node." .. nk) + end + for nnk in pairs(sounds.node[nk]) do + if type(sounds.node[nk][nnk]) == "SoundGroup" then + table.insert(groups_list, "node." .. nk .. "." .. nnk) + end + end + end + + table.sort(groups_list) + end + + local g = "" + local g_added = 0 + for _, k in ipairs(groups_list) do + if g_added > 0 then + g = g .. "," + end + g = g .. k + g_added = g_added + 1 + end + + fs = fs .. g .. "]" + .. "textlist[8.75,4;" .. fs_w-(5.5*2) .. "," .. fs_h-4.25 .. ";gsounds;" + + if p_cache.selected_group then + local group_name = groups_list[p_cache.selected_group] + local s_group + if group_name then + if string.find(group_name, ".") then + s_group = sounds + for _, subgroup in ipairs(group_name:split(".")) do + s_group = s_group[subgroup] + end + else + s_group = sounds[group_name] + end + end + + s_group = s_group or {} + + local s = "" + local s_added = 0 + for _, s_name in ipairs(s_group) do + local r_count = sounds.cache[s_name] or sounds.cache["sounds_" .. s_name] + if s_added > 0 then + s = s .. "," + end + s = s .. s_name + if type(r_count) == "number" then + s = s .. " (" .. r_count .. " sounds)" + end + + s_added = s_added + 1 + end + + fs = fs .. s + end + + fs = fs .. "]" + .. "button[" .. fs_w-1.75 .. ",4;1.5,0.5;btn_play_grp;" .. S("Play") .. "]" + .. "button[" .. fs_w-1.75 .. ",4.75;1.5,0.5;btn_rand;" .. S("Random") .. "]" + .. "button[" .. fs_w-1.75 .. ",5.5;1.5,0.5;btn_stop;" .. S("Stop") .. "]" + .. "checkbox[" .. fs_w-1.75 .. ",6.5;chk_loop;" .. S("Loop") .. ";" + .. tostring(p_cache.loop or "false") .. "]" + + return fs +end + +--- Displays sounds tests formspec. +-- +-- @local +-- @tparam string pname Player name to whom formspec is shown. +local show_tests = function(pname) + core.show_formspec(pname, "sounds_tests", get_tests_fs(pname)) +end + +--- Displays sounds tests formspec. +-- +-- @chatcmd sounds_tests +core.register_chatcommand("sounds_tests", { + description = S("Displays sounds tests formspec."), + func = function(pname, param) + show_tests(pname) + return true + end, +}) + + +core.register_on_player_receive_fields(function(player, formname, fields) + if formname == "sounds_tests" then + local pname = player:get_player_name() + player_cache[pname] = player_cache[pname] or {} + local p_cache = player_cache[pname] + + if fields.chk_loop ~= nil then + p_cache.loop = fields.chk_loop == "true" + end + + if fields.quit then + if s_handle then + sounds:stop(s_handle) + s_handle = nil + end + + player_cache[pname] = nil + elseif fields.btn_stop then + if s_handle then + sounds:stop(s_handle) + s_handle = nil + end + elseif fields.btn_play_man then + if s_handle then + sounds:stop(s_handle) + s_handle = nil + end + + local s_name = tostring(fields.input_name):trim() + if s_name ~= "" then + p_cache.name = s_name + p_cache.cached = S("no") + if sounds.cache[s_name] then + p_cache.cached = S("yes") + end + + s_handle = sounds:play(s_name, {to_player=pname, loop=p_cache.loop}) + + p_cache.played = S("no") + if s_handle then + p_cache.played = S("yes") + end + + p_cache.manual_play = s_name + show_tests(pname) + end + elseif fields.groups then + local selected_group = tostring(fields.groups):gsub("^CHG:", "") + p_cache.selected_group = tonumber(selected_group) + show_tests(pname) + elseif fields.gsounds then + local selected_sound = tostring(fields.gsounds):gsub("^CHG:", "") + p_cache.selected_sound = tonumber(selected_sound) + elseif fields.btn_play_grp then + if s_handle then + sounds:stop(s_handle) + s_handle = nil + end + + if p_cache then + local selected_group = p_cache.selected_group + if selected_group then + local group_name = groups_list[selected_group] + local sound_group + if group_name then + if string.find(group_name, ".") then + sound_group = sounds + for _, subgroup in ipairs(group_name:split(".")) do + sound_group = sound_group[subgroup] + end + else + sound_group = sounds[sound_group] + end + end + + if type(sound_group) == "SoundGroup" then + local s_idx = p_cache.selected_sound or 1 + local s_count = sound_group:count() + if s_idx > s_count then + s_idx = s_count + end + p_cache.selected_sound = s_idx + + local s_name + s_handle, s_name = sound_group(s_idx, {to_player=pname, loop=p_cache.loop}) + p_cache.name = s_name + + p_cache.cached = S("no") + if sounds.cache[s_name] then + p_cache.cached = S("yes") + end + p_cache.played = S("no") + if s_handle then + p_cache.played = S("yes") + end + + show_tests(pname) + end + end + end + elseif fields.btn_rand then + if s_handle then + sounds:stop(s_handle) + s_handle = nil + end + + if p_cache then + local selected_group = p_cache.selected_group + if selected_group then + local group_name = groups_list[selected_group] + local sound_group + if group_name then + if string.find(group_name, ".") then + sound_group = sounds + for _, subgroup in ipairs(group_name:split(".")) do + sound_group = sound_group[subgroup] + end + else + sound_group = sounds[sound_group] + end + end + + if type(sound_group) == "SoundGroup" then + local s_name + s_handle, s_name = sound_group({to_player=pname, loop=p_cache.loop}) + p_cache.name = s_name + + p_cache.cached = S("no") + if sounds.cache[s_name] then + p_cache.cached = S("yes") + end + p_cache.played = S("no") + if s_handle then + p_cache.played = S("yes") + end + + show_tests(pname) + end + end + end + end + + return true + end +end) diff --git a/mods/soviet/init.lua b/mods/soviet/init.lua new file mode 100644 index 0000000..880379b --- /dev/null +++ b/mods/soviet/init.lua @@ -0,0 +1,243 @@ +-- Solid nodes +minetest.register_node("soviet:autowasher", { + description = "Soviet Auto Washer", + tiles = + { + "soviet_machine.png", + "soviet_machine.png", + "soviet_machine.png", + "soviet_machine.png", + "soviet_machine.png", + "soviet_washer_auto.png" + }, + paramtype2 = "facedir", + groups = {cracky = 3}, +}) + +minetest.register_node("soviet:stove", { + description = "Soviet Gas Stove (DANGEROUS AS FUCK; CAN EXPLODE)", + tiles = + { + "soviet_stove_top.png", + "soviet_machine.png", + "soviet_machine.png", + "soviet_machine.png", + "soviet_machine.png", + "soviet_stove_front.png" + }, + paramtype2 = "facedir", + groups = {cracky = 3}, +}) + +minetest.register_node("soviet:concrete", { + description = "Concrete", + tiles = {"soviet_concrete.png"}, + is_ground_content = false, + groups = {cracky = 2}, + sounds = default.node_sound_stone_defaults(), +}) + +stairs.register_stair_and_slab( + "concrete", + "soviet:concrete", + {cracky = 2}, + {"soviet_concrete.png"}, + "Concrete Stair", + "Concrete Slab", + default.node_sound_stone_defaults(), + true +) + +minetest.register_node("soviet:concrete_window", { + description = "Chunk of Concrete with a Window in it", + tiles = {"soviet_concrete_window.png"}, + is_ground_content = false, + groups = {cracky = 2}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("soviet:staircase_flooring", { + description = "Apt Building Staircase/Lobby Flooring", + tiles = {"soviet_staircase_flooring.png"}, + is_ground_content = false, + groups = {cracky = 2}, + sounds = default.node_sound_stone_defaults(), +}) + +stairs.register_stair_and_slab( + "staircase_flooring", + "soviet:staircase_flooring", + {cracky = 2}, + {"soviet_staircase_flooring.png"}, + "Apt Staircase/Lobby Flooring Stair", + "Apt Staircase/Lobby Flooring Slab", + default.node_sound_stone_defaults(), + true +) + +minetest.register_node("soviet:glass", +{ + description = "Glass Mosaic", + drawtype = "glasslike", + tiles = {"soviet_glass.png"}, + inventory_image = minetest.inventorycube("soviet_glass.png"), + paramtype = "light", + use_texture_alpha = "blend", + sunlight_propagates = true, + sounds = default.node_sound_glass_defaults(), + is_ground_content = false, + groups = {cracky = 1}, +}) + +-- Plantlike nodes +minetest.register_node("soviet:laundry_detergent", { + description = "Laundry Detergent Powder", + drawtype = "plantlike", + tiles = {"soviet_laundry_detergent.png"}, + inventory_image = "soviet_laundry_detergent.png", + wield_image = "soviet_laundry_detergent.png", + paramtype = "light", + is_ground_content = false, + walkable = false, + selection_box = + { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} + }, + groups = {dig_immediate = 3, attached_node = 1}, + sounds = default.node_sound_sand_defaults(), +}) + +minetest.register_node("soviet:tea", { + description = "Glass of Tea", + drawtype = "plantlike", + tiles = {"soviet_tea.png"}, + inventory_image = "soviet_tea.png", + wield_image = "soviet_tea.png", + paramtype = "light", + is_ground_content = false, + walkable = false, + selection_box = + { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} + }, + groups = {dig_immediate = 3, attached_node = 1}, + sounds = default.node_sound_glass_defaults() +}) + +minetest.register_node("soviet:ceilling_light", { + description = "Ceilling Light", + drawtype = "plantlike", + tiles = {"soviet_lamp.png"}, + inventory_image = "soviet_lamp.png", + wield_image = "soviet_lamp.png", + paramtype = "light", + use_texture_alpha = "blend", + light_source = 15, + is_ground_content = false, + walkable = false, + groups = {cracky = 1}, + sounds = default.node_sound_glass_defaults(), +}) + +-- Nodeboxes +minetest.register_node("soviet:light_fixture", { + description = "Light Fixture", + tiles = { + "soviet_light.png", + "soviet_light.png", + "soviet_light.png", + "soviet_light.png", + "soviet_light.png", + "soviet_light.png" + }, + drawtype = "nodebox", + light_source = 14, + paramtype2 = "facedir", + paramtype = "light", + groups = {cracky = 3}, + node_box = { + type = "fixed", + fixed = { + {-0.1875, -0.125, 0.25, 0.1875, 0.3, 0.5}, + } + } +}) + +minetest.register_node("soviet:transradio", { + description = "Transistor Radio Receiver", + tiles = { + "soviet_transradio_top.png", + "default_wood.png", + "soviet_transradio_right.png", + "soviet_transradio_left.png", + "soviet_transradio_back.png", + "soviet_transradio_front.png", + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2}, + node_box = { + type = "fixed", + fixed = { + {-0.375, -0.5, -0.1875, 0.4375, 0, 0.125}, + {-0.375, 0, -0.125, -0.1875, 0.0625, -0.0625}, + {-0.1875, 0.0625, -0.125, 0, 0.125, -0.0625}, + {0, 0.125, -0.125, 0.1875, 0.1875, -0.0625}, + {0.1875, 0.1875, -0.125, 0.375, 0.25, -0.0625}, + } + } +}) + +minetest.register_node("soviet:concrete_thin", { + description = "Thin Concrete Wall", + tiles = {"soviet_concrete.png"}, + is_ground_content = false, + groups = {cracky = 2}, + sounds = default.node_sound_stone_defaults(), + paramtype2 = "wallmounted", + drawtype = "nodebox", + paramtype = "light", + node_box = { + type = "wallmounted", + fixed = { + {-0.5, -0.5, 0.4375, 0.5, 0.5, 0.5}, + } + } +}) + +minetest.register_node("soviet:concrete_thin_lower", { + description = "Thin Concrete Wall", + tiles = {"soviet_concrete.png"}, + is_ground_content = false, + groups = {cracky = 2}, + sounds = default.node_sound_stone_defaults(), + paramtype2 = "facedir", + drawtype = "nodebox", + paramtype = "light", + node_box = { + type = "fixed", + fixed = { + {-0.5, .0, 0.4375, 0.5, 0.5, 0.5}, + } + } +}) + +minetest.register_node("soviet:concrete_thin", { + description = "Thin Concrete Wall", + tiles = {"soviet_concrete.png"}, + is_ground_content = false, + groups = {cracky = 2}, + sounds = default.node_sound_stone_defaults(), + paramtype2 = "wallmounted", + drawtype = "nodebox", + paramtype = "light", + node_box = { + type = "wallmounted", + fixed = { + {-0.5, -0.5, 0.4375, 0.5, 0.5, 0.5}, + } + } +}) diff --git a/mods/soviet/mod.conf b/mods/soviet/mod.conf new file mode 100644 index 0000000..dae377c --- /dev/null +++ b/mods/soviet/mod.conf @@ -0,0 +1,3 @@ +name = soviet +description = A mod that adds decorational nodes inspired by objects common in Soviet/post-Soviet countries. +depends = sounds, stairs diff --git a/mods/soviet/textures/soviet_bookshelf.png b/mods/soviet/textures/soviet_bookshelf.png new file mode 100644 index 0000000..ea51a48 Binary files /dev/null and b/mods/soviet/textures/soviet_bookshelf.png differ diff --git a/mods/soviet/textures/soviet_concrete.png b/mods/soviet/textures/soviet_concrete.png new file mode 100644 index 0000000..42524f2 Binary files /dev/null and b/mods/soviet/textures/soviet_concrete.png differ diff --git a/mods/soviet/textures/soviet_concrete_window.png b/mods/soviet/textures/soviet_concrete_window.png new file mode 100644 index 0000000..aa38a37 Binary files /dev/null and b/mods/soviet/textures/soviet_concrete_window.png differ diff --git a/mods/soviet/textures/soviet_glass.png b/mods/soviet/textures/soviet_glass.png new file mode 100644 index 0000000..abcecc6 Binary files /dev/null and b/mods/soviet/textures/soviet_glass.png differ diff --git a/mods/soviet/textures/soviet_lamp.png b/mods/soviet/textures/soviet_lamp.png new file mode 100644 index 0000000..60a7d53 Binary files /dev/null and b/mods/soviet/textures/soviet_lamp.png differ diff --git a/mods/soviet/textures/soviet_laundry_detergent.png b/mods/soviet/textures/soviet_laundry_detergent.png new file mode 100644 index 0000000..66c055d Binary files /dev/null and b/mods/soviet/textures/soviet_laundry_detergent.png differ diff --git a/mods/soviet/textures/soviet_light.png b/mods/soviet/textures/soviet_light.png new file mode 100644 index 0000000..a361aff Binary files /dev/null and b/mods/soviet/textures/soviet_light.png differ diff --git a/mods/soviet/textures/soviet_machine.png b/mods/soviet/textures/soviet_machine.png new file mode 100644 index 0000000..cb5e711 Binary files /dev/null and b/mods/soviet/textures/soviet_machine.png differ diff --git a/mods/soviet/textures/soviet_staircase_flooring.png b/mods/soviet/textures/soviet_staircase_flooring.png new file mode 100644 index 0000000..5032281 Binary files /dev/null and b/mods/soviet/textures/soviet_staircase_flooring.png differ diff --git a/mods/soviet/textures/soviet_stove_front.png b/mods/soviet/textures/soviet_stove_front.png new file mode 100644 index 0000000..2ca4c2a Binary files /dev/null and b/mods/soviet/textures/soviet_stove_front.png differ diff --git a/mods/soviet/textures/soviet_stove_top.png b/mods/soviet/textures/soviet_stove_top.png new file mode 100644 index 0000000..84a668f Binary files /dev/null and b/mods/soviet/textures/soviet_stove_top.png differ diff --git a/mods/soviet/textures/soviet_tea.png b/mods/soviet/textures/soviet_tea.png new file mode 100644 index 0000000..4ce862a Binary files /dev/null and b/mods/soviet/textures/soviet_tea.png differ diff --git a/mods/soviet/textures/soviet_transradio_back.png b/mods/soviet/textures/soviet_transradio_back.png new file mode 100644 index 0000000..5a85621 Binary files /dev/null and b/mods/soviet/textures/soviet_transradio_back.png differ diff --git a/mods/soviet/textures/soviet_transradio_front.png b/mods/soviet/textures/soviet_transradio_front.png new file mode 100644 index 0000000..16f0a5d Binary files /dev/null and b/mods/soviet/textures/soviet_transradio_front.png differ diff --git a/mods/soviet/textures/soviet_transradio_left.png b/mods/soviet/textures/soviet_transradio_left.png new file mode 100644 index 0000000..67f569a Binary files /dev/null and b/mods/soviet/textures/soviet_transradio_left.png differ diff --git a/mods/soviet/textures/soviet_transradio_right.png b/mods/soviet/textures/soviet_transradio_right.png new file mode 100644 index 0000000..0c0b94e Binary files /dev/null and b/mods/soviet/textures/soviet_transradio_right.png differ diff --git a/mods/soviet/textures/soviet_transradio_top.png b/mods/soviet/textures/soviet_transradio_top.png new file mode 100644 index 0000000..e04764d Binary files /dev/null and b/mods/soviet/textures/soviet_transradio_top.png differ diff --git a/mods/soviet/textures/soviet_washer_auto.png b/mods/soviet/textures/soviet_washer_auto.png new file mode 100644 index 0000000..6bfa20b Binary files /dev/null and b/mods/soviet/textures/soviet_washer_auto.png differ diff --git a/mods/spawn/README.txt b/mods/spawn/README.txt new file mode 100644 index 0000000..fc16c2a --- /dev/null +++ b/mods/spawn/README.txt @@ -0,0 +1,7 @@ +Minetest Game mod: spawn +======================== +See license.txt for license information. + +Authors of source code +---------------------- +paramat (MIT) diff --git a/mods/spawn/init.lua b/mods/spawn/init.lua new file mode 100644 index 0000000..12c957f --- /dev/null +++ b/mods/spawn/init.lua @@ -0,0 +1,158 @@ +-- spawn/init.lua + +-- Disable by mapgen, setting or if 'static_spawnpoint' is set +-------------------------------------------------------------- + +local mg_name = minetest.get_mapgen_setting("mg_name") +if mg_name == "v6" or mg_name == "singlenode" or + minetest.settings:get("static_spawnpoint") or + minetest.settings:get_bool("engine_spawn") then + return +end + + +-- Parameters +------------- + +-- Resolution of search grid in nodes. +local res = 64 +-- Number of points checked in the square search grid (edge * edge). +local checks = 128 * 128 +-- Starting point for biome checks. This also sets the y co-ordinate for all +-- points checked, so the suitable biomes must be active at this y. +local pos = {x = 0, y = 8, z = 0} + + +-- Table of suitable biomes + +local biome_ids = { + minetest.get_biome_id("taiga"), + minetest.get_biome_id("coniferous_forest"), + minetest.get_biome_id("deciduous_forest"), + minetest.get_biome_id("grassland"), + minetest.get_biome_id("savanna"), +} + +-- End of parameters +-------------------- + + +-- Direction table + +local dirs = { + {x = 0, y = 0, z = 1}, + {x = -1, y = 0, z = 0}, + {x = 0, y = 0, z = -1}, + {x = 1, y = 0, z = 0}, +} + + +-- Initial variables + +local edge_len = 1 +local edge_dist = 0 +local dir_step = 0 +local dir_ind = 1 +local searched = false +local success = false +local spawn_pos = {} + + +-- Get world 'mapgen_limit' and 'chunksize' to calculate 'spawn_limit'. +-- This accounts for how mapchunks are not generated if they or their shell exceed +-- 'mapgen_limit'. + +local mapgen_limit = tonumber(minetest.get_mapgen_setting("mapgen_limit")) +local chunksize = tonumber(minetest.get_mapgen_setting("chunksize")) +local spawn_limit = math.max(mapgen_limit - (chunksize + 1) * 16, 0) + + +--Functions +----------- + +-- Get next position on square search spiral + +local function next_pos() + if edge_dist == edge_len then + edge_dist = 0 + dir_ind = dir_ind + 1 + if dir_ind == 5 then + dir_ind = 1 + end + dir_step = dir_step + 1 + edge_len = math.floor(dir_step / 2) + 1 + end + + local dir = dirs[dir_ind] + local move = vector.multiply(dir, res) + + edge_dist = edge_dist + 1 + + return vector.add(pos, move) +end + + +-- Spawn position search + +local function search() + for iter = 1, checks do + local biome_data = minetest.get_biome_data(pos) + -- Sometimes biome_data is nil + local biome = biome_data and biome_data.biome + for id_ind = 1, #biome_ids do + local biome_id = biome_ids[id_ind] + if biome == biome_id then + local spawn_y = minetest.get_spawn_level(pos.x, pos.z) + if spawn_y then + spawn_pos = {x = pos.x, y = spawn_y, z = pos.z} + return true + end + end + end + + pos = next_pos() + -- Check for position being outside world edge + if math.abs(pos.x) > spawn_limit or math.abs(pos.z) > spawn_limit then + return false + end + end + + return false +end + + +-- On new player spawn and player respawn + +-- Search for spawn position once per server session. If successful, store +-- position and reposition players, otherwise leave them at engine spawn +-- position. + +local function on_spawn(player) + if not searched then + success = search() + searched = true + end + if success then + player:set_pos(spawn_pos) + end + return success +end + +minetest.register_on_newplayer(function(player) + on_spawn(player) +end) + +local enable_bed_respawn = minetest.settings:get_bool("enable_bed_respawn") +if enable_bed_respawn == nil then + enable_bed_respawn = true +end + +minetest.register_on_respawnplayer(function(player) + -- Avoid respawn conflict with beds mod + if beds and enable_bed_respawn and + beds.spawn[player:get_player_name()] then + return + end + + return on_spawn(player) +end) diff --git a/mods/spawn/license.txt b/mods/spawn/license.txt new file mode 100644 index 0000000..a466aab --- /dev/null +++ b/mods/spawn/license.txt @@ -0,0 +1,24 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2018 paramat + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT diff --git a/mods/spawn/mod.conf b/mods/spawn/mod.conf new file mode 100644 index 0000000..ec3d564 --- /dev/null +++ b/mods/spawn/mod.conf @@ -0,0 +1,4 @@ +name = spawn +description = Minetest Game mod: spawn +depends = default +optional_depends = beds diff --git a/mods/stairs/README.txt b/mods/stairs/README.txt new file mode 100644 index 0000000..26317f7 --- /dev/null +++ b/mods/stairs/README.txt @@ -0,0 +1,27 @@ +Minetest Game mod: stairs +========================= +See license.txt for license information. + +Authors of source code +---------------------- +Originally by Kahrl (LGPLv2.1+) and +celeron55, Perttu Ahola (LGPLv2.1+) +Various Minetest developers and contributors (LGPLv2.1+) + +Authors of media (textures) +--------------------------- + +Textures +-------- +Copyright (c) 2018 Shara RedCat (CC BY-SA 3.0): + Derived from a texture by PilzAdam (CC BY-SA 3.0): + stairs_obsidian_glass_outer_stairside.png + stairs_obsidian_glass_stairside.png + +Copyright (c) 2018 TumeniNodes (CC BY-SA 3.0): + Derived from a texture by celeron55 (CC BY-SA 3.0) and + converted to bright white by Krock (CC BY-SA 3.0): + stairs_glass_stairside.png + stairs_glass_split.png + Derived from a texture by PilzAdam (CC BY-SA 3.0): + stairs_obsidian_glass_split.png diff --git a/mods/stairs/init.lua b/mods/stairs/init.lua new file mode 100644 index 0000000..8ce904c --- /dev/null +++ b/mods/stairs/init.lua @@ -0,0 +1,1145 @@ +-- stairs/init.lua + +-- Minetest 0.4 mod: stairs +-- See README.txt for licensing and other information. + + +-- Global namespace for functions + +stairs = {} + +-- Load support for MT game translation. +local S = minetest.get_translator("stairs") +-- Same as S, but will be ignored by translation file update scripts +local T = S + + +-- Register aliases for new pine node names + +minetest.register_alias("stairs:stair_pinewood", "stairs:stair_pine_wood") +minetest.register_alias("stairs:slab_pinewood", "stairs:slab_pine_wood") + + +-- Get setting for replace ABM + +local replace = minetest.settings:get_bool("enable_stairs_replace_abm") + +local function rotate_and_place(itemstack, placer, pointed_thing) + local p0 = pointed_thing.under + local p1 = pointed_thing.above + local param2 = 0 + + if placer then + local placer_pos = placer:get_pos() + if placer_pos then + param2 = minetest.dir_to_facedir(vector.subtract(p1, placer_pos)) + end + + local finepos = minetest.pointed_thing_to_face_pos(placer, pointed_thing) + local fpos = finepos.y % 1 + + if p0.y - 1 == p1.y or (fpos > 0 and fpos < 0.5) + or (fpos < -0.5 and fpos > -0.999999999) then + param2 = param2 + 20 + if param2 == 21 then + param2 = 23 + elseif param2 == 23 then + param2 = 21 + end + end + end + return minetest.item_place(itemstack, placer, pointed_thing, param2) +end + +local function warn_if_exists(nodename) + if minetest.registered_nodes[nodename] then + minetest.log("warning", "Overwriting stairs node: " .. nodename) + end +end + +-- get node settings to use for stairs +local function get_node_vars(nodename) + + local def = minetest.registered_nodes[nodename] + + if def then + return def.light_source, def.use_texture_alpha, def.sunlight_propagates + end + + return nil, nil, nil +end + +-- Register stair +-- Node will be called stairs:stair_ + +function stairs.register_stair(subname, recipeitem, groups, images, description, + sounds, worldaligntex) + local light_source, texture_alpha, sunlight = get_node_vars(recipeitem) + + -- Set backface culling and world-aligned textures + local stair_images = {} + for i, image in ipairs(images) do + if type(image) == "string" then + stair_images[i] = { + name = image, + backface_culling = true, + } + if worldaligntex then + stair_images[i].align_style = "world" + end + else + stair_images[i] = table.copy(image) + if stair_images[i].backface_culling == nil then + stair_images[i].backface_culling = true + end + if worldaligntex and stair_images[i].align_style == nil then + stair_images[i].align_style = "world" + end + end + end + local new_groups = table.copy(groups) + new_groups.stair = 1 + warn_if_exists("stairs:stair_" .. subname) + minetest.register_node(":stairs:stair_" .. subname, { + description = description, + drawtype = "nodebox", + tiles = stair_images, + use_texture_alpha = texture_alpha, + sunlight_propagates = sunlight, + light_source = light_source, + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = false, + groups = new_groups, + sounds = sounds, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.0, 0.5}, + {-0.5, 0.0, 0.0, 0.5, 0.5, 0.5}, + }, + }, + on_place = function(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + + return rotate_and_place(itemstack, placer, pointed_thing) + end, + }) + + -- for replace ABM + if replace then + minetest.register_node(":stairs:stair_" .. subname .. "upside_down", { + replace_name = "stairs:stair_" .. subname, + groups = {slabs_replace = 1}, + }) + end + + if recipeitem then + -- Recipe matches appearence in inventory + minetest.register_craft({ + output = "stairs:stair_" .. subname .. " 8", + recipe = { + {"", "", recipeitem}, + {"", recipeitem, recipeitem}, + {recipeitem, recipeitem, recipeitem}, + }, + }) + + -- Use stairs to craft full blocks again (1:1) + minetest.register_craft({ + output = recipeitem .. " 3", + recipe = { + {"stairs:stair_" .. subname, "stairs:stair_" .. subname}, + {"stairs:stair_" .. subname, "stairs:stair_" .. subname}, + }, + }) + + -- Fuel + local baseburntime = minetest.get_craft_result({ + method = "fuel", + width = 1, + items = {recipeitem} + }).time + if baseburntime > 0 then + minetest.register_craft({ + type = "fuel", + recipe = "stairs:stair_" .. subname, + burntime = math.floor(baseburntime * 0.75), + }) + end + end +end + + +-- Register slab +-- Node will be called stairs:slab_ + +function stairs.register_slab(subname, recipeitem, groups, images, description, + sounds, worldaligntex) + local light_source, texture_alpha, sunlight = get_node_vars(recipeitem) + + -- Set world-aligned textures + local slab_images = {} + for i, image in ipairs(images) do + if type(image) == "string" then + slab_images[i] = { + name = image, + } + if worldaligntex then + slab_images[i].align_style = "world" + end + else + slab_images[i] = table.copy(image) + if worldaligntex and image.align_style == nil then + slab_images[i].align_style = "world" + end + end + end + local new_groups = table.copy(groups) + new_groups.slab = 1 + warn_if_exists("stairs:slab_" .. subname) + minetest.register_node(":stairs:slab_" .. subname, { + description = description, + drawtype = "nodebox", + tiles = slab_images, + use_texture_alpha = texture_alpha, + sunlight_propagates = sunlight, + light_source = light_source, + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = false, + groups = new_groups, + sounds = sounds, + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + }, + on_place = function(itemstack, placer, pointed_thing) + local under = minetest.get_node(pointed_thing.under) + local wield_item = itemstack:get_name() + local player_name = placer and placer:get_player_name() or "" + + if under and under.name:find("^stairs:slab_") then + -- place slab using under node orientation + local dir = minetest.dir_to_facedir(vector.subtract( + pointed_thing.above, pointed_thing.under), true) + + local p2 = under.param2 + + -- Placing a slab on an upside down slab should make it right-side up. + if p2 >= 20 and dir == 8 then + p2 = p2 - 20 + -- same for the opposite case: slab below normal slab + elseif p2 <= 3 and dir == 4 then + p2 = p2 + 20 + end + + -- else attempt to place node with proper param2 + minetest.item_place_node(ItemStack(wield_item), placer, pointed_thing, p2) + if not minetest.is_creative_enabled(player_name) then + itemstack:take_item() + end + return itemstack + else + return rotate_and_place(itemstack, placer, pointed_thing) + end + end, + }) + + -- for replace ABM + if replace then + minetest.register_node(":stairs:slab_" .. subname .. "upside_down", { + replace_name = "stairs:slab_".. subname, + groups = {slabs_replace = 1}, + }) + end + + if recipeitem then + minetest.register_craft({ + output = "stairs:slab_" .. subname .. " 6", + recipe = { + {recipeitem, recipeitem, recipeitem}, + }, + }) + + -- Use 2 slabs to craft a full block again (1:1) + minetest.register_craft({ + output = recipeitem, + recipe = { + {"stairs:slab_" .. subname}, + {"stairs:slab_" .. subname}, + }, + }) + + -- Fuel + local baseburntime = minetest.get_craft_result({ + method = "fuel", + width = 1, + items = {recipeitem} + }).time + if baseburntime > 0 then + minetest.register_craft({ + type = "fuel", + recipe = "stairs:slab_" .. subname, + burntime = math.floor(baseburntime * 0.5), + }) + end + end +end + + +-- Optionally replace old "upside_down" nodes with new param2 versions. +-- Disabled by default. + +if replace then + minetest.register_abm({ + label = "Slab replace", + nodenames = {"group:slabs_replace"}, + interval = 16, + chance = 1, + action = function(pos, node) + node.name = minetest.registered_nodes[node.name].replace_name + node.param2 = node.param2 + 20 + if node.param2 == 21 then + node.param2 = 23 + elseif node.param2 == 23 then + node.param2 = 21 + end + minetest.set_node(pos, node) + end, + }) +end + + +-- Register inner stair +-- Node will be called stairs:stair_inner_ + +function stairs.register_stair_inner(subname, recipeitem, groups, images, + description, sounds, worldaligntex, full_description) + local light_source, texture_alpha, sunlight = get_node_vars(recipeitem) + + -- Set backface culling and world-aligned textures + local stair_images = {} + for i, image in ipairs(images) do + if type(image) == "string" then + stair_images[i] = { + name = image, + backface_culling = true, + } + if worldaligntex then + stair_images[i].align_style = "world" + end + else + stair_images[i] = table.copy(image) + if stair_images[i].backface_culling == nil then + stair_images[i].backface_culling = true + end + if worldaligntex and stair_images[i].align_style == nil then + stair_images[i].align_style = "world" + end + end + end + local new_groups = table.copy(groups) + new_groups.stair = 1 + if full_description then + description = full_description + else + description = "Inner " .. description + end + warn_if_exists("stairs:stair_inner_" .. subname) + minetest.register_node(":stairs:stair_inner_" .. subname, { + description = description, + drawtype = "nodebox", + tiles = stair_images, + use_texture_alpha = texture_alpha, + sunlight_propagates = sunlight, + light_source = light_source, + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = false, + groups = new_groups, + sounds = sounds, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.0, 0.5}, + {-0.5, 0.0, 0.0, 0.5, 0.5, 0.5}, + {-0.5, 0.0, -0.5, 0.0, 0.5, 0.0}, + }, + }, + on_place = function(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + + return rotate_and_place(itemstack, placer, pointed_thing) + end, + }) + + if recipeitem then + minetest.register_craft({ + output = "stairs:stair_inner_" .. subname .. " 7", + recipe = { + {"", recipeitem, ""}, + {recipeitem, "", recipeitem}, + {recipeitem, recipeitem, recipeitem}, + }, + }) + + -- Fuel + local baseburntime = minetest.get_craft_result({ + method = "fuel", + width = 1, + items = {recipeitem} + }).time + if baseburntime > 0 then + minetest.register_craft({ + type = "fuel", + recipe = "stairs:stair_inner_" .. subname, + burntime = math.floor(baseburntime * 0.875), + }) + end + end +end + + +-- Register outer stair +-- Node will be called stairs:stair_outer_ + +function stairs.register_stair_outer(subname, recipeitem, groups, images, + description, sounds, worldaligntex, full_description) + local light_source, texture_alpha, sunlight = get_node_vars(recipeitem) + + -- Set backface culling and world-aligned textures + local stair_images = {} + for i, image in ipairs(images) do + if type(image) == "string" then + stair_images[i] = { + name = image, + backface_culling = true, + } + if worldaligntex then + stair_images[i].align_style = "world" + end + else + stair_images[i] = table.copy(image) + if stair_images[i].backface_culling == nil then + stair_images[i].backface_culling = true + end + if worldaligntex and stair_images[i].align_style == nil then + stair_images[i].align_style = "world" + end + end + end + local new_groups = table.copy(groups) + new_groups.stair = 1 + if full_description then + description = full_description + else + description = "Outer " .. description + end + warn_if_exists("stairs:stair_outer_" .. subname) + minetest.register_node(":stairs:stair_outer_" .. subname, { + description = description, + drawtype = "nodebox", + tiles = stair_images, + use_texture_alpha = texture_alpha, + sunlight_propagates = sunlight, + light_source = light_source, + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = false, + groups = new_groups, + sounds = sounds, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.0, 0.5}, + {-0.5, 0.0, 0.0, 0.0, 0.5, 0.5}, + }, + }, + on_place = function(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + + return rotate_and_place(itemstack, placer, pointed_thing) + end, + }) + + if recipeitem then + minetest.register_craft({ + output = "stairs:stair_outer_" .. subname .. " 6", + recipe = { + {"", recipeitem, ""}, + {recipeitem, recipeitem, recipeitem}, + }, + }) + + -- Fuel + local baseburntime = minetest.get_craft_result({ + method = "fuel", + width = 1, + items = {recipeitem} + }).time + if baseburntime > 0 then + minetest.register_craft({ + type = "fuel", + recipe = "stairs:stair_outer_" .. subname, + burntime = math.floor(baseburntime * 0.625), + }) + end + end +end + + +-- Stair/slab registration function. +-- Nodes will be called stairs:{stair,slab}_ + +function stairs.register_stair_and_slab(subname, recipeitem, groups, images, + desc_stair, desc_slab, sounds, worldaligntex, + desc_stair_inner, desc_stair_outer) + stairs.register_stair(subname, recipeitem, groups, images, desc_stair, + sounds, worldaligntex) + stairs.register_stair_inner(subname, recipeitem, groups, images, + desc_stair, sounds, worldaligntex, desc_stair_inner) + stairs.register_stair_outer(subname, recipeitem, groups, images, + desc_stair, sounds, worldaligntex, desc_stair_outer) + stairs.register_slab(subname, recipeitem, groups, images, desc_slab, + sounds, worldaligntex) +end + +-- Local function so we can apply translations +local function my_register_stair_and_slab(subname, recipeitem, groups, images, + desc_stair, desc_slab, sounds, worldaligntex) + stairs.register_stair(subname, recipeitem, groups, images, S(desc_stair), + sounds, worldaligntex) + stairs.register_stair_inner(subname, recipeitem, groups, images, "", + sounds, worldaligntex, T("Inner " .. desc_stair)) + stairs.register_stair_outer(subname, recipeitem, groups, images, "", + sounds, worldaligntex, T("Outer " .. desc_stair)) + stairs.register_slab(subname, recipeitem, groups, images, S(desc_slab), + sounds, worldaligntex) +end + + +-- Register default stairs and slabs +--[[ +my_register_stair_and_slab( + "wood", + "default:wood", + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + {"default_wood.png"}, + "Wooden Stair", + "Wooden Slab", + default.node_sound_wood_defaults(), + false +) + +my_register_stair_and_slab( + "junglewood", + "default:junglewood", + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + {"default_junglewood.png"}, + "Jungle Wood Stair", + "Jungle Wood Slab", + default.node_sound_wood_defaults(), + false +) + +my_register_stair_and_slab( + "pine_wood", + "default:pine_wood", + {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + {"default_pine_wood.png"}, + "Pine Wood Stair", + "Pine Wood Slab", + default.node_sound_wood_defaults(), + false +) + +my_register_stair_and_slab( + "acacia_wood", + "default:acacia_wood", + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + {"default_acacia_wood.png"}, + "Acacia Wood Stair", + "Acacia Wood Slab", + default.node_sound_wood_defaults(), + false +) + +my_register_stair_and_slab( + "aspen_wood", + "default:aspen_wood", + {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + {"default_aspen_wood.png"}, + "Aspen Wood Stair", + "Aspen Wood Slab", + default.node_sound_wood_defaults(), + false +) + +my_register_stair_and_slab( + "stone", + "default:stone", + {cracky = 3}, + {"default_stone.png"}, + "Stone Stair", + "Stone Slab", + default.node_sound_stone_defaults(), + true +) + +my_register_stair_and_slab( + "cobble", + "default:cobble", + {cracky = 3}, + {"default_cobble.png"}, + "Cobblestone Stair", + "Cobblestone Slab", + default.node_sound_stone_defaults(), + true +) + +my_register_stair_and_slab( + "mossycobble", + "default:mossycobble", + {cracky = 3}, + {"default_mossycobble.png"}, + "Mossy Cobblestone Stair", + "Mossy Cobblestone Slab", + default.node_sound_stone_defaults(), + true +) + +my_register_stair_and_slab( + "stonebrick", + "default:stonebrick", + {cracky = 2}, + {"default_stone_brick.png"}, + "Stone Brick Stair", + "Stone Brick Slab", + default.node_sound_stone_defaults(), + false +) + +my_register_stair_and_slab( + "stone_block", + "default:stone_block", + {cracky = 2}, + {"default_stone_block.png"}, + "Stone Block Stair", + "Stone Block Slab", + default.node_sound_stone_defaults(), + true +) + +my_register_stair_and_slab( + "desert_stone", + "default:desert_stone", + {cracky = 3}, + {"default_desert_stone.png"}, + "Desert Stone Stair", + "Desert Stone Slab", + default.node_sound_stone_defaults(), + true +) + +my_register_stair_and_slab( + "desert_cobble", + "default:desert_cobble", + {cracky = 3}, + {"default_desert_cobble.png"}, + "Desert Cobblestone Stair", + "Desert Cobblestone Slab", + default.node_sound_stone_defaults(), + true +) + +my_register_stair_and_slab( + "desert_stonebrick", + "default:desert_stonebrick", + {cracky = 2}, + {"default_desert_stone_brick.png"}, + "Desert Stone Brick Stair", + "Desert Stone Brick Slab", + default.node_sound_stone_defaults(), + false +) + +my_register_stair_and_slab( + "desert_stone_block", + "default:desert_stone_block", + {cracky = 2}, + {"default_desert_stone_block.png"}, + "Desert Stone Block Stair", + "Desert Stone Block Slab", + default.node_sound_stone_defaults(), + true +) + +my_register_stair_and_slab( + "sandstone", + "default:sandstone", + {crumbly = 1, cracky = 3}, + {"default_sandstone.png"}, + "Sandstone Stair", + "Sandstone Slab", + default.node_sound_stone_defaults(), + true +) + +my_register_stair_and_slab( + "sandstonebrick", + "default:sandstonebrick", + {cracky = 2}, + {"default_sandstone_brick.png"}, + "Sandstone Brick Stair", + "Sandstone Brick Slab", + default.node_sound_stone_defaults(), + false +) + +my_register_stair_and_slab( + "sandstone_block", + "default:sandstone_block", + {cracky = 2}, + {"default_sandstone_block.png"}, + "Sandstone Block Stair", + "Sandstone Block Slab", + default.node_sound_stone_defaults(), + true +) + +my_register_stair_and_slab( + "desert_sandstone", + "default:desert_sandstone", + {crumbly = 1, cracky = 3}, + {"default_desert_sandstone.png"}, + "Desert Sandstone Stair", + "Desert Sandstone Slab", + default.node_sound_stone_defaults(), + true +) + +my_register_stair_and_slab( + "desert_sandstone_brick", + "default:desert_sandstone_brick", + {cracky = 2}, + {"default_desert_sandstone_brick.png"}, + "Desert Sandstone Brick Stair", + "Desert Sandstone Brick Slab", + default.node_sound_stone_defaults(), + false +) + +my_register_stair_and_slab( + "desert_sandstone_block", + "default:desert_sandstone_block", + {cracky = 2}, + {"default_desert_sandstone_block.png"}, + "Desert Sandstone Block Stair", + "Desert Sandstone Block Slab", + default.node_sound_stone_defaults(), + true +) + +my_register_stair_and_slab( + "silver_sandstone", + "default:silver_sandstone", + {crumbly = 1, cracky = 3}, + {"default_silver_sandstone.png"}, + "Silver Sandstone Stair", + "Silver Sandstone Slab", + default.node_sound_stone_defaults(), + true +) + +my_register_stair_and_slab( + "silver_sandstone_brick", + "default:silver_sandstone_brick", + {cracky = 2}, + {"default_silver_sandstone_brick.png"}, + "Silver Sandstone Brick Stair", + "Silver Sandstone Brick Slab", + default.node_sound_stone_defaults(), + false +) + +my_register_stair_and_slab( + "silver_sandstone_block", + "default:silver_sandstone_block", + {cracky = 2}, + {"default_silver_sandstone_block.png"}, + "Silver Sandstone Block Stair", + "Silver Sandstone Block Slab", + default.node_sound_stone_defaults(), + true +) + +my_register_stair_and_slab( + "obsidian", + "default:obsidian", + {cracky = 1, level = 2}, + {"default_obsidian.png"}, + "Obsidian Stair", + "Obsidian Slab", + default.node_sound_stone_defaults(), + true +) + +my_register_stair_and_slab( + "obsidianbrick", + "default:obsidianbrick", + {cracky = 1, level = 2}, + {"default_obsidian_brick.png"}, + "Obsidian Brick Stair", + "Obsidian Brick Slab", + default.node_sound_stone_defaults(), + false +) + +my_register_stair_and_slab( + "obsidian_block", + "default:obsidian_block", + {cracky = 1, level = 2}, + {"default_obsidian_block.png"}, + "Obsidian Block Stair", + "Obsidian Block Slab", + default.node_sound_stone_defaults(), + true +) + +my_register_stair_and_slab( + "brick", + "default:brick", + {cracky = 3}, + {"default_brick.png"}, + "Brick Stair", + "Brick Slab", + default.node_sound_stone_defaults(), + false +) + +my_register_stair_and_slab( + "steelblock", + "default:steelblock", + {cracky = 1, level = 2}, + {"default_steel_block.png"}, + "Steel Block Stair", + "Steel Block Slab", + default.node_sound_metal_defaults(), + true +) + +my_register_stair_and_slab( + "tinblock", + "default:tinblock", + {cracky = 1, level = 2}, + {"default_tin_block.png"}, + "Tin Block Stair", + "Tin Block Slab", + default.node_sound_metal_defaults(), + true +) + +my_register_stair_and_slab( + "copperblock", + "default:copperblock", + {cracky = 1, level = 2}, + {"default_copper_block.png"}, + "Copper Block Stair", + "Copper Block Slab", + default.node_sound_metal_defaults(), + true +) + +my_register_stair_and_slab( + "bronzeblock", + "default:bronzeblock", + {cracky = 1, level = 2}, + {"default_bronze_block.png"}, + "Bronze Block Stair", + "Bronze Block Slab", + default.node_sound_metal_defaults(), + true +) + +my_register_stair_and_slab( + "goldblock", + "default:goldblock", + {cracky = 1}, + {"default_gold_block.png"}, + "Gold Block Stair", + "Gold Block Slab", + default.node_sound_metal_defaults(), + true +) + +my_register_stair_and_slab( + "ice", + "default:ice", + {cracky = 3, cools_lava = 1, slippery = 3}, + {"default_ice.png"}, + "Ice Stair", + "Ice Slab", + default.node_sound_ice_defaults(), + true +) + +my_register_stair_and_slab( + "snowblock", + "default:snowblock", + {crumbly = 3, cools_lava = 1, snowy = 1}, + {"default_snow.png"}, + "Snow Block Stair", + "Snow Block Slab", + default.node_sound_snow_defaults(), + true +) + +-- Glass stair nodes need to be registered individually to utilize specialized textures. + +stairs.register_stair( + "glass", + "default:glass", + {cracky = 3, oddly_breakable_by_hand = 3}, + {"stairs_glass_split.png", "default_glass.png", + "stairs_glass_stairside.png^[transformFX", "stairs_glass_stairside.png", + "default_glass.png", "stairs_glass_split.png"}, + S("Glass Stair"), + default.node_sound_glass_defaults(), + false +) + +stairs.register_slab( + "glass", + "default:glass", + {cracky = 3, oddly_breakable_by_hand = 3}, + {"default_glass.png", "default_glass.png", "stairs_glass_split.png"}, + S("Glass Slab"), + default.node_sound_glass_defaults(), + false +) + +stairs.register_stair_inner( + "glass", + "default:glass", + {cracky = 3, oddly_breakable_by_hand = 3}, + {"stairs_glass_stairside.png^[transformR270", "default_glass.png", + "stairs_glass_stairside.png^[transformFX", "default_glass.png", + "default_glass.png", "stairs_glass_stairside.png"}, + "", + default.node_sound_glass_defaults(), + false, + S("Inner Glass Stair") +) + +stairs.register_stair_outer( + "glass", + "default:glass", + {cracky = 3, oddly_breakable_by_hand = 3}, + {"stairs_glass_stairside.png^[transformR90", "default_glass.png", + "stairs_glass_outer_stairside.png", "stairs_glass_stairside.png", + "stairs_glass_stairside.png^[transformR90","stairs_glass_outer_stairside.png"}, + "", + default.node_sound_glass_defaults(), + false, + S("Outer Glass Stair") +) + +stairs.register_stair( + "obsidian_glass", + "default:obsidian_glass", + {cracky = 3}, + {"stairs_obsidian_glass_split.png", "default_obsidian_glass.png", + "stairs_obsidian_glass_stairside.png^[transformFX", "stairs_obsidian_glass_stairside.png", + "default_obsidian_glass.png", "stairs_obsidian_glass_split.png"}, + S("Obsidian Glass Stair"), + default.node_sound_glass_defaults(), + false +) + +stairs.register_slab( + "obsidian_glass", + "default:obsidian_glass", + {cracky = 3}, + {"default_obsidian_glass.png", "default_obsidian_glass.png", "stairs_obsidian_glass_split.png"}, + S("Obsidian Glass Slab"), + default.node_sound_glass_defaults(), + false +) + +stairs.register_stair_inner( + "obsidian_glass", + "default:obsidian_glass", + {cracky = 3}, + {"stairs_obsidian_glass_stairside.png^[transformR270", "default_obsidian_glass.png", + "stairs_obsidian_glass_stairside.png^[transformFX", "default_obsidian_glass.png", + "default_obsidian_glass.png", "stairs_obsidian_glass_stairside.png"}, + "", + default.node_sound_glass_defaults(), + false, + S("Inner Obsidian Glass Stair") +) + +stairs.register_stair_outer( + "obsidian_glass", + "default:obsidian_glass", + {cracky = 3}, + {"stairs_obsidian_glass_stairside.png^[transformR90", "default_obsidian_glass.png", + "stairs_obsidian_glass_outer_stairside.png", "stairs_obsidian_glass_stairside.png", + "stairs_obsidian_glass_stairside.png^[transformR90","stairs_obsidian_glass_outer_stairside.png"}, + "", + default.node_sound_glass_defaults(), + false, + S("Outer Obsidian Glass Stair") +) +]] + +-- Dummy calls to S() to allow translation scripts to detect the strings. +-- To update this add this code to my_register_stair_and_slab: +-- for _,x in ipairs({"","Inner ","Outer "}) do print(("S(%q)"):format(x..desc_stair)) end +-- print(("S(%q)"):format(desc_slab)) + +--[[ +S("Wooden Stair") +S("Inner Wooden Stair") +S("Outer Wooden Stair") +S("Wooden Slab") +S("Jungle Wood Stair") +S("Inner Jungle Wood Stair") +S("Outer Jungle Wood Stair") +S("Jungle Wood Slab") +S("Pine Wood Stair") +S("Inner Pine Wood Stair") +S("Outer Pine Wood Stair") +S("Pine Wood Slab") +S("Acacia Wood Stair") +S("Inner Acacia Wood Stair") +S("Outer Acacia Wood Stair") +S("Acacia Wood Slab") +S("Aspen Wood Stair") +S("Inner Aspen Wood Stair") +S("Outer Aspen Wood Stair") +S("Aspen Wood Slab") +S("Stone Stair") +S("Inner Stone Stair") +S("Outer Stone Stair") +S("Stone Slab") +S("Cobblestone Stair") +S("Inner Cobblestone Stair") +S("Outer Cobblestone Stair") +S("Cobblestone Slab") +S("Mossy Cobblestone Stair") +S("Inner Mossy Cobblestone Stair") +S("Outer Mossy Cobblestone Stair") +S("Mossy Cobblestone Slab") +S("Stone Brick Stair") +S("Inner Stone Brick Stair") +S("Outer Stone Brick Stair") +S("Stone Brick Slab") +S("Stone Block Stair") +S("Inner Stone Block Stair") +S("Outer Stone Block Stair") +S("Stone Block Slab") +S("Desert Stone Stair") +S("Inner Desert Stone Stair") +S("Outer Desert Stone Stair") +S("Desert Stone Slab") +S("Desert Cobblestone Stair") +S("Inner Desert Cobblestone Stair") +S("Outer Desert Cobblestone Stair") +S("Desert Cobblestone Slab") +S("Desert Stone Brick Stair") +S("Inner Desert Stone Brick Stair") +S("Outer Desert Stone Brick Stair") +S("Desert Stone Brick Slab") +S("Desert Stone Block Stair") +S("Inner Desert Stone Block Stair") +S("Outer Desert Stone Block Stair") +S("Desert Stone Block Slab") +S("Sandstone Stair") +S("Inner Sandstone Stair") +S("Outer Sandstone Stair") +S("Sandstone Slab") +S("Sandstone Brick Stair") +S("Inner Sandstone Brick Stair") +S("Outer Sandstone Brick Stair") +S("Sandstone Brick Slab") +S("Sandstone Block Stair") +S("Inner Sandstone Block Stair") +S("Outer Sandstone Block Stair") +S("Sandstone Block Slab") +S("Desert Sandstone Stair") +S("Inner Desert Sandstone Stair") +S("Outer Desert Sandstone Stair") +S("Desert Sandstone Slab") +S("Desert Sandstone Brick Stair") +S("Inner Desert Sandstone Brick Stair") +S("Outer Desert Sandstone Brick Stair") +S("Desert Sandstone Brick Slab") +S("Desert Sandstone Block Stair") +S("Inner Desert Sandstone Block Stair") +S("Outer Desert Sandstone Block Stair") +S("Desert Sandstone Block Slab") +S("Silver Sandstone Stair") +S("Inner Silver Sandstone Stair") +S("Outer Silver Sandstone Stair") +S("Silver Sandstone Slab") +S("Silver Sandstone Brick Stair") +S("Inner Silver Sandstone Brick Stair") +S("Outer Silver Sandstone Brick Stair") +S("Silver Sandstone Brick Slab") +S("Silver Sandstone Block Stair") +S("Inner Silver Sandstone Block Stair") +S("Outer Silver Sandstone Block Stair") +S("Silver Sandstone Block Slab") +S("Obsidian Stair") +S("Inner Obsidian Stair") +S("Outer Obsidian Stair") +S("Obsidian Slab") +S("Obsidian Brick Stair") +S("Inner Obsidian Brick Stair") +S("Outer Obsidian Brick Stair") +S("Obsidian Brick Slab") +S("Obsidian Block Stair") +S("Inner Obsidian Block Stair") +S("Outer Obsidian Block Stair") +S("Obsidian Block Slab") +S("Brick Stair") +S("Inner Brick Stair") +S("Outer Brick Stair") +S("Brick Slab") +S("Steel Block Stair") +S("Inner Steel Block Stair") +S("Outer Steel Block Stair") +S("Steel Block Slab") +S("Tin Block Stair") +S("Inner Tin Block Stair") +S("Outer Tin Block Stair") +S("Tin Block Slab") +S("Copper Block Stair") +S("Inner Copper Block Stair") +S("Outer Copper Block Stair") +S("Copper Block Slab") +S("Bronze Block Stair") +S("Inner Bronze Block Stair") +S("Outer Bronze Block Stair") +S("Bronze Block Slab") +S("Gold Block Stair") +S("Inner Gold Block Stair") +S("Outer Gold Block Stair") +S("Gold Block Slab") +S("Ice Stair") +S("Inner Ice Stair") +S("Outer Ice Stair") +S("Ice Slab") +S("Snow Block Stair") +S("Inner Snow Block Stair") +S("Outer Snow Block Stair") +S("Snow Block Slab") +--]] diff --git a/mods/stairs/license.txt b/mods/stairs/license.txt new file mode 100644 index 0000000..57bd98c --- /dev/null +++ b/mods/stairs/license.txt @@ -0,0 +1,16 @@ +License of source code +---------------------- + +GNU Lesser General Public License, version 2.1 +Copyright (C) 2011-2017 Kahrl +Copyright (C) 2011-2017 celeron55, Perttu Ahola +Copyright (C) 2012-2017 Various Minetest developers and contributors + +This program is free software; you can redistribute it and/or modify it under the terms +of the GNU Lesser General Public License as published by the Free Software Foundation; +either version 2.1 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU Lesser General Public License for more details: +https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html diff --git a/mods/stairs/locale/stairs.de.tr b/mods/stairs/locale/stairs.de.tr new file mode 100644 index 0000000..beb4579 --- /dev/null +++ b/mods/stairs/locale/stairs.de.tr @@ -0,0 +1,145 @@ +# textdomain: stairs +Glass Stair=Glastreppe +Glass Slab=Glasplatte +Inner Glass Stair=Innere Glastreppe +Outer Glass Stair=Äußere Glastreppe +Obsidian Glass Stair=Obsidianglastreppe +Obsidian Glass Slab=Obsidianglasplatte +Inner Obsidian Glass Stair=Innere Obsidianglastreppe +Outer Obsidian Glass Stair=Äußere Obsidianglastreppe +Wooden Stair=Holztreppe +Inner Wooden Stair=Innere Holztreppe +Outer Wooden Stair=Äußere Holztreppe +Wooden Slab=Holzplatte +Jungle Wood Stair=Dschungelholztreppe +Inner Jungle Wood Stair=Innere Dschungelholztreppe +Outer Jungle Wood Stair=Äußere Dschungelholztreppe +Jungle Wood Slab=Dschungelholzplatte +Pine Wood Stair=Kiefernholztreppe +Inner Pine Wood Stair=Innere Kiefernholztreppe +Outer Pine Wood Stair=Äußere Kiefernholztreppe +Pine Wood Slab=Kiefernholzplatte +Acacia Wood Stair=Akazienholztreppe +Inner Acacia Wood Stair=Innere Akazienholztreppe +Outer Acacia Wood Stair=Äußere Akazienholztreppe +Acacia Wood Slab=Akazienholzplatte +Aspen Wood Stair=Espenholztreppe +Inner Aspen Wood Stair=Innere Espenholztreppe +Outer Aspen Wood Stair=Äußere Espenholztreppe +Aspen Wood Slab=Espenholzplatte +Stone Stair=Steintreppe +Inner Stone Stair=Innere Steintreppe +Outer Stone Stair=Äußere Steintreppe +Stone Slab=Steinplatte +Cobblestone Stair=Kopfsteinpflastertreppe +Inner Cobblestone Stair=Innere Kopfsteinpflastertreppe +Outer Cobblestone Stair=Äußere Kopfsteinpflastertreppe +Cobblestone Slab=Kopfsteinpflasterplatte +Mossy Cobblestone Stair=Moosige Kopfsteinpflastertreppe +Inner Mossy Cobblestone Stair=Innere moosige Kopfsteinpflastertreppe +Outer Mossy Cobblestone Stair=Äußere moosige Kopfsteinpflastertreppe +Mossy Cobblestone Slab=Moosige Kopfsteinpflasterplatte +Stone Brick Stair=Steinziegeltreppe +Inner Stone Brick Stair=Innere Steinziegeltreppe +Outer Stone Brick Stair=Äußere Steinziegeltreppe +Stone Brick Slab=Steinziegelplatte +Stone Block Stair=Steinblocktreppe +Inner Stone Block Stair=Innere Steinblocktreppe +Outer Stone Block Stair=Äußere Steinblocktreppe +Stone Block Slab=Steinblockplatte +Desert Stone Stair=Wüstensteintreppe +Inner Desert Stone Stair=Innere Wüstensteintreppe +Outer Desert Stone Stair=Äußere Wüstensteintreppe +Desert Stone Slab=Wüstensteinplatte +Desert Cobblestone Stair=Wüstenkopfsteinpflastertreppe +Inner Desert Cobblestone Stair=Innere Wüstenkopfsteinpflastertreppe +Outer Desert Cobblestone Stair=Äußere Wüstenkopfsteinpflastertreppe +Desert Cobblestone Slab=Wüstenkopfsteinpflasterplatte +Desert Stone Brick Stair=Wüstensteinziegeltreppe +Inner Desert Stone Brick Stair=Innere Wüstensteinziegeltreppe +Outer Desert Stone Brick Stair=Äußere Wüstensteinziegeltreppe +Desert Stone Brick Slab=Wüstensteinziegelplatte +Desert Stone Block Stair=Wüstensteinblocktreppe +Inner Desert Stone Block Stair=Innere Wüstensteinblocktreppe +Outer Desert Stone Block Stair=Äußere Wüstensteinblocktreppe +Desert Stone Block Slab=Wüstensteinblockplatte +Sandstone Stair=Sandsteintreppe +Inner Sandstone Stair=Innere Sandsteintreppe +Outer Sandstone Stair=Äußere Sandsteintreppe +Sandstone Slab=Sandsteinplatte +Sandstone Brick Stair=Sandsteinziegeltreppe +Inner Sandstone Brick Stair=Innere Sandsteinziegeltreppe +Outer Sandstone Brick Stair=Äußere Sandsteinziegeltreppe +Sandstone Brick Slab=Sandsteinziegelplatte +Sandstone Block Stair=Sandsteinblocktreppe +Inner Sandstone Block Stair=Innere Sandsteinblocktreppe +Outer Sandstone Block Stair=Äußere Sandsteinblocktreppe +Sandstone Block Slab=Sandsteinblockplatte +Desert Sandstone Stair=Wüstensandsteintreppe +Inner Desert Sandstone Stair=Innere Wüstensandsteintreppe +Outer Desert Sandstone Stair=Äußere Wüstensandsteintreppe +Desert Sandstone Slab=Wüstensandsteinplatte +Desert Sandstone Brick Stair=Wüstensandsteinziegeltreppe +Inner Desert Sandstone Brick Stair=Innere Wüstensandsteinziegeltreppe +Outer Desert Sandstone Brick Stair=Äußere Wüstensandsteinziegeltreppe +Desert Sandstone Brick Slab=Wüstensandsteinziegelplatte +Desert Sandstone Block Stair=Wüstensandsteinblocktreppe +Inner Desert Sandstone Block Stair=Innere Wüstensandsteinblocktreppe +Outer Desert Sandstone Block Stair=Äußere Wüstensandsteinblocktreppe +Desert Sandstone Block Slab=Wüstensandsteinblockplatte +Silver Sandstone Stair=Silbersandsteintreppe +Inner Silver Sandstone Stair=Innere Silbersandsteintreppe +Outer Silver Sandstone Stair=Äußere Silbersandsteintreppe +Silver Sandstone Slab=Silbersandsteinplatte +Silver Sandstone Brick Stair=Silbersandsteinziegeltreppe +Inner Silver Sandstone Brick Stair=Innere Silbersandsteinziegeltreppe +Outer Silver Sandstone Brick Stair=Äußere Silbersandsteinziegeltreppe +Silver Sandstone Brick Slab=Silbersandsteinziegelplatte +Silver Sandstone Block Stair=Silbersandsteinblocktreppe +Inner Silver Sandstone Block Stair=Innere Silbersandsteinblocktreppe +Outer Silver Sandstone Block Stair=Äußere Silbersandsteinblocktreppe +Silver Sandstone Block Slab=Silbersandsteinblockplatte +Obsidian Stair=Obsidiantreppe +Inner Obsidian Stair=Innere Obsidiantreppe +Outer Obsidian Stair=Äußere Obsidiantreppe +Obsidian Slab=Obsidianplatte +Obsidian Brick Stair=Obsidianziegeltreppe +Inner Obsidian Brick Stair=Innere Obsidianziegeltreppe +Outer Obsidian Brick Stair=Äußere Obsidianziegeltreppe +Obsidian Brick Slab=Obsidianziegelplatte +Obsidian Block Stair=Obsidianblocktreppe +Inner Obsidian Block Stair=Innere Obsidianblocktreppe +Outer Obsidian Block Stair=Äußere Obsidianblocktreppe +Obsidian Block Slab=Obsidianblockplatte +Brick Stair=Ziegeltreppe +Inner Brick Stair=Innere Ziegeltreppe +Outer Brick Stair=Äußere Ziegeltreppe +Brick Slab=Ziegelplatte +Steel Block Stair=Stahlblocktreppe +Inner Steel Block Stair=Innere Stahlblocktreppe +Outer Steel Block Stair=Äußere Stahlblocktreppe +Steel Block Slab=Stahlblockplatte +Tin Block Stair=Zinnblocktreppe +Inner Tin Block Stair=Innere Zinnblocktreppe +Outer Tin Block Stair=Äußere Zinnblocktreppe +Tin Block Slab=Zinnblockplatte +Copper Block Stair=Kupferblocktreppe +Inner Copper Block Stair=Innere Kupferblocktreppe +Outer Copper Block Stair=Äußere Kupferblocktreppe +Copper Block Slab=Kupferblockplatte +Bronze Block Stair=Bronzeblocktreppe +Inner Bronze Block Stair=Innere Bronzeblocktreppe +Outer Bronze Block Stair=Äußere Bronzeblocktreppe +Bronze Block Slab=Bronzeblockplatte +Gold Block Stair=Goldblocktreppe +Inner Gold Block Stair=Innere Goldblocktreppe +Outer Gold Block Stair=Äußere Goldblocktreppe +Gold Block Slab=Goldblockplatte +Ice Stair=Eistreppe +Inner Ice Stair=Innere Eistreppe +Outer Ice Stair=Äußere Eistreppe +Ice Slab=Eisplatte +Snow Block Stair=Schneeblocktreppe +Inner Snow Block Stair=Innere Schneeblocktreppe +Outer Snow Block Stair=Äußere Schneeblocktreppe +Snow Block Slab=Schneeblockplatte diff --git a/mods/stairs/locale/stairs.eo.tr b/mods/stairs/locale/stairs.eo.tr new file mode 100644 index 0000000..078cc9c --- /dev/null +++ b/mods/stairs/locale/stairs.eo.tr @@ -0,0 +1,145 @@ +# textdomain: stairs +Glass Stair=Vitra Ŝtupo +Glass Slab=Vitra Plato +Inner Glass Stair=Interna Vitra Ŝtupo +Outer Glass Stair=Ekstera Vitra Ŝtupo +Obsidian Glass Stair=Obsidiana Vitra Ŝtupo +Obsidian Glass Slab=Obsidiana Vitra Plato +Inner Obsidian Glass Stair=Interna Obsidiana Vitra Ŝtupo +Outer Obsidian Glass Stair=Ekstera Obsidiana Vitra Ŝtupo +Wooden Stair=Ligna Ŝtupo +Inner Wooden Stair=Interna Ligna Ŝtupo +Outer Wooden Stair=Ekstera Ligna Ŝtupo +Wooden Slab=Ligna Plato +Jungle Wood Stair=Ĝangala Ligna Ŝtupo +Inner Jungle Wood Stair=Interna Ĝangala Ligna Ŝtupo +Outer Jungle Wood Stair=Ekstera Ĝangala Ligna Ŝtupo +Jungle Wood Slab=Ĝangala Ligna Plato +Pine Wood Stair=Pina Ligna Ŝtupo +Inner Pine Wood Stair=Interna Pina Ligna Ŝtupo +Outer Pine Wood Stair=Ekstera Pina Ligna Ŝtupo +Pine Wood Slab=Pina Ligna Plato +Acacia Wood Stair=Akacia Ligna Ŝtupo +Inner Acacia Wood Stair=Interna Akacia Ligna Ŝtupo +Outer Acacia Wood Stair=Ekstera Akacia Ligna Ŝtupo +Acacia Wood Slab=Akacia Ligna Plato +Aspen Wood Stair=Tremola Ligna Ŝtupo +Inner Aspen Wood Stair=Interna Tremola Ligna Ŝtupo +Outer Aspen Wood Stair=Ekstera Tremola Ligna Ŝtupo +Aspen Wood Slab=Tremola Ligna Plato +Stone Stair=Ŝtona Ŝtupo +Inner Stone Stair=Interna Ŝtona Ŝtupo +Outer Stone Stair=Ekstera Ŝtona Ŝtupo +Stone Slab=Ŝtona Plato +Cobblestone Stair=Pavimŝtona Ŝtupo +Inner Cobblestone Stair=Interna Pavimŝtona Ŝtupo +Outer Cobblestone Stair=Ekstera Pavimŝtona Ŝtupo +Cobblestone Slab=Pavimŝtona Plato +Mossy Cobblestone Stair=Muska Pavimŝtona Ŝtupo +Inner Mossy Cobblestone Stair=Interna Muska Pavimŝtona Ŝtupo +Outer Mossy Cobblestone Stair=Ekstera Muska Pavimŝtona Ŝtupo +Mossy Cobblestone Slab=Muska Pavimŝtona Plato +Stone Brick Stair=Ŝtona Brika Ŝtupo +Inner Stone Brick Stair=Interna Ŝtona Brika Ŝtupo +Outer Stone Brick Stair=Ekstera Ŝtona Brika Ŝtupo +Stone Brick Slab=Ŝtona Brika Plato +Stone Block Stair=Ŝtona Ŝtipa Ŝtupo +Inner Stone Block Stair=Interna Ŝtona Ŝtipa Ŝtupo +Outer Stone Block Stair=Ekstera Ŝtona Ŝtipa Ŝtupo +Stone Block Slab=Ŝtona Ŝtipa Plato +Desert Stone Stair=Dezerta Ŝtona Ŝtupo +Inner Desert Stone Stair=Interna Dezerta Ŝtona Ŝtupo +Outer Desert Stone Stair=Ekstera Dezerta Ŝtona Ŝtupo +Desert Stone Slab=Dezerta Ŝtona Plato +Desert Cobblestone Stair=Dezerta Pavimŝtona Ŝtupo +Inner Desert Cobblestone Stair=Interna Dezerta Pavimŝtona Ŝtupo +Outer Desert Cobblestone Stair=Ekstera Dezerta Pavimŝtona Ŝtupo +Desert Cobblestone Slab=Dezerta Pavimŝtona Plato +Desert Stone Brick Stair=Dezerta Ŝtona Brika Ŝtupo +Inner Desert Stone Brick Stair=Interna Dezerta Ŝtona Brika Ŝtupo +Outer Desert Stone Brick Stair=Ekstera Dezerta Ŝtona Brika Ŝtupo +Desert Stone Brick Slab=Dezerta Ŝtona Brika Plato +Desert Stone Block Stair=Dezerta Ŝtona Bloko Ŝtupo +Inner Desert Stone Block Stair=Interna Dezerta Ŝtona Bloko Stupo +Outer Desert Stone Block Stair=Ekstera Dezerta Ŝtona Bloko Ŝtupo +Desert Stone Block Slab=Dezerta Ŝtona Bloko Plato +Sandstone Stair=Sablŝtona Ŝtupo +Inner Sandstone Stair=Interna Ŝablŝtona Ŝtupo +Outer Sandstone Stair=Ekstera Ŝablŝtona Ŝtupo +Sandstone Slab=Ŝablŝtona Plato +Sandstone Brick Stair=Ŝablŝtona Brika Ŝtupo +Inner Sandstone Brick Stair=Interna Ŝablŝtona Brika Ŝtupo +Outer Sandstone Brick Stair=Ekstera Ŝablŝtona Brika Ŝtupo +Sandstone Brick Slab=Ŝablŝtona Brika Plato +Sandstone Block Stair=Ŝablŝtona Ŝtipa Ŝtupo +Inner Sandstone Block Stair=Interna Ŝablŝtona Ŝtipa Ŝtupo +Outer Sandstone Block Stair=Ekstera Ŝablŝtona Ŝtipa Ŝtupo +Sandstone Block Slab=Ŝablŝtona Ŝtipa Plato +Desert Sandstone Stair=Dezerta Ŝablŝtona Ŝtupo +Inner Desert Sandstone Stair=Interna Dezerta Ŝablŝtona Ŝtupo +Outer Desert Sandstone Stair=Ekstera Dezerta Ŝablŝtona Ŝtupo +Desert Sandstone Slab=Dezerta Ŝablŝtona Plato +Desert Sandstone Brick Stair=Dezerta Ŝablŝtona Brika Ŝtupo +Inner Desert Sandstone Brick Stair=Interna Dezerta Ŝablŝtona Brika Ŝtupo +Outer Desert Sandstone Brick Stair=Ekstera Dezerta Ŝablŝtona Brika Ŝtupo +Desert Sandstone Brick Slab=Dezerta Ŝablŝtona Brika Plato +Desert Sandstone Block Stair=Dezerta Ŝablŝtona Ŝtipa Ŝtupo +Inner Desert Sandstone Block Stair=Interna Dezerta Ŝablŝtona Brika Ŝtupo +Outer Desert Sandstone Block Stair=Ekstera Dezerta Ŝablŝtona Brika Ŝtupo +Desert Sandstone Block Slab=Dezerta Ŝablŝtona Ŝtipa Plato +Silver Sandstone Stair=Arĝenta Ŝablŝtona Ŝtupo +Inner Silver Sandstone Stair=Interna Arĝenta Ŝablŝtona Ŝtupo +Outer Silver Sandstone Stair=Ekstera Arĝenta Ŝablŝtona Ŝtupo +Silver Sandstone Slab=Arĝenta Ŝablŝtona Plato +Silver Sandstone Brick Stair=Arĝenta Ŝablŝtona Brika Ŝtupo +Inner Silver Sandstone Brick Stair=Interna Arĝenta Ŝablŝtona Brika Ŝtupo +Outer Silver Sandstone Brick Stair=Ekstera Arĝenta Ŝablŝtona Brika Ŝtupo +Silver Sandstone Brick Slab=Arĝenta Ŝablŝtona Brika Plato +Silver Sandstone Block Stair=Arĝenta Ŝablŝtona Ŝtipa Ŝtupo +Inner Silver Sandstone Block Stair=Interna Arĝenta Ŝablŝtona Ŝtipa Ŝtupo +Outer Silver Sandstone Block Stair=Ekstera Arĝenta Ŝablŝtona Ŝtipa Ŝtupo +Silver Sandstone Block Slab=Arĝenta Ŝablŝtona Ŝtipa Plato +Obsidian Stair=Obsidiana Ŝtupo +Inner Obsidian Stair=Interna Obsidiana Ŝtupo +Outer Obsidian Stair=Ekstera Obsidiana Ŝtupo +Obsidian Slab=Obsidiana Plato +Obsidian Brick Stair=Obsidiana Brika Ŝtupo +Inner Obsidian Brick Stair=Interna Obsidiana Brika Ŝtupo +Outer Obsidian Brick Stair=Ekstera Obsidiana Brika Ŝtupo +Obsidian Brick Slab=Obsidiana Brika Plato +Obsidian Block Stair=Obsidiana Ŝtipa Ŝtupo +Inner Obsidian Block Stair=Interna Obsidiana Ŝtipa Ŝtupo +Outer Obsidian Block Stair=Ekstera Obsidiana Ŝtipa Ŝtupo +Obsidian Block Slab=Obsidiana Ŝtipa Plato +Brick Stair=Brika Ŝtupo +Inner Brick Stair=Interna Brika Ŝtupo +Outer Brick Stair=Ekstera Brika Ŝtupo +Brick Slab=Brika Plato +Steel Block Stair=Ŝtala Ŝtipa Ŝtupo +Inner Steel Block Stair=Interna Ŝtala Ŝtipa Ŝtupo +Outer Steel Block Stair=Ekstera Ŝtala Ŝtipa Ŝtupo +Steel Block Slab=Ŝtala Ŝtipa Plato +Tin Block Stair=Stana Ŝtipa Ŝtupo +Inner Tin Block Stair=Interna Stana Ŝtipa Ŝtupo +Outer Tin Block Stair=Ekstera Stana Ŝtipa Ŝtupo +Tin Block Slab=Stana Ŝtipa Plato +Copper Block Stair=Kupra Ŝtipa Ŝtupo +Inner Copper Block Stair=Interna Kupra Ŝtipa Ŝtupo +Outer Copper Block Stair=Ekstera Kupra Ŝtipa Ŝtupo +Copper Block Slab=Kupra Ŝtipa Plato +Bronze Block Stair=Bronza Ŝtipa Ŝtupo +Inner Bronze Block Stair=Interna Bronza Ŝtipa Ŝtupo +Outer Bronze Block Stair=Ekstera Bronza Ŝtipa Ŝtupo +Bronze Block Slab=Bronza Ŝtipa Plato +Gold Block Stair=Ora Ŝtipa Ŝtupo +Inner Gold Block Stair=Interna Ora Ŝtipa Ŝtupo +Outer Gold Block Stair=Ekstera Ora Ŝtipa Ŝtupo +Gold Block Slab=Ora Ŝtipa Plato +Ice Stair=Glacia Ŝtupo +Inner Ice Stair=Interna Glacia Ŝtupo +Outer Ice Stair=Ekstera Glacia Ŝtupo +Ice Slab=Glacia Plato +Snow Block Stair=Neĝa Ŝtipa Ŝtupo +Inner Snow Block Stair=Interna Neĝa Ŝtipa Ŝtupo +Outer Snow Block Stair=Ekstera Neĝa Ŝtipa Ŝtupo +Snow Block Slab=Neĝa Ŝtipa Plato diff --git a/mods/stairs/locale/stairs.es.tr b/mods/stairs/locale/stairs.es.tr new file mode 100644 index 0000000..374540c --- /dev/null +++ b/mods/stairs/locale/stairs.es.tr @@ -0,0 +1,145 @@ +# textdomain: stairs +Glass Stair=Escalera de vidrio +Glass Slab=Losa de vidrio +Inner Glass Stair=Escalera interior de vidrio +Outer Glass Stair=Escalera exterior de vidrio +Obsidian Glass Stair=Escalera de vidrio de obsidiana +Obsidian Glass Slab=Losa de vidrio de obsidiana +Inner Obsidian Glass Stair=Escalera interior de vidrio de obsidiana +Outer Obsidian Glass Stair=Escalera exterior de vidrio de obsidiana +Wooden Stair=Escalera de madera +Inner Wooden Stair=Escalera interior de madera +Outer Wooden Stair=Escalera exterior de madera +Wooden Slab=Losa de madera +Jungle Wood Stair=Escalera de madera tropical +Inner Jungle Wood Stair=Escalera interior de madera tropical +Outer Jungle Wood Stair=Escalera exterior de madera tropical +Jungle Wood Slab=Losa de madera tropical +Pine Wood Stair=Escalera de pino +Inner Pine Wood Stair=Escalera interior de pino +Outer Pine Wood Stair=Escalera exterior de pino +Pine Wood Slab=Losa de pino +Acacia Wood Stair=Escalera de acacia +Inner Acacia Wood Stair=Escalera interior de acacia +Outer Acacia Wood Stair=Escalera exterior de acacia +Acacia Wood Slab=Losa de acacia +Aspen Wood Stair=Escalera de álamo +Inner Aspen Wood Stair=Escalera interior de álamo +Outer Aspen Wood Stair=Escalera exterior de álamo +Aspen Wood Slab=Losa de álamo +Stone Stair=Escalera de piedra +Inner Stone Stair=Escalera interior de piedra +Outer Stone Stair=Escalera exterior de piedra +Stone Slab=Losa de piedra +Cobblestone Stair=Escalera de adoquines +Inner Cobblestone Stair=Escalera interior de adoquines +Outer Cobblestone Stair=Escalera exterior de adoquines +Cobblestone Slab=Losa de adoquines +Mossy Cobblestone Stair=Escalera de adoquines musgosos +Inner Mossy Cobblestone Stair=Escalera interior de adoquines musgosos +Outer Mossy Cobblestone Stair=Escalera exterior de adoquines musgosos +Mossy Cobblestone Slab=Losa de adoquines musgosos +Stone Brick Stair=Escalera de ladrillos de piedra +Inner Stone Brick Stair=Escalera interior de ladrillos de piedra +Outer Stone Brick Stair=Escalera exterior de ladrillos de piedra +Stone Brick Slab=Losa de ladrillos de piedra +Stone Block Stair=Escalera de bloques de piedra +Inner Stone Block Stair=Escalera interior de bloques de piedra +Outer Stone Block Stair=Escalera exterior de bloques de piedra +Stone Block Slab=Losa de bloques de piedra +Desert Stone Stair=Escalera de piedra desértica +Inner Desert Stone Stair=Escalera interior de piedra desértica +Outer Desert Stone Stair=Escalera exterior de piedra desértica +Desert Stone Slab=Losa de piedra desértica +Desert Cobblestone Stair=Escalera de adoquines desérticos +Inner Desert Cobblestone Stair=Escalera interior de adoquines desérticos +Outer Desert Cobblestone Stair=Escalera exterior de adoquines desérticos +Desert Cobblestone Slab=Losa de adoquines desérticos +Desert Stone Brick Stair=Escalera de ladrillos desérticos +Inner Desert Stone Brick Stair=Escalera interior de ladrillos desérticos +Outer Desert Stone Brick Stair=Escalera exterior de ladrillos desérticos +Desert Stone Brick Slab=Losa de ladrillos desérticos +Desert Stone Block Stair=Escalera de bloques de piedra desértica +Inner Desert Stone Block Stair=Escalera interior de bloques de piedra desértica +Outer Desert Stone Block Stair=Escalera exterior de bloques de piedra desértica +Desert Stone Block Slab=Losa de bloques de piedra desértica +Sandstone Stair=Escalera de arenisca +Inner Sandstone Stair=Escalera interior de arenisca +Outer Sandstone Stair=Escalera exterior de arenisca +Sandstone Slab=Losa de arenisca +Sandstone Brick Stair=Escalera de ladrillos de arenisca +Inner Sandstone Brick Stair=Escalera interior de ladrillos de arenisca +Outer Sandstone Brick Stair=Escalera exterior de ladrillos de arenisca +Sandstone Brick Slab=Losa de ladrillos de arenisca +Sandstone Block Stair=Escalera de bloques de arenisca +Inner Sandstone Block Stair=Escalera interior de bloques de arenisca +Outer Sandstone Block Stair=Escalera exterior de bloques de arenisca +Sandstone Block Slab=Losa de bloques de arenisca +Desert Sandstone Stair=Escalera de arenisca desértica +Inner Desert Sandstone Stair=Escalera interior de arenisca desértica +Outer Desert Sandstone Stair=Escalera exterior de arenisca desértica +Desert Sandstone Slab=Losa de arenisca desértica +Desert Sandstone Brick Stair=Escalera de ladrillos de arenisca desértica +Inner Desert Sandstone Brick Stair=Escalera interior de ladrillos de arenisca desértica +Outer Desert Sandstone Brick Stair=Escalera exterior de ladrillos de arenisca desértica +Desert Sandstone Brick Slab=Losa de ladrillos de arenisca desértica +Desert Sandstone Block Stair=Escalera de bloques de arenisca desértica +Inner Desert Sandstone Block Stair=Escalera interior de bloques de arenisca desértica +Outer Desert Sandstone Block Stair=Escalera exterior de bloques de arenisca desértica +Desert Sandstone Block Slab=Losa de bloques de arenisca desértica +Silver Sandstone Stair=Escalera de arenisca plateada +Inner Silver Sandstone Stair=Escalera interior de arenisca plateada +Outer Silver Sandstone Stair=Escalera exterior de arenisca plateada +Silver Sandstone Slab=Losa de arenisca plateada +Silver Sandstone Brick Stair=Escalera de ladrillos de arenisca plateada +Inner Silver Sandstone Brick Stair=Escalera interior de ladrillos de arenisca plateada +Outer Silver Sandstone Brick Stair=Escalera exterior de ladrillos de arenisca plateada +Silver Sandstone Brick Slab=Losa de ladrillos de arenisca plateada +Silver Sandstone Block Stair=Escalera de bloques de arenisca plateada +Inner Silver Sandstone Block Stair=Escalera interior de bloques de arenisca plateada +Outer Silver Sandstone Block Stair=Escalera exterior de bloques de arenisca plateada +Silver Sandstone Block Slab=Losa de bloques de arenisca plateada +Obsidian Stair=Escalera de obsidiana +Inner Obsidian Stair=Escalera interior de obsidiana +Outer Obsidian Stair=Escalera exterior de obsidiana +Obsidian Slab=Losa de obsidiana +Obsidian Brick Stair=Escalera de ladrillos de obsidiana +Inner Obsidian Brick Stair=Escalera interior de ladrillos de obsidiana +Outer Obsidian Brick Stair=Escalera exterior de ladrillos de obsidiana +Obsidian Brick Slab=Losa de ladrillos de obsidiana +Obsidian Block Stair=Escalera de bloques de obsidiana +Inner Obsidian Block Stair=Escalera interior de bloques de obsidiana +Outer Obsidian Block Stair=Escalera exterior de bloques de obsidiana +Obsidian Block Slab=Losa de bloques de obsidiana +Brick Stair=Escalera de ladrillos +Inner Brick Stair=Escalera interior de ladrillos +Outer Brick Stair=Escalera exterior de ladrillos +Brick Slab=Losa de ladrillos +Steel Block Stair=Escalera de acero +Inner Steel Block Stair=Escalera interior de acero +Outer Steel Block Stair=Escalera exterior de acero +Steel Block Slab=Losa de acero +Tin Block Stair=Escalera de estaño +Inner Tin Block Stair=Escalera interior de estaño +Outer Tin Block Stair=Escalera exterior de estaño +Tin Block Slab=Losa de estaño +Copper Block Stair=Escalera de cobre +Inner Copper Block Stair=Escalera interior de cobre +Outer Copper Block Stair=Escalera exterior de cobre +Copper Block Slab=Losa de cobre +Bronze Block Stair=Escalera de bronce +Inner Bronze Block Stair=Escalera interior de bronce +Outer Bronze Block Stair=Escalera exterior de bronce +Bronze Block Slab=Losa de bronce +Gold Block Stair=Escalera de oro +Inner Gold Block Stair=Escalera interior de oro +Outer Gold Block Stair=Escalera exterior de oro +Gold Block Slab=Losa de oro +Ice Stair=Escalera de hielo +Inner Ice Stair=Escalera interior de hielo +Outer Ice Stair=Escalera exterior de hielo +Ice Slab=Losa de hielo +Snow Block Stair=Escalera de nieve +Inner Snow Block Stair=Escalera interior de nieve +Outer Snow Block Stair=Escalera exterior de nieve +Snow Block Slab=Losa de nieve diff --git a/mods/stairs/locale/stairs.fr.tr b/mods/stairs/locale/stairs.fr.tr new file mode 100644 index 0000000..81b575e --- /dev/null +++ b/mods/stairs/locale/stairs.fr.tr @@ -0,0 +1,145 @@ +# textdomain: stairs +Glass Stair=Escalier de verre +Glass Slab=Dalle de verre +Inner Glass Stair=Escalier intérieur de verre +Outer Glass Stair=Escalier extérieur de verre +Obsidian Glass Stair=Escalier de verre d'obsidienne +Obsidian Glass Slab=Dalle de verre d'obsidienne +Inner Obsidian Glass Stair=Escalier intérieur de verre d'obsidienne +Outer Obsidian Glass Stair=Escalier extérieur de verre d'obsidienne +Wooden Stair=Escalier en bois +Inner Wooden Stair=Escalier intérieur en bois +Outer Wooden Stair=Escalier extérieur en bois +Wooden Slab=Dalle de bois +Jungle Wood Stair=Escalier en bois de la jungle +Inner Jungle Wood Stair=Escalier intérieur en bois de la jungle +Outer Jungle Wood Stair=Escalier extérieur en bois de la jungle +Jungle Wood Slab=Dalle en bois de la jungle +Pine Wood Stair=Escalier en pin +Inner Pine Wood Stair=Escalier intérieur en pin +Outer Pine Wood Stair=Escalier extérieur en pin +Pine Wood Slab=Dalle en pin +Acacia Wood Stair=Escalier en acacia +Inner Acacia Wood Stair=Escalier intérieur en acacia +Outer Acacia Wood Stair=Escalier extérieur en acacia +Acacia Wood Slab=Dalle en acacia +Aspen Wood Stair=Escalier en tremble +Inner Aspen Wood Stair=Escalier intérieur en tremble +Outer Aspen Wood Stair=Escalier extérieur en tremble +Aspen Wood Slab=Dalle en tremble +Stone Stair=Escalier de pierre +Inner Stone Stair=Escalier intérieur de pierre +Outer Stone Stair=Escalier extérieur de pierre +Stone Slab=Dalle de pierre +Cobblestone Stair=Escalier en pavé +Inner Cobblestone Stair=Escalier intérieur en pavé +Outer Cobblestone Stair=Escalier extérieur en pavé +Cobblestone Slab=Dalle en pavé +Mossy Cobblestone Stair=Escalier en pavé moussu +Inner Mossy Cobblestone Stair=Escalier intérieur en pavé moussu +Outer Mossy Cobblestone Stair=Escalier extérieur en pavé moussu +Mossy Cobblestone Slab=Dalle en pavé moussu +Stone Brick Stair=Escalier en brique de pierre +Inner Stone Brick Stair=Escalier intérieur en brique de pierre +Outer Stone Brick Stair=Escalier extérieur en brique de pierre +Stone Brick Slab=Dalle en brique de pierre +Stone Block Stair=Escalier en bloc de pierre +Inner Stone Block Stair=Escalier intérieur en bloc de pierre +Outer Stone Block Stair=Escalier extérieur en bloc de pierre +Stone Block Slab=Dalle en bloc de pierre +Desert Stone Stair=Escalier en pierre du désert +Inner Desert Stone Stair=Escalier intérieur en pierre du désert +Outer Desert Stone Stair=Escalier extérieur en pierre du désert +Desert Stone Slab=Dalle en pierre du désert +Desert Cobblestone Stair=Escalier en pavé du désert +Inner Desert Cobblestone Stair=Escalier intérieur en pavé du désert +Outer Desert Cobblestone Stair=Escalier extérieur en pavé du désert +Desert Cobblestone Slab=Dalle en pavé du désert +Desert Stone Brick Stair=Escalier en brique de pierre du désert +Inner Desert Stone Brick Stair=Escalier intérieur en brique de pierre du désert +Outer Desert Stone Brick Stair=Escalier extérieur en brique de pierre du désert +Desert Stone Brick Slab=Dalle en brique de pierre du désert +Desert Stone Block Stair=Escalier en bloc de pierre du désert +Inner Desert Stone Block Stair=Escalier intérieur en bloc de pierre du désert +Outer Desert Stone Block Stair=Escalier extérieur en bloc de pierre du désert +Desert Stone Block Slab=Dalle en bloc de pierre du désert +Sandstone Stair=Escalier en grès +Inner Sandstone Stair=Escalier intérieur en grès +Outer Sandstone Stair=Escalier extérieur en grès +Sandstone Slab=Dalle en grès +Sandstone Brick Stair=Escalier en brique de grès +Inner Sandstone Brick Stair=Escalier intérieur en brique de grès +Outer Sandstone Brick Stair=Escalier extérieur en brique de grès +Sandstone Brick Slab=Dalle en brique de grès +Sandstone Block Stair=Escalier en bloc de grès +Inner Sandstone Block Stair=Escalier intérieur en bloc de grès +Outer Sandstone Block Stair=Escalier extérieur en bloc de grès +Sandstone Block Slab=Dalle en bloc de grès +Desert Sandstone Stair=Escalier en grès du désert +Inner Desert Sandstone Stair=Escalier intérieur en grès du désert +Outer Desert Sandstone Stair=Escalier extérieur en grès du désert +Desert Sandstone Slab=Dalle en grès du désert +Desert Sandstone Brick Stair=Escalier en brique de grès du désert +Inner Desert Sandstone Brick Stair=Escalier intérieur en brique de grès du désert +Outer Desert Sandstone Brick Stair=Escalier extérieur en brique de grès du désert +Desert Sandstone Brick Slab=Dalle en brique de grès du désert +Desert Sandstone Block Stair=Escalier en bloc de grès du désert +Inner Desert Sandstone Block Stair=Escalier intérieur en bloc de grès du désert +Outer Desert Sandstone Block Stair=Escalier extérieur en bloc de grès du désert +Desert Sandstone Block Slab=Dalle en bloc de grès du désert +Silver Sandstone Stair=Escalier en grès argenté +Inner Silver Sandstone Stair=Escalier intérieur en grès argenté +Outer Silver Sandstone Stair=Escalier extérieur en grès argenté +Silver Sandstone Slab=Dalle en grès argenté +Silver Sandstone Brick Stair=Escalier en brique de grès argenté +Inner Silver Sandstone Brick Stair=Escalier intérieur en brique de grès argenté +Outer Silver Sandstone Brick Stair=Escalier extérieur en brique de grès argenté +Silver Sandstone Brick Slab=Dalle en brique de grès argenté +Silver Sandstone Block Stair=Escalier en bloc de grès argenté +Inner Silver Sandstone Block Stair=Escalier intérieur en bloc de grès argenté +Outer Silver Sandstone Block Stair=Escalier extérieur en bloc de grès argenté +Silver Sandstone Block Slab=Dalle en bloc de grès argenté +Obsidian Stair=Escalier en obsidienne +Inner Obsidian Stair=Escalier intérieur en obsidienne +Outer Obsidian Stair=Escalier extérieur en obsidienne +Obsidian Slab=Dalle en obsidienne +Obsidian Brick Stair=Escalier en brique d'obsidienne +Inner Obsidian Brick Stair=Escalier intérieur en brique d'obsidienne +Outer Obsidian Brick Stair=Escalier extérieur en brique d'obsidienne +Obsidian Brick Slab=Dalle en brique d'obsidienne +Obsidian Block Stair=Escalier en bloc d'obsidienne +Inner Obsidian Block Stair=Escalier intérieur en bloc d'obsidienne +Outer Obsidian Block Stair=Escalier extérieur en bloc d'obsidienne +Obsidian Block Slab=Dalle en bloc d'obsidienne +Brick Stair=Escalier en brique +Inner Brick Stair=Escalier intérieur en brique +Outer Brick Stair=Escalier extérieur en brique +Brick Slab=Dalle en brique +Steel Block Stair=Escalier en acier +Inner Steel Block Stair=Escalier intérieur en acier +Outer Steel Block Stair=Escalier extérieur en acier +Steel Block Slab=Dalle en acier +Tin Block Stair=Escalier en bloc d'étain +Inner Tin Block Stair=Escalier intérieur en bloc d'étain +Outer Tin Block Stair=Escalier extérieur en bloc d'étain +Tin Block Slab=Dalle en bloc d'étain +Copper Block Stair=Escalier en bloc de cuivre +Inner Copper Block Stair=Escalier intérieur en bloc de cuivre +Outer Copper Block Stair=Escalier extérieur en bloc de cuivre +Copper Block Slab=Dalle en bloc de cuivre +Bronze Block Stair=Escalier en bronze +Inner Bronze Block Stair=Escalier intérieur en bronze +Outer Bronze Block Stair=Escalier extérieur en bronze +Bronze Block Slab=Dalle en bronze +Gold Block Stair=Escalier en bloc d'or +Inner Gold Block Stair=Escalier intérieur en bloc d'or +Outer Gold Block Stair=Escalier extérieur en bloc d'or +Gold Block Slab=Dalle en bloc d'or +Ice Stair=Escalier de glace +Inner Ice Stair=Escalier intérieur de glace +Outer Ice Stair=Escalier extérieur de glace +Ice Slab=Dalle de glace +Snow Block Stair=Escalier en bloc de neige +Inner Snow Block Stair=Escalier intérieur en bloc de neige +Outer Snow Block Stair=Escalier extérieur en bloc de neige +Snow Block Slab=Dalle en bloc de neige diff --git a/mods/stairs/locale/stairs.id.tr b/mods/stairs/locale/stairs.id.tr new file mode 100644 index 0000000..dbdfaa0 --- /dev/null +++ b/mods/stairs/locale/stairs.id.tr @@ -0,0 +1,145 @@ +# textdomain: stairs +Glass Stair=Tangga Kaca +Glass Slab=Lempengan Kaca +Inner Glass Stair=Tangga Kaca Dalam +Outer Glass Stair=Tangga Kaca Luar +Obsidian Glass Stair=Tangga Kaca Obsidian +Obsidian Glass Slab=Lempengan Kaca Obsidian +Inner Obsidian Glass Stair=Tangga Kaca Obsidian Dalam +Outer Obsidian Glass Stair=Tangga Kaca Obsidian Luar +Wooden Stair=Tangga Kayu +Inner Wooden Stair=Tangga Kayu Dalam +Outer Wooden Stair=Tangga Kayu Luar +Wooden Slab=Lempengan Kayu +Jungle Wood Stair=Tangga Kayu Rimba +Inner Jungle Wood Stair=Tangga Kayu Rimba Dalam +Outer Jungle Wood Stair=Tangga Kayu Rimba Luar +Jungle Wood Slab=Lempengan Kayu Rimba +Pine Wood Stair=Tangga Kayu Pinus +Inner Pine Wood Stair=Tangga Kayu Pinus Dalam +Outer Pine Wood Stair=Tangga Kayu Pinus Luar +Pine Wood Slab=Lempengan Kayu Pinus +Acacia Wood Stair=Tangga Kayu Akasia +Inner Acacia Wood Stair=Tangga Kayu Akasia Dalam +Outer Acacia Wood Stair=Tangga Kayu Akasia Luar +Acacia Wood Slab=Lempengan Kayu Akasia +Aspen Wood Stair=Tangga Kayu Aspen +Inner Aspen Wood Stair=Tangga Kayu Aspen Dalam +Outer Aspen Wood Stair=Tangga Kayu Aspen Luar +Aspen Wood Slab=Lempengan Kayu Aspen +Stone Stair=Tangga Batu +Inner Stone Stair=Tangga Batu Dalam +Outer Stone Stair=Tangga Batu Luar +Stone Slab=Lempengan Batu +Cobblestone Stair=Tangga Bongkahan Batu +Inner Cobblestone Stair=Tangga Bongkahan Batu Dalam +Outer Cobblestone Stair=Tangga Bongkahan Batu Luar +Cobblestone Slab=Lempengan Bongkahan Batu +Mossy Cobblestone Stair=Tangga Bongkahan Batu Berlumut +Inner Mossy Cobblestone Stair=Tangga Bongkahan Batu Berlumut Dalam +Outer Mossy Cobblestone Stair=Tangga Bongkahan Batu Berlumut Luar +Mossy Cobblestone Slab=Lempengan Bongkahan Batu Berlumut +Stone Brick Stair=Tangga Tembok Batu +Inner Stone Brick Stair=Tangga Tembok Batu Dalam +Outer Stone Brick Stair=Tangga Tembok Batu Luar +Stone Brick Slab=Lempengan Tembok Batu +Stone Block Stair=Tangga Balok Batu +Inner Stone Block Stair=Tangga Balok Batu Dalam +Outer Stone Block Stair=Tangga Balok Batu Luar +Stone Block Slab=Lempengan Balok Batu +Desert Stone Stair=Tangga Batu Gurun +Inner Desert Stone Stair=Tangga Batu Gurun Dalam +Outer Desert Stone Stair=Tangga Batu Gurun Luar +Desert Stone Slab=Lempengan Batu Gurun +Desert Cobblestone Stair=Tangga Bongkahan Batu Gurun +Inner Desert Cobblestone Stair=Tangga Bongkahan Batu Gurun Dalam +Outer Desert Cobblestone Stair=Tangga Bongkahan Batu Gurun Luar +Desert Cobblestone Slab=Lempengan Bongkahan Batu Gurun +Desert Stone Brick Stair=Tangga Tembok Batu Gurun +Inner Desert Stone Brick Stair=Tangga Tembok Batu Gurun Dalam +Outer Desert Stone Brick Stair=Tangga Tembok Batu Gurun Luar +Desert Stone Brick Slab=Lempengan Tembok Batu Gurun +Desert Stone Block Stair=Tangga Balok Batu Gurun +Inner Desert Stone Block Stair=Tangga Balok Batu Gurun Dalam +Outer Desert Stone Block Stair=Tangga Balok Batu Gurun Luar +Desert Stone Block Slab=Lempengan Balok Batu Gurun +Sandstone Stair=Tangga Batu Pasir +Inner Sandstone Stair=Tangga Batu Pasir Dalam +Outer Sandstone Stair=Tangga Batu Pasir Luar +Sandstone Slab=Lempengan Batu Pasir +Sandstone Brick Stair=Tangga Tembok Batu Pasir +Inner Sandstone Brick Stair=Tangga Tembok Batu Pasir Dalam +Outer Sandstone Brick Stair=Tangga Tembok Batu Pasir Luar +Sandstone Brick Slab=Lempengan Tembok Batu Pasir +Sandstone Block Stair=Tangga Balok Batu Pasir +Inner Sandstone Block Stair=Tangga Balok Batu Pasir Dalam +Outer Sandstone Block Stair=Tangga Balok Batu Pasir Luar +Sandstone Block Slab=Lempengan Balok Batu Pasir +Desert Sandstone Stair=Tangga Batu Pasir Gurun +Inner Desert Sandstone Stair=Tangga Batu Pasir Gurun Dalam +Outer Desert Sandstone Stair=Tangga Batu Pasir Gurun Luar +Desert Sandstone Slab=Lempengan Batu Pasir Gurun +Desert Sandstone Brick Stair=Tangga Tembok Batu Pasir Gurun +Inner Desert Sandstone Brick Stair=Tangga Tembok Batu Pasir Gurun Dalam +Outer Desert Sandstone Brick Stair=Tangga Tembok Batu Pasir Gurun Luar +Desert Sandstone Brick Slab=Lempengan Tembok Batu Pasir Gurun +Desert Sandstone Block Stair=Tangga Balok Batu Pasir Gurun +Inner Desert Sandstone Block Stair=Tangga Balok Batu Pasir Gurun Dalam +Outer Desert Sandstone Block Stair=Tangga Balok Batu Pasir Gurun Luar +Desert Sandstone Block Slab=Lempengan Balok Batu Pasir Gurun +Silver Sandstone Stair=Tangga Batu Pasir Perak +Inner Silver Sandstone Stair=Tangga Batu Pasir Perak Dalam +Outer Silver Sandstone Stair=Tangga Batu Pasir Perak Luar +Silver Sandstone Slab=Lempengan Batu Pasir Perak +Silver Sandstone Brick Stair=Tangga Tembok Batu Pasir Perak +Inner Silver Sandstone Brick Stair=Tangga Tembok Batu Pasir Perak Dalam +Outer Silver Sandstone Brick Stair=Tangga Tembok Batu Pasir Perak Luar +Silver Sandstone Brick Slab=Lempengan Tembok Batu Pasir Perak +Silver Sandstone Block Stair=Tangga Balok Batu Pasir Perak +Inner Silver Sandstone Block Stair=Tangga Balok Batu Pasir Perak Dalam +Outer Silver Sandstone Block Stair=Tangga Balok Batu Pasir Perak Luar +Silver Sandstone Block Slab=Lempengan Balok Batu Pasir Perak +Obsidian Stair=Tangga Obsidian +Inner Obsidian Stair=Tangga Obsidian Dalam +Outer Obsidian Stair=Tangga Obsidian Luar +Obsidian Slab=Lempengan Obsidian +Obsidian Brick Stair=Tangga Tembok Obsidian +Inner Obsidian Brick Stair=Tangga Tembok Obsidian Dalam +Outer Obsidian Brick Stair=Tangga Tembok Obsidian Luar +Obsidian Brick Slab=Lempengan Tembok Obsidian +Obsidian Block Stair=Tangga Balok Obsidian +Inner Obsidian Block Stair=Tangga Balok Obsidian Dalam +Outer Obsidian Block Stair=Tangga Balok Obsidian Luar +Obsidian Block Slab=Lempengan Balok Obsidian +Brick Stair=Tangga Bata +Inner Brick Stair=Tangga Bata Dalam +Outer Brick Stair=Tangga Bata Luar +Brick Slab=Lempengan Bata +Steel Block Stair=Tangga Balok Baja +Inner Steel Block Stair=Tangga Balok Baja Dalam +Outer Steel Block Stair=Tangga Balok Baja Luar +Steel Block Slab=Lempengan Balok Baja +Tin Block Stair=Tangga Balok Timah +Inner Tin Block Stair=Tangga Balok Timah Dalam +Outer Tin Block Stair=Tangga Balok Timah Luar +Tin Block Slab=Lempengan Balok Timah +Copper Block Stair=Tangga Balok Tembaga +Inner Copper Block Stair=Tangga Balok Tembaga Dalam +Outer Copper Block Stair=Tangga Balok Tembaga Luar +Copper Block Slab=Lempengan Balok Tembaga +Bronze Block Stair=Tangga Balok Perunggu +Inner Bronze Block Stair=Tangga Balok Perunggu Dalam +Outer Bronze Block Stair=Tangga Balok Perunggu Luar +Bronze Block Slab=Lempengan Balok Perunggu +Gold Block Stair=Tangga Balok Emas +Inner Gold Block Stair=Tangga Balok Emas Dalam +Outer Gold Block Stair=Tangga Balok Emas Luar +Gold Block Slab=Lempengan Balok Emas +Ice Stair=Tangga Es +Inner Ice Stair=Tangga Es Dalam +Outer Ice Stair=Tangga Es Luar +Ice Slab=Lempengan Es +Snow Block Stair=Tangga Balok Salju +Inner Snow Block Stair=Tangga Balok Salju Dalam +Outer Snow Block Stair=Tangga Balok Salju Luar +Snow Block Slab=Lempengan Balok Salju diff --git a/mods/stairs/locale/stairs.it.tr b/mods/stairs/locale/stairs.it.tr new file mode 100644 index 0000000..16945ec --- /dev/null +++ b/mods/stairs/locale/stairs.it.tr @@ -0,0 +1,145 @@ +# textdomain: stairs +Glass Stair=Scala di vetro +Glass Slab=Lastra di vetro +Inner Glass Stair=Scala di vetro interna +Outer Glass Stair=Scala di vetro esterna +Obsidian Glass Stair=Scala di vetro d'ossidiana +Obsidian Glass Slab=Lastra di vetro d'ossidiana +Inner Obsidian Glass Stair=Scala di vetro d'ossidiana interna +Outer Obsidian Glass Stair=Scala di vetro d'ossidiana esterna +Wooden Stair=Scala di legno +Inner Wooden Stair=Scala di legno interna +Outer Wooden Stair=Scala di legno esterna +Wooden Slab=Lastra di legno +Jungle Wood Stair=Scala di legno della giungla +Inner Jungle Wood Stair=Scala di legno della giungla interna +Outer Jungle Wood Stair=Scala di legno della giungla esterna +Jungle Wood Slab=Lastra di legno della giungla +Pine Wood Stair=Scala di legno di pino +Inner Pine Wood Stair=Scala di legno di pino interna +Outer Pine Wood Stair=Scala di legno di pino esterna +Pine Wood Slab=Lastra di legno di pino +Acacia Wood Stair=Scala di legno d'acacia +Inner Acacia Wood Stair=Scala di legno d'acacia interna +Outer Acacia Wood Stair=Scala di legno d'acacia esterna +Acacia Wood Slab=Lastra di legno d'acacia +Aspen Wood Stair=Scala di legno di pioppo +Inner Aspen Wood Stair=Scala di legno di pioppo interna +Outer Aspen Wood Stair=Scala di legno di pioppo esterna +Aspen Wood Slab=Lastra di legno di pioppo +Stone Stair=Scala di pietra +Inner Stone Stair=Scala di pietra interna +Outer Stone Stair=Scala di pietra esterna +Stone Slab=Lastra di pietra +Cobblestone Stair=Scala di ciottoli +Inner Cobblestone Stair=Scala di ciottoli interna +Outer Cobblestone Stair=Scala di ciottoli esterna +Cobblestone Slab=Lastra di ciottoli +Mossy Cobblestone Stair=Scala di ciottoli muschiosi +Inner Mossy Cobblestone Stair=Scala di ciottoli muschiosi interna +Outer Mossy Cobblestone Stair=Scala di ciottoli muschiosi esterna +Mossy Cobblestone Slab=Lastra di ciottoli muschiosi +Stone Brick Stair=Scala di mattone di pietra +Inner Stone Brick Stair=Scala di mattone di pietra interna +Outer Stone Brick Stair=Scala di mattone di pietra esterna +Stone Brick Slab=Lastra di mattone di pietra +Stone Block Stair=Scala di blocco di pietra +Inner Stone Block Stair=Scala di blocco di pietra interna +Outer Stone Block Stair=Scala di blocco di pietra esterna +Stone Block Slab=Lastra di blocco di pietra +Desert Stone Stair=Scala di pietra del deserto +Inner Desert Stone Stair=Scala di pietra del deserto interna +Outer Desert Stone Stair=Scala di pietra del deserto esterna +Desert Stone Slab=Lastra di pietra del deserto +Desert Cobblestone Stair=Scala di ciottoli del deserto +Inner Desert Cobblestone Stair=Scala di ciottoli del deserto interna +Outer Desert Cobblestone Stair=Scala di ciottoli del deserto esterna +Desert Cobblestone Slab=Lastra di ciottoli del deserto +Desert Stone Brick Stair=Scala di mattone di pietra del deserto +Inner Desert Stone Brick Stair=Scala di mattone di pietra del deserto interna +Outer Desert Stone Brick Stair=Scala di mattone di pietra del deserto esterna +Desert Stone Brick Slab=Lastra di mattone di pietra del deserto +Desert Stone Block Stair=Scala di blocco di pietra del deserto +Inner Desert Stone Block Stair=Scala di blocco di pietra del deserto interna +Outer Desert Stone Block Stair=Scala di blocco di pietra del deserto esterna +Desert Stone Block Slab=Lastra di blocco di pietra del deserto +Sandstone Stair=Scala d'arenaria +Inner Sandstone Stair=Scala d'arenaria interna +Outer Sandstone Stair=Scala d'arenaria esterna +Sandstone Slab=Lastra d'arenaria +Sandstone Brick Stair=Scala di mattone d'arenaria +Inner Sandstone Brick Stair=Scala di mattone d'arenaria interna +Outer Sandstone Brick Stair=Scala di mattone d'arenaria esterna +Sandstone Brick Slab=Lastra di mattone d'arenaria +Sandstone Block Stair=Scala di blocco d'arenaria +Inner Sandstone Block Stair=Scala di blocco d'arenaria interna +Outer Sandstone Block Stair=Scala di blocco d'arenaria esterna +Sandstone Block Slab=Lastra di blocco d'arenaria +Desert Sandstone Stair=Scala d'arenaria del deserto +Inner Desert Sandstone Stair=Scala d'arenaria del deserto interna +Outer Desert Sandstone Stair=Scala d'arenaria del deserto esterna +Desert Sandstone Slab=Lastra d'arenaria del deserto +Desert Sandstone Brick Stair=Scala di mattone d'arenaria del deserto +Inner Desert Sandstone Brick Stair=Scala di mattone d'arenaria del deserto interna +Outer Desert Sandstone Brick Stair=Scala di mattone d'arenaria del deserto esterna +Desert Sandstone Brick Slab=Lastra di mattone d'arenaria del deserto +Desert Sandstone Block Stair=Scala di blocco d'arenaria del deserto +Inner Desert Sandstone Block Stair=Scala di blocco d'arenaria del deserto interna +Outer Desert Sandstone Block Stair=Scala di blocco d'arenaria del deserto esterna +Desert Sandstone Block Slab=Lastra di blocco d'arenaria del deserto +Silver Sandstone Stair=Scala d'arenaria argentata +Inner Silver Sandstone Stair=Scala d'arenaria argentata interna +Outer Silver Sandstone Stair=Scala d'arenaria argentata esterna +Silver Sandstone Slab=Lastra d'arenaria argentata +Silver Sandstone Brick Stair=Scala di mattone d'arenaria argentata +Inner Silver Sandstone Brick Stair=Scala di mattone d'arenaria argentata interna +Outer Silver Sandstone Brick Stair=Scala di mattone d'arenaria argentata esterna +Silver Sandstone Brick Slab=Lastra di mattone d'arenaria argentata +Silver Sandstone Block Stair=Scala di blocco d'arenaria argentata +Inner Silver Sandstone Block Stair=Scala di blocco d'arenaria argentata interna +Outer Silver Sandstone Block Stair=Scala di blocco d'arenaria argentata esterna +Silver Sandstone Block Slab=Lastra di blocco d'arenaria argentata +Obsidian Stair=Scala d'ossidiana +Inner Obsidian Stair=Scala d'ossidiana interna +Outer Obsidian Stair=Scala d'ossidiana esterna +Obsidian Slab=Lastra d'ossidiana +Obsidian Brick Stair=Scala di mattone d'ossidiana +Inner Obsidian Brick Stair=Scala di mattone d'ossidiana interna +Outer Obsidian Brick Stair=Scala di mattone d'ossidiana esterna +Obsidian Brick Slab=Lastra di mattone d'ossidiana +Obsidian Block Stair=Scala di blocco d'ossidiana +Inner Obsidian Block Stair=Scala di blocco d'ossidiana interna +Outer Obsidian Block Stair=Scala di blocco d'ossidiana esterna +Obsidian Block Slab=Lastra di blocco d'ossidiana +Brick Stair=Scala di mattone +Inner Brick Stair=Scala di mattone interna +Outer Brick Stair=Scala di mattone esterna +Brick Slab=Lastra di mattone +Steel Block Stair=Scala di blocco d'acciaio +Inner Steel Block Stair=Scala di blocco d'acciaio interna +Outer Steel Block Stair=Scala di blocco d'acciaio esterna +Steel Block Slab=Lastra di blocco d'acciaio +Tin Block Stair=Scala di blocco di stagno +Inner Tin Block Stair=Scala di blocco di stagno interna +Outer Tin Block Stair=Scala di blocco di stagno esterna +Tin Block Slab=Lastra di blocco di stagno +Copper Block Stair=Scala di blocco di rame +Inner Copper Block Stair=Scala di blocco di rame interna +Outer Copper Block Stair=Scala di blocco di rame esterna +Copper Block Slab=Lastra di blocco di rame +Bronze Block Stair=Scala di blocco di bronzo +Inner Bronze Block Stair=Scala di blocco di bronzo interna +Outer Bronze Block Stair=Scala di blocco di bronzo esterna +Bronze Block Slab=Lastra di blocco di bronzo +Gold Block Stair=Scala di blocco d'oro +Inner Gold Block Stair=Scala di blocco d'oro interna +Outer Gold Block Stair=Scala di blocco d'oro esterna +Gold Block Slab=Lastra di blocco d'oro +Ice Stair=Scala di ghiaccio +Inner Ice Stair=Scala di ghiaccio interna +Outer Ice Stair=Scala di ghiaccio esterna +Ice Slab=Lastra di ghiaccio +Snow Block Stair=Scala di blocco di neve +Inner Snow Block Stair=Scala di blocco di neve interna +Outer Snow Block Stair=Scala di blocco di neve esterna +Snow Block Slab=Lastra di blocco di neve diff --git a/mods/stairs/locale/stairs.ja.tr b/mods/stairs/locale/stairs.ja.tr new file mode 100644 index 0000000..73e2703 --- /dev/null +++ b/mods/stairs/locale/stairs.ja.tr @@ -0,0 +1,145 @@ +# textdomain: stairs +Glass Stair=ガラスの階段 +Glass Slab=ガラスのハーフブロック +Inner Glass Stair=へっこんだガラスの階段 +Outer Glass Stair=でっぱったガラスの階段 +Obsidian Glass Stair=黒曜石ガラスの階段 +Obsidian Glass Slab=黒曜石ガラスのハーフブロック +Inner Obsidian Glass Stair=へっこんだ黒曜石ガラスの階段 +Outer Obsidian Glass Stair=でっぱった黒曜石ガラスの階段 +Wooden Stair=木の階段 +Inner Wooden Stair=へっこんだ木の階段 +Outer Wooden Stair=でっぱった木の階段 +Wooden Slab=木のハーフブロック +Jungle Wood Stair=ジャングルの階段 +Inner Jungle Wood Stair=へっこんだジャングルの階段 +Outer Jungle Wood Stair=でっぱったジャングルの階段 +Jungle Wood Slab=ジャングルのハーフブロック +Pine Wood Stair=マツの木の階段 +Inner Pine Wood Stair=へっこんだマツの階段 +Outer Pine Wood Stair=でっぱったマツの階段 +Pine Wood Slab=マツのハーフブロック +Acacia Wood Stair=アカシアの階段 +Inner Acacia Wood Stair=へっこんだアカシアの階段 +Outer Acacia Wood Stair=でっぱったアカシアの階段 +Acacia Wood Slab=アカシアのハーフブロック +Aspen Wood Stair=ポプラの階段 +Inner Aspen Wood Stair=へっこんだポプラの階段 +Outer Aspen Wood Stair=でっぱったポプラの階段 +Aspen Wood Slab=ポプラのハーフブロック +Stone Stair=石の階段 +Inner Stone Stair=へっこんだ石の階段 +Outer Stone Stair=でっぱった石の階段 +Stone Slab=石のハーフブロック +Cobblestone Stair=丸石の階段 +Inner Cobblestone Stair=へっこんだ丸石の階段 +Outer Cobblestone Stair=でっぱった丸石の階段 +Cobblestone Slab=丸石のハーフブロック +Mossy Cobblestone Stair=苔むした丸石の階段 +Inner Mossy Cobblestone Stair=へっこんだ苔むした丸石の階段 +Outer Mossy Cobblestone Stair=でっぱった苔むした丸石の階段 +Mossy Cobblestone Slab=苔むした丸石のハーフブロック +Stone Brick Stair=石レンガの階段 +Inner Stone Brick Stair=へっこんだ石レンガの階段 +Outer Stone Brick Stair=でっぱった石レンガの階段 +Stone Brick Slab=石レンガのハーフブロック +Stone Block Stair=石ブロックの階段 +Inner Stone Block Stair=へっこんだ石ブロックの階段 +Outer Stone Block Stair=でっぱった石ブロックの階段 +Stone Block Slab=石ブロックのハーフブロック +Desert Stone Stair=砂漠の石の階段 +Inner Desert Stone Stair=へっこんだ砂漠の石の階段 +Outer Desert Stone Stair=でっぱった砂漠の石の階段 +Desert Stone Slab=砂漠の石のハーフブロック +Desert Cobblestone Stair=砂漠の丸石の階段 +Inner Desert Cobblestone Stair=へっこんだ砂漠の丸石の階段 +Outer Desert Cobblestone Stair=でっぱった砂漠の丸石の階段 +Desert Cobblestone Slab=砂漠の丸石のハーフブロック +Desert Stone Brick Stair=砂漠の石レンガの階段 +Inner Desert Stone Brick Stair=へっこんだ砂漠の石レンガの階段 +Outer Desert Stone Brick Stair=でっぱった砂漠の石レンガの階段 +Desert Stone Brick Slab=砂漠の石レンガのハーフブロック +Desert Stone Block Stair=砂漠の石ブロックの階段 +Inner Desert Stone Block Stair=へっこんだ砂漠の石ブロックの階段 +Outer Desert Stone Block Stair=でっぱった砂漠の石ブロックの階段 +Desert Stone Block Slab=砂漠の石ブロックのハーフブロック +Sandstone Stair=砂岩の階段 +Inner Sandstone Stair=へっこんだ砂岩の階段 +Outer Sandstone Stair=でっぱった砂岩の階段 +Sandstone Slab=砂岩のハーフブロック +Sandstone Brick Stair=砂岩レンガの階段 +Inner Sandstone Brick Stair=へっこんだ砂岩レンガの階段 +Outer Sandstone Brick Stair=でっぱった砂岩レンガの階段 +Sandstone Brick Slab=砂岩レンガのハーフブロック +Sandstone Block Stair=砂岩ブロックの階段 +Inner Sandstone Block Stair=へっこんだ砂岩ブロックの階段 +Outer Sandstone Block Stair=でっぱった砂岩ブロックの階段 +Sandstone Block Slab=砂岩ブロックのハーフブロック +Desert Sandstone Stair=砂漠の砂岩の階段 +Inner Desert Sandstone Stair=へっこんだ砂漠の砂岩の階段 +Outer Desert Sandstone Stair=でっぱった砂漠の砂岩の階段 +Desert Sandstone Slab=砂漠の砂岩のハーフブロック +Desert Sandstone Brick Stair=砂漠の砂岩レンガの階段 +Inner Desert Sandstone Brick Stair=へっこんだ砂漠の砂岩レンガの階段 +Outer Desert Sandstone Brick Stair=でっぱった砂漠の砂岩レンガの階段 +Desert Sandstone Brick Slab=砂漠の砂岩レンガのハーフブロック +Desert Sandstone Block Stair=砂漠の砂岩ブロックの階段 +Inner Desert Sandstone Block Stair=へっこんだ砂漠の砂岩ブロックの階段 +Outer Desert Sandstone Block Stair=でっぱった砂漠の砂岩ブロックの階段 +Desert Sandstone Block Slab=砂漠の砂岩ブロックのハーフブロック +Silver Sandstone Stair=銀の砂岩の階段 +Inner Silver Sandstone Stair=へっこんだ銀の砂岩の階段 +Outer Silver Sandstone Stair=でっぱった銀の砂岩の階段 +Silver Sandstone Slab=銀の砂岩のハーフブロック +Silver Sandstone Brick Stair=銀の砂岩レンガの階段 +Inner Silver Sandstone Brick Stair=へっこんだ銀の砂岩レンガの階段 +Outer Silver Sandstone Brick Stair=でっぱった銀の砂岩レンガの階段 +Silver Sandstone Brick Slab=銀の砂岩レンガのハーフブロック +Silver Sandstone Block Stair=銀の砂岩ブロックの階段 +Inner Silver Sandstone Block Stair=へっこんだ銀の砂岩ブロックの階段 +Outer Silver Sandstone Block Stair=でっぱった銀の砂岩ブロックの階段 +Silver Sandstone Block Slab=銀の砂岩ブロックのハーフブロック +Obsidian Stair=黒曜石の階段 +Inner Obsidian Stair=へっこんだ黒曜石の階段 +Outer Obsidian Stair=でっぱった黒曜石の階段 +Obsidian Slab=黒曜石のハーフブロック +Obsidian Brick Stair=黒曜石レンガの階段 +Inner Obsidian Brick Stair=へっこんだ黒曜石レンガの階段 +Outer Obsidian Brick Stair=でっぱった黒曜石レンガの階段 +Obsidian Brick Slab=黒曜石レンガのハーフブロック +Obsidian Block Stair=黒曜石ブロックの階段 +Inner Obsidian Block Stair=へっこんだ黒曜石ブロックの階段 +Outer Obsidian Block Stair=でっぱった黒曜石ブロックの階段 +Obsidian Block Slab=黒曜石ブロックのハーフブロック +Brick Stair=レンガの階段 +Inner Brick Stair=へっこんだレンガの階段 +Outer Brick Stair=でっぱったレンガの階段 +Brick Slab=レンガのハーフブロック +Steel Block Stair=鉄ブロックの階段 +Inner Steel Block Stair=へっこんだ鉄ブロックの階段 +Outer Steel Block Stair=でっぱった鉄ブロックの階段 +Steel Block Slab=鉄ブロックのハーフブロック +Tin Block Stair=スズの階段 +Inner Tin Block Stair=へっこんだスズの階段 +Outer Tin Block Stair=でっぱったスズの階段 +Tin Block Slab=スズのハーフブロック +Copper Block Stair=銅ブロックの階段 +Inner Copper Block Stair=へっこんだ銅ブロックの階段 +Outer Copper Block Stair=でっぱった銅ブロックの階段 +Copper Block Slab=銅ブロックのハーフブロック +Bronze Block Stair=青銅ブロックの階段 +Inner Bronze Block Stair=へっこんだ青銅ブロックの階段 +Outer Bronze Block Stair=でっぱった青銅ブロックの階段 +Bronze Block Slab=青銅ブロックのハーフブロック +Gold Block Stair=金ブロックの階段 +Inner Gold Block Stair=へっこんだ金ブロックの階段 +Outer Gold Block Stair=でっぱった金ブロックの階段 +Gold Block Slab=金ブロックのハーフブロック +Ice Stair=氷の階段 +Inner Ice Stair=へっこんだ氷の階段 +Outer Ice Stair=でっぱった氷の階段 +Ice Slab=氷のハーフブロック +Snow Block Stair=雪の階段 +Inner Snow Block Stair=へっこんだ雪の階段 +Outer Snow Block Stair=でっぱった雪の階段 +Snow Block Slab=雪のハーフブロック diff --git a/mods/stairs/locale/stairs.jbo.tr b/mods/stairs/locale/stairs.jbo.tr new file mode 100644 index 0000000..91d2806 --- /dev/null +++ b/mods/stairs/locale/stairs.jbo.tr @@ -0,0 +1,145 @@ +# textdomain: stairs +Glass Stair=lo blaci serti +Glass Slab=lo blaci xadba bliku +Inner Glass Stair=lo zo'i blaci serti +Outer Glass Stair=lo ze'o blaci serti +Obsidian Glass Stair=lo je'erma'ablaci blaci serti +Obsidian Glass Slab=lo je'erma'ablaci blaci ke xadba bliku +Inner Obsidian Glass Stair=lo zo'i je'erma'ablaci blaci serti +Outer Obsidian Glass Stair=lo ze'o je'erma'ablaci blaci serti +Wooden Stair=lo mudri serti +Inner Wooden Stair=lo zo'i mudri serti +Outer Wooden Stair=lo ze'o mudri serti +Wooden Slab=lo mudri ke xadba bliku +Jungle Wood Stair=lo glatimdemricfoi mudri serti +Inner Jungle Wood Stair=lo zo'i glatimdemricfoi mudri serti +Outer Jungle Wood Stair=lo ze'o glatimdemricfoi mudri serti +Jungle Wood Slab=lo glatimdemricfoi mudri ke xadba bliku +Pine Wood Stair=lo ku'urmudri serti +Inner Pine Wood Stair=lo zo'i ku'urmudri serti +Outer Pine Wood Stair=lo ze'o ku'urmudri serti +Pine Wood Slab=lo ku'urmudri ke xadba bliku +Acacia Wood Stair=lo atkaci,ia mudri serti +Inner Acacia Wood Stair=lo zo'i atkaci,ia mudri serti +Outer Acacia Wood Stair=lo ze'o atkaci,ia mudri serti +Acacia Wood Slab=lo atkaci,ia mudri ke xadba bliku +Aspen Wood Stair=lo mudrpopulu serti +Inner Aspen Wood Stair=lo zo'i mudrpopulu serti +Outer Aspen Wood Stair=lo ze'o mudrpopulu serti +Aspen Wood Slab=lo mudrpopulu ke xadba bliku +Stone Stair=lo rokci serti +Inner Stone Stair=lo zo'i rokci serti +Outer Stone Stair=lo ze'o rokci serti +Stone Slab=lo rokci ke xadba bliku +Cobblestone Stair=lo lolro'iboi serti +Inner Cobblestone Stair=lo zo'i lolro'iboi serti +Outer Cobblestone Stair=lo ze'o lolro'iboi serti +Cobblestone Slab=lo lolro'iboi xadba bliku +Mossy Cobblestone Stair=lo clika lolro'iboi serti +Inner Mossy Cobblestone Stair=lo zo'i clika lolro'iboi serti +Outer Mossy Cobblestone Stair=lo ze'o clika lolro'iboi serti +Mossy Cobblestone Slab=lo clika lolro'iboi ke xadba bliku +Stone Brick Stair=lo morna rokci serti +Inner Stone Brick Stair=lo zo'i morna rokci serti +Outer Stone Brick Stair=lo ze'o morna rokci serti +Stone Brick Slab=lo morna rokci ke xadba bliku +Stone Block Stair=lo rokci bliku serti +Inner Stone Block Stair=lo zo'i rokci bliku serti +Outer Stone Block Stair=lo ze'o rokci bliku serti +Stone Block Slab=lo rokci bliku ke xadba bliku +Desert Stone Stair=lo cantu'a rokci serti +Inner Desert Stone Stair=lo zo'i cantu'a rokci serti +Outer Desert Stone Stair=lo ze'o cantu'a rokci serti +Desert Stone Slab=lo cantu'a rokci ke xadba bliku +Desert Cobblestone Stair=lo cantu'a lolro'iboi serti +Inner Desert Cobblestone Stair=lo zo'i cantu'a lolro'iboi serti +Outer Desert Cobblestone Stair=lo ze'o cantu'a lolro'iboi serti +Desert Cobblestone Slab=lo cantu'a lolro'iboi ke xadba bliku +Desert Stone Brick Stair=lo morna ke cantu'a rokci serti +Inner Desert Stone Brick Stair=lo zo'i morna ke cantu'a rokci serti +Outer Desert Stone Brick Stair=lo ze'o morna ke cantu'a rokci serti +Desert Stone Brick Slab=lo morna ke cantu'a rokci ke xadba bliku +Desert Stone Block Stair=lo cantu'a rokci bliku serti +Inner Desert Stone Block Stair=lo zo'i cantu'a rokci bliku serti +Outer Desert Stone Block Stair=lo ze'o cantu'a rokci bliku serti +Desert Stone Block Slab=lo cantu'a rokci bliku ke xadba bliku +Sandstone Stair=lo canro'i serti +Inner Sandstone Stair=lo zo'i canro'i serti +Outer Sandstone Stair=lo ze'o canro'i serti +Sandstone Slab=lo canro'i ke xadba bliku +Sandstone Brick Stair=lo morna ke canro'i serti +Inner Sandstone Brick Stair=lo zo'i morna ke canro'i serti +Outer Sandstone Brick Stair=lo ze'o morna ke canro'i serti +Sandstone Brick Slab=lo morna canro'i ke xadba bliku +Sandstone Block Stair=lo canro'i bliku serti +Inner Sandstone Block Stair=lo zo'i canro'i bliku serti +Outer Sandstone Block Stair=lo ze'o canro'i bliku serti +Sandstone Block Slab=lo canro'i bliku ke xadba bliku +Desert Sandstone Stair=lo cantu'a canro'i serti +Inner Desert Sandstone Stair=lo zo'i cantu'a canro'i serti +Outer Desert Sandstone Stair=lo ze'o cantu'a canro'i serti +Desert Sandstone Slab=lo cantu'a canro'i ke xadba bliku +Desert Sandstone Brick Stair=lo morna ke cantu'a canro'i serti +Inner Desert Sandstone Brick Stair=lo zo'i morna ke cantu'a canro'i serti +Outer Desert Sandstone Brick Stair=lo ze'o morna ke cantu'a canro'i serti +Desert Sandstone Brick Slab=lo morna ke cantu'a canro'i ke xadba bliku +Desert Sandstone Block Stair=lo cantu'a canro'i bliku serti +Inner Desert Sandstone Block Stair=lo zo'i cantu'a canro'i bliku serti +Outer Desert Sandstone Block Stair=lo ze'o cantu'a canro'i bliku serti +Desert Sandstone Block Slab=lo cantu'a canro'i ke xadba bliku +Silver Sandstone Stair=lo rijyska canro'i serti +Inner Silver Sandstone Stair=lo zo'i rijyska canro'i serti +Outer Silver Sandstone Stair=lo ze'o rijyska canro'i serti +Silver Sandstone Slab=lo rijyska canro'i ke xadba bliku +Silver Sandstone Brick Stair=lo morna ke rijyska canro'i serti +Inner Silver Sandstone Brick Stair=lo zo'i morna ke rijyska canro'i serti +Outer Silver Sandstone Brick Stair=lo ze'o morna ke rijyska canro'i serti +Silver Sandstone Brick Slab=lo morna ke rijyska canro'i ke xadba bliku +Silver Sandstone Block Stair=lo rijyska canro'i bliku serti +Inner Silver Sandstone Block Stair=lo zo'i rijyska canro'i bliku serti +Outer Silver Sandstone Block Stair=lo ze'o rijyska canro'i bliku serti +Silver Sandstone Block Slab=lo rijyska canro'i bliku ke xadba bliku +Obsidian Stair=lo je'erma'ablaci serti +Inner Obsidian Stair=lo zo'i je'erma'ablaci serti +Outer Obsidian Stair=lo ze'o je'erma'ablaci serti +Obsidian Slab=lo je'erma'ablaci ke xadba bliku +Obsidian Brick Stair=lo morna ke je'erma'ablaci serti +Inner Obsidian Brick Stair=lo zo'i morna ke je'erma'ablaci serti +Outer Obsidian Brick Stair=lo ze'o morna ke je'erma'ablaci serti +Obsidian Brick Slab=lo morna je'erma'ablaci ke xadba bliku +Obsidian Block Stair=lo je'erma'ablaci bliku serti +Inner Obsidian Block Stair=lo zo'i je'erma'ablaci bliku serti +Outer Obsidian Block Stair=lo ze'o je'erma'ablaci bliku serti +Obsidian Block Slab=lo je'erma'ablaci bliku ke xadba bliku +Brick Stair=lo kitybli serti +Inner Brick Stair=lo zo'i kitybli serti +Outer Brick Stair=lo ze'o kitybli serti +Brick Slab=lo kitybli xadba bliku +Steel Block Stair=lo gasta bliku serti +Inner Steel Block Stair=lo zo'i gasta bliku serti +Outer Steel Block Stair=lo ze'o gasta bliku serti +Steel Block Slab=lo gasta bliku ke xadba bliku +Tin Block Stair=lo tinci bliku serti +Inner Tin Block Stair=lo zo'i tinci bliku serti +Outer Tin Block Stair=lo ze'o tinci bliku serti +Tin Block Slab=lo tinci bliku ke xadba bliku +Copper Block Stair=lo tunka bliku serti +Inner Copper Block Stair=lo zo'i tunka bliku serti +Outer Copper Block Stair=lo ze'o tunka bliku serti +Copper Block Slab=lo tunka xadba bliku +Bronze Block Stair=lo ransu bliku serti +Inner Bronze Block Stair=lo zo'i ransu bliku serti +Outer Bronze Block Stair=lo ze'o ransu bliku serti +Bronze Block Slab=lo ransu xadba bliku +Gold Block Stair=lo solji bliku serti +Inner Gold Block Stair=lo zo'i solji bliku serti +Outer Gold Block Stair=lo ze'o solji bliku serti +Gold Block Slab=lo solji bliku ke xadba bliku +Ice Stair=lo bisli serti +Inner Ice Stair=lo zo'i bisli serti +Outer Ice Stair=lo ze'o bisli serti +Ice Slab=lo bisli ke xadba bliku +Snow Block Stair=lo snime bliku serti +Inner Snow Block Stair=lo zo'i snime bliku serti +Outer Snow Block Stair=lo ze'o snime bliku serti +Snow Block Slab=lo snime bliku ke xadba bliku diff --git a/mods/stairs/locale/stairs.ms.tr b/mods/stairs/locale/stairs.ms.tr new file mode 100644 index 0000000..a39c7f6 --- /dev/null +++ b/mods/stairs/locale/stairs.ms.tr @@ -0,0 +1,145 @@ +# textdomain: stairs +Glass Stair=Tangga Kaca +Glass Slab=Papak Kaca +Inner Glass Stair=Tangga Kaca Dalaman +Outer Glass Stair=Tangga Kaca Luaran +Obsidian Glass Stair=Tangga Obsidia +Obsidian Glass Slab=Papak Obsidia +Inner Obsidian Glass Stair=Tangga Obsidia Dalaman +Outer Obsidian Glass Stair=Tangga Obsidia Luaran +Wooden Stair=Tangga Kayu +Inner Wooden Stair=Tangga Kayu Dalaman +Outer Wooden Stair=Tangga Kayu Luaran +Wooden Slab=Papak Kayu +Jungle Wood Stair=Tangga Kayu Hutan +Inner Jungle Wood Stair=Tangga Kayu Hutan Dalaman +Outer Jungle Wood Stair=Tangga Kayu Hutan Luaran +Jungle Wood Slab=Papak Kayu Hutan +Pine Wood Stair=Tangga Kayu Pain +Inner Pine Wood Stair=Tangga Kayu Pain Dalaman +Outer Pine Wood Stair=Tangga Kayu Pain Luaran +Pine Wood Slab=Papak Kayu Pain +Acacia Wood Stair=Tangga Kayu Akasia +Inner Acacia Wood Stair=Tangga Kayu Akasia Dalaman +Outer Acacia Wood Stair=Tangga Kayu Akasia Luaran +Acacia Wood Slab=Papak Kayu Akasia +Aspen Wood Stair=Tangga Kayu Aspen +Inner Aspen Wood Stair=Tangga Kayu Aspen Dalaman +Outer Aspen Wood Stair=Tangga Kayu Aspen Luaran +Aspen Wood Slab=Papak Kayu Aspen +Stone Stair=Tangga Batu +Inner Stone Stair=Tangga Batu Dalaman +Outer Stone Stair=Tangga Batu Luaran +Stone Slab=Papak Batu +Cobblestone Stair=Tangga Batu Buntar +Inner Cobblestone Stair=Tangga Batu Buntar Dalaman +Outer Cobblestone Stair=Tangga Batu Buntar Luaran +Cobblestone Slab=Papak Batu Buntar +Mossy Cobblestone Stair=Tangga Batu Buntar Berlumut +Inner Mossy Cobblestone Stair=Tangga Batu Buntar Berlumut Dalaman +Outer Mossy Cobblestone Stair=Tangga Batu Buntar Berlumut Luaran +Mossy Cobblestone Slab=Papak Batu Buntar Berlumut +Stone Brick Stair=Tangga Bata Batu +Inner Stone Brick Stair=Tangga Bata Batu Dalaman +Outer Stone Brick Stair=Tangga Bata Batu Luaran +Stone Brick Slab=Papak Bata Batu +Stone Block Stair=Tangga Bongkah Batu +Inner Stone Block Stair=Tangga Bongkah Batu Dalaman +Outer Stone Block Stair=Tangga Bongkah Batu Luaran +Stone Block Slab=Papak Bongkah Batu +Desert Stone Stair=Tangga Batu Gurun +Inner Desert Stone Stair=Tangga Batu Gurun Dalaman +Outer Desert Stone Stair=Tangga Batu Gurun Luaran +Desert Stone Slab=Papak Batu Gurun +Desert Cobblestone Stair=Tangga Batu Buntar Gurun +Inner Desert Cobblestone Stair=Tangga Batu Buntar Gurun Dalaman +Outer Desert Cobblestone Stair=Tangga Batu Buntar Gurun Luaran +Desert Cobblestone Slab=Papak Batu Buntar Gurun +Desert Stone Brick Stair=Tangga Bata Batu Gurun +Inner Desert Stone Brick Stair=Tangga Bata Batu Gurun Dalaman +Outer Desert Stone Brick Stair=Tangga Bata Batu Gurun Luaran +Desert Stone Brick Slab=Papak Bata Batu Gurun +Desert Stone Block Stair=Tangga Bongkah Batu Gurun +Inner Desert Stone Block Stair=Tangga Bongkah Batu Gurun Dalaman +Outer Desert Stone Block Stair=Tangga Bongkah Batu Gurun Luaran +Desert Stone Block Slab=Papak Bongkah Batu Gurun +Sandstone Stair=Tangga Batu Pasir +Inner Sandstone Stair=Tangga Batu Pasir Dalaman +Outer Sandstone Stair=Tangga Batu Pasir Luaran +Sandstone Slab=Papak Batu Pasir +Sandstone Brick Stair=Tangga Bata Batu Pasir +Inner Sandstone Brick Stair=Tangga Bata Batu Pasir Dalaman +Outer Sandstone Brick Stair=Tangga Bata Batu Pasir Luaran +Sandstone Brick Slab=Papak Bata Batu Pasir +Sandstone Block Stair=Tangga Bongkah Batu Pasir +Inner Sandstone Block Stair=Tangga Bongkah Batu Pasir Dalaman +Outer Sandstone Block Stair=Tangga Bongkah Batu Pasir Luaran +Sandstone Block Slab=Papak Bongkah Batu Pasir +Desert Sandstone Stair=Tangga Batu Pasir Gurun +Inner Desert Sandstone Stair=Tangga Batu Pasir Gurun Dalaman +Outer Desert Sandstone Stair=Tangga Batu Pasir Gurun Luaran +Desert Sandstone Slab=Papak Batu Pasir Gurun +Desert Sandstone Brick Stair=Tangga Bata Batu Pasir Gurun +Inner Desert Sandstone Brick Stair=Tangga Bata Batu Pasir Gurun Dalaman +Outer Desert Sandstone Brick Stair=Tangga Bata Batu Pasir Gurun Luaran +Desert Sandstone Brick Slab=Papak Bata Batu Pasir Gurun +Desert Sandstone Block Stair=Tangga Bongkah Batu Pasir Gurun +Inner Desert Sandstone Block Stair=Tangga Bongkah Batu Pasir Gurun Dalaman +Outer Desert Sandstone Block Stair=Tangga Bongkah Batu Pasir Gurun Luaran +Desert Sandstone Block Slab=Papak Bongkah Batu Pasir Gurun +Silver Sandstone Stair=Tangga Batu Pasir Perak +Inner Silver Sandstone Stair=Tangga Batu Pasir Perak Dalaman +Outer Silver Sandstone Stair=Tangga Batu Pasir Perak Luaran +Silver Sandstone Slab=Papak Batu Pasir Perak +Silver Sandstone Brick Stair=Tangga Bata Batu Pasir Perak +Inner Silver Sandstone Brick Stair=Tangga Bata Batu Pasir Perak Dalaman +Outer Silver Sandstone Brick Stair=Tangga Bata Batu Pasir Perak Luaran +Silver Sandstone Brick Slab=Papak Bata Batu Pasir Perak +Silver Sandstone Block Stair=Tangga Bongkah Batu Pasir Perak +Inner Silver Sandstone Block Stair=Tangga Bongkah Batu Pasir Perak Dalaman +Outer Silver Sandstone Block Stair=Tangga Bongkah Batu Pasir Perak Luaran +Silver Sandstone Block Slab=Papak Bongkah Batu Pasir Perak +Obsidian Stair=Tangga Obsidia +Inner Obsidian Stair=Tangga Obsidia Dalaman +Outer Obsidian Stair=Tangga Obsidia Luaran +Obsidian Slab=Papak Obsidia +Obsidian Brick Stair=Tangga Bata Obsidia +Inner Obsidian Brick Stair=Tangga Bata Obsidia Dalaman +Outer Obsidian Brick Stair=Tangga Bata Obsidia Luaran +Obsidian Brick Slab=Papak Bata Obsidia +Obsidian Block Stair=Tangga Bongkah Obsidia +Inner Obsidian Block Stair=Tangga Bongkah Obsidia Dalaman +Outer Obsidian Block Stair=Tangga Bongkah Obsidia Luaran +Obsidian Block Slab=Papak Bongkah Obsidia +Brick Stair=Tangga Bata +Inner Brick Stair=Tangga Bata Dalaman +Outer Brick Stair=Tangga Bata Luaran +Brick Slab=Papak Bata +Steel Block Stair=Tangga Bongkah Keluli +Inner Steel Block Stair=Tangga Bongkah Keluli Dalaman +Outer Steel Block Stair=Tangga Bongkah Keluli Luaran +Steel Block Slab=Papak Bongkah Keluli +Tin Block Stair=Tangga Bongkah Timah +Inner Tin Block Stair=Tangga Bongkah Timah Dalaman +Outer Tin Block Stair=Tangga Bongkah Timah Luaran +Tin Block Slab=Papak Bongkah Timah +Copper Block Stair=Tangga Bongkah Tembaga +Inner Copper Block Stair=Tangga Bongkah Tembaga Dalaman +Outer Copper Block Stair=Tangga Bongkah Tembaga Luaran +Copper Block Slab=Papak Bongkah Tembaga +Bronze Block Stair=Tangga Bongkah Gangsa +Inner Bronze Block Stair=Tangga Bongkah Gangsa Dalaman +Outer Bronze Block Stair=Tangga Bongkah Gangsa Luaran +Bronze Block Slab=Papak Bongkah Gangsa +Gold Block Stair=Tangga Bongkah Emas +Inner Gold Block Stair=Tangga Bongkah Emas Dalaman +Outer Gold Block Stair=Tangga Bongkah Emas Luaran +Gold Block Slab=Papak Bongkah Emas +Ice Stair=Tangga Ais +Inner Ice Stair=Tangga Ais Dalaman +Outer Ice Stair=Tangga Ais Luaran +Ice Slab=Papak Ais +Snow Block Stair=Tangga Bongkah Salji +Inner Snow Block Stair=Tangga Bongkah Salji Dalaman +Outer Snow Block Stair=Tangga Bongkah Salji Luaran +Snow Block Slab=Papak Bongkah Salji diff --git a/mods/stairs/locale/stairs.pl.tr b/mods/stairs/locale/stairs.pl.tr new file mode 100644 index 0000000..14eed7b --- /dev/null +++ b/mods/stairs/locale/stairs.pl.tr @@ -0,0 +1,145 @@ +# textdomain: stairs +Glass Stair=Schody ze szkła +Glass Slab=Półblok ze szkła +Inner Glass Stair=Wewnętrzne schody ze szkła +Outer Glass Stair=Zewnętrzne schody ze szkła +Obsidian Glass Stair=Schody z obsydianowego szkła +Obsidian Glass Slab=Półblok z obsydianowego szkła +Inner Obsidian Glass Stair=Wewnętrzne schody z obsydianowego szkła +Outer Obsidian Glass Stair=Zewnętrzne schody z obsydianowego szkła +Wooden Stair=Schody z drewna +Inner Wooden Stair=Wewnętrzne schody z drewna +Outer Wooden Stair=Zewnętrzne schody z drewna +Wooden Slab=Półblok z drewna +Jungle Wood Stair=Schody z dżunglowego drewna +Inner Jungle Wood Stair=Wewnętrzne schody z dżunglowego drewna +Outer Jungle Wood Stair=Zewnętrzne schody z dżunglowego drewna +Jungle Wood Slab=Półblok z dżunglowego drewna +Pine Wood Stair=Schody z sosnowego drzewa +Inner Pine Wood Stair=Wewnętrzne schody z sosnowego drewna +Outer Pine Wood Stair=Zewnętrzne schody z sosnowego drewna +Pine Wood Slab=Półblok z sosnowego drewna +Acacia Wood Stair=Schody z akacjowego drewna +Inner Acacia Wood Stair=Wewnętrzne schody z akacjowego drewna +Outer Acacia Wood Stair=Zewnętrzne schody z akacjowego drewna +Acacia Wood Slab=Półblok z akacjowego drewna +Aspen Wood Stair=Schody z brzozowego drewna +Inner Aspen Wood Stair=Wewnętrzne schody z brzozowego drewna +Outer Aspen Wood Stair=Zewnętrzne schody z brzozowego drewna +Aspen Wood Slab=Półblok z brzozowego drewna +Stone Stair=Schody z kamienia +Inner Stone Stair=Wewnętrzne schody z kamienia +Outer Stone Stair=Zewnętrzne schody z kamienia +Stone Slab=Półblok z kamienia +Cobblestone Stair=Schody z bruku +Inner Cobblestone Stair=Wewnętrzne schody z bruku +Outer Cobblestone Stair=Zewnętrzne schody z bruku +Cobblestone Slab=Półblok z bruku +Mossy Cobblestone Stair=Schody z bruku z mchem +Inner Mossy Cobblestone Stair=Wewnętrzne schody z bruku z mchem +Outer Mossy Cobblestone Stair=Zewnętrzne schody z bruku z mchem +Mossy Cobblestone Slab=Półblok z bruku z mchem +Stone Brick Stair=Schody z kamiennych cegieł +Inner Stone Brick Stair=Wewnętrzne schody z kamiennych cegieł +Outer Stone Brick Stair=Zewnętrzne schody z kamiennych cegieł +Stone Brick Slab=Półblok z kamiennych cegieł +Stone Block Stair=Schody z kamiennego bloku +Inner Stone Block Stair=Wewnętrzne schody z kamiennego bloku +Outer Stone Block Stair=Zewnętrzne schody z kamiennego bloku +Stone Block Slab=Półblok z kamiennego bloku +Desert Stone Stair=Schody z pustynnego kamienia +Inner Desert Stone Stair=Wewnętrzne schody z pustynnego kamienia +Outer Desert Stone Stair=Zewnętrzne schody z pustynnego kamienia +Desert Stone Slab=Półblok z pustynnego kamienia +Desert Cobblestone Stair=Schody z pustynnego bruku +Inner Desert Cobblestone Stair=Wewnętrzne schody z pustynnego bruku +Outer Desert Cobblestone Stair=Zewnętrzne schody z pustynnego bruku +Desert Cobblestone Slab=Półblok z pustynnego bruku +Desert Stone Brick Stair=Schody z pustynnych kamiennych cegieł +Inner Desert Stone Brick Stair=Wewnętrzne schody z pustynnych kamiennych cegieł +Outer Desert Stone Brick Stair=Zewnętrzne schody z pustynnych kamiennych cegieł +Desert Stone Brick Slab=Półblok z pustynnych kamiennych cegieł +Desert Stone Block Stair=Schody z pustynnego kamiennego bloku +Inner Desert Stone Block Stair=Wewnętrzne schody z pustynnego kamiennego bloku +Outer Desert Stone Block Stair=Zewnętrzne schody z pustynnego kamiennego bloku +Desert Stone Block Slab=Półblok z pustynnego kamiennego bloku +Sandstone Stair=Schody z piaskowca +Inner Sandstone Stair=Wewnętrzne schody z piaskowca +Outer Sandstone Stair=Zewnętrzne schody z piaskowca +Sandstone Slab=Półblok z piaskowca +Sandstone Brick Stair=Schody z piaskowcowych cegieł +Inner Sandstone Brick Stair=Wewnętrzne schody z piaskowcowych cegieł +Outer Sandstone Brick Stair=Zewnętrzne schody z piaskowcowych cegieł +Sandstone Brick Slab=Półblok z piaskowcowych cegieł +Sandstone Block Stair=Schody z piaskowcowego bloku +Inner Sandstone Block Stair=Wewnętrzne schody z piaskowcowego bloku +Outer Sandstone Block Stair=Zewnętrzne schody z piaskowcowego bloku +Sandstone Block Slab=Półblok z piaskowcowego bloku +Desert Sandstone Stair=Schody z pustynnego piaskowca +Inner Desert Sandstone Stair=Wewnętrzne schody z pustynnego piaskowca +Outer Desert Sandstone Stair=Zewnętrzne schody z pustynnego piaskowca +Desert Sandstone Slab=Półblok z pustynnego piaskowca +Desert Sandstone Brick Stair=Schody z pustynnych piaskowcowych cegieł +Inner Desert Sandstone Brick Stair=Wewnętrzne schody z pustynnych piaskowcowych cegieł +Outer Desert Sandstone Brick Stair=Zewnętrzne schody z pustynnych piaskowcowych cegieł +Desert Sandstone Brick Slab=Półblok z pustynnych piaskowcowych cegieł +Desert Sandstone Block Stair=Schody z pustynnego piaskowcowego bloku +Inner Desert Sandstone Block Stair=Wewnętrzne schody z pustynnego piaskowcowego bloku +Outer Desert Sandstone Block Stair=Zewnętrzne schody z pustynnego piaskowcowego bloku +Desert Sandstone Block Slab=Półblok z pustynnego piaskowcowego bloku +Silver Sandstone Stair=Schody z srebrnego piaskowca +Inner Silver Sandstone Stair=Wewnętrzne schody z srebrnego piaskowca +Outer Silver Sandstone Stair=Zewnętrzne schody z srebrnego piaskowca +Silver Sandstone Slab=Półblok z srebrnego piaskowca +Silver Sandstone Brick Stair=Schody z srebrnych piaskowcowych cegieł +Inner Silver Sandstone Brick Stair=Wewnętrzne schody z srebrnych piaskowcowych cegieł +Outer Silver Sandstone Brick Stair=Zewnętrzne schody z srebrnych piaskowcowych cegieł +Silver Sandstone Brick Slab=Półblok z srebrnych piaskowcowych cegieł +Silver Sandstone Block Stair=Schody z srebrnego piaskowcowego bloku +Inner Silver Sandstone Block Stair=Wewnętrzne schody z srebrnego piaskowcowego bloku +Outer Silver Sandstone Block Stair=Zewnętrzne schody z srebrnego piaskowcowego bloku +Silver Sandstone Block Slab=Półblok z srebrnego piaskowcowego bloku +Obsidian Stair=Schody z obsydianu +Inner Obsidian Stair=Wewnętrzne schody z obsydianu +Outer Obsidian Stair=Zewnętrzne schody z obsydianu +Obsidian Slab=Półblok z obsydianu +Obsidian Brick Stair=Schody z obsydianowych cegieł +Inner Obsidian Brick Stair=Wewnętrzne schody z obsydianowych cegieł +Outer Obsidian Brick Stair=Zewnętrzne schody z obsydianowych cegieł +Obsidian Brick Slab=Półblok z obsydianowych cegieł +Obsidian Block Stair=Schody z obsydianowego bloku +Inner Obsidian Block Stair=Wewnętrzne schody z obsydianowego bloku +Outer Obsidian Block Stair=Zewnętrzne schody z obsydianowego bloku +Obsidian Block Slab=Półblok z obsydianowego bloku +Brick Stair=Schody z cegieł +Inner Brick Stair=Wewnętrzne schody z cegieł +Outer Brick Stair=Zewnętrzne schody z cegieł +Brick Slab=Półblok z cegieł +Steel Block Stair=Schody z bloku stali +Inner Steel Block Stair=Wewnętrzne schody z bloku stali +Outer Steel Block Stair=Zewnętrzne schody z bloku stali +Steel Block Slab=Półblok z bloku stali +Tin Block Stair=Schody z bloku cyny +Inner Tin Block Stair=Wewnętrzne schody z bloku cyny +Outer Tin Block Stair=Zewnętrzne schody z bloku cyny +Tin Block Slab=Półblok z bloku cyny +Copper Block Stair=Schody z bloku miedzi +Inner Copper Block Stair=Wewnętrzne schody z bloku miedzi +Outer Copper Block Stair=Zewnętrzne schody z bloku miedzi +Copper Block Slab=Półblok z bloku miedzi +Bronze Block Stair=Schody z bloku brązu +Inner Bronze Block Stair=Wewnętrnze schody z bloku brązu +Outer Bronze Block Stair=Zewnętrzne schody z bloku brązu +Bronze Block Slab=Półblok z bloku brązu +Gold Block Stair=Schody z bloku złota +Inner Gold Block Stair=Wewnętrzne schody z block złota +Outer Gold Block Stair=Zewnętrzne schody z bloku złota +Gold Block Slab=Półblok z bloku złota +Ice Stair=Schody z lodu +Inner Ice Stair=Wewnętrzne schody z lodu +Outer Ice Stair=Zewnętrzne schody z lodu +Ice Slab=Półblok z lodu +Snow Block Stair=Schody ze śniegu +Inner Snow Block Stair=Wewnętrzne schody ze śniegu +Outer Snow Block Stair=Zewnętrzne schody ze śniegu +Snow Block Slab=Półblok ze śniegu diff --git a/mods/stairs/locale/stairs.pt_BR.tr b/mods/stairs/locale/stairs.pt_BR.tr new file mode 100644 index 0000000..41777a8 --- /dev/null +++ b/mods/stairs/locale/stairs.pt_BR.tr @@ -0,0 +1,145 @@ +# textdomain: stairs +Glass Stair=Escada de vidro +Glass Slab=Placa de vidro +Inner Glass Stair=Escada interior de vidro +Outer Glass Stair=Escada exterior de vidro +Obsidian Glass Stair=Escada de vidro de obsidiana +Obsidian Glass Slab=Placa de vidro de obsidiana +Inner Obsidian Glass Stair=Escada interior de vidro de obsidiana +Outer Obsidian Glass Stair=Escada exterior de vidro de obsidiana +Wooden Stair=Escada de madeira +Inner Wooden Stair=Escada interior de madeira +Outer Wooden Stair=Escada exterior de madeira +Wooden Slab=Laje de madeira +Jungle Wood Stair=Escada de madeira da selva +Inner Jungle Wood Stair=Escada interior de madeira da selva +Outer Jungle Wood Stair=Escada exterior de madeira da selva +Jungle Wood Slab=Laje de madeira da selva +Pine Wood Stair=Escada de madeira de pinho +Inner Pine Wood Stair=Escada interior de madeira de pinho +Outer Pine Wood Stair=Escada exterior de madeira de pinho +Pine Wood Slab=Laje de madeira de pinho +Acacia Wood Stair=Escada de madeira de acácia +Inner Acacia Wood Stair=Escada interior de madeira de acácia +Outer Acacia Wood Stair=Escada exterior de madeira de acácia +Acacia Wood Slab=Placa de madeira de acácia +Aspen Wood Stair=Escada de Álamo +Inner Aspen Wood Stair=Escada interior de Álamo +Outer Aspen Wood Stair=Escada exterior de Álamo +Aspen Wood Slab=Laje de Álamo +Stone Stair=Escada de Pedra +Inner Stone Stair=Escada interior de Pedra +Outer Stone Stair=Escada exterior de Pedra +Stone Slab=Laje de pedra +Cobblestone Stair=Escada de paralelepípedo +Inner Cobblestone Stair=Escada interior de paralelepípedo +Outer Cobblestone Stair=Escada exterior de paralelepípedo +Cobblestone Slab=Laje de paralelepípedo +Mossy Cobblestone Stair=Escada de paralelepípedo com musgo +Inner Mossy Cobblestone Stair=Escada interior de paralelepípedo com musgo +Outer Mossy Cobblestone Stair=Escada exterior de paralelepípedo com musgo +Mossy Cobblestone Slab=Laje de paralelepípedo com musgo +Stone Brick Stair=Escada de tijolo de pedra +Inner Stone Brick Stair=Escada interior de tijolo de pedra +Outer Stone Brick Stair=Escada exterior de tijolo de pedra +Stone Brick Slab=Laje de tijolo de pedra +Stone Block Stair=Escada Bloco de Pedra +Inner Stone Block Stair=Escada Interna de Bloco de Pedra +Outer Stone Block Stair=Escada Externa de Bloco de Pedra +Stone Block Slab=Laje de bloco de pedra +Desert Stone Stair=Escada de Pedra do Deserto +Inner Desert Stone Stair=Escada Interior de Pedra do Deserto +Outer Desert Stone Stair=Escada Exterior de Pedra do Deserto +Desert Stone Slab=Laje de pedra do deserto +Desert Cobblestone Stair=Escada de paralelepípedo do deserto +Inner Desert Cobblestone Stair=Escada interior de paralelepípedo do deserto +Outer Desert Cobblestone Stair=Escada exterior de paralelepípedo do deserto +Desert Cobblestone Slab=Laje de paralelepípedo do deserto +Desert Stone Brick Stair=Escada de tijolo de pedra do deserto +Inner Desert Stone Brick Stair=Escada interior de tijolos de pedra do deserto +Outer Desert Stone Brick Stair=Escada exterior de tijolos de pedra do deserto +Desert Stone Brick Slab=Laje de tijolo de pedra do deserto +Desert Stone Block Stair=Escada de Bloco de Pedra do Deserto +Inner Desert Stone Block Stair=Escada interior de bloco de pedra do deserto +Outer Desert Stone Block Stair=Escada exterior de Bloco de Pedra do Deserto +Desert Stone Block Slab=Laje do bloco de pedra do deserto +Sandstone Stair=Escada de arenito +Inner Sandstone Stair=Escada interior de arenito +Outer Sandstone Stair=Escada Exterior de Arenito +Sandstone Slab=Laje de arenito +Sandstone Brick Stair=Escada de tijolo de arenito +Inner Sandstone Brick Stair=Escada interior de tijolos de arenito +Outer Sandstone Brick Stair=Escada Exterior de Tijolo de Arenito +Sandstone Brick Slab=Laje de tijolo de arenito +Sandstone Block Stair=Escada do Bloco de Arenito +Inner Sandstone Block Stair=Escada interior de bloco de arenito +Outer Sandstone Block Stair=Escada exterior de bloco de arenito +Sandstone Block Slab=Laje de bloco de arenito +Desert Sandstone Stair=Escada de arenito do deserto +Inner Desert Sandstone Stair=Escada interior de arenito do deserto +Outer Desert Sandstone Stair=Escada exterior de arenito do deserto +Desert Sandstone Slab=Laje de arenito do deserto +Desert Sandstone Brick Stair=Escada de tijolos de arenito do deserto +Inner Desert Sandstone Brick Stair=Escada interior de tijolos de arenito do deserto +Outer Desert Sandstone Brick Stair=Escada exterior de tijolos de arenito do deserto +Desert Sandstone Brick Slab=Laje de tijolo de arenito do deserto +Desert Sandstone Block Stair=Escada do bloco de arenito do deserto +Inner Desert Sandstone Block Stair=Escada interior do bloco de arenito do deserto +Outer Desert Sandstone Block Stair=Escada exterior de bloco de arenito do deserto +Desert Sandstone Block Slab=Laje de bloco de arenito do deserto +Silver Sandstone Stair=Escada de arenito prateado +Inner Silver Sandstone Stair=Escada interior de Arenito Prateado +Outer Silver Sandstone Stair=Escada exterior de Arenito Prateado +Silver Sandstone Slab=Laje de arenito prateado +Silver Sandstone Brick Stair=Escada de tijolos de arenito prateado +Inner Silver Sandstone Brick Stair=Escada interior de tijolos de arenito prateado +Outer Silver Sandstone Brick Stair=Escada exterior de tijolos de arenito prateado +Silver Sandstone Brick Slab=Laje de tijolo de arenito prateado +Silver Sandstone Block Stair=Escada de blocos de arenito prateado +Inner Silver Sandstone Block Stair=Escada interior de bloco de arenito prateado +Outer Silver Sandstone Block Stair=Escada exterior de bloco de arenito prateado +Silver Sandstone Block Slab=Laje de bloco de arenito prateado +Obsidian Stair=Escada de Obsidiana +Inner Obsidian Stair=Escada interior de Obsidiana +Outer Obsidian Stair=Escada exterior de Obsidiana +Obsidian Slab=Laje de Obsidiana +Obsidian Brick Stair=Escada de Tijolos de Obsidiana +Inner Obsidian Brick Stair=Escada interna de Tijolos de Obsidiana +Outer Obsidian Brick Stair=Escada externa de Tijolos de Obsidiana +Obsidian Brick Slab=Laje de tijolos de obsidiana +Obsidian Block Stair=Escada de Bloco de Obsidiana +Inner Obsidian Block Stair=Escada interior de Bloco de obsidiana +Outer Obsidian Block Stair=Escada exterior de Bloco de obsidiana +Obsidian Block Slab=Laje de bloco de obsidiana +Brick Stair=Escada de Tijolos +Inner Brick Stair=Escada interior de Tijolos +Outer Brick Stair=Escada exterior de Tijolos +Brick Slab=Laje de tijolos +Steel Block Stair=Escada de bloco de aço +Inner Steel Block Stair=Escada interior de bloco de aço +Outer Steel Block Stair=Escada exterior de bloco de aço +Steel Block Slab=Laje de bloco de aço +Tin Block Stair=Escada de bloco de estanho +Inner Tin Block Stair=Escada interior de bloco de estanho +Outer Tin Block Stair=Escada exterior de bloco de lata +Tin Block Slab=Laje de bloco de estanho +Copper Block Stair=Escada de bloco de cobre +Inner Copper Block Stair=Escada interior de Bloco de Cobre +Outer Copper Block Stair=Escada exterior do Bloco de Cobre +Copper Block Slab=Laje de bloco de cobre +Bronze Block Stair=Escada Bloco de Bronze +Inner Bronze Block Stair=Escada interior de bloco de bronze +Outer Bronze Block Stair=Escada exterior de Bloco de Bronze +Bronze Block Slab=Laje de bloco de bronze +Gold Block Stair=Escada Bloco de Ouro +Inner Gold Block Stair=Escada interior de Bloco de Ouro +Outer Gold Block Stair=Escada exterior de Bloco de Ouro +Gold Block Slab=Laje de Bloco de Ouro +Ice Stair=Escada de gelo +Inner Ice Stair=Escada de gelo interior +Outer Ice Stair=Escada de gelo exterior +Ice Slab=Laje de gelo +Snow Block Stair=Escada Bloco de Neve +Inner Snow Block Stair=Escada de bloco de neve interior +Outer Snow Block Stair=Escada de bloco de neve exterior +Snow Block Slab=Laje de bloco de neve diff --git a/mods/stairs/locale/stairs.ru.tr b/mods/stairs/locale/stairs.ru.tr new file mode 100644 index 0000000..2d5850e --- /dev/null +++ b/mods/stairs/locale/stairs.ru.tr @@ -0,0 +1,145 @@ +# textdomain: stairs +Glass Stair=Стеклянная Ступень +Glass Slab=Стеклянная Плита +Inner Glass Stair=Угловая Стеклянная Ступень (Внутренний Угол) +Outer Glass Stair=Угловая Стеклянная Ступень (Внешний Угол) +Obsidian Glass Stair=Стеклянная Ступень Из Обсидиана +Obsidian Glass Slab=Стеклянная Плита Из Обсидиана +Inner Obsidian Glass Stair=Угловая Стеклянная Ступень Из Обсидиана (Внутренний Угол) +Outer Obsidian Glass Stair=Угловая Стеклянная Ступень Из Обсидиана (Внешний Угол) +Wooden Stair=Яблоневая Деревянная Ступень +Inner Wooden Stair=Угловая Яблоневая Деревянная Ступень (Внутренний Угол) +Outer Wooden Stair=Угловая Яблоневая Деревянная Ступень (Внешний Угол) +Wooden Slab=Яблоневая Деревянная Плита +Jungle Wood Stair=Тропическая Деревянная Ступень +Inner Jungle Wood Stair=Угловая Тропическая Деревянная Ступень (Внутренний Угол) +Outer Jungle Wood Stair=Угловая Тропическая Деревянная Ступень (Внешний Угол) +Jungle Wood Slab=Тропическая Деревянная Плита +Pine Wood Stair=Сосновая Деревянная Ступень +Inner Pine Wood Stair=Угловая Сосновая Деревянная Ступень (Внутренний Угол) +Outer Pine Wood Stair=Угловая Сосновая Деревянная Ступень (Внешний Угол) +Pine Wood Slab=Сосновая Деревянная Плита +Acacia Wood Stair=Деревянная Ступень Из Акации +Inner Acacia Wood Stair=Угловая Деревянная Ступень Из Акации (Внутренний Угол) +Outer Acacia Wood Stair=Угловая Деревянная Ступень Из Акации (Внешний Угол) +Acacia Wood Slab=Деревянная Плита Из Акации +Aspen Wood Stair=Осиновая Деревянная Ступень +Inner Aspen Wood Stair=Угловая Осиновая Деревянная Ступень (Внутренний Угол) +Outer Aspen Wood Stair=Угловая осиновая Деревянная Ступень (Внешний Угол) +Aspen Wood Slab=Осиновая Деревянная Плита +Stone Stair=Каменная Ступень +Inner Stone Stair=Угловая Каменная Ступень (Внутренний Угол) +Outer Stone Stair=Угловая Каменная Ступень (Внешний Угол) +Stone Slab=Каменная Плита +Cobblestone Stair=Булыжниковая Ступень +Inner Cobblestone Stair=Угловая Булыжниковая Ступень (Внутренний Угол) +Outer Cobblestone Stair=Угловая Булыжниковая Ступень (Внешний Угол) +Cobblestone Slab=Булыжниковая Плита +Mossy Cobblestone Stair=Мшистая Булыжниковая Ступень +Inner Mossy Cobblestone Stair=Угловая Мшистая Булыжниковая Ступень (Внутренний Угол) +Outer Mossy Cobblestone Stair=Угловая Мшистая Булыжниковая Ступень (Внешний Угол) +Mossy Cobblestone Slab=Мшистая Булыжниковая Плита +Stone Brick Stair=Cтупень Из Каменных Кирпичей +Inner Stone Brick Stair=Угловая Ступень Из Каменных Кирпичей (Внутренний Угол) +Outer Stone Brick Stair=Угловая Ступень Из Каменных Кирпичей (Внешний Угол) +Stone Brick Slab=Плита Из Каменных Кирпичей +Stone Block Stair=Ступень Из Каменного Блока +Inner Stone Block Stair=Угловая Ступень Из Каменного Блока (Внутренний Угол) +Outer Stone Block Stair=Угловая Ступень Из Каменного Блока (Внешний Угол) +Stone Block Slab=Плита Из Каменного Блока +Desert Stone Stair=Ступень Из Пустынного Камня +Inner Desert Stone Stair=Угловая Ступень Из Пустынного Камня (Внутренний Угол) +Outer Desert Stone Stair=Угловая Ступень Из Пустынного Камня (Внешний Угол) +Desert Stone Slab=Плита Из Пустынного Камня +Desert Cobblestone Stair=Ступень Из Пустынного Булыжника +Inner Desert Cobblestone Stair=Угловая Ступень Из Пустынного Булыжника (Внутренний Угол) +Outer Desert Cobblestone Stair=Угловая Ступень Из Пустынного Булыжника (Внешний Угол) +Desert Cobblestone Slab=Плита Из Пустынного Камня +Desert Stone Brick Stair=Ступень Из Кирпичей Пустынного Камня +Inner Desert Stone Brick Stair=Угловая Ступень Из Кирпичей Пустынного Камня (Внутренний Угол) +Outer Desert Stone Brick Stair=Угловая Ступень Из Кирпичей Пустынного Камня (Внешний Угол) +Desert Stone Brick Slab=Плита Из Кирпичей Пустынного Камня +Desert Stone Block Stair=Ступень Из Пустынного Каменного Блока +Inner Desert Stone Block Stair=Угловая Ступень Из Пустынного Каменного Блока (Внутренний Угол) +Outer Desert Stone Block Stair=Угловая Ступень Из Пустынного Каменного Блока (Внешний Угол) +Desert Stone Block Slab=Плита Из Пустынного Каменного Блока +Sandstone Stair=Песчаниковая Ступень +Inner Sandstone Stair=Угловая Песчаниковая Ступень (Внутренний Угол) +Outer Sandstone Stair=Угловая Песчаниковая Ступень (Внешний Угол) +Sandstone Slab=Песчаниковая Плита +Sandstone Brick Stair=Ступень Из Песчаниковых Кирпичей +Inner Sandstone Brick Stair=Угловая Ступень Из Песчаниковых Кирпичей (Внутренний Угол) +Outer Sandstone Brick Stair=Угловая Ступень Из Песчаниковых Кирпичей (Внешний Угол) +Sandstone Brick Slab=Плита Из Песчаниковых Кирпичей +Sandstone Block Stair=Ступень Из Песчаникового Блока +Inner Sandstone Block Stair=Угловая Ступень Из Песчаникового Блока (Внутренний Угол) +Outer Sandstone Block Stair=Угловая Ступень Из Песчаникового Блока (Внешний Угол) +Sandstone Block Slab=Плита Из Песчаникового Блока +Desert Sandstone Stair=Ступень Из Пустынного Песчаника +Inner Desert Sandstone Stair=Угловая Ступень Из Пустынного Песчаника (Внутренний Угол) +Outer Desert Sandstone Stair=Угловая Ступень Из Пустынного Песчаника (Внешний Угол) +Desert Sandstone Slab=Плита Из Пустынного Песчаника +Desert Sandstone Brick Stair=Ступень Из Кирпичей Пустынного Песчаника +Inner Desert Sandstone Brick Stair=Угловая Ступень Из Кирпичей Пустынного Песчаника (Внутренний Угол) +Outer Desert Sandstone Brick Stair=Угловая Ступень Из Кирпичей Пустынного Песчаника (Внешний Угол) +Desert Sandstone Brick Slab=Плита Из Кирпичей Пустынного Песчаника +Desert Sandstone Block Stair=Ступень Из Пустынного Песчаникового Блока +Inner Desert Sandstone Block Stair=Угловая Ступень Из Пустынного Песчаникового Блока (Внутренний Угол) +Outer Desert Sandstone Block Stair=Угловая Ступень Из Пустынного Песчаникового Блока (Внешний Угол) +Desert Sandstone Block Slab=Плита Из Пустынного Песчаникового Блока +Silver Sandstone Stair=Ступень Из Серебрянного Песчаника +Inner Silver Sandstone Stair=Угловая Ступень Из Серебряного Песчаника (Внутренний Угол) +Outer Silver Sandstone Stair=Угловая Ступень Из Серебряного Песчаника (Внешний Угол) +Silver Sandstone Slab=Плита Из Серебряного Песчаника +Silver Sandstone Brick Stair=Ступень Из Кирпичей Серебряного Песчаника +Inner Silver Sandstone Brick Stair=Угловая Ступень Из Кирпичей Серебряного Песчаника (Внутренний Угол) +Outer Silver Sandstone Brick Stair=Угловая Ступень Из Кирпичей Серебряного Песчаника (Внешний Угол) +Silver Sandstone Brick Slab=Плита Из Кирпичей Серебряного Песчаника +Silver Sandstone Block Stair=Ступень Из Серебряного Песчаникового Блока +Inner Silver Sandstone Block Stair=Угловая Ступень Из Серебряного Песчаникового Блока (Внутренний Угол) +Outer Silver Sandstone Block Stair=Угловая Ступень Из Серебряного Песчаникового Блока (Внешний Угол) +Silver Sandstone Block Slab=Плита Из Серебряного Песчаникового Блока +Obsidian Stair=Обсидиановая Ступень +Inner Obsidian Stair=Угловая Обсидиановая Ступень (Внутренний Угол) +Outer Obsidian Stair=Угловая Обсидиановая Ступень (Внешний Угол) +Obsidian Slab=Обсидиановая Плита +Obsidian Brick Stair=Ступень Из Обсидиановых Кирпичей +Inner Obsidian Brick Stair=Угловая Ступень Из Обсидиановых Кирпичей (Внутренний Угол) +Outer Obsidian Brick Stair=Угловая Ступень Из Обсидиановых Кирпичей (Внешний Угол) +Obsidian Brick Slab=Плита Из Обсидиановых Кирпичей +Obsidian Block Stair=Ступень Из Обсидианового Блока +Inner Obsidian Block Stair=Угловая Ступень Из Обсидианового Блока (Внутренний Угол) +Outer Obsidian Block Stair=Угловая Ступень Из Обсидианового Блока (Внешний Угол) +Obsidian Block Slab=Плита Из Обсидианового Блока +Brick Stair=Ступень Из Кирпичей +Inner Brick Stair=Угловая Ступень Из Кирпичей (Внутренний Угол) +Outer Brick Stair=Угловая Ступень Из Кирпичей (Внешний Угол) +Brick Slab=Плита Из Кирпичей +Steel Block Stair=Ступень Из Стального Блока +Inner Steel Block Stair=Угловая Ступень Из Стального Блока (Внутренний Угол) +Outer Steel Block Stair=Угловая Ступень Из Стального Блока (Внешний Угол) +Steel Block Slab=Плита Из Стального Блока +Tin Block Stair=Ступень Из Оловянного Блока +Inner Tin Block Stair=Угловая Ступень Из Оловянного Блока (Внутренний Угол) +Outer Tin Block Stair=Угловая Ступень Из Оловянного Блока (Внешний Угол) +Tin Block Slab=Плита Из Оловянного Блока +Copper Block Stair=Ступень Из Медного Блока +Inner Copper Block Stair=Угловая Ступень Из Медного Блока (Внутренний Угол) +Outer Copper Block Stair=Угловая Ступень Из Медного Блока (Внешний Угол) +Copper Block Slab=Плита Из Медного Блока +Bronze Block Stair=Ступень Из Бронзового Блока +Inner Bronze Block Stair=Угловая Ступень Из Бронзового Блока (Внутренний Угол) +Outer Bronze Block Stair=Угловая Ступень Из Бронзового Блока (Внешний Угол) +Bronze Block Slab=Плита Из Бронзового Блока +Gold Block Stair=Ступень Из Золотого Блока +Inner Gold Block Stair=Угловая Ступень Из Золотого Блока (Внутренний Угол) +Outer Gold Block Stair=Угловая Ступень Из Золотого Блока (Внешний Угол) +Gold Block Slab=Плита Из Золотого Блока +Ice Stair=Ледяная Ступень +Inner Ice Stair=Угловая Ледяная Ступень (Внутренний Угол) +Outer Ice Stair=Угловая Ледяная Ступень (Внешний Угол) +Ice Slab=Ледяная Плита +Snow Block Stair=Ступень Из Снежного Блока +Inner Snow Block Stair=Угловая Ступень Из Снежного Блока (Внутренний Угол) +Outer Snow Block Stair=Угловая Ступень Из Снежного Блока (Внешний Угол) +Snow Block Slab=Плита Из Снежного Блока diff --git a/mods/stairs/locale/stairs.sk.tr b/mods/stairs/locale/stairs.sk.tr new file mode 100644 index 0000000..b006fdb --- /dev/null +++ b/mods/stairs/locale/stairs.sk.tr @@ -0,0 +1,145 @@ +# textdomain: stairs +Glass Stair=Sklenené schod +Glass Slab=Sklenený stupienok +Inner Glass Stair=Vnútorný sklenené schod +Outer Glass Stair=Vonkajší sklenené schod +Obsidian Glass Stair=Obsidiánové sklenené schod +Obsidian Glass Slab=Obsidiánový sklenený stupienok +Inner Obsidian Glass Stair=Vnútorný obsidiánové sklenené schod +Outer Obsidian Glass Stair=Vonkajší obsidiánové sklenené schod +Wooden Stair=Drevené schod +Inner Wooden Stair=Vnútorný drevené schod +Outer Wooden Stair=Vonkajší drevené schod +Wooden Slab=Drevený stupienok +Jungle Wood Stair=Drevené schod z džungľového dreva +Inner Jungle Wood Stair=Vnútorný drevené schod z džungľového dreva +Outer Jungle Wood Stair=Vonkajší drevené schod z džungľového dreva +Jungle Wood Slab=Stupienok z džungľového dreva +Pine Wood Stair=Drevené schod z borovicového dreva +Inner Pine Wood Stair=Vnútorný drevené schod z borovicového dreva +Outer Pine Wood Stair=Vonkajší drevené schod z borovicového dreva +Pine Wood Slab=Stupienok z borovicového dreva +Acacia Wood Stair=Drevené schod z akáciového dreva +Inner Acacia Wood Stair=Vnútorný drevené schod z akáciového dreva +Outer Acacia Wood Stair=Vonkajší drevené schod z akáciového dreva +Acacia Wood Slab=Stupienok z akáciového dreva +Aspen Wood Stair=Drevené schod z osiky +Inner Aspen Wood Stair=Vnútorný drevené schod z osiky +Outer Aspen Wood Stair=Vonkajší drevené schod z osiky +Aspen Wood Slab=Stupienok z osiky +Stone Stair=Kamenné schod +Inner Stone Stair=Vnútorný kamenné schod +Outer Stone Stair=Vonkajší kamenné schod +Stone Slab=Kamenný stupienok +Cobblestone Stair=Schod z dlažbového kameňa +Inner Cobblestone Stair=Vnútorný schod z dlažbového kameňa +Outer Cobblestone Stair=Vonkajší schod z dlažbového kameňa +Cobblestone Slab=Stupienok z dlažbového kameňa +Mossy Cobblestone Stair=Schod dlažbového kameňa obrastené machom +Inner Mossy Cobblestone Stair=Vnútorný schod dlažbového kameňa obrastené machom +Outer Mossy Cobblestone Stair=Vonkajší schod dlažbového kameňa obrastené machom +Mossy Cobblestone Slab=Stupienok z dlažbového kameňa obrastený machom +Stone Brick Stair=Schod z kamenných tehál +Inner Stone Brick Stair=Vnútorný schod z kamenných tehál +Outer Stone Brick Stair=Vonkajší schod z kamenných tehál +Stone Brick Slab=Stupienok z kamenných tehál +Stone Block Stair=Schod z kameňa +Inner Stone Block Stair=Vnútorný schod z kameňa +Outer Stone Block Stair=Vonkajší schod z kameňa +Stone Block Slab=Stupienok z kameňa +Desert Stone Stair=Schod z púštneho kameňa +Inner Desert Stone Stair=Vnútorný schod z púštneho kameňa +Outer Desert Stone Stair=Vonkajší schod z púštneho kameňa +Desert Stone Slab=Stupienok z púštneho kameňa +Desert Cobblestone Stair=Schod z púštneho dlažbového kameňa +Inner Desert Cobblestone Stair=Vnútorný schod z púštneho dlažbového kameňa +Outer Desert Cobblestone Stair=Vonkajší schod z púštneho dlažbového kameňa +Desert Cobblestone Slab=Stupienok z púštneho dlažbového kameňa +Desert Stone Brick Stair=Schod z tehiel z púštneho kameňa +Inner Desert Stone Brick Stair=Vnútorný schod z tehiel z púštneho kameňa +Outer Desert Stone Brick Stair=Vonkajší schod z tehiel z púštneho kameňa +Desert Stone Brick Slab=Stupienok z tehiel z púštneho kameňa +Desert Stone Block Stair=Schod z blokov púštneho kameňa +Inner Desert Stone Block Stair=Vnútorný schod z blokov púštneho kameňa +Outer Desert Stone Block Stair=Vonkajší schod z blokov púštneho kameňa +Desert Stone Block Slab=Stupienok z blokov púštneho kameňa +Sandstone Stair=Schod z pieskovca +Inner Sandstone Stair=Vnútorný schod z pieskovca +Outer Sandstone Stair=Vonkajší schod z pieskovca +Sandstone Slab=Stupienok z pieskovca +Sandstone Brick Stair=Schod z tehál pieskovca +Inner Sandstone Brick Stair=Vnútorný schod z tehál pieskovca +Outer Sandstone Brick Stair=Vonkajší schod z tehál pieskovca +Sandstone Brick Slab=Stupienok z tehál pieskovca +Sandstone Block Stair=Schod z blokov pieskovca +Inner Sandstone Block Stair=Vnútorný schod z blokov pieskovca +Outer Sandstone Block Stair=Vonkajší schod z blokov pieskovca +Sandstone Block Slab=Stupienok z blokov pieskovca +Desert Sandstone Stair=Schod z púštneho pieskovca +Inner Desert Sandstone Stair=Vnútorný schod z púštneho pieskovca +Outer Desert Sandstone Stair=Vonkajší schod z púštneho pieskovca +Desert Sandstone Slab=Stupienok z púštneho pieskovca +Desert Sandstone Brick Stair=Schod z tehál z púštneho pieskovca +Inner Desert Sandstone Brick Stair=Vnútorný schod z tehál z púštneho pieskovca +Outer Desert Sandstone Brick Stair=Vonkajší schod z tehál z púštneho pieskovca +Desert Sandstone Brick Slab=Stupienok z tehál z púštneho pieskovca +Desert Sandstone Block Stair=Schod z blokov púštneho pieskovca +Inner Desert Sandstone Block Stair=Vnútorný schod z blokov púštneho pieskovca +Outer Desert Sandstone Block Stair=Vonkajší schod z blokov púštneho pieskovca +Desert Sandstone Block Slab=Stupienok z blokov púštneho pieskovca +Silver Sandstone Stair=Schod zo strieborného pieskovca +Inner Silver Sandstone Stair=Vnútorný schod zo strieborného pieskovca +Outer Silver Sandstone Stair=Vonkajší schod zo strieborného pieskovca +Silver Sandstone Slab=Stupienok zo strieborného pieskovca +Silver Sandstone Brick Stair=Schod z tehál zo strieborného pieskovca +Inner Silver Sandstone Brick Stair=Vnútorný schod z tehál zo strieborného pieskovca +Outer Silver Sandstone Brick Stair=Vonkajší schod z tehál zo strieborného pieskovca +Silver Sandstone Brick Slab=Stupienok z tehál zo strieborného pieskovca +Silver Sandstone Block Stair=Schod z blokov strieborného pieskovca +Inner Silver Sandstone Block Stair=Vnútorný schod z blokov strieborného pieskovca +Outer Silver Sandstone Block Stair=Vonkajší schod z blokov strieborného pieskovca +Silver Sandstone Block Slab=Stupienok z blokov strieborného pieskovca +Obsidian Stair=Schod z obsidiánu +Inner Obsidian Stair=Vnútorný schod z obsidiánu +Outer Obsidian Stair=Vonkajší schod z obsidiánu +Obsidian Slab=Stupienok z obsidiánu +Obsidian Brick Stair=Schod z tehál obsidiánu +Inner Obsidian Brick Stair=Vnútorný schod z tehál obsidiánu +Outer Obsidian Brick Stair=Vonkajší schod z tehál obsidiánu +Obsidian Brick Slab=Stupienok z tehál obsidiánu +Obsidian Block Stair=Schod z bloku obsidiánu +Inner Obsidian Block Stair=Vnútorný schod z bloku obsidiánu +Outer Obsidian Block Stair=Vonkajší schod z bloku obsidiánu +Obsidian Block Slab=Stupienok z bloku obsidiánu +Brick Stair=Schod z tehál +Inner Brick Stair=Vnútorný schod z tehál +Outer Brick Stair=Vonkajší schod z tehál +Brick Slab=Stupienok z tehál +Steel Block Stair=Oceľový schod +Inner Steel Block Stair=Vnútorný oceľový schod +Outer Steel Block Stair=Vonkajší oceľový schod +Steel Block Slab=Oceľový stupienok +Tin Block Stair=Cínový schod +Inner Tin Block Stair=Vnútorný cínový schod +Outer Tin Block Stair=Vonkajší cínový schod +Tin Block Slab=Cínový stupienok +Copper Block Stair=Medený schod +Inner Copper Block Stair=Vnútorný medený schod +Outer Copper Block Stair=Vonkajší medený schod +Copper Block Slab=Medený stupienok +Bronze Block Stair=Bronzový schod +Inner Bronze Block Stair=Vnútorný bronzový schod +Outer Bronze Block Stair=Vonkajší bronzový schod +Bronze Block Slab=Bronzový stupienok +Gold Block Stair=Zlatý schod +Inner Gold Block Stair=Vnútorný zlatý schod +Outer Gold Block Stair=Vonkajší zlatý schod +Gold Block Slab=Zlatý stupienok +Ice Stair=Ľadový schod +Inner Ice Stair=Vnútorný ľadový schod +Outer Ice Stair=Vonkajší ľadový schod +Ice Slab=Ľadový stupienok +Snow Block Stair=Snehový schod +Inner Snow Block Stair=Vnútorný snehový schod +Outer Snow Block Stair=Vonkajší snehový schod +Snow Block Slab=Snehový stupienok diff --git a/mods/stairs/locale/stairs.sv.tr b/mods/stairs/locale/stairs.sv.tr new file mode 100644 index 0000000..8044af8 --- /dev/null +++ b/mods/stairs/locale/stairs.sv.tr @@ -0,0 +1,145 @@ +# textdomain: stairs +Glass Stair=Glastrappa +Glass Slab=Glasplatta +Inner Glass Stair=Inre glasstrappa +Outer Glass Stair=Yttre glasstrappa +Obsidian Glass Stair=Obsidianglasstrappa +Obsidian Glass Slab=Obsidianglasplatta +Inner Obsidian Glass Stair=Inre obsidianglastrappa +Outer Obsidian Glass Stair=Yttre obsidianglastrappa +Wooden Stair=Trätrappa +Inner Wooden Stair=Inre trätrappa +Outer Wooden Stair=Yttre trätrappa +Wooden Slab=Träplatta +Jungle Wood Stair=Djungelträtrappa +Inner Jungle Wood Stair=Inre djungelträtrappa +Outer Jungle Wood Stair=Ytter djungelträtrappa +Jungle Wood Slab=Djungelträplatta +Pine Wood Stair=Tallträplatta +Inner Pine Wood Stair=Inre tallträplatta +Outer Pine Wood Stair=Ytter tallträplatta +Pine Wood Slab=Tallskiva +Acacia Wood Stair=Acaciatrappa +Inner Acacia Wood Stair=Inre acaciatrappa +Outer Acacia Wood Stair=Yttre acaciatrappa +Acacia Wood Slab=Acaciaplatta +Aspen Wood Stair=Aspträtrappa +Inner Aspen Wood Stair=Inre aspträtrappa +Outer Aspen Wood Stair=Yttre aspträtrappa +Aspen Wood Slab=Aspträplatta +Stone Stair=Stentrappa +Inner Stone Stair=Inre stentrappa +Outer Stone Stair=Yttre stentrappa +Stone Slab=Stenplatta +Cobblestone Stair=Kullerstenstrappa +Inner Cobblestone Stair=Inre kullerstenstrappa +Outer Cobblestone Stair=Yttre kullerstenstrappa +Cobblestone Slab=Kullerstenplatta +Mossy Cobblestone Stair=Mossig kullerstenstrappa +Inner Mossy Cobblestone Stair=Inre mossig kullerstenstrappa +Outer Mossy Cobblestone Stair=Yttre mossig kullerstenstrappa +Mossy Cobblestone Slab=Mossig kullerstenplatta +Stone Brick Stair=Stentegeltrappa +Inner Stone Brick Stair=Inre stentegeltrappa +Outer Stone Brick Stair=Yttre stentegeltrappa +Stone Brick Slab=Stentegelplatta +Stone Block Stair=Stenblockstrappa +Inner Stone Block Stair=Inre stenblockstrappa +Outer Stone Block Stair=Yttre stenblockstrappa +Stone Block Slab=Stenblocksplatta +Desert Stone Stair=Ökenstentrappa +Inner Desert Stone Stair=Inre ökenstentrappa +Outer Desert Stone Stair=Yttre ökenstentrappa +Desert Stone Slab=Ökenstenplatta +Desert Cobblestone Stair=Ökenkullerstenstrappa +Inner Desert Cobblestone Stair=Inre ökenkullerstenstrappa +Outer Desert Cobblestone Stair=Yttre ökenkullerstenstrappa +Desert Cobblestone Slab=Ökenkullerstensplatta +Desert Stone Brick Stair=Ökentegelstenstrappa +Inner Desert Stone Brick Stair=Inre Ökentegelstenstrappa +Outer Desert Stone Brick Stair=Yttre Ökentegelstenstrappa +Desert Stone Brick Slab=Ökentegelstensplatta +Desert Stone Block Stair=Ökenstenblockstrappa +Inner Desert Stone Block Stair=Inre ökenstenblockstrappa +Outer Desert Stone Block Stair=Yttre ökenstenblockstrappa +Desert Stone Block Slab=Ökenstenblocksplatta +Sandstone Stair=Sandstenstrappa +Inner Sandstone Stair=Inre Sandstenstrappa +Outer Sandstone Stair=Yttre Sandstenstrappa +Sandstone Slab=Sandstenplatta +Sandstone Brick Stair=Sandstentegeltrappa +Inner Sandstone Brick Stair=Inre Sandstentegeltrappa +Outer Sandstone Brick Stair=Yttre Sandstentegeltrappa +Sandstone Brick Slab=Sandstentegelplatta +Sandstone Block Stair=Sandstenblockstrappa +Inner Sandstone Block Stair=Inre Sandstenblockstrappa +Outer Sandstone Block Stair=Yttre Sandstenblockstrappa +Sandstone Block Slab=Sandstenblocksplatta +Desert Sandstone Stair=Ökensandstenstrappa +Inner Desert Sandstone Stair=Inre ökensandstenstrappa +Outer Desert Sandstone Stair=Yttre ökensandstenstrappa +Desert Sandstone Slab=Ökensandstensplatta +Desert Sandstone Brick Stair=Ökensandstentegeltrappa +Inner Desert Sandstone Brick Stair=Inre ökensandstentegeltrappa +Outer Desert Sandstone Brick Stair=Yttre ökensandstentegeltrappa +Desert Sandstone Brick Slab=Ökensandstentegelplatta +Desert Sandstone Block Stair=Ökensandstentegeltrappa +Inner Desert Sandstone Block Stair=Inre ökensandstentegeltrappa +Outer Desert Sandstone Block Stair=Yttre ökensandstentegeltrappa +Desert Sandstone Block Slab=Ökensandstentegelplatta +Silver Sandstone Stair=Silversandstenstrappa +Inner Silver Sandstone Stair=Inre silversandstenstrappa +Outer Silver Sandstone Stair=Yttre silversandstenstrappa +Silver Sandstone Slab=Silversandstenstrappa +Silver Sandstone Brick Stair=Silversandstenstegeltrappa +Inner Silver Sandstone Brick Stair=Inre silversandstenstegeltrappa +Outer Silver Sandstone Brick Stair=Yttre silversandstenstegeltrappa +Silver Sandstone Brick Slab=Silversandstenstegelplatta +Silver Sandstone Block Stair=Silversandstenblockstrappa +Inner Silver Sandstone Block Stair=Inre silversandstenblockstrappa +Outer Silver Sandstone Block Stair=Yttre silversandstenblockstrappa +Silver Sandstone Block Slab=Silversandstenblocksplatta +Obsidian Stair=Obsidiantrappa +Inner Obsidian Stair=Inre obsidiantrappa +Outer Obsidian Stair=Yttre obsidiantrappa +Obsidian Slab=Obsidianplatta +Obsidian Brick Stair=Obsidiantegeltrappa +Inner Obsidian Brick Stair=Inre obsidiantegeltrappa +Outer Obsidian Brick Stair=Yttre obsidiantegeltrappa +Obsidian Brick Slab=Obsidiantegelplatta +Obsidian Block Stair=Obsidianblocktrappa +Inner Obsidian Block Stair=Inre Obsidianblocktrappa +Outer Obsidian Block Stair=Yttre Obsidianblocktrappa +Obsidian Block Slab=Obsidianblockplatta +Brick Stair=Tegeltrappa +Inner Brick Stair=Inre tegeltrappa +Outer Brick Stair=Yttre tegeltrappa +Brick Slab=Tegelplatta +Steel Block Stair=Ståltrappa +Inner Steel Block Stair=Inre ståltrappa +Outer Steel Block Stair=Yttre ståltrappa +Steel Block Slab=Stålplatta +Tin Block Stair=Tenntrappa +Inner Tin Block Stair=Inre tenntrappa +Outer Tin Block Stair=Yttre tenntrappa +Tin Block Slab=Tennplatta +Copper Block Stair=Koppartrappa +Inner Copper Block Stair=Inre koppartrappa +Outer Copper Block Stair=Yttre koppartrappa +Copper Block Slab=Kopparplatta +Bronze Block Stair=Bronstrappa +Inner Bronze Block Stair=Inre bronstrappa +Outer Bronze Block Stair=Yttre bronstrappa +Bronze Block Slab=Bronsplatta +Gold Block Stair=Guldtrappa +Inner Gold Block Stair=Inre guldtrappa +Outer Gold Block Stair=Yttre guldtrappa +Gold Block Slab=Guldplatta +Ice Stair=Istrappa +Inner Ice Stair=Inre istrappa +Outer Ice Stair=Yttre istrappa +Ice Slab=Isplatta +Snow Block Stair=Snöblockstrappa +Inner Snow Block Stair=Inre snöblockstrappa +Outer Snow Block Stair=Yttre snöblockstrappa +Snow Block Slab=Snöblocksplatta diff --git a/mods/stairs/locale/stairs.uk.tr b/mods/stairs/locale/stairs.uk.tr new file mode 100644 index 0000000..f501b5e --- /dev/null +++ b/mods/stairs/locale/stairs.uk.tr @@ -0,0 +1,145 @@ +# textdomain: stairs +Glass Stair=Скляна Сходинка +Glass Slab=Скляна Плита +Inner Glass Stair=Кутова Скляна Сходинка (Внутрішній Кут) +Outer Glass Stair=Кутова Скляна Сходинка (Зовнішній Кут) +Obsidian Glass Stair=Скляна Сходинка З Обсидіану +Obsidian Glass Slab=Скляна Плита З Обсидіану +Inner Obsidian Glass Stair=Кутова Скляна Сходинка З Обсидіану (Внутрішній Кут) +Outer Obsidian Glass Stair=Кутова Скляна Сходинка З Обсидіану (Зовнішній Кут) +Wooden Stair=Яблунева Дерев'яна Сходинка +Inner Wooden Stair=Кутова Яблунева Дерев'яна Сходинка (Внутрішній Кут) +Outer Wooden Stair=Кутова Яблунева Дерев'яна Сходинка (Внутрішній Кут) +Wooden Slab=Яблунева Дерев'яна Плита +Jungle Wood Stair=Дерев'яна Сходинка З Тропічного Дерева +Inner Jungle Wood Stair=Кутова Дерев'яна Сходинка З Тропічного Дерева (Внутрішній Кут) +Outer Jungle Wood Stair=Кутова Дерев'яна Сходинка З Тропічного Дерева (Зовнішній Кут) +Jungle Wood Slab=Дерев'яна Плита З Тропічного Дерева +Pine Wood Stair=Дерев'яна Сходинка З Сосни +Inner Pine Wood Stair=Кутова Дерев'яна Сходинка З Сосни (Внутрішній Кут) +Outer Pine Wood Stair=Кутова Дерев'яна Сходинка З Сосни (Зовнішній Кут) +Pine Wood Slab=Дерев'яна Плита З Сосни +Acacia Wood Stair=Дерев'яна Сходинка З Акації +Inner Acacia Wood Stair=Кутова Дерев'яна Сходинка З Акації (Внутрішній Кут) +Outer Acacia Wood Stair=Кутова Дерев'яна Сходинка З Акації (Зовнішній Кут) +Acacia Wood Slab=Дерев'яна Плита З Акації +Aspen Wood Stair=Дерев'яна Сходинка З Осики +Inner Aspen Wood Stair=Кутова Дерев'яна Сходинка З Осики (Внутрішній Кут) +Outer Aspen Wood Stair=Кутова Дерев'яна Сходинка З Осики (Зовнішній Кут) +Aspen Wood Slab=Дерев'яна Плита З Осики +Stone Stair=Кам'яна Сходинка +Inner Stone Stair=Кутова Кам'яна Сходинка (Внутрішній Кут) +Outer Stone Stair=Кутова Кам'яна Сходинка (Зовнішній Кут) +Stone Slab=Кам'яна Плита +Cobblestone Stair=Сходинка З Кругляку +Inner Cobblestone Stair=Кутова Сходинка З Кругляку (Внутрішній Кут) +Outer Cobblestone Stair=Кутова Сходинка З Кругляку (Зовнішній Кут) +Cobblestone Slab=Плита З Кругляку +Mossy Cobblestone Stair=Мохова Сходинка З Кругляку +Inner Mossy Cobblestone Stair=Кутова Мохова Сходинка З Кругляку (Внутрішній Кут) +Outer Mossy Cobblestone Stair=Кутова Мохова Сходинка З Кругляку (Зовнішній Кут) +Mossy Cobblestone Slab=Мохова Плита З Кругляку +Stone Brick Stair=Сходинка З Кам'яної Цегли +Inner Stone Brick Stair=Кутова Сходинка З Кам'яної Цегли (Внутрішній Кут) +Outer Stone Brick Stair=Кутова Сходинка З Кам'яної Цегли (Зовнішній Кут) +Stone Brick Slab=Плита З Кам'яної Цегли +Stone Block Stair=Сходинка З Кам'яного Блоку +Inner Stone Block Stair=Кутова Сходинка З Кам'яного Блоку (Внутрішній Кут) +Outer Stone Block Stair=Кутова Сходинка З Кам'яного Блоку (Зовнішній Кут) +Stone Block Slab=Плита З Кам'яного Блоку +Desert Stone Stair=Сходинка З Пустельного Каменю +Inner Desert Stone Stair=Кутова Сходинка З Пустельного Каменю (Внутрішній Кут) +Outer Desert Stone Stair=Кутова Сходинка З Пустельного Каменю (Зовнішній Кут) +Desert Stone Slab=Плита З Пустельного Каменю +Desert Cobblestone Stair=Сходинка З Пустельного Кругляку +Inner Desert Cobblestone Stair=Кутова Сходинка З Пустельного Кругляку (Внутрішній Кут) +Outer Desert Cobblestone Stair=Кутова Сходинка З Пустельного Кругляку (Зовнішній Кут) +Desert Cobblestone Slab=Плита З Пустельного Каменю +Desert Stone Brick Stair=Сходинка З Цегли Із Пустельного Каменю +Inner Desert Stone Brick Stair=Кутова Сходинка З Цегли Із Пустельного Каменю (Внутрішній Кут) +Outer Desert Stone Brick Stair=Кутова Сходинка З Цегли Із Пустельного Каменю (Зовнішній Кут) +Desert Stone Brick Slab=Плита З Цегли Із Пустельного Каменю +Desert Stone Block Stair=Сходинка З Пустельного Кам'яного Блоку +Inner Desert Stone Block Stair=Кутова Сходинка З Пустельного Кам'яного Блоку (Внутрішній Кут) +Outer Desert Stone Block Stair=Кутова Сходинка З Пустельного Кам'яного Блоку (Зовнішній Кут) +Desert Stone Block Slab=Плита З Пустельного Кам'яного Блоку +Sandstone Stair=Сходинка З Піщанику +Inner Sandstone Stair=Кутова Сходинка З Піщанику (Внутрішній Кут) +Outer Sandstone Stair=Кутова Сходинка З Піщанику (Зовнішній Кут) +Sandstone Slab=Плита З Піщанику +Sandstone Brick Stair=Сходинка З Цегли Із Піщанику +Inner Sandstone Brick Stair=Кутова Сходинка З Цегли Із Піщанику (Внутрішній Кут) +Outer Sandstone Brick Stair=Кутова Сходинка З Цегли Із Піщанику (Зовнішній Кут) +Sandstone Brick Slab=Плита З Цегли Із Піщанику +Sandstone Block Stair=Сходинка З Блоку Із Піщанику +Inner Sandstone Block Stair=Кутова Сходинка З Блоку Із Піщанику (Внутрішній Кут) +Outer Sandstone Block Stair=Кутова Сходинка З Блоку Із Піщанику (Зовнішній Кут) +Sandstone Block Slab=Плита З Блоку Із Піщанику +Desert Sandstone Stair=Сходинка З Пустельного Піщанику +Inner Desert Sandstone Stair=Кутова Сходинка З Пустельного Піщанику (Внутрішній Кут) +Outer Desert Sandstone Stair=Кутова Сходинка З Пустельного Піщанику (Зовнішній Кут) +Desert Sandstone Slab=Плита З Пустельного Піщанику +Desert Sandstone Brick Stair=Сходинка З Цегли Із Пустельного Піщанику +Inner Desert Sandstone Brick Stair=Кутова Сходинка З Цегли Із Пустельного Піщанику (Внутрішній Кут) +Outer Desert Sandstone Brick Stair=Кутова Сходинка З Цегли Із Пустельного Піщанику (Зовнішній Кут) +Desert Sandstone Brick Slab=Плита З Цегли Із Пустельного Піщанику +Desert Sandstone Block Stair=Сходинка З Блоку Із Пустельного Піщанику +Inner Desert Sandstone Block Stair=Кутова Сходинка З Блоку Із Пустельного Піщанику (Внутрішній Кут) +Outer Desert Sandstone Block Stair=Кутова Сходинка З Блоку Із Пустельного Піщанику (Зовнішній Кут) +Desert Sandstone Block Slab=Плита З Блоку Із Пустельного Піщанику +Silver Sandstone Stair=Сходинка З Срібного Піщанику +Inner Silver Sandstone Stair=Кутова Сходинка З Срібного Піщанику (Внутрішній Кут) +Outer Silver Sandstone Stair=Кутова Сходинка З Срібного Піщанику (Зовнішній Кут) +Silver Sandstone Slab=Плита З Срібного Піщанику +Silver Sandstone Brick Stair=Сходинка З Цегли Із Срібного Піщанику +Inner Silver Sandstone Brick Stair=Кутова Сходинка З Цегли Із Срібного Піщанику (Внутрішній Кут) +Outer Silver Sandstone Brick Stair=Кутова Сходинка З Цегли Із Срібного Піщанику (Зовнішній Кут) +Silver Sandstone Brick Slab=Плита З Цегли Із Срібного Піщанику +Silver Sandstone Block Stair=Сходинка З Блоку Із Срібного Піщанику +Inner Silver Sandstone Block Stair=Кутова Сходинка З Блоку Із Срібного Піщанику (Внутрішній Кут) +Outer Silver Sandstone Block Stair=Кутова Сходинка З Блоку Із Срібного Піщанику (Зовнішній Кут) +Silver Sandstone Block Slab=Плита З Блоку Із Срібного Піщанику +Obsidian Stair=Обсидіанова Сходинка +Inner Obsidian Stair=Кутова Обсидіанова Сходинка (Внутрішній Кут) +Outer Obsidian Stair=Кутова Обсидіанова Сходинка (Зовнішній Кут) +Obsidian Slab=Обсидіанова Плита +Obsidian Brick Stair=Сходинка З Обсидіанової Цегли +Inner Obsidian Brick Stair=Кутова Сходинка З Обсидіанової Цегли (Внутрішній Кут) +Outer Obsidian Brick Stair=Кутова Сходинка З Обсидіанової Цегли (Зовнішній Кут) +Obsidian Brick Slab=Плита З Обсидіанової Цегли +Obsidian Block Stair=Сходинка З Обсидіанового Блоку +Inner Obsidian Block Stair=Кутова Сходинка З Обсидіанового Блоку (Внутрішній Кут) +Outer Obsidian Block Stair=Кутова Сходинка З Обсидіанового Блоку (Зовнішній Кут) +Obsidian Block Slab=Плита З Обсидіанового Блоку +Brick Stair=Сходинка З Цегли +Inner Brick Stair=Кутова Сходинка З Цегли (Внутрішній Кут) +Outer Brick Stair=Кутова Сходинка З Цегли (Зовнішній Кут) +Brick Slab=Плита З Цегли +Steel Block Stair=Сходинка Із Сталевого Блоку +Inner Steel Block Stair=Кутова Сходинка Із Сталевого Блоку (Внутрішній Кут) +Outer Steel Block Stair=Кутова Сходинка Із Сталевого Блоку (Зовнішній Кут) +Steel Block Slab=Плита Із Сталевого Блоку +Tin Block Stair=Сходинка З Олов'яного Блоку +Inner Tin Block Stair=Кутова Сходинка З Олов'яного Блоку (Внутрішній Кут) +Outer Tin Block Stair=Кутова Сходинка З Олов'яного Блоку (Зовнішній Кут) +Tin Block Slab=Плита З Олов'яного Блоку +Copper Block Stair=Сходинка З Мідного Блоку +Inner Copper Block Stair=Кутова Сходинка З Мідного Блоку (Внутрішній Кут) +Outer Copper Block Stair=Кутова Сходинка З Мідного Блоку (Зовнішній Кут) +Copper Block Slab=Плита З Мідного Блоку +Bronze Block Stair=Сходинка З Бронзового Блоку +Inner Bronze Block Stair=Кутова Сходинка З Бронзового Блоку (Внутрішній Кут) +Outer Bronze Block Stair=Кутова Сходинка З Бронзового Блоку (Зовнішній Кут) +Bronze Block Slab=Плита З Бронзового Блоку +Gold Block Stair=Сходинка З Золотого Блоку +Inner Gold Block Stair=Сходинка З Золотого Блоку (Внутрішній Кут) +Outer Gold Block Stair=Сходинка З Золотого Блоку (Зовнішній Кут) +Gold Block Slab=Плита З Золотого Блоку +Ice Stair=Крижана Сходинка +Inner Ice Stair=Кутова Крижана Сходинка (Внутрішній Кут) +Outer Ice Stair=Кутова Крижана Сходинка (Зовнішній Кут) +Ice Slab=Крижана Плита +Snow Block Stair=Ступінь З Крижаного Блоку +Inner Snow Block Stair=Кутова Ступінь З Крижаного Блоку (Внутрішній Кут) +Outer Snow Block Stair=Кутова Ступінь З Крижаного Блоку (Зовнішній Кут) +Snow Block Slab=Плита З Крижаного Блоку diff --git a/mods/stairs/locale/stairs.zh_CN.tr b/mods/stairs/locale/stairs.zh_CN.tr new file mode 100644 index 0000000..e37ebcb --- /dev/null +++ b/mods/stairs/locale/stairs.zh_CN.tr @@ -0,0 +1,153 @@ +# textdomain: stairs +Glass Stair=玻璃楼梯 +Glass Slab=玻璃台阶 +Inner Glass Stair=玻璃楼梯(内) +Outer Glass Stair=玻璃楼梯(外) +Obsidian Glass Stair=黑曜石玻璃楼梯 +Obsidian Glass Slab=黑曜石玻璃台阶 +Inner Obsidian Glass Stair=黑曜石玻璃楼梯(内) +Outer Obsidian Glass Stair=黑曜石玻璃楼梯(外) +Wooden Stair=木楼梯 +Inner Wooden Stair=木楼梯(内) +Outer Wooden Stair=木楼梯(外) +Wooden Slab=木台阶 +Jungle Wood Stair=丛林木楼梯 +Inner Jungle Wood Stair=丛林木楼梯(内) +Outer Jungle Wood Stair=丛林木楼梯(外) +Jungle Wood Slab=丛林木台阶 +Pine Wood Stair=松木楼梯 +Inner Pine Wood Stair=松木楼梯(内) +Outer Pine Wood Stair=松木楼梯(外) +Pine Wood Slab=松木台阶 +Acacia Wood Stair=金合欢木楼梯 +Inner Acacia Wood Stair=金合欢木楼梯(内) +Outer Acacia Wood Stair=金合欢木楼梯(外) +Acacia Wood Slab=金合欢木台阶 +Aspen Wood Stair=白杨木楼梯 +Inner Aspen Wood Stair=白杨木楼梯(内) +Outer Aspen Wood Stair=白杨木楼梯(外) +Aspen Wood Slab=白杨木台阶 +Stone Stair=石楼梯 +Inner Stone Stair=石楼梯(内) +Outer Stone Stair=石楼梯(外) +Stone Slab=石台阶 +Cobblestone Stair=鹅卵石楼梯 +Inner Cobblestone Stair=鹅卵石楼梯(内) +Outer Cobblestone Stair=鹅卵石楼梯(外) +Cobblestone Slab=鹅卵石台阶 +Mossy Cobblestone Stair=苔藓覆盖的鹅卵石楼梯 +Inner Mossy Cobblestone Stair=苔藓覆盖的鹅卵石楼梯(内) +Outer Mossy Cobblestone Stair=苔藓覆盖的鹅卵石楼梯(外) +Mossy Cobblestone Slab=苔藓覆盖的鹅卵石台阶 +Stone Brick Stair=石砖楼梯 +Inner Stone Brick Stair=石砖楼梯(内) +Outer Stone Brick Stair=石砖楼梯(外) +Stone Brick Slab=石砖台阶 +Stone Block Stair=石块楼梯 +Inner Stone Block Stair=石块楼梯(内) +Outer Stone Block Stair=石块楼梯(外) +Stone Block Slab=石块台阶 +Desert Stone Stair=沙漠石楼梯 +Inner Desert Stone Stair=沙漠石楼梯(内) +Outer Desert Stone Stair=沙漠石楼梯(外) +Desert Stone Slab=沙漠石台阶 +Desert Cobblestone Stair=沙漠鹅卵石楼梯 +Inner Desert Cobblestone Stair=沙漠鹅卵石楼梯(内) +Outer Desert Cobblestone Stair=沙漠鹅卵石楼梯(外) +Desert Cobblestone Slab=沙漠鹅卵石台阶 +Desert Stone Brick Stair=沙漠石砖楼梯 +Inner Desert Stone Brick Stair=沙漠石砖楼梯(内) +Outer Desert Stone Brick Stair=沙漠石砖楼梯(外) +Desert Stone Brick Slab=沙漠石砖台阶 +Desert Stone Block Stair=沙漠石块楼梯 +Inner Desert Stone Block Stair=沙漠石块楼梯(内) +Outer Desert Stone Block Stair=沙漠石块楼梯(外) +Desert Stone Block Slab=沙漠石块台阶 +Sandstone Stair=沙石楼梯 +Inner Sandstone Stair=沙石楼梯(内) +Outer Sandstone Stair=沙石楼梯(外) +Sandstone Slab=沙石台阶 +Sandstone Brick Stair=沙石砖楼梯 +Inner Sandstone Brick Stair=沙石砖楼梯(内) +Outer Sandstone Brick Stair=沙石砖楼梯(外) +Sandstone Brick Slab=沙石砖台阶 +Sandstone Block Stair=沙石块楼梯 +Inner Sandstone Block Stair=沙石块楼梯(内) +Outer Sandstone Block Stair=沙石块楼梯(外) +Sandstone Block Slab=沙石块台阶 +Desert Sandstone Stair=沙漠沙石楼梯 +Inner Desert Sandstone Stair=沙漠沙石楼梯(内) +Outer Desert Sandstone Stair=沙漠沙石楼梯(外) +Desert Sandstone Slab=沙漠沙石台阶 +Desert Sandstone Brick Stair=沙漠沙石砖楼梯 +Inner Desert Sandstone Brick Stair=沙漠沙石砖楼梯(内) +Outer Desert Sandstone Brick Stair=沙漠沙石砖楼梯(外) +Desert Sandstone Brick Slab=沙漠沙石砖台阶 +Desert Sandstone Block Stair=沙漠沙石块楼梯 +Inner Desert Sandstone Block Stair=沙漠沙石块楼梯(内) +Outer Desert Sandstone Block Stair=沙漠沙石块楼梯(外) +Desert Sandstone Block Slab=沙漠沙石块台阶 +Silver Sandstone Stair=银沙石楼梯 +Inner Silver Sandstone Stair=银沙石楼梯(内) +Outer Silver Sandstone Stair=银沙石楼梯(外) +Silver Sandstone Slab=银沙石台阶 +Silver Sandstone Brick Stair=银沙石砖楼梯 +Inner Silver Sandstone Brick Stair=银沙石砖楼梯(内) +Outer Silver Sandstone Brick Stair=银沙石砖楼梯(外) +Silver Sandstone Brick Slab=银沙石砖台阶 +Silver Sandstone Block Stair=银沙石块楼梯 +Inner Silver Sandstone Block Stair=银沙石块楼梯(内) +Outer Silver Sandstone Block Stair=银沙石块楼梯(外) +Silver Sandstone Block Slab=银沙石块台阶 +Obsidian Stair=黑曜石楼梯 +Inner Obsidian Stair=黑曜石楼梯(内) +Outer Obsidian Stair=黑曜石楼梯(外) +Obsidian Slab=黑曜石台阶 +Obsidian Brick Stair=黑曜石砖楼梯 +Inner Obsidian Brick Stair=黑曜石砖楼梯(内) +Outer Obsidian Brick Stair=黑曜石砖楼梯(外) +Obsidian Brick Slab=黑曜石砖台阶 +Obsidian Block Stair=黑曜石块楼梯 +Inner Obsidian Block Stair=黑曜石块楼梯(内) +Outer Obsidian Block Stair=黑曜石块楼梯(外) +Obsidian Block Slab=黑曜石块台阶 +Brick Stair=砖楼梯 +Inner Brick Stair=砖楼梯(内) +Outer Brick Stair=砖楼梯(外) +Brick Slab=砖台阶 +Steel Block Stair=铁块楼梯 +Inner Steel Block Stair=铁块楼梯(内) +Outer Steel Block Stair=铁块楼梯(外) +Steel Block Slab=铁块台阶 +Tin Block Stair=锡块楼梯 +Inner Tin Block Stair=锡块楼梯(内) +Outer Tin Block Stair=锡块楼梯(外) +Tin Block Slab=锡块台阶 +Copper Block Stair=铜块楼梯 +Inner Copper Block Stair=铜块楼梯(内) +Outer Copper Block Stair=铜块楼梯(外) +Copper Block Slab=铜块台阶 +Bronze Block Stair=青铜块楼梯 +Inner Bronze Block Stair=青铜块楼梯(内) +Outer Bronze Block Stair=青铜块楼梯(外) +Bronze Block Slab=青铜块台阶 +Gold Block Stair=金块楼梯 +Inner Gold Block Stair=金块楼梯(内) +Outer Gold Block Stair=金块楼梯(外) +Gold Block Slab=金块台阶 +Ice Stair=冰楼梯 +Inner Ice Stair=冰块楼梯(内) +Outer Ice Stair=冰块楼梯(外) +Ice Slab=冰台阶 +Snow Block Stair=雪块楼梯 +Inner Snow Block Stair=雪块楼梯(内) +Outer Snow Block Stair=雪块楼梯(外) +Snow Block Slab=雪块台阶 + + +##### not used anymore ##### + +Blue Stained Stair=蓝木楼梯 +Inner Blue Stained Stair=蓝木楼梯(内) +Outer Blue Stained Stair=蓝木楼梯(外) +Blue Stained Slab=蓝木台阶 diff --git a/mods/stairs/locale/stairs.zh_TW.tr b/mods/stairs/locale/stairs.zh_TW.tr new file mode 100644 index 0000000..eaed61f --- /dev/null +++ b/mods/stairs/locale/stairs.zh_TW.tr @@ -0,0 +1,153 @@ +# textdomain: stairs +Glass Stair=玻璃樓梯 +Glass Slab=玻璃臺階 +Inner Glass Stair=玻璃樓梯(內) +Outer Glass Stair=玻璃樓梯(外) +Obsidian Glass Stair=黑曜石玻璃樓梯 +Obsidian Glass Slab=黑曜石玻璃臺階 +Inner Obsidian Glass Stair=黑曜石玻璃樓梯(內) +Outer Obsidian Glass Stair=黑曜石玻璃樓梯(外) +Wooden Stair=木製樓梯 +Inner Wooden Stair=木樓梯(內) +Outer Wooden Stair=木樓梯(外) +Wooden Slab=木製臺階 +Jungle Wood Stair=叢林木樓梯 +Inner Jungle Wood Stair=叢林木樓梯(內) +Outer Jungle Wood Stair=叢林木樓梯(外) +Jungle Wood Slab=叢林木臺階 +Pine Wood Stair=松木樓梯 +Inner Pine Wood Stair=松木樓梯(內) +Outer Pine Wood Stair=松木樓梯(外) +Pine Wood Slab=松木臺階 +Acacia Wood Stair=金合歡木樓梯 +Inner Acacia Wood Stair=金合歡木樓梯(內) +Outer Acacia Wood Stair=金合歡木樓梯(外) +Acacia Wood Slab=金合歡木臺階 +Aspen Wood Stair=白楊木樓梯 +Inner Aspen Wood Stair=白楊木樓梯(內) +Outer Aspen Wood Stair=白楊木樓梯(外) +Aspen Wood Slab=白楊木臺階 +Stone Stair=石樓梯 +Inner Stone Stair=石樓梯(內) +Outer Stone Stair=石樓梯(外) +Stone Slab=石臺階 +Cobblestone Stair=圓石樓梯 +Inner Cobblestone Stair=圓石樓梯(內) +Outer Cobblestone Stair=圓石樓梯(外) +Cobblestone Slab=圓石臺階 +Mossy Cobblestone Stair=苔石樓梯 +Inner Mossy Cobblestone Stair=苔石樓梯(內) +Outer Mossy Cobblestone Stair=苔石樓梯(外) +Mossy Cobblestone Slab=苔石臺階 +Stone Brick Stair=石磚樓梯 +Inner Stone Brick Stair=石磚樓梯(內) +Outer Stone Brick Stair=石磚樓梯(外) +Stone Brick Slab=石磚臺階 +Stone Block Stair=石塊樓梯 +Inner Stone Block Stair=石塊樓梯(內) +Outer Stone Block Stair=石塊樓梯(外) +Stone Block Slab=石塊臺階 +Desert Stone Stair=沙漠石樓梯 +Inner Desert Stone Stair=沙漠石樓梯(內) +Outer Desert Stone Stair=沙漠石樓梯(外) +Desert Stone Slab=沙漠石臺階 +Desert Cobblestone Stair=沙漠圓石樓梯 +Inner Desert Cobblestone Stair=沙漠圓石樓梯(內) +Outer Desert Cobblestone Stair=沙漠圓石樓梯(外) +Desert Cobblestone Slab=沙漠圓石臺階 +Desert Stone Brick Stair=沙漠石磚樓梯 +Inner Desert Stone Brick Stair=沙漠石磚樓梯(內) +Outer Desert Stone Brick Stair=沙漠石磚樓梯(外) +Desert Stone Brick Slab=沙漠石磚臺階 +Desert Stone Block Stair=沙漠石塊樓梯 +Inner Desert Stone Block Stair=沙漠石塊樓梯(內) +Outer Desert Stone Block Stair=沙漠石塊樓梯(外) +Desert Stone Block Slab=沙漠石塊臺階 +Sandstone Stair=沙石樓梯 +Inner Sandstone Stair=沙石樓梯(內) +Outer Sandstone Stair=沙石樓梯(外) +Sandstone Slab=沙石臺階 +Sandstone Brick Stair=沙石磚樓梯 +Inner Sandstone Brick Stair=沙石磚樓梯(內) +Outer Sandstone Brick Stair=沙石磚樓梯(外) +Sandstone Brick Slab=沙石磚臺階 +Sandstone Block Stair=沙石塊樓梯 +Inner Sandstone Block Stair=沙石塊樓梯(內) +Outer Sandstone Block Stair=沙石塊樓梯(外) +Sandstone Block Slab=沙石塊臺階 +Desert Sandstone Stair=沙漠沙石樓梯 +Inner Desert Sandstone Stair=沙漠沙石樓梯(內) +Outer Desert Sandstone Stair=沙漠沙石樓梯(外) +Desert Sandstone Slab=沙漠沙石臺階 +Desert Sandstone Brick Stair=沙漠沙石磚樓梯 +Inner Desert Sandstone Brick Stair=沙漠沙石磚樓梯(內) +Outer Desert Sandstone Brick Stair=沙漠沙石磚樓梯(外) +Desert Sandstone Brick Slab=沙漠沙石磚臺階 +Desert Sandstone Block Stair=沙漠沙石塊樓梯 +Inner Desert Sandstone Block Stair=沙漠沙石塊樓梯(內) +Outer Desert Sandstone Block Stair=沙漠沙石塊樓梯(外) +Desert Sandstone Block Slab=沙漠沙石塊臺階 +Silver Sandstone Stair=銀沙石樓梯 +Inner Silver Sandstone Stair=銀沙石樓梯(內) +Outer Silver Sandstone Stair=銀沙石樓梯(外) +Silver Sandstone Slab=銀沙石臺階 +Silver Sandstone Brick Stair=銀沙石磚樓梯 +Inner Silver Sandstone Brick Stair=銀沙石磚樓梯(內) +Outer Silver Sandstone Brick Stair=銀沙石磚樓梯(外) +Silver Sandstone Brick Slab=銀沙石磚臺階 +Silver Sandstone Block Stair=銀沙石塊樓梯 +Inner Silver Sandstone Block Stair=銀沙石塊樓梯(內) +Outer Silver Sandstone Block Stair=銀沙石塊樓梯(外) +Silver Sandstone Block Slab=銀沙石塊臺階 +Obsidian Stair=黑曜石樓梯 +Inner Obsidian Stair=黑曜石樓梯(內) +Outer Obsidian Stair=黑曜石樓梯(外) +Obsidian Slab=黑曜石臺階 +Obsidian Brick Stair=黑曜石磚樓梯 +Inner Obsidian Brick Stair=黑曜石磚樓梯(內) +Outer Obsidian Brick Stair=黑曜石磚樓梯(外) +Obsidian Brick Slab=黑曜石磚臺階 +Obsidian Block Stair=黑曜石塊樓梯 +Inner Obsidian Block Stair=黑曜石塊樓梯(內) +Outer Obsidian Block Stair=黑曜石塊樓梯(外) +Obsidian Block Slab=黑曜石塊臺階 +Brick Stair=磚樓梯 +Inner Brick Stair=磚樓梯(內) +Outer Brick Stair=磚樓梯(外) +Brick Slab=磚制臺階 +Steel Block Stair=鐵塊樓梯 +Inner Steel Block Stair=鐵塊樓梯(內) +Outer Steel Block Stair=鐵塊樓梯(外) +Steel Block Slab=鐵塊臺階 +Tin Block Stair=錫塊樓梯 +Inner Tin Block Stair=錫塊樓梯(內) +Outer Tin Block Stair=錫塊樓梯(外) +Tin Block Slab=錫塊臺階 +Copper Block Stair=銅塊樓梯 +Inner Copper Block Stair=銅塊樓梯(內) +Outer Copper Block Stair=銅塊樓梯(外) +Copper Block Slab=銅塊臺階 +Bronze Block Stair=青銅塊樓梯 +Inner Bronze Block Stair=青銅塊樓梯(內) +Outer Bronze Block Stair=青銅塊樓梯(外) +Bronze Block Slab=青銅塊臺階 +Gold Block Stair=金塊樓梯 +Inner Gold Block Stair=金塊樓梯(內) +Outer Gold Block Stair=金塊樓梯(外) +Gold Block Slab=金塊臺階 +Ice Stair=冰階梯 +Inner Ice Stair=冰塊樓梯(內) +Outer Ice Stair=冰塊樓梯(外) +Ice Slab=冰臺階 +Snow Block Stair=雪塊樓梯 +Inner Snow Block Stair=雪塊樓梯(內) +Outer Snow Block Stair=雪塊樓梯(外) +Snow Block Slab=雪塊臺階 + + +##### not used anymore ##### + +Blue Stained Stair=藍木樓梯 +Inner Blue Stained Stair=藍木樓梯(內) +Outer Blue Stained Stair=藍木樓梯(外) +Blue Stained Slab=藍木臺階 diff --git a/mods/stairs/locale/template.txt b/mods/stairs/locale/template.txt new file mode 100644 index 0000000..ca2c865 --- /dev/null +++ b/mods/stairs/locale/template.txt @@ -0,0 +1,145 @@ +# textdomain: stairs +Glass Stair= +Glass Slab= +Inner Glass Stair= +Outer Glass Stair= +Obsidian Glass Stair= +Obsidian Glass Slab= +Inner Obsidian Glass Stair= +Outer Obsidian Glass Stair= +Wooden Stair= +Inner Wooden Stair= +Outer Wooden Stair= +Wooden Slab= +Jungle Wood Stair= +Inner Jungle Wood Stair= +Outer Jungle Wood Stair= +Jungle Wood Slab= +Pine Wood Stair= +Inner Pine Wood Stair= +Outer Pine Wood Stair= +Pine Wood Slab= +Acacia Wood Stair= +Inner Acacia Wood Stair= +Outer Acacia Wood Stair= +Acacia Wood Slab= +Aspen Wood Stair= +Inner Aspen Wood Stair= +Outer Aspen Wood Stair= +Aspen Wood Slab= +Stone Stair= +Inner Stone Stair= +Outer Stone Stair= +Stone Slab= +Cobblestone Stair= +Inner Cobblestone Stair= +Outer Cobblestone Stair= +Cobblestone Slab= +Mossy Cobblestone Stair= +Inner Mossy Cobblestone Stair= +Outer Mossy Cobblestone Stair= +Mossy Cobblestone Slab= +Stone Brick Stair= +Inner Stone Brick Stair= +Outer Stone Brick Stair= +Stone Brick Slab= +Stone Block Stair= +Inner Stone Block Stair= +Outer Stone Block Stair= +Stone Block Slab= +Desert Stone Stair= +Inner Desert Stone Stair= +Outer Desert Stone Stair= +Desert Stone Slab= +Desert Cobblestone Stair= +Inner Desert Cobblestone Stair= +Outer Desert Cobblestone Stair= +Desert Cobblestone Slab= +Desert Stone Brick Stair= +Inner Desert Stone Brick Stair= +Outer Desert Stone Brick Stair= +Desert Stone Brick Slab= +Desert Stone Block Stair= +Inner Desert Stone Block Stair= +Outer Desert Stone Block Stair= +Desert Stone Block Slab= +Sandstone Stair= +Inner Sandstone Stair= +Outer Sandstone Stair= +Sandstone Slab= +Sandstone Brick Stair= +Inner Sandstone Brick Stair= +Outer Sandstone Brick Stair= +Sandstone Brick Slab= +Sandstone Block Stair= +Inner Sandstone Block Stair= +Outer Sandstone Block Stair= +Sandstone Block Slab= +Desert Sandstone Stair= +Inner Desert Sandstone Stair= +Outer Desert Sandstone Stair= +Desert Sandstone Slab= +Desert Sandstone Brick Stair= +Inner Desert Sandstone Brick Stair= +Outer Desert Sandstone Brick Stair= +Desert Sandstone Brick Slab= +Desert Sandstone Block Stair= +Inner Desert Sandstone Block Stair= +Outer Desert Sandstone Block Stair= +Desert Sandstone Block Slab= +Silver Sandstone Stair= +Inner Silver Sandstone Stair= +Outer Silver Sandstone Stair= +Silver Sandstone Slab= +Silver Sandstone Brick Stair= +Inner Silver Sandstone Brick Stair= +Outer Silver Sandstone Brick Stair= +Silver Sandstone Brick Slab= +Silver Sandstone Block Stair= +Inner Silver Sandstone Block Stair= +Outer Silver Sandstone Block Stair= +Silver Sandstone Block Slab= +Obsidian Stair= +Inner Obsidian Stair= +Outer Obsidian Stair= +Obsidian Slab= +Obsidian Brick Stair= +Inner Obsidian Brick Stair= +Outer Obsidian Brick Stair= +Obsidian Brick Slab= +Obsidian Block Stair= +Inner Obsidian Block Stair= +Outer Obsidian Block Stair= +Obsidian Block Slab= +Brick Stair= +Inner Brick Stair= +Outer Brick Stair= +Brick Slab= +Steel Block Stair= +Inner Steel Block Stair= +Outer Steel Block Stair= +Steel Block Slab= +Tin Block Stair= +Inner Tin Block Stair= +Outer Tin Block Stair= +Tin Block Slab= +Copper Block Stair= +Inner Copper Block Stair= +Outer Copper Block Stair= +Copper Block Slab= +Bronze Block Stair= +Inner Bronze Block Stair= +Outer Bronze Block Stair= +Bronze Block Slab= +Gold Block Stair= +Inner Gold Block Stair= +Outer Gold Block Stair= +Gold Block Slab= +Ice Stair= +Inner Ice Stair= +Outer Ice Stair= +Ice Slab= +Snow Block Stair= +Inner Snow Block Stair= +Outer Snow Block Stair= +Snow Block Slab= diff --git a/mods/stairs/mod.conf b/mods/stairs/mod.conf new file mode 100644 index 0000000..c46bb48 --- /dev/null +++ b/mods/stairs/mod.conf @@ -0,0 +1,2 @@ +name = stairs +description = MTG Stairs, modified for Insane Protestor diff --git a/mods/stairs/textures/stairs_glass_outer_stairside.png b/mods/stairs/textures/stairs_glass_outer_stairside.png new file mode 100644 index 0000000..9b298c8 Binary files /dev/null and b/mods/stairs/textures/stairs_glass_outer_stairside.png differ diff --git a/mods/stairs/textures/stairs_glass_split.png b/mods/stairs/textures/stairs_glass_split.png new file mode 100644 index 0000000..6287959 Binary files /dev/null and b/mods/stairs/textures/stairs_glass_split.png differ diff --git a/mods/stairs/textures/stairs_glass_stairside.png b/mods/stairs/textures/stairs_glass_stairside.png new file mode 100644 index 0000000..c424294 Binary files /dev/null and b/mods/stairs/textures/stairs_glass_stairside.png differ diff --git a/mods/stairs/textures/stairs_obsidian_glass_outer_stairside.png b/mods/stairs/textures/stairs_obsidian_glass_outer_stairside.png new file mode 100644 index 0000000..0098f68 Binary files /dev/null and b/mods/stairs/textures/stairs_obsidian_glass_outer_stairside.png differ diff --git a/mods/stairs/textures/stairs_obsidian_glass_split.png b/mods/stairs/textures/stairs_obsidian_glass_split.png new file mode 100644 index 0000000..7647b9b Binary files /dev/null and b/mods/stairs/textures/stairs_obsidian_glass_split.png differ diff --git a/mods/stairs/textures/stairs_obsidian_glass_stairside.png b/mods/stairs/textures/stairs_obsidian_glass_stairside.png new file mode 100644 index 0000000..40b1754 Binary files /dev/null and b/mods/stairs/textures/stairs_obsidian_glass_stairside.png differ diff --git a/mods/story/ccbysa30.txt b/mods/story/ccbysa30.txt new file mode 100644 index 0000000..90f931b --- /dev/null +++ b/mods/story/ccbysa30.txt @@ -0,0 +1,60 @@ +THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. + +BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. + +1. Definitions + + "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License. + "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined below) for the purposes of this License. + "Creative Commons Compatible License" means a license that is listed at https://creativecommons.org/compatiblelicenses that has been approved by Creative Commons as being essentially equivalent to this License, including, at a minimum, because that license: (i) contains terms that have the same purpose, meaning and effect as the License Elements of this License; and, (ii) explicitly permits the relicensing of adaptations of works made available under that license under this License or a Creative Commons jurisdiction license with the same License Elements as this License. + "Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership. + "License Elements" means the following high-level license attributes as selected by Licensor and indicated in the title of this License: Attribution, ShareAlike. + "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License. + "Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast. + "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work. + "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation. + "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images. + "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium. + +2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws. + +3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below: + + to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections; + to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified."; + to Distribute and Publicly Perform the Work including as incorporated in Collections; and, + to Distribute and Publicly Perform Adaptations. + + For the avoidance of doubt: + Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; + Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and, + Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License. + +The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved. + +4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: + + You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(c), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(c), as requested. + You may Distribute or Publicly Perform an Adaptation only under the terms of: (i) this License; (ii) a later version of this License with the same License Elements as this License; (iii) a Creative Commons jurisdiction license (either this or a later license version) that contains the same License Elements as this License (e.g., Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons Compatible License. If you license the Adaptation under one of the licenses mentioned in (iv), you must comply with the terms of that license. If you license the Adaptation under the terms of any of the licenses mentioned in (i), (ii) or (iii) (the "Applicable License"), you must comply with the terms of the Applicable License generally and the following provisions: (I) You must include a copy of, or the URI for, the Applicable License with every copy of each Adaptation You Distribute or Publicly Perform; (II) You may not offer or impose any terms on the Adaptation that restrict the terms of the Applicable License or the ability of the recipient of the Adaptation to exercise the rights granted to that recipient under the terms of the Applicable License; (III) You must keep intact all notices that refer to the Applicable License and to the disclaimer of warranties with every copy of the Work as included in the Adaptation You Distribute or Publicly Perform; (IV) when You Distribute or Publicly Perform the Adaptation, You may not impose any effective technological measures on the Adaptation that restrict the ability of a recipient of the Adaptation from You to exercise the rights granted to that recipient under the terms of the Applicable License. This Section 4(b) applies to the Adaptation as incorporated in a Collection, but this does not require the Collection apart from the Adaptation itself to be made subject to the terms of the Applicable License. + If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Ssection 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4(c) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties. + Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise. + +5. Representations, Warranties and Disclaimer + +UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. + +6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. Termination + + This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. + Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above. + +8. Miscellaneous + + Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License. + Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License. + If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent. + This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You. + The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law. diff --git a/mods/story/init.lua b/mods/story/init.lua new file mode 100644 index 0000000..f540340 --- /dev/null +++ b/mods/story/init.lua @@ -0,0 +1,76 @@ +local modpath = minetest.get_modpath("story") +local currentPage = 0 +storyText = {} +storyText[0] = "Click next to continue. Do NOT close the formspec by pressing the Escape key, or the game may break. To my knowledge, this is impossible to solve with the current Lua API." +storyText[1] = "Your name is Vyacheslav Mikhaylov and you live in the Eastern European country of Absurdistan..." +storyText[2] = "The government of your country has a long history of corruption and oppressing its citizens." +storyText[3] = "It didn't bother you much until last week when you were watching the news on TV..." +storyText[4] = "The government started forcefully drafting people into the military." +storyText[5] = "You were among the first people to get their draft notice in the mail." +storyText[6] = "You were devastated when you realized that you'll be sent away to die in a war that doesn't even concern you." +storyText[7] = "\"I've got nothing to lose at this point, how about I teach those damn bastards a lesson.\", you thought to yourself." +storyText[8] = "Click \"Next\" to generate the world." +story = {} + +function getStoryFormspec(number) + storyFormspec = + { + "formspec_version[4]", + "size[18, 16]", + "bgcolor[#3A41EA]", + "position[0.5, 0.5]", + "style_type[button;bgcolor=#1010FF;textcolor=yellow]", + "hypertext[1, 12.5; 12, 5;;" .. storyText[number] .. "]\n", + "image[1, .2; 16, 12;" .. number .. ".png]", + "button[13, 12.3; 4, 1;back;Back]", + "button[13, 13.6; 4, 1;next;Next]", + "button[13, 14.9; 4, 1;exit;Quit]" + } + return storyFormspec +end + + + +minetest.register_on_joinplayer(function(player) + minetest.show_formspec(player:get_player_name(), "story:story_formspec", table.concat(getStoryFormspec(0), "\n")) + music = minetest.sound_play("4K", { + gain = 0, + pitch = 1.2, + loop = true, + }) + + minetest.sound_fade(music, .1, 1) +end) +--[[ +minetest.register_on_newplayer(function(ObjectRef) + minetest.place_schematic({x = 0, y = -1, z = 0}, minetest.get_modpath("story") .. "/schems/citymap-v1.mts", "0", nil, true) + ObjectRef:set_pos({x = 20, y = 0, z = 20}) +end)]] + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "story:story_formspec" then + return + end + + if formname == "story:story_formspec" then + if fields.next then + if currentPage >= 8 then + minetest.close_formspec(player:get_player_name(), "story:story_formspec") + return + end + currentPage = currentPage + 1 -- Fuck Lua and its lack of arithmetic assignment operators + minetest.show_formspec(player:get_player_name(), "story:story_formspec", table.concat(getStoryFormspec(currentPage), "\n")) + + elseif fields.back and currentPage >= 0 then + currentPage = currentPage - 1 -- Fuck Lua and its lack of arithmetic assignment operators + minetest.show_formspec(player:get_player_name(), "story:story_formspec", table.concat(getStoryFormspec(currentPage), "\n")) + + elseif fields.exit then + --minetest.kick_player(player:get_player_name(), "Fuck you in particular") + minetest.request_shutdown("The game has crashed due to the citizen's neglience.\n This incident will be reported.") + + elseif fields.quit then + minetest.after(0.2, function() minetest.show_formspec(player:get_player_name(), "story:story_formspec", table.concat(getStoryFormspec(currentPage), "\n")) end) + end + end +end) diff --git a/mods/story/license.txt b/mods/story/license.txt new file mode 100644 index 0000000..87878e2 --- /dev/null +++ b/mods/story/license.txt @@ -0,0 +1,4 @@ + +The Sam texture (textures/sam.png) was made by Jordach, licensed under Creative Commons Attribution ShareAlike 3.0 Unported, the license text of which can be found in ccbysa30.txt + +The Samantha texture (textures/samantha.png) by MCL is based upon the work of Jordach, it is licensed under the Creative Commons Attribution ShareAlike 3.0 Unported license, the license text of which can be found in ccbysa30.txt \ No newline at end of file diff --git a/mods/story/mod.conf b/mods/story/mod.conf new file mode 100644 index 0000000..52023b0 --- /dev/null +++ b/mods/story/mod.conf @@ -0,0 +1,4 @@ +name = story +description = Adds a story to Minetest/XtreemTest +author = MCL +title = Story diff --git a/mods/story/readme.txt b/mods/story/readme.txt new file mode 100644 index 0000000..0f4a445 --- /dev/null +++ b/mods/story/readme.txt @@ -0,0 +1,31 @@ +[Mod] XtreemSex [sex] +Version 0.2.0 (released 2022-10-01) +Written by MCL (https://mcl.sovnat.info) + +Say NO to censorship! +On September 19th, this mod's topic od Minetest Forums was brutally removed by a moderator. +We cannot let this ruthless act go unnoticed! + +See license.txt for licensing information. + + + +Changelog: +0.2.0 (2022-10-01): + - Added anti-censorship message + - Added an age selection formspec + - Race and sex are now saved to a file. + +0.1.1 (2022-09-17): + - Created the changelog + - Changed the Samantha texture so that she has a longer skirt + - Changed the formspec text + +0.1.0 (2022-09-12): + - INITIAL RELEASE + - Added the Sam and Samantha textures + - Added ccbysa30.txt + - Added init.lua + - Added mod.conf + - Added readme.txt + - Added license.txt \ No newline at end of file diff --git a/mods/story/schems/bldg_11_floors.mts b/mods/story/schems/bldg_11_floors.mts new file mode 100644 index 0000000..8f8b074 Binary files /dev/null and b/mods/story/schems/bldg_11_floors.mts differ diff --git a/mods/story/schems/citymap-v1.mts b/mods/story/schems/citymap-v1.mts new file mode 100644 index 0000000..228ead2 Binary files /dev/null and b/mods/story/schems/citymap-v1.mts differ diff --git a/mods/story/sounds/4K.ogg b/mods/story/sounds/4K.ogg new file mode 100644 index 0000000..6c23aae Binary files /dev/null and b/mods/story/sounds/4K.ogg differ diff --git a/mods/story/sounds/AbsurdExpectations.ogg b/mods/story/sounds/AbsurdExpectations.ogg new file mode 100644 index 0000000..5244654 Binary files /dev/null and b/mods/story/sounds/AbsurdExpectations.ogg differ diff --git a/mods/story/textures/0.png b/mods/story/textures/0.png new file mode 100644 index 0000000..9f25c98 Binary files /dev/null and b/mods/story/textures/0.png differ diff --git a/mods/story/textures/1.png b/mods/story/textures/1.png new file mode 100644 index 0000000..8adef89 Binary files /dev/null and b/mods/story/textures/1.png differ diff --git a/mods/story/textures/1.xcf b/mods/story/textures/1.xcf new file mode 100644 index 0000000..88df554 Binary files /dev/null and b/mods/story/textures/1.xcf differ diff --git a/mods/story/textures/2.png b/mods/story/textures/2.png new file mode 100644 index 0000000..150f1ce Binary files /dev/null and b/mods/story/textures/2.png differ diff --git a/mods/story/textures/3.png b/mods/story/textures/3.png new file mode 100644 index 0000000..e8b47ab Binary files /dev/null and b/mods/story/textures/3.png differ diff --git a/mods/story/textures/4.png b/mods/story/textures/4.png new file mode 100644 index 0000000..e4a6312 Binary files /dev/null and b/mods/story/textures/4.png differ diff --git a/mods/story/textures/5.png b/mods/story/textures/5.png new file mode 100644 index 0000000..bfad92f Binary files /dev/null and b/mods/story/textures/5.png differ diff --git a/mods/story/textures/6.png b/mods/story/textures/6.png new file mode 100644 index 0000000..f7a4685 Binary files /dev/null and b/mods/story/textures/6.png differ diff --git a/mods/story/textures/7.png b/mods/story/textures/7.png new file mode 100644 index 0000000..cf682b0 Binary files /dev/null and b/mods/story/textures/7.png differ diff --git a/mods/story/textures/7.xcf b/mods/story/textures/7.xcf new file mode 100644 index 0000000..e4d6dc7 Binary files /dev/null and b/mods/story/textures/7.xcf differ diff --git a/mods/terumet/description.txt b/mods/terumet/description.txt new file mode 100644 index 0000000..7dff7f3 --- /dev/null +++ b/mods/terumet/description.txt @@ -0,0 +1 @@ +Terumetal v3.0 - Make life easier with alloys and heat machinery! \ No newline at end of file diff --git a/mods/terumet/init.lua b/mods/terumet/init.lua new file mode 100644 index 0000000..f033a70 --- /dev/null +++ b/mods/terumet/init.lua @@ -0,0 +1,328 @@ +--[[ Terumet v3.0 + +Mod for open-source voxel game Minetest (https://www.minetest.net/) +Written for Minetest version 5.0.0 +Now also supports Minetest 0.4.17 + +Creates a new ore in the world which can be used to make useful alloys +and heat-powered machines. + +By Terumoc [https://github.com/Terumoc] +and with contributions from: + > obl3pplifp (https://github.com/obl3pplifp) for bug reports, information, ideas, and other considerable contributions + > RSL-Redstonier [https://github.com/RSL-Redstonier] + > Chem871 [https://github.com/Chemguy99] for many ideas and requests + +BIG Thanks to all contributors for their input! + +]]-- + +--[[ Copyright (C) 2017-2019 Terumoc (Scott Horvath) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . ]] + +terumet = {} +terumet.version = {major=3, minor=0, patch=0} +local ver = terumet.version +terumet.version_text = ver.major .. '.' .. ver.minor .. '.' .. ver.patch +terumet.mod_name = "terumet" + +-- this isn't the suggested way to check for game version but... it works for my purposes +terumet.legacy = minetest.get_version().string:find('0.4') + +if terumet.legacy then + minetest.log('[terumet] MTv0.4.* detected - in legacy mode!') +end + +terumet.RAND = PcgRandom(os.time()) + +local FMT = string.format +minetest.register_chatcommand( 'item_info', { + params = '', + description = 'Get a complete description of the ItemStack in your hand', + privs = {debug=true}, + func = function(name) + local player = minetest.get_player_by_name(name) + if player then + local witem = player:get_wielded_item() + if witem:is_empty() then + return true, "You're not holding anything." + else + local def = witem:get_definition() + local wear = witem:get_wear() + local wear_pct = FMT('%.1f%%', wear / 65535 * 100.0) + if def then + return true, FMT('%s "%s" #%s/%s w:%s (%s)', + minetest.colorize('#ff0', witem:get_name()), + def.description, + witem:get_count(), + minetest.colorize('#0ff', def.stack_max), + minetest.colorize('#f0f', wear), + minetest.colorize('#f0f', wear_pct) + ) + else + return true, FMT('*NO DEF* %s #%s w:%s (%s)', + minetest.colorize('#ff0', witem:get_name()), + witem:get_count(), + minetest.colorize('#f0f', wear), + minetest.colorize('#f0f', wear_pct) + ) + end + end + else + return false, "You aren't a player somehow, sorry?!" + end + end +}) + +function terumet.chance(pct) + if pct <= 0 then return false end + if pct >= 100 then return true end + return terumet.RAND:next(1,100) <= pct +end + +-- function for a node's on_blast callback to be removed with a pct% chance +function terumet.blast_chance(pct, id) + return function(pos) + if terumet.chance(pct) then + minetest.remove_node(pos) + return {id} + else + return nil + end + end +end + +-- empty function useful for where a callback is necessary but using nil would cause undesired default behavior +terumet.NO_FUNCTION = function() end +terumet.EMPTY = {} +terumet.ZERO_XYZ = {x=0,y=0,z=0} + +function terumet.recipe_3x3(i) + return { + {i, i, i}, {i, i, i}, {i, i, i} + } +end + +function terumet.recipe_box(outer, inner) + return { + {outer, outer, outer}, {outer, inner, outer}, {outer, outer, outer} + } +end + +function terumet.recipe_plus(i) + return { + {'', i, ''}, {i, i, i}, {'', i, ''} + } +end + +function terumet.random_velocity(max_tenths) + return { + x = terumet.RAND:next(-max_tenths,max_tenths) / 10, + y = terumet.RAND:next(-max_tenths,max_tenths) / 10, + z = terumet.RAND:next(-max_tenths,max_tenths) / 10 + } +end + +function terumet.particle_stream(pointA, pointB, density, particle_data, player) + local dist_vector = {x=(pointB.x-pointA.x), y=(pointB.y-pointA.y), z=(pointB.z-pointA.z)} + local dist = vector.length(dist_vector) + local pcount = dist * density + if pcount < 1 then return end -- guard against div/0 + local step = {x=(dist_vector.x/pcount), y=(dist_vector.y/pcount), z=(dist_vector.z/pcount)} + local ppos = vector.new(pointA) + for _ = 1,pcount do + ppos = util3d.pos_plus(ppos, step) + minetest.add_particle{ + pos = vector.new(ppos), + velocity=terumet.random_velocity(5), + expirationtime=(particle_data.expiration or 1), + size=(particle_data.size or 1), + glow=(particle_data.glow or 1), + playername=player, + texture=particle_data.texture, + animation=particle_data.animation + } + end +end + +function terumet.format_time(t) + return string.format('%.1f s', t or 0) +end + +function terumet.do_lua_file(name) + dofile(minetest.get_modpath(terumet.mod_name) .. '/' .. name .. '.lua') +end + +-- create a copy of node groups from an unlit machine for lit version of machine +function terumet.create_lit_node_groups(unlit_groups) + local new_groups = {not_in_creative_inventory=1} + for k,v in pairs(unlit_groups) do new_groups[k] = v end + return new_groups +end + +function terumet.itemstack_desc(stack) + local stack_desc = stack:get_definition().description + -- use only what is before a newline if one is in the description + if stack_desc:find('\n') then stack_desc = stack_desc:match('(.*)\n') end + if stack:get_count() > 1 then + return string.format('%s (x%d)', stack_desc, stack:get_count()) + else + return stack_desc + end +end + +-- given a table with 'group:XXX' keys and a node/item definition with groups, return the +-- (first) value in the table where node/item has a group key of XXX, otherwise nil +function terumet.match_group_key(table, def) + if not def then return nil end + for group_name,_ in pairs(def.groups) do + local grp_key = 'group:'..group_name + if table[grp_key] then + return table[grp_key] + end + end + return nil +end + +function terumet.id(id, number) + if number then + return string.format('%s:%s %d', terumet.mod_name, id, number) + else + return string.format('%s:%s', terumet.mod_name, id) + end +end + +function terumet.give_player_item(pos, player, stack) + local inv = player:get_inventory() + local leftover = inv:add_item("main", stack) + if leftover and not leftover:is_empty() then + minetest.item_drop(leftover, player, player:get_pos()) + end +end + +function terumet.tex(id) + -- accepts both base ids (assuming this mod) and full mod ids + -- ex: terumet.tex('ingot_raw') -> 'terumet_ingot_raw.png' + -- terumet.tex('default:cobble') -> 'default_cobble.png' + if id:match(':') then + return string.format('%s.png', id:gsub(':', '_')) + else + return string.format('%s_%s.png', terumet.mod_name, id) + end +end + +function terumet.item_desc(name, xinfo) + if xinfo then + return string.format("%s\n%s", name, minetest.colorize(terumet.options.misc.TIP_COLOR, xinfo)) + else + return name + end +end + +function terumet.crystal_tex(color) + return string.format('%s^[multiply:%s', terumet.tex('item_cryst'), color) +end + +function terumet.tex_comp(base_tex, overlay_id) + return base_tex .. '^' .. terumet.tex(overlay_id) +end + +function terumet.tex_trans(id, rot) + return terumet.tex(id) .. '^[transform' .. rot +end + +local HEAR_DIST = 12 +terumet.squishy_node_sounds = { + footstep = {name='terumet_squish_step', max_hear_distance=HEAR_DIST}, + dig = {name='terumet_squish_dig', max_hear_distance=HEAR_DIST}, + dug = {name='terumet_squish_dug', max_hear_distance=HEAR_DIST}, + place = {name='terumet_squish_place', max_hear_distance=HEAR_DIST}, +} + +terumet.do_lua_file('util3d') + +terumet.do_lua_file('interop/terumet_api') +terumet.do_lua_file('options') +terumet.do_lua_file('material/reg_alloy') + + +-- reg_alloy(name, id, block hardness level, repair material value) +terumet.reg_alloy('Terucopper', 'tcop', 1, 20) +terumet.reg_alloy('Terutin', 'ttin', 1, 15) +terumet.reg_alloy('Terusteel', 'tste', 2, 40) +terumet.reg_alloy('Terugold', 'tgol', 3, 80) +terumet.reg_alloy('Coreglass', 'cgls', 4, 120) +terumet.reg_alloy('Teruchalcum', 'tcha', 2, 60) + +terumet.do_lua_file('material/ceramic') +--terumet.do_lua_file('material/thermese') +terumet.do_lua_file('material/coil') +--terumet.do_lua_file('material/crushed') +--terumet.do_lua_file('material/pwood') +--terumet.do_lua_file('material/tglass') +terumet.do_lua_file('material/rebar') +terumet.do_lua_file('material/misc') +terumet.do_lua_file('material/crystallized') +--terumet.do_lua_file('material/battery') + +local id = terumet.id + +-- register raw terumetal ingot as weak repair-material +terumet.register_repair_material(id('ingot_raw'), 10) + +--terumet.do_lua_file('tool/reg_tools') + +local sword_opts = terumet.options.tools.sword_damage + + +--terumet.do_lua_file('tool/ore_saw') + + + + + + +-- register repairable default tools and materials +-- {value of 1 item, item id}: +local dmv_values = { + steel={10, 'default:steel_ingot'}, + bronze={30, 'default:bronze_ingot'}, + mese={90, 'default:mese_crystal'}, + diamond={100, 'default:diamond'} +} + +for dmat, v in pairs(dmv_values) do + terumet.register_repairable_item("default:pick_"..dmat, v[1]*3) + terumet.register_repairable_item("default:axe_"..dmat, v[1]*3) + terumet.register_repairable_item("default:shovel_"..dmat, v[1]) + terumet.register_repairable_item("default:sword_"..dmat, v[1]*2) + terumet.register_repair_material(v[2], v[1]) +end + +terumet.do_lua_file('material/concrete') +terumet.do_lua_file('material/coalproc') + +--experimental stuff +--terumet.do_lua_file('material/meson') + +local INTEROPS = {'3d_armor', 'doors', 'unified_inventory', 'tubelib', 'dungeon_loot', 'moreores', 'farming', 'extra'} +for _,mod in ipairs(INTEROPS) do + if minetest.get_modpath(mod) then terumet.do_lua_file('interop/'..mod) end +end + +local vacfood_options = terumet.options.vac_oven.VAC_FOOD +if vacfood_options and vacfood_options.ACTIVE then terumet.do_lua_file('material/vacfood') end + +terumet.do_lua_file('interop/crusher_misc') \ No newline at end of file diff --git a/mods/terumet/interop/3d_armor.lua b/mods/terumet/interop/3d_armor.lua new file mode 100644 index 0000000..ed31761 --- /dev/null +++ b/mods/terumet/interop/3d_armor.lua @@ -0,0 +1,219 @@ +-- add armor when 3darmor mod is also active +local opts = terumet.options.armor + +local function gen_armor_groups(type, data) + local grps = { + armor_use=data.uses, + armor_heal=(data.heal or 0), + armor_water=(data.breathing or 0), + armor_fire=data.fire, + physics_speed=(data.speed or 0), + physics_gravity=(data.gravity or 0), + physics_jump=(data.jump or 0), + } + grps[type]=1 + return grps +end + +local function reg_recipe_boots(id, mat) + minetest.register_craft{output=id, recipe={ + {mat, '', mat}, + {mat, '', mat} + }} +end + +local function reg_recipe_legs(id, mat) + minetest.register_craft{output=id, recipe={ + {mat, mat, mat}, + {mat, '', mat}, + {mat, '', mat} + }} +end + +local function reg_recipe_chest(id, mat) + minetest.register_craft{output=id, recipe={ + {mat, '', mat}, + {mat, mat, mat}, + {mat, mat, mat} + }} +end + +local function reg_recipe_helm(id, mat) + minetest.register_craft{output=id, recipe={ + {mat, mat, mat}, + {mat, '', mat}, + }} +end + +local function reg_terumet_armor(data) + if not data or not data.suffix or not data.mat then error('Missing data on registering Terumetal armor') end + data.uses = data.uses or 500 + data.mrv = data.mrv or 10 -- material repair value of 1x mat + data.dgroups = data.dgroups or {cracky=3, snappy=3, choppy=3, crumbly=3, level=1} + data.name = data.name or data.suffix + + local low_def = data.total_def / 6 + local hi_def = data.total_def / 3 + + data.heal = data.total_heal / 4 + data.speed = data.weight / -100 + data.gravity = data.weight / 50 + + local boots_id = terumet.id('armboots_'..data.suffix) + armor:register_armor(boots_id, { + description = terumet.item_desc(data.name..' Boots', data.xinfo), + inventory_image = terumet.tex('invboots_'..data.suffix), + texture = terumet.tex('armboots_'..data.suffix), + preview = terumet.tex('prvboots_'..data.suffix), + groups = gen_armor_groups('armor_feet', data), + armor_groups = {fleshy=low_def}, + damage_groups = data.dgroups, + }) + reg_recipe_boots(boots_id, data.mat) + terumet.register_repairable_item(boots_id, data.mrv*4) + + local helm_id = terumet.id('armhelm_'..data.suffix) + armor:register_armor(helm_id, { + description= terumet.item_desc(data.name..' Helmet', data.xinfo), + inventory_image = terumet.tex('invhelm_'..data.suffix), + texture = terumet.tex('armhelm_'..data.suffix), + preview = terumet.tex('prvhelm_'..data.suffix), + groups = gen_armor_groups('armor_head', data), + armor_groups = {fleshy=low_def}, + damage_groups = data.dgroups, + }) + reg_recipe_helm(helm_id, data.mat) + terumet.register_repairable_item(helm_id, data.mrv*5) + + local chest_id = terumet.id('armchest_'..data.suffix) + armor:register_armor(chest_id, { + description= terumet.item_desc(data.name..' Chestpiece', data.xinfo), + inventory_image = terumet.tex('invchest_'..data.suffix), + texture = terumet.tex('armchest_'..data.suffix), + preview = terumet.tex('prvchest_'..data.suffix), + groups = gen_armor_groups('armor_torso', data), + armor_groups = {fleshy=hi_def}, + damage_groups = data.dgroups, + }) + reg_recipe_chest(chest_id, data.mat) + terumet.register_repairable_item(chest_id, data.mrv*8) + + local legs_id = terumet.id('armlegs_'..data.suffix) + armor:register_armor(legs_id, { + description= terumet.item_desc(data.name..' Leggings', data.xinfo), + inventory_image = terumet.tex('invlegs_'..data.suffix), + texture = terumet.tex('armlegs_'..data.suffix), + preview = terumet.tex('prvlegs_'..data.suffix), + groups = gen_armor_groups('armor_legs', data), + armor_groups = {fleshy=hi_def}, + damage_groups = data.dgroups, + }) + reg_recipe_legs(legs_id, data.mat) + terumet.register_repairable_item(legs_id, data.mrv*7) +end + +-- enable terumet bracers +if opts.BRACERS then + -- I would love to colorize every texture rather than require a seperate armor & preview texture for every bracer + -- but it seems that 3d_armor textures do NOT support texture generation with ^ layering and ^[multiply :( + local function bracer_inv_texture(color) + if color then + return string.format('(%s^(%s^[multiply:%s))', terumet.tex('invbrcr_base'), terumet.tex('invbrcr_color'), color) + else + return terumet.tex('invbrcr_base') + end + end + + local function core_texture(color) + return string.format('%s^[multiply:%s', terumet.tex('item_brcrcrys'), color) + end + + table.insert(armor.elements, "terumet_brcr") + + local brcrcrys_id = terumet.id('item_brcrcrys') + minetest.register_craftitem( brcrcrys_id, { + description = 'Blank Bracer Core', + inventory_image = terumet.tex(brcrcrys_id) + }) + -- add vulcan crystallizer recipe for blank bracer core + terumet.options.vulcan.recipes[opts.BRACER_CRYSTAL_ITEM] = {brcrcrys_id, 2} + + local function reg_terumet_band(data) + if not data or not data.suffix then error('Missing data on registering Terumetal bracer') end + data.uses = data.uses or 500 + data.def = data.def or 0 + data.dgroups = data.dgroups or {cracky=3, snappy=3, choppy=3, crumbly=3, level=1} + data.name = data.name or data.suffix + -- generate groups now to update xinfo if necessary before registering it + local groups = gen_armor_groups('armor_terumet_brcr', data) + + local band_id = terumet.id('brcr_'..data.suffix) + armor:register_armor(band_id, { + description= terumet.item_desc(data.name..' Bracers', data.xinfo), + inventory_image = bracer_inv_texture(data.color), + texture = terumet.tex('armbrcr_'..data.suffix), + preview = terumet.tex('prvbrcr_'..data.suffix), + groups = groups, + armor_groups = {fleshy=data.def}, + damage_groups = data.dgroups, + on_equip = data.on_equip, + on_unequip = data.on_unequip, + on_damage = data.on_damage, + on_punched = data.on_punched + }) + + if data.mat then + local ecryst_id = terumet.id('item_brcrcrys_'..data.suffix) + minetest.register_craftitem( ecryst_id, { + description = data.name..' Bracer Core', + inventory_image = core_texture(data.color) + }) + + terumet.register_alloy_recipe{result=ecryst_id, flux=4, time=10.0, input={brcrcrys_id, data.mat}} + + terumet.register_alloy_recipe{result=band_id, flux=0, time=120.0, input={terumet.id('brcr_base'), ecryst_id .. ' 8'}} + else + local metal = terumet.id('item_cryst_raw') + local coil = terumet.id('item_coil_tgol') + minetest.register_craft{output=band_id, recipe={ + {coil, metal, coil}, + {metal, metal, metal}, + {coil, metal, coil} + }} + end + + terumet.register_repairable_item(band_id, data.rep or 80) + end + + reg_terumet_band{suffix='base', name='Terumetal', xinfo='No effects', def=5, uses=500, rep=80} + + for band_id, band_data in pairs(opts.BRACERS) do + if (not band_data.fire) or armor.config.fire_protect then + band_data.suffix = band_id + reg_terumet_band(band_data) + end + end +end + +if not armor.config.fire_protect then + minetest.log('warning', 'terumet: fire protection on armor will not function - 3d_armor fire protection option not activated') +end + +-- 3d_armor fire protection notes: total fire protection must meet or exceed the following values to be immune +-- torches = 1, fire = 3, lava = 5 +-- this seems to be the only effect it has + +reg_terumet_armor{suffix='cgls', name='Coreglass', mat=terumet.id('ingot_cgls'), + mrv=120, total_def=78, total_heal=36, weight=3, xinfo='Weight +3', uses=120, fire=0.75} -- 2 pcs = immune to torches, 4 pcs = immune to fire +reg_terumet_armor{suffix='tcha', name='Teruchalcum', mat=terumet.id('ingot_tcha'), + mrv=60, total_def=64, total_heal=8, weight=2, xinfo='Weight +2', uses=260} +reg_terumet_armor{suffix='tste', name='Terusteel', mat=terumet.id('ingot_tste'), + mrv=40, total_def=56, total_heal=12, weight=1, xinfo='Weight +1', uses=190} +reg_terumet_armor{suffix='tcop', name='Terucopper', mat=terumet.id('ingot_tcop'), + mrv=20, total_def=45, total_heal=4, weight=0, uses=280} +reg_terumet_armor{suffix='tgol', name='Terugold', mat=terumet.id('ingot_tgol'), + mrv=80, total_def=24, total_heal=65, weight=-1, xinfo='Weight -1', uses=720} +reg_terumet_armor{suffix='ttin', name='Terutin', mat=terumet.id('ingot_ttin'), + mrv=21, total_def=38, total_heal=24, weight=-2, xinfo='Weight -2', uses=410, fire=0.34, breathing=.1} -- 3 pcs = immune to torches +reg_terumet_armor{suffix='rsuit', name='Vulcansuit', mat=terumet.id('item_rsuitmat'), + mrv=180, total_def=78, total_heal=50, weight=-3, xinfo='Weight -3', uses=120, fire=1} -- 1 pc = immune to torches, 3 pcs = immune to fire diff --git a/mods/terumet/interop/crusher_misc.lua b/mods/terumet/interop/crusher_misc.lua new file mode 100644 index 0000000..c8f7174 --- /dev/null +++ b/mods/terumet/interop/crusher_misc.lua @@ -0,0 +1,47 @@ +-- add crushing recipes for various mods if they are active + +local function add_crush(item, result) + terumet.options.crusher.recipes[item] = result +end + + +if minetest.get_modpath('bushes') then + add_crush('bushes:BushLeaves1', 'terumet:item_dust_bio') + add_crush('bushes:BushLeaves2', 'terumet:item_dust_bio') +end + +if minetest.get_modpath('dryplants') then + add_crush('dryplants:grass', 'terumet:item_dust_bio') +end + +if minetest.get_modpath('vines') then + add_crush('vines:vines', 'terumet:item_dust_bio') +end + +if minetest.get_modpath('farming') then + -- small crops turn into 2 biomatter + local small_crops = { + 'wheat', 'peas', 'barley', 'beans', 'pepper', 'beetroot', 'chili_pepper', 'blueberries', + 'cucumber', 'grapes', 'garlic', 'onion', 'pea_pod', 'pineapple_ring', 'pineapple_top', 'potato', + 'raspberries', 'tomato', 'corn', 'rhubarb' + } + + for _,crop in ipairs(small_crops) do + local crop_id = 'farming:'..crop + if minetest.registered_items[crop_id] then + add_crush(crop_id, 'terumet:item_dust_bio 2') + end + end + + -- big crops turn into 5 biomatter + local big_crops = { + 'pumpkin', 'pineapple', 'melon_8' + } + + for _,crop in ipairs(big_crops) do + local crop_id = 'farming'..crop + if minetest.registered_items[crop_id] then + add_crush(crop_id, 'terumet:item_dust_bio 5') + end + end +end \ No newline at end of file diff --git a/mods/terumet/interop/doors.lua b/mods/terumet/interop/doors.lua new file mode 100644 index 0000000..726a0bd --- /dev/null +++ b/mods/terumet/interop/doors.lua @@ -0,0 +1,79 @@ +-- order door type can be converted +local type_order = {'full', 'mesh', 'slat', 'vert'} +local type_names = { + full='Solid %s Door', + mesh='Meshed %s Door', + slat='Slatted %s Door', + vert='Fancy %s Door' +} + +local materials = { + tcop={ + item=terumet.id('ingot_tcop'), + name='Terucopper', + level=1 + }, + ttin={ + item=terumet.id('ingot_ttin'), + name='Terutin', + level=1 + }, + tste={ + item=terumet.id('ingot_tste'), + name='Terusteel', + level=2 + }, + tcha={ + item=terumet.id('ingot_tcha'), + name='Teruchalcum', + level=2 + }, + tgol={ + item=terumet.id('ingot_tgol'), + name='Terugold', + level=3 + }, + cgls={ + item=terumet.id('ingot_cgls'), + name='Coreglass', + level=4 + } +} + +for mat_id, mat_data in pairs(materials) do + local first_door_id = nil + local prev_door_id = nil + for _, type_id in pairs(type_order) do + local type_name = type_names[type_id] + local door_id = terumet.id(string.format('door%s_%s', type_id, mat_id)) + local door_tex = terumet.tex(string.format('door%s_%s', type_id, mat_id)) + local door_invtex = terumet.tex(string.format('dinv%s_%s', type_id, mat_id)) + local door_recipe = nil + if not prev_door_id then + door_recipe = { + {mat_data.item, mat_data.item}, + {mat_data.item, mat_data.item}, + {mat_data.item, mat_data.item} + } + end + doors.register(door_id, { + tiles = {{name = door_tex, backface_culling = true}}, + description = string.format(type_name, mat_data.name), + inventory_image = door_invtex, + protected = true, + groups = {cracky = 1, level = mat_data.level}, + sounds = default.node_sound_metal_defaults(), + sound_open = 'doors_steel_door_open', + sound_close = 'doors_steel_door_close', + recipe = door_recipe + }) + + if prev_door_id then + minetest.register_craft{ type='shapeless', output=door_id, recipe={prev_door_id} } + end + + if not first_door_id then first_door_id = door_id end + prev_door_id = door_id + end + minetest.register_craft{ type='shapeless', output=first_door_id, recipe={prev_door_id} } +end diff --git a/mods/terumet/interop/dungeon_loot.lua b/mods/terumet/interop/dungeon_loot.lua new file mode 100644 index 0000000..bf63ac9 --- /dev/null +++ b/mods/terumet/interop/dungeon_loot.lua @@ -0,0 +1,44 @@ + +local rloot = dungeon_loot.register +local id = terumet.id + +local BOTTOM = -32768 +local TOP = 32768 + +-- still a WIP on balance/items put into loot + +rloot{name=id('item_col_raw'), chance=0.8, count={1,9}, y={-64, TOP}} +rloot{name=id('item_col_tcop'), chance=0.8, count={1,9}, y={-512, 32}} +rloot{name=id('item_col_tgol'), chance=0.8, count={1,9}, y={BOTTOM, 0}} + +rloot{name=id('lump_raw'), chance=0.8, count={2,6}, y={0, TOP}} +rloot{name=id('ingot_raw'), chance=0.7, count={1,4}, y={0, TOP}} +rloot{name=id('lump_raw'), chance=0.85, count={1,12}} +rloot{name=id('ingot_raw'), chance=0.75, count={1,9}} + +rloot{name=id('item_glue'), chance=0.95, count={3,24}, y={-16, TOP}} +rloot{name=id('item_coke'), chance=0.85, count={1,10}, y={-128, -32}} +rloot{name=id('item_tarball'), chance=0.75, count={1,10}, y={BOTTOM, -96}} + +rloot{name=id('block_pwood'), chance=0.85, count={8,24}, y={-16, TOP}} +rloot{name=id('block_conmix'), chance=0.65, count={8,24}, y={-64, 128}} +rloot{name=id('block_asphalt'), chance=0.75, count={8,24}, y={-128, -48}} + +rloot{name=id('item_ceramic'), chance=0.65, count={2,10}, y={-8, TOP}} +rloot{name=id('item_ceramic'), chance=0.85, count={6,24}, y={-256, -8}} +rloot{name=id('block_ceramic'), chance=0.45, count={1,3}, y={BOTTOM, -128}} + +rloot{name=id('item_batt_cop_full'), chance=0.10, y={-128, 0}} +rloot{name=id('item_batt_therm_full'), chance=0.05, y={BOTTOM, -128}} + +rloot{name=id('item_htglass'), chance=0.5, count={1,3}, y={-128, 0}} +rloot{name=id('item_entropy'), chance=0.2, y={BOTTOM, -128}} + +rloot{name=id('repmat_drop'), chance=0.5, count={1,24}, y={BOTTOM, -8}} + +-- TODO: weight alloys by value +for _,alloy_data in pairs(terumet.alloys) do + rloot{name=alloy_data.ingot, chance=0.30, count={1,2}, y={-24, TOP}} + rloot{name=alloy_data.ingot, chance=0.50, count={1,5}, y={-128, 0}} + rloot{name=alloy_data.ingot, chance=0.70, count={3,9}, y={BOTTOM, -96}} +end \ No newline at end of file diff --git a/mods/terumet/interop/extra.lua b/mods/terumet/interop/extra.lua new file mode 100644 index 0000000..42db299 --- /dev/null +++ b/mods/terumet/interop/extra.lua @@ -0,0 +1,14 @@ +local food_opts = terumet.options.vac_oven.VAC_FOOD + +-- add farming foods to vac-food whitelist if it's active +if food_opts and food_opts.ACTIVE then + local foods = { + 'potato_crisps', 'french_fries', 'onion_rings', 'blooming_onion', 'fish_sticks', 'grilled_patty', 'hamburger', 'cheeseburger', + 'corn_dog', 'meatloaf', 'flour_tortilla', 'taco', 'super_taco', 'quesadilla', 'pepperoni', 'garlic_bread', 'spaghetti', 'lasagna', 'cheese_pizza', + 'salsa', 'pepperoni_pizza', 'deluxe_pizza', 'pineapple_pizza', 'cornbread' + } + + for _,id in ipairs(foods) do + food_opts.WHITELIST[string.format('extra:%s', id)]=1 + end +end \ No newline at end of file diff --git a/mods/terumet/interop/farming.lua b/mods/terumet/interop/farming.lua new file mode 100644 index 0000000..9948dae --- /dev/null +++ b/mods/terumet/interop/farming.lua @@ -0,0 +1,13 @@ +local food_opts = terumet.options.vac_oven.VAC_FOOD + +-- add farming foods to vac-food whitelist if it's active +if food_opts and food_opts.ACTIVE then + local foods = { + 'baked_potato', 'potato_salad', 'pumpkin_bread', 'toast_sandwich', 'donut', 'donut_chocolate', 'donut_apple', 'porridge', 'turkish_delight', + 'chili_bowl', 'rhubarb_pie', 'garlic_bread', 'muffin_blueberry', 'chocolate_dark' + } + + for _,id in ipairs(foods) do + food_opts.WHITELIST[string.format('farming:%s', id)]=1 + end +end \ No newline at end of file diff --git a/mods/terumet/interop/mesecons.lua b/mods/terumet/interop/mesecons.lua new file mode 100644 index 0000000..4120234 --- /dev/null +++ b/mods/terumet/interop/mesecons.lua @@ -0,0 +1,7 @@ +-- interop bugfix with Mesecons/piston mod +-- fix for https://github.com/Terumoc/terumet/issues/16 + +terumet.machine.register_on_new_machine_node(function (id, def) + -- register every terumetal machine node as a "stopper" for pistons + mesecon.register_mvps_stopper(id, true) +end) \ No newline at end of file diff --git a/mods/terumet/interop/moreores.lua b/mods/terumet/interop/moreores.lua new file mode 100644 index 0000000..36bffbd --- /dev/null +++ b/mods/terumet/interop/moreores.lua @@ -0,0 +1,22 @@ + +local crys_mithril = terumet.register_crystal{ + suffix='mith', + color='#6161d5', + name='Crystallized Mithril', + cooking_result='moreores:mithril_ingot' +} +terumet.register_vulcan_result('moreores:mithril_lump', crys_mithril) +terumet.register_vulcan_result('moreores:mineral_mithril', crys_mithril, 1) + +local crys_silver = terumet.register_crystal{ + suffix='silv', + color='#d3fffb', + name='Crystallized Silver', + cooking_result='moreores:silver_ingot' +} +terumet.register_vulcan_result('moreores:silver_lump', crys_silver) +terumet.register_vulcan_result('moreores:mineral_silver', crys_silver, 1) + + +terumet.crystal_ids.mitril = crys_mithril +terumet.crystal_ids.silver = crys_silver \ No newline at end of file diff --git a/mods/terumet/interop/terumet_api.lua b/mods/terumet/interop/terumet_api.lua new file mode 100644 index 0000000..7d15b0f --- /dev/null +++ b/mods/terumet/interop/terumet_api.lua @@ -0,0 +1,234 @@ +-- API for other mods to interface with this mod + + +-- register an external block for use in making heatline versions and/or reinforced versions +-- if you wish to exclude one or the other, pass {heatline=true} or {reinforced=true} as 3rd argument + + +-- register an item that provide Repair Material to Equipment Reformer +-- value = repair material value provided by 1 item +function terumet.register_repair_material(id, value) + -- TODO error checking + terumet.options.repm.repair_mats[id] = value +end + +-- register a tool that can be repaired in Equipment Reformer +-- needed_mat = amount of repair material value to repair fully worn tool +function terumet.register_repairable_item(id, needed_mat) + -- TODO error checking + terumet.options.repm.repairable[id] = needed_mat +end + +-- register a new alloy smelter recipe +-- required data keys and descriptions: +local ALLOY_REQUIRED = { + result='[itemstack string] what will be output', + input='[table, 1-4 stacks] table of itemstacks consumed as input', + time='[float] time in seconds to process', + flux='[integer] amount of terumetal flux consumed from tank', +} +function terumet.register_alloy_recipe(data) + if not data then + error('terumet.register_alloy_recipe: no recipe data provided') + end + for req_key, desc in pairs(ALLOY_REQUIRED) do + if not data[req_key] then + error(string.format('terumet.register_alloy_recipe: recipe data is missing required key %s: %s', req_key, desc)) + end + end + if type(data.input) ~= 'table' or #data.input < 1 or #data.input > 4 then + error('terumet.register_alloy_recipe: invalid input; must be a table of 1-4 itemstack strings (inclusive)') + end + table.insert(terumet.options.smelter.recipes, 1, data) +end + +-- TODO error checking +function terumet.register_vacoven_recipe(data) + table.insert(terumet.options.vac_oven.recipes, data) +end + +-- register a new crystallized material with the provided data +-- ID of created item will be 'terumet:item_cryst_' +-- IMPORTANT NOTE: a single source item can only be defined as a single crystal +-- for example, trying to add a new crystal for 'default:copper_lump' will override the default one +-- +-- required data keys and descriptions: +local CRYSTAL_REQUIRED = { + suffix='[string] ID suffix for crystallized item', + color='[colorspec] minetest colorspec for crystallized item color', + name='[string] name of crystallized item', + cooking_result='[itemstack string] result of cooking crystallized item', +} + + +function terumet.register_crystal(data) + local this_func = 'terumet.register_crystal' + if not data then + error(this_func..': no data provided') + end + for req_key, desc in pairs(CRYSTAL_REQUIRED) do + if not data[req_key] then + error(string.format('%s: data missing required key %s: %s', this_func, req_key, desc)) + end + end + local crys_id = terumet.id('item_cryst_'..data.suffix) + minetest.register_craftitem( crys_id, { + description = data.name, + inventory_image = terumet.crystal_tex(data.color), + }) + minetest.register_craft{ type = 'cooking', + output = data.cooking_result, + recipe = crys_id, + cooktime = 5 + } + return crys_id -- returns crystal item ID +end + +-- register an item that can be put into crystal vulcanizer +-- requires source item and result, optionally include integer modifier +-- by default creates 2 result items, but count_modifier is added to that value +-- +1 more result item if vulcanizer has upgrade +function terumet.register_vulcan_result(source, result, count_modifier, specialized) + count_modifier = count_modifier or 0 + local this_func = 'terumet.register_vulcan_result' + if not source then error(this_func..': no source item provided') end + if not result then error(this_func..': no result item provided') end + local count = 2 + count_modifier + if( count < 1 ) then count = 1 end + terumet.options.vulcan.recipes[source] = {result, count, specialized} +end + +-- register that a node can generate heat when extracted by the Environmental Entropy Extraction Heater (EEE Heater) +local ENTROPIC_REQUIRED = { + node='[string] id of node that can be extracted', + hu_per_s='[integer] number of heat units extracted per second', + extract_time='[float] total amount of time to extract this node', +} +-- optional keys: +-- change_to: [string] what node this node will change into after extraction - if nil, the node will not change and thus can be extracted over and over (like air by default) +function terumet.register_entropic_node(data) + if not data then + error('terumet.register_entropic_node: no data provided') + end + for req_key, desc in pairs(ENTROPIC_REQUIRED) do + if not data[req_key] then + error(string.format('terumet.register_entropic_node: data is missing required key %s: %s', req_key, desc)) + end + end + terumet.options.heater.entropy.EFFECTS[data.node] = {hu_per_s=data.hu_per_s, extract_time=data.extract_time, change_to=data.change_to} +end + + +local STANDARD_INV_LISTS = {'in', 'out', 'fuel', 'upgrade'} +local EXTERNAL_MACHINES = {} +local MACHINE_REQUIRED = { + name='[string] Name of machine', + node_tiles='[minetest tiles definition] Tiles for machine node', + heat_max='[integer] Base maximum heat units that can be stored by machine', + input_slots='[integer, 0-4 expected] Size of input inventory', + output_slots='[integer, 0-4 expected] Size of output inventory', + has_fuel_slot='[boolean] Whether machine has direct fuel slot', + upgrade_slots='[integer, 0-6 expected] Size of upgrade inventory', + tick_time='[float] Time in seconds between machine ticks', + tick_function='[fn(machine_state, dt) -> boolean] Function called when machine ticks. Return true to tick again in tick_time seconds.' +} +-- optional keys: +-- heat_provider: [boolean] true if machine generates/provides heat to adjacent machines +-- heat_transfer: [integer] Maximum amount of heat machine can send in 1 tick +-- node_name: [string] name to give machine's node. if not provided, uses same as 'name' +-- node_param2: [string] param2 to give machine's node (same as minetest's nodedef param2 setting: facedir/none/etc. ) +-- custom_init: [fn(pos, meta, inv) -> nil] custom initialization for setting inventories or other metadata of a new machine +-- custom_write: [fn(machine_state)] function to call when saving machine state to metadata +-- custom_read: [fn(machine_state)] function to call when reading machine state from metadata +-- -- machine formspec options -- +-- +-- machinefs_theme: [string] definition of background/listcolors for machine's formspec +-- machinefs_func: [fn(machine_state) -> string] custom function that returns formspec definition for main area above inventory in interface +-- -- -- +-- custom_fsdef: [fsdef table] entire customized formspec definition table for machine to use, see terumet/machine/machine.lua:build_fs for more information +-- [IMPORTANT] => using custom_fsdef completely overrides use of machinefs_* funcs and default formspec so everything must be defined + +function terumet.register_heat_machine( id, data ) + if not data then + error('terumet.register_heat_machine: no data provided') + end + for req_key, desc in pairs(MACHINE_REQUIRED) do + if not data[req_key] then + error(string.format('terumet.register_heat_machine: data is missing required key %s: %s', req_key, desc)) + end + end + + local machine_tm_class = { + name = data.name, + timer = data.tick_time, + fsdef = data.custom_fsdef or { + control_buttons = { + terumet.machine.buttondefs.HEAT_XFER_TOGGLE, + }, + machine = data.machinefs_func or terumet.NO_FUNCTION, + input = {data.input_slots > 0}, + output = {data.output_slots > 0}, + fuel_slot = {data.fuel_slot}, + theme = data.machinefs_theme, + }, + default_heat_xfer = (data.heat_provider and terumet.machine.HEAT_XFER_MODE.PROVIDE_ONLY) or terumet.machine.HEAT_XFER_MODE.ACCEPT, + get_drop_contents = function(machine) + local drops = {} + for _,std_list in ipairs(STANDARD_INV_LISTS) do + default.get_inventory_drops(machine.pos, std_list, drops) + end + return drops + end + } + + local node_def = terumet.machine.nodedef{ + description = data.node_name or data.name, + tiles = data.node_tiles, + param2 = data.node_param2, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if data.upgrade_slots > 0 then inv:set_size('upgrade', data.upgrade_slots) end + if data.input_slots > 0 then inv:set_size('in', data.input_slots) end + if data.output_slots > 0 then inv:set_size('out', data.output_slots) end + if data.has_fuel_slot then inv:set_size('fuel', 1) end + if data.custom_init then data.custom_init(pos, meta, inv) end + local init = { + class = machine_tm_class, + state = 0, + state_time = 0, + heat_level = 0, + max_heat = data.heat_max, + status_text = 'New', + inv = inv, + meta = meta, + pos = pos, + } + terumet.machine.write_state(pos, init) + terumet.machine.set_timer(init) + end, + on_timer = function(pos, dt) + local machine = terumet.machine.tick_read_state(pos) + local re_tick = false + if not terumet.machine.check_overheat(machine, data.heat_max) then + re_tick = data.tick_function(machine, dt) + if machine.heat_xfer_mode == terumet.machine.HEAT_XFER_MODE.PROVIDE_ONLY then + terumet.machine.push_heat_adjacent(machine, data.heat_transfer or 50) + end + + if data.has_fuel_slot then + terumet.machine.process_fuel(machine) + re_tick = not machine.need_heat + end + end + -- write status back to meta + terumet.machine.write_state(pos, machine) + return re_tick + end, + _terumach_class = machine_tm_class + } + + minetest.register_node( id, node_def ) + + EXTERNAL_MACHINES[id] = data +end diff --git a/mods/terumet/interop/tubelib.lua b/mods/terumet/interop/tubelib.lua new file mode 100644 index 0000000..7a286ca --- /dev/null +++ b/mods/terumet/interop/tubelib.lua @@ -0,0 +1,52 @@ +local tube = 'tubelib:tubeS' +if tubelib.version < 2.0 then + tube = 'tubelib:tube1' +end + +terumet.register_machine_upgrade('tubelib', 'Tube Support Upgrade', {terumet.id('item_upg_base'), tube}, nil, 'simple', 'Allows machine to interface with tubelib tubes') + +local machine_check = function(machine, player_name) + return machine and terumet.machine.has_upgrade(machine, 'tubelib') + ---terumet.machine.has_auth(machine, player_name) +end + +local PUSH_FUNC = function(pos, side, item, player_name) + local machine = terumet.machine.readonly_state(pos) + if machine_check(machine) then + local result = tubelib.put_item(machine.meta, 'in', item) + if result then machine.class.on_inventory_change(machine) end + return result + end + return false +end + +local TUBELIB_MACHINE_DEF = { + on_pull_item = function(pos, side, player_name) + local machine = terumet.machine.readonly_state(pos) + if machine_check(machine) then + return tubelib.get_item(machine.meta, 'out') + end + return nil + end, + on_push_item = PUSH_FUNC, + on_unpull_item = PUSH_FUNC +} + +terumet.machine.register_on_place(function (pos, machine, placer) + tubelib.add_node(pos, machine.class.name) +end) + +terumet.machine.register_on_remove(function (pos, machine) + tubelib.remove_node(pos) +end) + +tubelib.register_node(terumet.id('mach_asmelt'), {terumet.id('mach_asmelt_lit')}, TUBELIB_MACHINE_DEF) +tubelib.register_node(terumet.id('mach_htfurn'), {terumet.id('mach_htfurn_lit')}, TUBELIB_MACHINE_DEF) +tubelib.register_node(terumet.id('mach_lavam'), {terumet.id('mach_lavam_lit')}, TUBELIB_MACHINE_DEF) +tubelib.register_node(terumet.id('mach_htr_furnace'), {terumet.id('mach_htr_furnace_lit')}, TUBELIB_MACHINE_DEF) +tubelib.register_node(terumet.id('mach_crusher'), {terumet.id('mach_crusher_lit')}, TUBELIB_MACHINE_DEF) +--oops: mese garden has no upgrade slots... consider adding it if support for other upgrades is added in future +--tubelib.register_node(terumet.id('mach_meseg'), terumet.EMPTY, TUBELIB_MACHINE_DEF) +tubelib.register_node(terumet.id('mach_repm'), terumet.EMPTY, TUBELIB_MACHINE_DEF) +tubelib.register_node(terumet.id('mach_vulcan'), terumet.EMPTY, TUBELIB_MACHINE_DEF) + diff --git a/mods/terumet/interop/unified_inventory.lua b/mods/terumet/interop/unified_inventory.lua new file mode 100644 index 0000000..942cda1 --- /dev/null +++ b/mods/terumet/interop/unified_inventory.lua @@ -0,0 +1,163 @@ +local function add_terumet_recipes() + -- add each defined alloy recipe to UnInv + for _, recipe in pairs(terumet.options.smelter.recipes) do + local listed = {} + for i=1,#recipe.input do listed[#listed+1] = recipe.input[i] end + if recipe.flux > 0 then + listed[#listed+1] = terumet.id('uninv_flux_req', recipe.flux) + end + listed[#listed+1] = terumet.id('uninv_time_req', math.ceil(recipe.time)) + unified_inventory.register_craft{ + type = 'terumet_alloy', + output = recipe.result, + items = listed + } + end + + -- add each defined vacuum oven recipe (1 entry for each output) + for _, recipe in ipairs(terumet.options.vac_oven.recipes) do + local time = terumet.id('uninv_time_req', math.ceil(recipe.time)) + for _, output in ipairs(recipe.results) do + unified_inventory.register_craft{ + type = 'terumet_vacoven', + output = output, + items = {recipe.input, time} + } + end + end + + -- add each defined flux source to UnInv + for source, details in pairs(terumet.options.smelter.FLUX_ITEMS) do + unified_inventory.register_craft{ + type = 'terumet_alloy', + output = terumet.id('uninv_flux_req'), + items = {source, terumet.id('uninv_time_req', math.ceil(details.time))} + } + end + + -- add each crusher recipe to UnInv + for source, result in pairs(terumet.options.crusher.recipes) do + unified_inventory.register_craft{ + type = 'terumet_crush', + output = result, + items = {source} + } + end + + -- add each repair material to UnInv + for id, repmatval in pairs(terumet.options.repm.repair_mats) do + unified_inventory.register_craft{ + type = 'terumet_repmat', + output = terumet.id('uninv_repmat', repmatval), + items = {id} + } + end + + -- add each repairable tool to UnInv + for id, rmreq in pairs(terumet.options.repm.repairable) do + unified_inventory.register_craft{ + type = 'terumet_repair', + output = id, + items = {id, terumet.id('uninv_repmat', rmreq)} + } + end + + -- add each crystal vulcanizer recipe to UnInv + for source, result in pairs(terumet.options.vulcan.recipes) do + --minetest.log(string.format('%s => %s x %s', source or 'NIL', result[1] or 'NIL', result[2] or 'NIL')) + unified_inventory.register_craft{ + type = 'terumet_vulcan', + output = result[1] .. ' ' .. result[2], + items = {source} + } + end + + -- add each valid ore for ore saw to UnInv + for node, _ in pairs(terumet.options.ore_saw.VALID_ORES) do + unified_inventory.register_craft{ + type = 'terumet_ore_saw', + output = node, + items = {node} + } + end +end + +-- dummy item to display amount of flux needed to alloy +minetest.register_craftitem( terumet.id('uninv_flux_req'), { + description = "terumetal flux (in smelter tank)", + inventory_image = terumet.tex('uninv_flux_req'), + groups={not_in_creative_inventory=1} +}) + +-- dummy item to display amount of time needed to alloy +minetest.register_craftitem( terumet.id('uninv_time_req'), { + description = "time (seconds)", + inventory_image = terumet.tex('uninv_time_req'), + groups={not_in_creative_inventory=1} +}) + +-- dummy item to display amount of repair material +minetest.register_craftitem( terumet.id('uninv_repmat'), { + description = "repair material value", + inventory_image = terumet.tex('uninv_repmat'), + groups={not_in_creative_inventory=1} +}) + +-- register terumetal alloying with UnInv +unified_inventory.register_craft_type( 'terumet_alloy', { + description = 'Terumetal Alloy Smelting', + icon = 'terumet_asmelt_front_lit.png', + width=3, + height=2, +}) + +-- register crushing with UnInv +unified_inventory.register_craft_type( 'terumet_crush', { + description = 'Expansion Crusher', + icon = 'terumet_crush_front_lit.png', + width=1, + height=1, +}) + +-- register repair materials with UnInv +unified_inventory.register_craft_type( 'terumet_repmat', { + description = 'Equipment Reformer\n(material)', + icon = 'terumet_repm_front.png', + width=1, + height=1, +}) + +-- register tool repair with UnInv +unified_inventory.register_craft_type( 'terumet_repair', { + description = 'Equipment Reformer\n(for 100% wear)', + icon = 'terumet_repm_front.png', + width=2, + height=1, +}) + +-- register crystal vulcanizing with UnInv +unified_inventory.register_craft_type( 'terumet_vulcan', { + description = 'Crystal Vulcanizer', + icon = 'terumet_vulcan_front.png', + width=1, + height=1, +}) + +-- register ore saw gathering +unified_inventory.register_craft_type( 'terumet_ore_saw', { + description = 'Ore-cutting Saw', + icon = 'terumet_tool_ore_saw.png^[transformFX', + width=1, + height=1, +}) + +-- register vacuum oven with UnInv +unified_inventory.register_craft_type( 'terumet_vacoven', { + description = 'Vacuum Oven', + icon = 'terumet_vacoven_front.png', + width=3, + height=2, +}) + +-- call after all mods are loaded to catch new submod recipes/changes +minetest.after(0.01, function() add_terumet_recipes() end) \ No newline at end of file diff --git a/mods/terumet/material/ceramic.lua b/mods/terumet/material/ceramic.lua new file mode 100644 index 0000000..8d533bb --- /dev/null +++ b/mods/terumet/material/ceramic.lua @@ -0,0 +1,23 @@ +local cplate_id = terumet.id('item_ceramic') +local cblock_id = terumet.id('block_ceramic') + +minetest.register_craftitem( cplate_id, { + description = 'Teruceramic Plate', + inventory_image = terumet.tex(cplate_id) +}) + +minetest.register_node( cblock_id, { + description = 'Teruceramic Block', + tiles = {terumet.tex(cblock_id)}, + is_ground_content = false, + groups={cracky=1, level=1, puts_out_fire=1}, + sounds = default.node_sound_glass_defaults() +}) + +minetest.register_craft{ output = cblock_id, + recipe = terumet.recipe_3x3(cplate_id) +} + +minetest.register_craft{ type = 'shapeless', output = terumet.id('item_ceramic', 9), + recipe = {cblock_id} +} \ No newline at end of file diff --git a/mods/terumet/material/coalproc.lua b/mods/terumet/material/coalproc.lua new file mode 100644 index 0000000..7c3cfa7 --- /dev/null +++ b/mods/terumet/material/coalproc.lua @@ -0,0 +1,120 @@ +local coke_id = terumet.id('item_coke') + +minetest.register_craftitem( coke_id, { + description = 'Coke Lump', + inventory_image = terumet.tex(coke_id), + groups = {coal = 1, flammable = 1}, +}) + +minetest.register_craft({ + type = "fuel", + recipe = coke_id, + burntime = 80, +}) + +local coke_block_id = terumet.id('block_coke') + +minetest.register_node( coke_block_id, { + description = 'Coke Block', + tiles = {terumet.tex(coke_block_id)}, + is_ground_content = false, + groups = {cracky = 3}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_craft({ + type = "fuel", + recipe = coke_block_id, + burntime = 740, +}) + +minetest.register_craft{ output = coke_block_id, + recipe = terumet.recipe_3x3(coke_id) +} + +minetest.register_craft{ type = 'shapeless', output = coke_id .. ' 9', + recipe = {coke_block_id}, +} + +local tarball_id = terumet.id('item_tarball') + +minetest.register_craftitem( tarball_id, { + description = 'Tarball', + inventory_image = terumet.tex(tarball_id), + groups = {glue=1} +}) + +minetest.register_craft({ + type = "fuel", + recipe = tarball_id, + burntime = 30, +}) + +local tarblock_id = terumet.id('block_tar') + +minetest.register_node( tarblock_id, { + description = 'Tar Block', + tiles = {terumet.tex(tarblock_id)}, + is_ground_content = false, + groups = {level=2, crumbly=2, cracky=1, snappy=2, choppy=2, disable_jump=1, fall_damage_add_percent=-100}, + sounds = terumet.squishy_node_sounds +}) + + +minetest.register_craft{ output = tarblock_id, + recipe = terumet.recipe_box(tarball_id, '') +} + +minetest.register_craft{ type = 'shapeless', output = tarball_id .. ' 8', recipe = {tarblock_id} } + +local prerubber_id = terumet.id('item_prerub') + +minetest.register_craftitem( prerubber_id, { + description = 'Bio-tar Mixture', + inventory_image = terumet.tex(prerubber_id) +}) + +minetest.register_craft{ output = prerubber_id, + recipe = { + {'', tarball_id, ''}, + {tarball_id, 'terumet:item_dust_bio', tarball_id}, + {'', tarball_id, ''} + } +} + +local rubber_bar_id = terumet.id('item_rubber') + +terumet.options.vulcan.recipes[prerubber_id] = {rubber_bar_id, 1} + +minetest.register_craftitem( rubber_bar_id, { + description = 'Synthetic Rubber Bar', + inventory_image = terumet.tex(rubber_bar_id) +}) + +local rsuit_mat = terumet.id('item_rsuitmat') + +minetest.register_craftitem( rsuit_mat, { + description = 'Vulcansuit Plate', + inventory_image = terumet.tex(rsuit_mat) +}) + +terumet.register_alloy_recipe{result=rsuit_mat, flux=8, time=20.0, input={rubber_bar_id, 'terumet:ingot_cgls', 'terumet:item_ceramic'}} + +local asphalt_id = terumet.id('block_asphalt') + +minetest.register_node( asphalt_id, { + description = 'Asphalt Block', + tiles = {terumet.tex(asphalt_id)}, + is_ground_content = false, + groups = {cracky = 3, crumbly = 1, level = 1}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_craft({ + output = asphalt_id..' 8', + recipe = terumet.recipe_box('default:gravel', tarball_id) +}) + + +walls.register(terumet.id('wall_asphalt'), 'Asphalt Wall', terumet.tex(asphalt_id), asphalt_id, default.node_sound_stone_defaults()) +stairs.register_stair_and_slab('asphalt', asphalt_id, {cracky = 3, crumbly = 1, level = 1}, {terumet.tex(asphalt_id)}, 'Asphalt Stair', 'Asphalt Slab', default.node_sound_stone_defaults(), false ) diff --git a/mods/terumet/material/coil.lua b/mods/terumet/material/coil.lua new file mode 100644 index 0000000..fa86de9 --- /dev/null +++ b/mods/terumet/material/coil.lua @@ -0,0 +1,20 @@ +local reg_coil = function(name, mat) + local coil_id = terumet.id('item_coil_'..mat) + minetest.register_craftitem( coil_id, { + description = name, + inventory_image = terumet.tex(coil_id) + }) + local ingot_id = terumet.id('ingot_'..mat) + minetest.register_craft{ output=coil_id .. ' 3', + recipe = { + {ingot_id}, + {ingot_id}, + {ingot_id}, + } + } +end + +reg_coil('Pure Terumetal Coil', 'raw') +reg_coil('Terucopper Coil', 'tcop') +reg_coil('Terugold Coil', 'tgol') + diff --git a/mods/terumet/material/concrete.lua b/mods/terumet/material/concrete.lua new file mode 100644 index 0000000..256e21d --- /dev/null +++ b/mods/terumet/material/concrete.lua @@ -0,0 +1,152 @@ +local CONCRETE_COLORS = { + '#FFF',--white + '#AAA',--grey + '#666',--dark grey + '#333',--black + '#722ed4',--violet + '#2e56d4',--blue + '#5484ac',--cyan + '#135918',--dark green + '#3ad42e',--green + '#d4c12e',--yellow + '#592e13',--brown + '#d4652e',--orange + '#d42e2e',--red + '#d80481',--magenta + '#ff7272',--pink +} +local mix_base = terumet.id('block_conmix') +local block_base = terumet.id('block_con') + +local FMT = string.format + +local function mix_id(dye_index) + return FMT("%s_%s", mix_base, dye.dyes[dye_index][1]) +end +function terumet.concrete_block_id(dye_index) + return FMT("%s_%s", block_base, dye.dyes[dye_index][1]) +end + +local NAMEFORMATS = { + mix="%s Concrete Mix", + block="%s Concrete Block", + door="%s Concrete Door", + wall="%s Concrete Wall", + stair="%s Concrete Stair", + slab="%s Concrete Slab" +} + +local function make_name(name, dye_index) + return FMT(NAMEFORMATS[name], dye.dyes[dye_index][2]) +end + +local function texture(base, dye_index) + return FMT("%s^[multiply:%s", base, CONCRETE_COLORS[dye_index]) +end +local function mix_texture(dye_index) + return texture(terumet.tex('block_conmix'), dye_index) +end +local function block_texture(dye_index) + return texture(terumet.tex('block_con'), dye_index) +end +local function door_texture(dye_index) + return texture(terumet.tex('door_con'), dye_index) +end +local function door_item_texture(dye_index) + return texture(terumet.tex('dinv_con'), dye_index) +end + +local HARDEN_LIST = {} +local MIXES_LIST = {} + +for index,dye_info in ipairs(dye.dyes) do + local con_id = 'con_'..dye_info[1] + + minetest.register_node(mix_id(index), { + description = make_name('mix', index), + tiles = {mix_texture(index)}, + is_ground_content = false, + groups = {crumbly=2}, + --sounds = default.node_sound_sand_defaults(), + }) + + local block_id = terumet.concrete_block_id(index) + + minetest.register_node(block_id, { + description = make_name('block', index), + tiles = {block_texture(index)}, + is_ground_content = false, + groups = {cracky = 2, level = 1}, + sounds = default.node_sound_stone_defaults(), + }) + + if index ~= 1 then + local dye_id = "group:dye,color_"..dye_info[1] + local basic_powder = mix_id(1) + minetest.register_craft{ + output = mix_id(index)..' 8', + recipe = terumet.recipe_box(basic_powder, dye_id) + } + + minetest.register_craft{ + output = mix_id(index)..' 8', + recipe = terumet.recipe_box(basic_powder, 'dye:'..dye_info[1]) + } + end + + HARDEN_LIST[mix_id(index)] = block_id + table.insert(MIXES_LIST, mix_id(index)) + + + walls.register(terumet.id('wall_'..con_id), make_name('wall', index), block_texture(index), block_id, default.node_sound_stone_defaults()) + + doors.register(terumet.id('door_'..con_id), { + tiles = {{name = door_texture(index), backface_culling = true}}, + description = make_name('door', index), + inventory_image = door_item_texture(index), + protected = true, + groups = {cracky = 2, level = 1}, + sounds = default.node_sound_stone_defaults(), + sound_open = 'doors_steel_door_open', + sound_close = 'doors_steel_door_close', + recipe = { + {block_id}, + {'doors:door_steel'}, + {block_id}, + } + }) + + stairs.register_stair_and_slab(con_id, block_id, + {cracky = 2, level = 1}, + {block_texture(index)}, + make_name('stair',index), make_name('slab', index), + default.node_sound_stone_defaults(), + false + ) +end + +minetest.register_abm{ + label = 'Concrete mix hardening', + nodenames = MIXES_LIST, + neighbors = {'default:water_source', 'default:water_flowing'}, + interval = 3.0, -- Run every 3 seconds + chance = 1, -- always + action = function(pos, node, active_object_count, active_object_count_wider) + local harden_id = HARDEN_LIST[node.name] + if harden_id then + minetest.set_node(pos, {name = harden_id}) + end + end +} + +local gravel_id = 'default:gravel' +local any_sand = 'group:sand' + +minetest.register_craft{ + output = mix_id(1)..' 8', + recipe = { + {any_sand, gravel_id, any_sand}, + {gravel_id, '', gravel_id}, + {any_sand, gravel_id, any_sand} + } +} \ No newline at end of file diff --git a/mods/terumet/material/crushed.lua b/mods/terumet/material/crushed.lua new file mode 100644 index 0000000..70237d5 --- /dev/null +++ b/mods/terumet/material/crushed.lua @@ -0,0 +1,96 @@ +local biomat_item = terumet.id('item_dust_bio') +local biomat_block = terumet.id('block_dust_bio') + +local woodmulch_item = terumet.id('item_dust_wood') + +local glue_item = terumet.id('item_glue') + +minetest.register_craftitem( terumet.id('item_dust_ob'), { + description = 'Obsidian Grit', + inventory_image = terumet.tex('item_dust_ob') +}) + +-- ======================================================== + +minetest.register_craftitem( woodmulch_item, { + description = 'Wood Mulch', + inventory_image = terumet.tex('item_dust_wood') +}) + +minetest.register_craft({ + type = 'fuel', + recipe = woodmulch_item, + burntime = 10, +}) + +minetest.register_craft{ output = 'default:paper', + type = 'shapeless', + recipe = {'bucket:bucket_water', woodmulch_item, woodmulch_item}, + replacements={{'bucket:bucket_water','bucket:bucket_empty'}} +} + +-- ======================================================= + +minetest.register_craftitem( biomat_item, { + description = 'Biomatter', + inventory_image = terumet.tex('item_dust_bio') +}) + +minetest.register_craft{ + type = 'fuel', + recipe = biomat_item, + burntime = 30, +} + +minetest.register_node( biomat_block, { + description = 'Biomatter Block', + tiles = {terumet.tex('block_dust_bio')}, + is_ground_content = false, + groups={crumbly=3, oddly_breakable_by_hand=2, flammable=1}, + sounds = default.node_sound_leaves_defaults() +}) + +minetest.register_craft{ + type = 'fuel', + recipe = biomat_block, + burntime = 280, +} + +minetest.register_craft{ output = biomat_block, + recipe = terumet.recipe_3x3(biomat_item) +} + +minetest.register_craft{ output = biomat_item..' 9', + type = 'shapeless', + recipe = {biomat_block} +} + +minetest.register_craft{ output = 'default:torch 4', + recipe = { {biomat_item}, + {'group:stick'}} +} +-- ======================================================= + +minetest.register_craftitem( glue_item, { + description = 'Plant Glue', + groups = {glue=1}, + inventory_image = terumet.tex('item_glue') +}) + +minetest.register_craft{ output = glue_item, + type = 'shapeless', + recipe = {'bucket:bucket_water', biomat_item}, + replacements={{'bucket:bucket_water','bucket:bucket_empty'}} +} + +minetest.register_craft{ output = glue_item .. ' 9', + type = 'shapeless', + recipe = {'bucket:bucket_water', biomat_block}, + replacements={{'bucket:bucket_water','bucket:bucket_empty'}} +} + +minetest.register_craft{ output = glue_item .. ' 8', + type = 'shapeless', + recipe = {'bucket:bucket_water', 'farming:flour'}, + replacements={{'bucket:bucket_water','bucket:bucket_empty'}} +} \ No newline at end of file diff --git a/mods/terumet/material/crystallized.lua b/mods/terumet/material/crystallized.lua new file mode 100644 index 0000000..0c75c1f --- /dev/null +++ b/mods/terumet/material/crystallized.lua @@ -0,0 +1,88 @@ +local id=terumet.id +local opts = terumet.options.vulcan + +local crys_terumetal = terumet.register_crystal{ + suffix='raw', + color='#a33d57', + name='Crystallized Terumetal', + cooking_result=id('ingot_raw') +} +terumet.register_vulcan_result(id('lump_raw'), crys_terumetal, nil, true) -- 4th arg indicates it is a terumetal specialized recipe +terumet.register_vulcan_result(id('ore_raw'), crys_terumetal, 1, true) +terumet.register_vulcan_result(id('ore_raw_desert'), crys_terumetal, 2, true) + +local crys_copper = terumet.register_crystal{ + suffix='copper', + color='#ec923a', + name='Crystallized Copper', + cooking_result='default:copper_ingot' +} +terumet.register_vulcan_result('default:copper_lump', crys_copper) +terumet.register_vulcan_result('default:stone_with_copper', crys_copper, 1) + +local crys_tin = terumet.register_crystal{ + suffix='tin', + color='#dddddd', + name='Crystallized Tin', + cooking_result='default:tin_ingot' +} +terumet.register_vulcan_result('default:tin_lump', crys_tin ) +terumet.register_vulcan_result('default:stone_with_tin', crys_tin, 1) + +local crys_iron = terumet.register_crystal{ + suffix='iron', + color='#ffdcb5', + name='Crystallized Iron', + cooking_result='default:steel_ingot' +} +terumet.register_vulcan_result('default:iron_lump', crys_iron) +terumet.register_vulcan_result('default:stone_with_iron', crys_iron, 1) + +local crys_gold = terumet.register_crystal{ + suffix='gold', + color='#ffcb15', + name='Crystallized Gold', + cooking_result='default:gold_ingot' +} +terumet.register_vulcan_result('default:gold_lump', crys_gold) +terumet.register_vulcan_result('default:stone_with_gold', crys_gold, 1) + +local crys_ob = terumet.register_crystal{ + suffix='ob', + color='#351569', + name='Crystallized Obsidian', + cooking_result='default:obsidian' +} +if opts.LIMIT_OBSIDIAN then + terumet.register_vulcan_result('default:obsidian', crys_ob, -1) +else + terumet.register_vulcan_result('default:obsidian', crys_ob) +end + +local crys_mese = terumet.register_crystal{ + suffix='mese', + color='#fffb81', + name='Crystallized Mese', + cooking_result='default:mese_crystal' +} +terumet.register_vulcan_result('default:stone_with_mese', crys_mese) + +local crys_dia = terumet.register_crystal{ + suffix='dia', + color='#66f6ff', + name='Crystallized Diamond', + cooking_result='default:diamond' +} +terumet.register_vulcan_result('default:stone_with_diamond', crys_dia) + +-- outside mods can access ids of default crystallized materials through terumet.crystal_ids +terumet.crystal_ids = { + terumetal=crys_terumetal, + copper=crys_copper, + tin=crys_tin, + iron=crys_iron, + gold=crys_gold, + obsidian=crys_ob, + mese=crys_mese, + diamond=crys_dia +} diff --git a/mods/terumet/material/entropy.lua b/mods/terumet/material/entropy.lua new file mode 100644 index 0000000..7fc8c67 --- /dev/null +++ b/mods/terumet/material/entropy.lua @@ -0,0 +1,26 @@ +local ent_crystal_id = terumet.id('item_entropy') +local ent_matrix_id = terumet.id('block_entropy') + +minetest.register_craftitem( ent_crystal_id, { + description = 'Entropic Crystal', + inventory_image = terumet.tex(ent_crystal_id) +}) + +minetest.register_node( ent_matrix_id, { + description = 'Entropic Matrix\nPlace directly above EEE Heater', + tiles = {terumet.tex(ent_matrix_id)}, + is_ground_content = false, + groups={cracky=1, level=2}, + sounds = default.node_sound_glass_defaults() +}) + +minetest.register_craft{ output = ent_crystal_id, + recipe = { + { terumet.id('item_dust_ob'), terumet.id('item_cryst_mese'), terumet.id('item_dust_ob') }, + { terumet.id('item_cryst_mese'), terumet.id('item_cryst_dia'), terumet.id('item_cryst_mese') }, + { terumet.id('item_dust_ob'), terumet.id('item_cryst_mese'), terumet.id('item_dust_ob') }, +}} + +minetest.register_craft{ output = ent_matrix_id, + recipe = terumet.recipe_box(ent_crystal_id, 'default:diamondblock') +} \ No newline at end of file diff --git a/mods/terumet/material/meson.lua b/mods/terumet/material/meson.lua new file mode 100644 index 0000000..e32980f --- /dev/null +++ b/mods/terumet/material/meson.lua @@ -0,0 +1,41 @@ +local ingot_id = terumet.id('ingot_meson') +local meson_color = '#be61ff' + +minetest.register_craftitem( ingot_id, { + description = 'Fused Meson Ingot', + inventory_image = terumet.tex(ingot_id), + groups = {ingot = 1}, +}) + +local toolstat = {times={1.3, 1.1, 0.9}, uses=0, maxlevel=5} + +minetest.register_tool( terumet.id('tool_meson'), { + description = minetest.colorize(meson_color, 'Fused Meson Omni-tool'), + inventory_image = terumet.tex('tool_meson'), + wield_scale={x=1.8, y=1.8, z=1.4}, + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level = 99, + groupcaps = { + cracky = toolstat, + crumbly = toolstat, + choppy = toolstat, + snappy = toolstat, + }, + damage_groups = {fleshy=4}, + }, +}) + +--[[ +Meson Fusion Reactor + +Accepts items that yield repair material to create a critical mass. This mass is then superheated and Meson Fusion is attempted. + +The chance of successful fusion is based on: + - The quality of materials used (the fewer items used -> higher chance) + - The time taken to reach the necessary heat (less time -> higher chance) + +For 1 attempt at fusion the following is needed: + 60 x 50 = 3500 RMP (repair material points) -- This averages to approx. 50 between alloyed iron and gold. + 500000 HU -- assuming an average of 10000/second, averages to 50 seconds +]] \ No newline at end of file diff --git a/mods/terumet/material/misc.lua b/mods/terumet/material/misc.lua new file mode 100644 index 0000000..1d06cd1 --- /dev/null +++ b/mods/terumet/material/misc.lua @@ -0,0 +1,64 @@ + +local htg_id = terumet.id('item_htglass') +minetest.register_craftitem( htg_id, { + description = 'Heat-transference Glass', + inventory_image = terumet.tex(htg_id) +}) + +minetest.register_craft{ output = htg_id .. ' 3', + recipe = { + {'', 'default:obsidian_glass', ''}, + {terumet.id('item_cryst_tin'), terumet.id('item_glue'), terumet.id('item_cryst_tin')}, + {'', terumet.id('item_dust_ob'), ''} + } +} + +-- ============================================= + +local emit_id = terumet.id('item_heatunit') + +minetest.register_craftitem( emit_id, { + description = 'High Energy Alpha-wave Transmission Unit', + inventory_image = terumet.tex(emit_id) +}) + +minetest.register_craft{ output = emit_id, + recipe = { + {terumet.id('ingot_tgol'), 'default:obsidian_glass', terumet.id('ingot_tgol')}, + {terumet.id('item_thermese'), 'default:mese_crystal', terumet.id('item_thermese')}, + {terumet.id('item_ceramic'), terumet.id('item_coil_tgol'), terumet.id('item_ceramic')} + } +} + +-- ============================================= + +local press_id = terumet.id('item_press') +minetest.register_craftitem( press_id, { + description = 'Terutin Expansion Press', + inventory_image = terumet.tex(press_id) +}) + +minetest.register_craft{ output = press_id, + recipe = { + {'default:stone', terumet.id('block_ttin'), 'default:stone'}, + {terumet.id('ingot_tcha'), terumet.id('ingot_tcha'), terumet.id('ingot_tcha')}, + {terumet.id('ingot_ttin'), terumet.id('ingot_ttin'), terumet.id('ingot_ttin')} + } +} + +-- ============================================= + +local cryscham_id = terumet.id('item_cryscham') +minetest.register_craftitem( cryscham_id, { + description = 'Crystal Growth Chamber', + inventory_image = terumet.tex(cryscham_id) +}) + +minetest.register_craft{ output = cryscham_id, + recipe = { + {'default:obsidian_glass', 'default:obsidian_glass', 'default:obsidian_glass'}, + {terumet.id('item_dust_ob'), terumet.id('item_dust_ob'), terumet.id('item_dust_ob')}, + {terumet.id('ingot_tcha'), 'bucket:bucket_water', terumet.id('ingot_tcha')} + }, + replacements={{'bucket:bucket_water','bucket:bucket_empty'}} +} diff --git a/mods/terumet/material/pwood.lua b/mods/terumet/material/pwood.lua new file mode 100644 index 0000000..62a7005 --- /dev/null +++ b/mods/terumet/material/pwood.lua @@ -0,0 +1,34 @@ +local pwood_ytex = terumet.tex('block_pwood') +local pwood_xztex = terumet.tex('block_pwood_sides') +local pwood_tiles = {pwood_ytex, pwood_ytex, pwood_xztex} + +local pwood_id = terumet.id('block_pwood') + +minetest.register_node(pwood_id, { + description = "Pressed Wood", + tiles = pwood_tiles, + is_ground_content = false, + groups = {choppy = 2, oddly_breakable_by_hand = 2}, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_craft{ output = pwood_id..' 16', + recipe = terumet.recipe_box(terumet.id('item_dust_wood'), 'group:glue'), +} + +if minetest.get_modpath('stairs') then + stairs.register_stair_and_slab( + 'terumet_pwood', + pwood_id, + {choppy = 2, oddly_breakable_by_hand = 2}, + pwood_tiles, + 'Pressed Wood Stair', + 'Pressed Wood Slab', + default.node_sound_wood_defaults() + ) +end + +if minetest.get_modpath('walls') then + walls.register(terumet.id('walls_pwood'), 'Pressed Wood Wall', pwood_tiles, + pwood_id, default.node_sound_stone_defaults()) +end \ No newline at end of file diff --git a/mods/terumet/material/raw.lua b/mods/terumet/material/raw.lua new file mode 100644 index 0000000..9609a60 --- /dev/null +++ b/mods/terumet/material/raw.lua @@ -0,0 +1,16 @@ +local id = terumet.id +local tex = terumet.tex + +local function items(item, count) + return item .. ' ' .. count +end + +local ore_stone = id('ore_raw') +local ore_stone_dense = id('ore_dense_raw') + +local ore_desert_stone = id('ore_raw_desert') +local ore_desert_stone_dense = id('ore_raw_desert_dense') + +local lump = id('lump_raw') +local ingot = id('ingot_raw') +local block = id('block_raw') diff --git a/mods/terumet/material/rebar.lua b/mods/terumet/material/rebar.lua new file mode 100644 index 0000000..e55b2af --- /dev/null +++ b/mods/terumet/material/rebar.lua @@ -0,0 +1,82 @@ +local rebar_id = terumet.id('item_rebar') + +minetest.register_craftitem( rebar_id, { + description = 'Teruchalcum Rebar', + inventory_image = terumet.tex('item_rebar'), +}) + +minetest.register_craft{ output=rebar_id..' 5', recipe=terumet.recipe_plus('terumet:ingot_tcha') } + +local desc = {'Reinforced %s', 'Double-reinforced %s', 'Triple-reinforced %s'} +local blchance = {40, 20, 3} + +local function reinf_block_id(code, rlv) + return minetest.get_current_modname()..':reinf_block_'..code..rlv +end + +function terumet.register_reinforced_block(base, code) + local base_def = minetest.registered_nodes[base] + if not base_def then error('base '..base..' is not defined') end + + for rlv = 1,3 do + local def = {} + for k,v in pairs(base_def) do + if k == 'groups' then + def.groups = {} + for gk,gv in pairs(v) do + if not terumet.options.misc.BLOCK_REMOVE_GROUPS[gk] then + def.groups[gk]=gv + end + end + else + def[k] = v + end + end + if not base_def.groups then + def.groups = {level=(rlv+1)} + else + def.groups.level = (base_def.groups.level or 1) + rlv + end + local id = reinf_block_id(code, rlv) + + def.description = string.format(desc[rlv], base_def.description) + + local visibility = terumet.options.cosmetic.REINFORCING_VISIBLE + if visibility then + local tileov = terumet.tex('blockov_rebar'..rlv) + if visibility == 1 then + def.overlay_tiles = {tileov, tileov, '', '', '', ''} + else + def.overlay_tiles = {tileov} + end + end + + def.on_blast = terumet.blast_chance(blchance[rlv], id) + + minetest.register_node(id, def) + + local recbase + if rlv == 1 then + recbase = base + minetest.register_craft{ output=id..' 4', recipe = { + {rebar_id, recbase, rebar_id}, + {recbase, '', recbase}, + {rebar_id, recbase, rebar_id} + }} + elseif rlv == 2 then + recbase = reinf_block_id(code, 1) + minetest.register_craft{ output=id..' 4', recipe = { + {rebar_id, recbase, rebar_id}, + {recbase, '', recbase}, + {rebar_id, recbase, rebar_id} + }} + else + recbase = reinf_block_id(code, 2) + minetest.register_craft{ output=id..' 4', recipe = { + {rebar_id, recbase, rebar_id}, + {recbase, '', recbase}, + {rebar_id, recbase, rebar_id} + }} + end + end +end diff --git a/mods/terumet/material/reg_alloy.lua b/mods/terumet/material/reg_alloy.lua new file mode 100644 index 0000000..f788333 --- /dev/null +++ b/mods/terumet/material/reg_alloy.lua @@ -0,0 +1,35 @@ +local id = terumet.id +local tex = terumet.tex + +terumet.alloys = {} + +function terumet.reg_alloy(name, alloy_id, block_level, repairmat_value) + local ingot_id = 'ingot_' .. alloy_id + local block_id = 'block_' .. alloy_id + + minetest.register_craftitem( id(ingot_id), { + description = name .. ' Ingot', + inventory_image = tex(ingot_id), + groups = {ingot=1} + }) + + minetest.register_node( id(block_id), { + description = name .. ' Block', + tiles = {tex(block_id)}, + is_ground_content = false, + groups = {cracky=1, level=block_level}, + --sounds = default.node_sound_metal_defaults() + }) + + minetest.register_craft{ output = id(block_id), + recipe = terumet.recipe_3x3(id(ingot_id)) + } + + minetest.register_craft{ type = 'shapeless', output = id(ingot_id, 9), + recipe = {id(block_id)} + } + + terumet.alloys[alloy_id] = {ingot=id(ingot_id), block=id(block_id)} + + terumet.register_repair_material(id(ingot_id), repairmat_value) +end \ No newline at end of file diff --git a/mods/terumet/material/tglass.lua b/mods/terumet/material/tglass.lua new file mode 100644 index 0000000..00565c5 --- /dev/null +++ b/mods/terumet/material/tglass.lua @@ -0,0 +1,38 @@ +local tglass_id = terumet.id('block_tglass') + +local tiles, glowtiles + +if terumet.options.cosmetic.CLEAR_GLASS then + tiles = {terumet.tex('block_tglass_frame'), terumet.tex('blank')} + glowtiles = {terumet.tex('block_tglassglow_frame'), terumet.tex('blank')} +else + tiles = {terumet.tex('block_tglass_frame'), terumet.tex('block_tglass_streak')} + glowtiles = {terumet.tex('block_tglassglow_frame'), terumet.tex('block_tglassglow_streak')} +end + +minetest.register_node(tglass_id, { + description = 'Terumetal Glass', + drawtype= 'glasslike_framed_optional', + paramtype = "light", + tiles = tiles, + is_ground_content = false, + sunlight_propagates = true, + groups = {cracky = 1, level = 2}, + sounds = default.node_sound_glass_defaults(), + on_blast = terumet.blast_chance(30, tglass_id), +}) + +local tglass_glow_id = tglass_id..'glow' + +minetest.register_node(tglass_glow_id, { + description = 'Terumetal Glow Glass', + drawtype= 'glasslike_framed_optional', + paramtype = "light", + tiles = glowtiles, + is_ground_content = false, + sunlight_propagates = true, + light_source=13, + groups = {cracky = 1, level = 2}, + sounds = default.node_sound_glass_defaults(), + on_blast = terumet.blast_chance(15, tglass_glow_id), +}) \ No newline at end of file diff --git a/mods/terumet/material/vacfood.lua b/mods/terumet/material/vacfood.lua new file mode 100644 index 0000000..60fe828 --- /dev/null +++ b/mods/terumet/material/vacfood.lua @@ -0,0 +1,97 @@ +--[[ + Adds food to the vacuum oven recipes: + * Upgrades food items - vacuum two food items to create a condensed and packaged version that restores 3 times as much health/stamina. + * Food items are items that are of the group "food_*" and have an on_use (presumably minetest.item_eat) + * To ensure all food items are seen, any mods that add foods must be added as a dependent mod to Terumet - by default only "farming" is +]]-- +local options = terumet.options.vac_oven.VAC_FOOD +local FMT = string.format +local generated_vacfoods = {} + +local function make_vacfood_image(img) + return FMT('[combine:32x32:0,0=%s:8,8=%s', terumet.tex('item_vacfood'), img) +end + +local function make_vacfood(item_id) + local def = minetest.registered_items[item_id] + if generated_vacfoods[item_id] or (not def) then return end + local mod, item = item_id:match('^(%S+):(%S+)') + if mod and item then + local vf_id = terumet.id(FMT('vacf_%s_%s', mod, item)) + local image + if def.inventory_image and def.inventory_image ~= '' then + image = make_vacfood_image(def.inventory_image) + elseif def.tiles and def.tiles[1] and def.tiles[1] ~= '' then + image = make_vacfood_image(def.tiles[1]) + else + image = terumet.tex('item_vacfood') + end + + local item_sound + if def.sound then + item_sound = table.copy(def.sound) + else + item_sound = {} + end + item_sound.eat = 'terumet_eat_vacfood' + + minetest.register_craftitem(vf_id, { + description = 'Vacuum-packed ' .. def.description, + inventory_image = image, + sound=item_sound, + _terumet_vacfood = true, + on_use = def.on_use, + }) + + terumet.register_vacoven_recipe{ + input=item_id..' 2', + results={vf_id}, + time=4.0 + } + + generated_vacfoods[item_id]=vf_id + else + minetest.log('warning', FMT('terumet: valid item "%s" was selected for vacfood but mod or item-id did not parse properly', item_id)) + end +end + +if options.AUTO_GENERATE then + for id,def in pairs(minetest.registered_items) do + local blacklisted = false + if options.BLACKLIST then + blacklisted = options.BLACKLIST[id] + if not blacklisted then + blacklisted = terumet.match_group_key(options.BLACKLIST, def) + end + end + if not blacklisted then + local is_food = false + for group,_ in pairs(def.groups) do + if def.on_use and group:match('^food_') then + is_food = true + break + end + end + if is_food then make_vacfood(id) end + end + end +end + +if options.WHITELIST then + for id,_ in pairs(options.WHITELIST) do + make_vacfood(id) + end +end +-- add a wrapper to core function of do_item_eat which triples hp_change value of items with _terumet_vacfood flag +-- there's no way to read what value individual food items are calling minetest.item_eat() with, so this is the next best way to multiply the value + +local old_item_eat = core.do_item_eat + +core.do_item_eat = function(hp_change, replace_with_item, itemstack, ...) + local def = itemstack:get_definition() + if def and def._terumet_vacfood then + return old_item_eat(hp_change * 3, replace_with_item, itemstack, ...) + else + return old_item_eat(hp_change, replace_with_item, itemstack, ...) + end +end diff --git a/mods/terumet/mod.conf b/mods/terumet/mod.conf new file mode 100644 index 0000000..a267a91 --- /dev/null +++ b/mods/terumet/mod.conf @@ -0,0 +1,4 @@ +name=terumet +description=Terumetal v3.0 - Make life easier with alloys and heat machinery! +depends=walls, stairs, doors, dye +optional_depends=unified_inventory,tubelib,stairs,doors,tnt,mesecons,dungeon_loot,bushes,dryplants,vines,mobs_animal,main,extra diff --git a/mods/terumet/options.lua b/mods/terumet/options.lua new file mode 100644 index 0000000..7778077 --- /dev/null +++ b/mods/terumet/options.lua @@ -0,0 +1,512 @@ +terumet.options = {} + +terumet.options.protection = { + -- List of potential external mods that will handle machine protection in lieu of the default owner system + -- If any of these mods are found on load, the default protection system will NOT be active + -- and all machine protection will be based on mintest.is_protected implemented by external mods + -- (1 has no specific meaning, only to provide a value) + EXTERNAL_MODS = { + ['areas']=1 + } +} + +terumet.options.cosmetic = { + -- Set to false/nil for Terumetal Glass to be streaky similar to default Minetest glass + CLEAR_GLASS = true, + -- Style of reinforced blocks: + -- 1 = rebar on top/bottom only + -- 2 = rebar on all faces + -- false/nil = not visible (reinforced blocks look exact same as original block) + REINFORCING_VISIBLE = 1, + -- Set to false/nil for heatline blocks to not have visible ports + BLOCK_HEATLINE_VISIBLE = true, +} + +terumet.options.misc = { + -- Groups to remove from converted blocks (heatline/reinforced blocks) + -- ex: 'wood' prevents wood planks with heatlines/reinforcing from being used as wood in general recipes + -- if any other groups cause problems when transferred over to a block, add it here + -- (1 has no specific meaning, only to provide a value) + BLOCK_REMOVE_GROUPS = { + ['wood']=1, + ['stone']=1, + ['flammable']=1, + }, + + -- text color for additional info on items + TIP_COLOR = '#ffa2ba', +} + +terumet.options.tools = { + -- + -- TOOL SETTINGS + -- + sword_damage = { + -- damage inflicted by each type of sword + TERUMETAL = 6, + COPPER_ALLOY = 8, + IRON_ALLOY = 9, + GOLD_ALLOY = 7, + BRONZE_ALLOY = 10, + COREGLASS = 12 + }, + + -- Comment out/remove this section to disable all upgraded tools + UPGRADES = { + -- comment out/remove a single line to disable that upgrade + rng = {color='#ffda00', nametag='Kinetic', xinfo='Longer reach', item='terumet:item_cryst_mese 3', time=20.0, flux=8, repmult=1.5, effect=8}, -- effect=new range + spd = {color='#4aeffd', nametag='Expert', xinfo='Faster speed', item='terumet:item_cryst_dia 3', time=20.0, flux=8, repmult=2, effect=0.8}, -- effect=multiplier to tool speeds + dur = {color='#68905a', nametag='Durable', xinfo='Degrades slower', item='terumet:item_rubber 3', time=20.0, flux=8, repmult=1.5, effect=1.6}, -- effect=multiplier to tool uses + } +} + +terumet.options.machine = { + -- + -- GENERAL MACHINE SETTINGS + -- + -- Heat sources that can be used in fuel slots of machines + BASIC_HEAT_SOURCES = { + ['bucket:bucket_lava']={ hus=20000, return_item='bucket:bucket_empty' }, + }, + -- Whether machines emit smoke particles or not while working + PARTICLES = true, + -- Text descriptions of heat transfer modes of machines + HEAT_TRANSFER_MODE_NAMES = { + [0]='Disabled', + [1]='Accept', + [2]='Provide', + }, + -- Sounds played by machines, (nil to disable) + OVERHEAT_SOUND = 'terumet_venting', -- when overheating and discharging + HEATIN_SOUND = 'terumet_heatin', -- when accepting heat from an item/battery + HEATOUT_SOUND = 'terumet_heatout', -- when depositing heat in a battery + + DEFAULT_INPUT_SIDE = 3, + DEFAULT_OUTPUT_SIDE = 4, + + -- tooltip colors for machine items + TIP_HU_COLOR = '#ff9d15', + TIP_PERCENT_COLOR = '#ffdcac', +} + +terumet.options.heater = { + furnace={ + -- + -- FURNACE HEATER SETTINGS + -- + -- Maximum HUs Furnace Heater can store + MAX_HEAT = 10000, + -- Maximum HUs Furnace Heater can transfer per tick + HEAT_TRANSFER_RATE = 500, + -- HU generation per second of burn time + GEN_HUPS = 100 + }, + solar={ + -- + -- SOLAR HEATER SETTINGS + -- + -- Maximum HUs Solar Heater can store + MAX_HEAT = 40000, + -- HUs Solar Heater generates per second based on sunlight level + SOLAR_HUPS = { 0, 0, 0, 0, 0, 10, 10, 15, 20, 25, 30, 35, 40, 45, 50, 60 }, + -- Maximum HUs Solar Heater can transfer per tick + HEAT_TRANSFER_RATE = 1000, + }, + entropy={ + -- + -- ENTROPIC HEATER SETTINGS + -- + MAX_HEAT = 200000, + HEAT_TRANSFER_RATE = 5000, + -- the maximum extent the heater "scans" from the main machine + MAX_RANGE = {x=5, y=5, z=5}, + -- if a node time is not defined, use this time + DEFAULT_DRAIN_TIME = 1.0, + EFFECTS = { + ['default:water_source']={change='default:ice', time=5.0, hups=1000}, + ['default:water_flowing']={change='default:ice', time=2.5, hups=1200}, + ['default:lava_source']={change='default:obsidian', time=2.0, hups=10000}, + ['default:lava_flowing']={change='default:obsidian', time=1.0, hups=5000}, + ['default:dirt_with_grass']={change='default:dirt', hups=1000}, + ['default:sandstone']={change='default:sand', hups=3000}, + ['default:silver_sandstone']={change='default:silver_sand', hups=3000}, + ['default:stone']={change='default:cobble', time=3.0, hups=1000}, + ['default:cobble']={change='default:gravel', time=3.0, hups=800}, + ['default:gravel']={change='default:silver_sand', time=3.0, hups=500}, + ['default:coalblock']={change='default:stone_with_coal', time=60.0, hups=1500}, + ['default:stone_with_coal']={change='default:stone', time=10.0, hups=1500}, + ['default:mossycobble']={change='default:cobble', time=15.0, hups=500}, + ['default:clay']={change='default:dirt', time=5.0, hups=500}, + ['default:cactus']={change='air', time=10.0, hups=2000}, + ['default:papyrus']={change='air', time=20.0, hups=2000}, + ['group:flora']={change='default:dry_shrub', time=6.0, hups=150}, + ['default:dry_shrub']={change='air', time=3.0, hups=1500}, + ['fire:basic_flame']={change='air', time=0.5, hups=10000}, + ['fire:permanent_flame']={change='air', time=0.5, hups=10000}, + ['air']={time=1.0, hups=500}, + ['group:tree']={change='air', time=12.0, hups=3000}, + ['group:sapling']={change='air', time=4.0, hups=4000}, + ['group:wood']={change='air', time=9.0, hups=1000}, + ['group:leaves']={change='air', time=4.0, hups=2000}, + } + } +} + +terumet.options.crusher = { + -- + -- CRUSHER SETTINGS + -- + + MAX_HEAT = 5000, + + HEAT_HUPS = 150, + TIME_HEATING = 4.0, -- in sec. + TIME_COOLING = 6.0, -- in sec. + + recipes = { + ['default:stone']='default:cobble', + ['default:cobble']='default:gravel', + ['default:gravel']='default:silver_sand', + ['default:obsidian']='default:obsidian_shard 9', + ['default:obsidian_shard']='terumet:item_dust_ob', + ['default:sandstone']='default:sand', + ['default:silver_sandstone']='default:silver_sand', + ['default:coalblock']='default:coal_lump 9', + ['default:apple']='terumet:item_dust_bio 2', + ['default:papyrus']='terumet:item_dust_bio 3', + ['group:flora']='terumet:item_dust_bio', + ['group:leaves']='terumet:item_dust_bio', + ['group:sapling']='terumet:item_dust_bio', + ['group:tree']='terumet:item_dust_wood 4', + ['group:wood']='terumet:item_dust_wood 1', + } +} + +terumet.options.thermobox = { + -- + -- THERMOBOX SETTINGS + -- + MAX_HEAT = 200000, + HEAT_TRANSFER_RATE = 2500 +} + +terumet.options.thermdist = { + -- + -- THERMAL DISTRIBUTOR SETTINGS + MAX_HEAT = 20000, + HEAT_TRANSFER_RATE = 2500 +} + +terumet.options.heatline = { + -- + -- HEATLINE SETTINGS + -- + -- Maximum HUs heatline input can contain + MAX_HEAT = 50000, + -- Maximum distance over a heatline input can send (in blocks of heatline) + -- when a heatline extends beyond this, it will occasionally display smoke particles to warn + MAX_DIST = 36, + -- Every RECHECK_LINKS_TIMER seconds, recheck the heatline network on an input + RECHECK_LINKS_TIMER = 4.0, + -- Max heat transferred every tick (divided among all connected machines in order of distance) + HEAT_TRANSFER_MAX = 2500, + -- whether /heatlines chat command is available to list all heatline network info + DEBUG_CHAT_COMMAND = false, +} + +terumet.options.heat_ray = { + -- + -- HEAT RAY EMITTER SETTINGS + -- + -- Maximum HUs emitter can contain + MAX_HEAT = 20000, + -- HUs sent in one ray + SEND_AMOUNT = 10000, + -- maximum number of nodes emitter will seek before giving up + MAX_DISTANCE = 1000, + -- set to zero to disable particle display of ray + RAY_PARTICLES_PER_NODE = 6 +} + +terumet.options.smelter = { + -- + -- TERUMETAL ALLOY SMELTER SETTINGS + -- + -- Maximum HUs smelter can contain + MAX_HEAT = 20000, + -- Amount of flux value (FV) one item is worth + FLUX_VALUE = 2, + -- Maximum stored FV of an alloy smelter's flux tank + -- NOTE: if FLUX_MAXIMUM / FLUX_VALUE > 99, flux could be lost on breaking a smelter + -- (only a maximum of 1 stack of Crystallized Terumetal will be dropped) + -- also if stored flux < FLUX_VALUE, that amount will be lost (minimum 1 Crystallized Terumetal dropped) + FLUX_MAXIMUM = 100, + -- Heat expended per second melting flux + MELT_HUPS = 20, + -- Heat expended per second alloying + ALLOY_HUPS = 10, + -- Default items usable as flux + FLUX_ITEMS = { + ['terumet:lump_raw']={time=3.0}, + ['terumet:ingot_raw']={time=2.0}, + ['terumet:item_cryst_raw']={time=1.0}, + }, + -- Default alloy-making recipes + recipes = { + -- Standard Bronze + -- Note these are first in the recipe list to override single terucopper/terutin if all elements for bronze are available + {result='default:bronze_ingot 9', flux=0, time=8.0, input={'default:copper_lump 8', 'default:tin_lump'}}, + {result='default:bronze_ingot 9', flux=0, time=6.0, input={'default:copper_ingot 8', 'default:tin_ingot'}}, + {result='default:bronzeblock 9', flux=0, time=40.5, input={'default:copperblock 8', 'default:tinblock'}}, + {result='default:bronze_ingot 9', flux=0, time=2.0, input={'terumet:item_cryst_copper 8', 'terumet:item_cryst_tin'}}, + -- Terumetal Glass + {result='terumet:block_tglass 4', flux=1, time=8.0, input={'default:glass 4', 'default:silver_sand'}}, + -- Terumetal Glow Glass + {result='terumet:block_tglassglow 4', flux=1, time=8.0, input={'terumet:block_tglass 4', 'default:mese_crystal'}}, + -- Teruchalchum + {result='terumet:ingot_tcha 3', flux=9, time=6.0, input={'default:bronze_ingot', 'default:tin_lump 2'}}, + {result='terumet:ingot_tcha 3', flux=9, time=4.0, input={'default:bronze_ingot', 'default:tin_ingot 2'}}, + {result='terumet:block_tcha 3', flux=75, time=54.0, input={'default:bronzeblock', 'default:tinblock 2'}}, + {result='terumet:ingot_tcha 3', flux=9, time=3.0, input={'default:bronze_ingot', 'terumet:item_cryst_tin 2'}}, + -- Terucopper + {result='terumet:ingot_tcop', flux=1, time=3.0, input={'default:copper_lump'}}, + {result='terumet:ingot_tcop', flux=1, time=2.5, input={'default:copper_ingot'}}, + {result='terumet:block_tcop', flux=8, time=22.5, input={'default:copperblock'}}, + {result='terumet:ingot_tcop', flux=1, time=1.0, input={'terumet:item_cryst_copper'}}, + -- Terutin + {result='terumet:ingot_ttin', flux=1, time=2.0, input={'default:tin_lump'}}, + {result='terumet:ingot_ttin', flux=1, time=1.5, input={'default:tin_ingot'}}, + {result='terumet:block_ttin', flux=8, time=15.0, input={'default:tinblock'}}, + {result='terumet:ingot_ttin', flux=1, time=0.5, input={'terumet:item_cryst_tin'}}, + -- Terusteel + {result='terumet:ingot_tste', flux=2, time=4.5, input={'default:iron_lump'}}, + {result='terumet:ingot_tste', flux=2, time=3.5, input={'default:steel_ingot'}}, + {result='terumet:block_tste', flux=16, time=31.5, input={'default:steelblock'}}, + {result='terumet:ingot_tste', flux=2, time=2.0, input={'terumet:item_cryst_iron'}}, + -- Terugold + {result='terumet:ingot_tgol', flux=3, time=5.0, input={'default:gold_lump'}}, + {result='terumet:ingot_tgol', flux=3, time=4.0, input={'default:gold_ingot'}}, + {result='terumet:block_tgol', flux=25, time=36.0, input={'default:goldblock'}}, + {result='terumet:ingot_tgol', flux=3, time=2.5, input={'terumet:item_cryst_gold'}}, + -- Coreglass + {result='terumet:ingot_cgls', flux=5, time=10.0, input={'default:diamond', 'default:obsidian_shard'}}, + {result='terumet:block_cgls', flux=30, time=90.0, input={'default:diamondblock', 'default:obsidian'}}, + {result='terumet:ingot_cgls', flux=5, time=5.0, input={'terumet:item_cryst_dia', 'terumet:item_cryst_ob'}}, + -- Teruceramic + {result='terumet:item_ceramic', flux=2, time=3.0, input={'default:clay_lump'}}, + -- Thermese + {result='terumet:item_thermese', flux=4, time=8.0, input={'default:mese_crystal'}}, + }, +} + +terumet.options.furnace = { + -- + -- HIGH-TEMP FURNACE SETTINGS + -- + -- Maximum HUs ht-furnace can contain + MAX_HEAT = 30000, + -- Heat cost per second + COOK_HUPS = 100, + -- Multiplier applied to normal cooking time + -- NOTE: This multiplier is ignored for battery heating + TIME_MULT = 0.5, +} + +terumet.options.vac_oven = { + -- + -- VACUUM OVEN SETTINGS + -- + -- Maximum HUs machine can contain + MAX_HEAT = 100000, + -- HU cost per tick of cooking + COOK_HUPS = 500, + + recipes = { + {results={'terumet:item_tarball 4', 'terumet:item_coke'}, time=10.0, input='default:coal_lump'}, + {results={'terumet:item_tarball 40', 'terumet:block_coke'}, time=80.0, input='default:coalblock'}, + }, + + VAC_FOOD = { + ACTIVE = true, -- make false to disable vacuum-packed food entirely + -- if AUTO_GENERATE is true, the mod scans all items defined as of this mod's initialization + -- if an item has an on_use and has the group food_*, it is assumed to be a food and adds a vacuum-packed version + -- to ensure a mod's items are scanned, it should be added to terumet's list of dependent mods in mod.conf/depends.txt + AUTO_GENERATE = true, + -- items that are flagged as food by AUTO_GENERATE you do not want to be made into a vacfood can be added through this list + -- if AUTO_GENERATE is false, this list has no effect + -- (1 is meaningless and just to provide a value) + BLACKLIST = { + ['mobs:glass_milk']=1, + ['mobs:bucket_milk']=1, + ['main:honey_bottle']=1, + ['mobs:egg']=1, + ['group:food_butter']=1, -- you can use groups too + }, + -- items that aren't automatically recognized as food can be added through this list + -- even if AUTO_GENERATE is false, these items will be made into a vacfood + -- (1 is meaningless and just to provide a value) + WHITELIST = { + ['moretrees:acorn_muffin']=1, + } + -- see interop/farming.lua for foods from "farming" mod + -- see interop/extra.lua for foods from "extra" mod + }, + + MAX_RESULTS = 2, -- Maximum number of result items from recipes (adjust this if any larger recipes are added) +} + +terumet.options.vulcan = { + -- + -- CRYSTAL VULCANIZER SETTINGS + -- + -- populated through registration, see interop/terumet_api.lua + recipes = {}, -- DO NOT CHANGE + -- Maximum HUs vulcanizer can contain + MAX_HEAT = 60000, + -- Heat cost per second of vulcanizing + VULCANIZE_HUPS = 200, + -- Time to process one item (in seconds) + PROCESS_TIME = 6.0, + -- when true, crystalizing obsidian always produces exactly one crystal. + -- this prevents easy infinite obsidian loops. + LIMIT_OBSIDIAN = true, +} + +terumet.options.lavam = { + -- + -- LAVA MELTER SETTINGS + -- + -- Maximum HUs melter can contain + MAX_HEAT = 30000, + -- Nodes that can be melted to lava + -- related number is total required heat to melt + VALID_STONES = { + ['default:stone']=15000, + ['default:cobble']=20000, + ['default:desert_stone']=14000, + ['default:desert_cobble']=18000 + }, + -- total time for 1 item required in seconds (best if required heat/MELT_TIME is a whole number) + MELT_TIME = 200 +} + +terumet.options.meseg = { + -- + -- MESE GARDEN SETTINGS + -- + -- Maximum HUs garden can contain + MAX_HEAT = 50000, + -- HUs required to begin growing + START_HEAT = 10000, + -- HUs required per second when growing + HEAT_HUPS = 350, + -- Multiplier applied to efficiency every second not heated or seeded + EFFIC_LOSS_RATE = 0.75, + -- Maximum efficiency "points" (at this level, progress is 100% of possible rate) + -- Efficiency points increase by number of seed crystals each second until max + MAX_EFFIC = 2000, + -- Progress "points" needed to grow a new shard + -- points gained each second = number of seed crystals x efficiency + PROGRESS_NEED = 300, + -- item id of seed crystal + SEED_ITEM = 'default:mese_crystal', + -- item id of produced item + PRODUCE_ITEM = 'default:mese_crystal_fragment', + -- Chance to lose a seed crystal each growth is 1/(SEED_LOSS_CHANCE-seed crystal count) + -- so SEED_LOSS_CHANCE = 101 means: + -- 1 seed crystal = 1/100 chance (very low) + -- 99 seed crystals = 1/2 chance (coin flip) + -- You can set to false or nil to disable losing seeds, even if it's overpowered. + SEED_LOSS_CHANCE = 101, + -- sound to play at Garden node when a seed is lost (nil for none) + SEED_LOSS_SOUND = 'terumet_break', + -- true if particle effects occur when a seed is lost (default machine PARTICLES option false will also disable) + SEED_LOSS_PARTICLES = true +} + +terumet.options.repm = { + -- + -- EQUIPMENT REFORMER SETTINGS + -- + MAX_HEAT = 50000, + + -- HUs/sec to melt repair material and repair material units processed per tick + MELT_HUPS = 100, + MELTING_RATE = 10, + -- HUs/sec to repair one item and repair material units applied to repairing per tick + REPAIR_HUPS = 30, + REPAIR_RATE = 10, + -- maximum units of repair material that can be stored + RMAT_MAXIMUM = 1000, + + -- items that can be turned into "repair-material" and how much + -- populated through registration, see interop/terumet_api.lua + repair_mats = {}, -- DO NOT CHANGE + + -- all items that can be repaired and how much "repair-material" is required to remove a full wear bar + -- (TODO) mods can add addtional ones through the API terumet.register_repairable_item -- see interop/terumet_api.lua + repairable = {}, -- DO NOT CHANGE +} + +terumet.options.ore_saw = { + -- + -- ORE SAW SETTINGS + -- + -- Nodes that can be gathered directly via saw (1 is meaningless and just to provide a value) + VALID_ORES = { + ['default:stone_with_diamond']=1, + ['default:stone_with_mese']=1, + ['default:stone_with_copper']=1, + ['default:stone_with_tin']=1, + ['default:stone_with_iron']=1, + ['default:stone_with_gold']=1, + ['default:stone_with_coal']=1, + ['terumet:ore_raw']=1, + ['terumet:ore_raw_desert']=1, + ['asteroid:copperore']=1, + ['asteroid:diamondore']=1, + ['asteroid:goldore']=1, + ['asteroid:ironore']=1, + ['asteroid:meseore']=1, + ['moreores:mineral_mithril']=1, + ['moreores:mineral_silver']=1, + ['titanium:titanium_in_ground']=1, + ['quartz:quartz_ore']=1, + ['nether:titanium_ore']=1, + }, + -- Number of times basic ore saw can be used before breaking + BASIC_USES = 40, + -- Number of times advanced ore saw can be used before breaking + ADVANCED_USES = 200, +} + +-- NOTE: Armor and bracers will only be available if the mod "3d_armor" by stujones11 (https://github.com/stujones11/minetest-3d_armor) is active +terumet.options.armor = { + -- delete or comment out entire BRACERS = {...} block to disable all bracers + BRACERS = { -- delete single line or comment out (add -- to start) to disable that type of bracer + -- water-breathing bracer + aqua={name='Aqua', color='#0010ff', mat='default:papyrus', xinfo='Underwater breathing', + def=5, uses=65535/150, rep=100, breathing=1}, + -- high jump bracer + jump={name='Jump', color='#ffac00', mat='terumet:item_cryst_mese', xinfo='Increase jump height', + def=5, uses=65535/200, rep=150, jump=0.5}, + -- movement speed bracer + spd={ name='Speed', color='#4eff00', mat='terumet:item_cryst_dia', xinfo='Increase move speed', + def=5, uses=65535/150, rep=400, speed=0.8}, + -- anti-gravity bracer + agv={ name='Antigravity', color='#7600ff', mat='terumet:item_entropy', xinfo='Reduce gravity', + def=5, uses=65535/100, rep=400, speed=-0.1, gravity=-0.5, jump=-0.1}, + -- high heal bracer + heal={name='Heal', color='#ff0086', mat='terumet:block_dust_bio', xinfo='Heal +10', + heal=10, uses=65535/200, rep=600}, + -- high defense bracer + def={ name='Defense', color='#727272', mat='terumet:item_rsuitmat', xinfo='Defense +30', + def=30, uses=65535/150, rep=300}, + -- fire protection bracer + -- 3darmor must have the option "Enable fire protection" on in order for this bracer to function or be loaded + fire={name='Fireproof', color='#ff5d00', mat='terumet:item_cryst_ob', xinfo='Immunity to fire/lava', + uses=65535/100, rep=300, fire=99}, + }, + -- Item used to create bracer crystals + BRACER_CRYSTAL_ITEM = 'default:steelblock', +} diff --git a/mods/terumet/screenshot.png b/mods/terumet/screenshot.png new file mode 100644 index 0000000..f578a3e Binary files /dev/null and b/mods/terumet/screenshot.png differ diff --git a/mods/terumet/sounds/terumet_break.0.ogg b/mods/terumet/sounds/terumet_break.0.ogg new file mode 100644 index 0000000..694a6d0 Binary files /dev/null and b/mods/terumet/sounds/terumet_break.0.ogg differ diff --git a/mods/terumet/sounds/terumet_break.1.ogg b/mods/terumet/sounds/terumet_break.1.ogg new file mode 100644 index 0000000..a6b60f1 Binary files /dev/null and b/mods/terumet/sounds/terumet_break.1.ogg differ diff --git a/mods/terumet/sounds/terumet_break.2.ogg b/mods/terumet/sounds/terumet_break.2.ogg new file mode 100644 index 0000000..833f09c Binary files /dev/null and b/mods/terumet/sounds/terumet_break.2.ogg differ diff --git a/mods/terumet/sounds/terumet_break.3.ogg b/mods/terumet/sounds/terumet_break.3.ogg new file mode 100644 index 0000000..4aae08d Binary files /dev/null and b/mods/terumet/sounds/terumet_break.3.ogg differ diff --git a/mods/terumet/sounds/terumet_eat_vacfood.ogg b/mods/terumet/sounds/terumet_eat_vacfood.ogg new file mode 100644 index 0000000..1db8cca Binary files /dev/null and b/mods/terumet/sounds/terumet_eat_vacfood.ogg differ diff --git a/mods/terumet/sounds/terumet_heatin.ogg b/mods/terumet/sounds/terumet_heatin.ogg new file mode 100644 index 0000000..4c97927 Binary files /dev/null and b/mods/terumet/sounds/terumet_heatin.ogg differ diff --git a/mods/terumet/sounds/terumet_heatout.ogg b/mods/terumet/sounds/terumet_heatout.ogg new file mode 100644 index 0000000..97be382 Binary files /dev/null and b/mods/terumet/sounds/terumet_heatout.ogg differ diff --git a/mods/terumet/sounds/terumet_saw.ogg b/mods/terumet/sounds/terumet_saw.ogg new file mode 100644 index 0000000..518d541 Binary files /dev/null and b/mods/terumet/sounds/terumet_saw.ogg differ diff --git a/mods/terumet/sounds/terumet_saw_fail.ogg b/mods/terumet/sounds/terumet_saw_fail.ogg new file mode 100644 index 0000000..60e393b Binary files /dev/null and b/mods/terumet/sounds/terumet_saw_fail.ogg differ diff --git a/mods/terumet/sounds/terumet_squish_dig.0.ogg b/mods/terumet/sounds/terumet_squish_dig.0.ogg new file mode 100644 index 0000000..b712302 Binary files /dev/null and b/mods/terumet/sounds/terumet_squish_dig.0.ogg differ diff --git a/mods/terumet/sounds/terumet_squish_dig.1.ogg b/mods/terumet/sounds/terumet_squish_dig.1.ogg new file mode 100644 index 0000000..5a822bd Binary files /dev/null and b/mods/terumet/sounds/terumet_squish_dig.1.ogg differ diff --git a/mods/terumet/sounds/terumet_squish_dig.2.ogg b/mods/terumet/sounds/terumet_squish_dig.2.ogg new file mode 100644 index 0000000..395b769 Binary files /dev/null and b/mods/terumet/sounds/terumet_squish_dig.2.ogg differ diff --git a/mods/terumet/sounds/terumet_squish_dug.ogg b/mods/terumet/sounds/terumet_squish_dug.ogg new file mode 100644 index 0000000..2504b17 Binary files /dev/null and b/mods/terumet/sounds/terumet_squish_dug.ogg differ diff --git a/mods/terumet/sounds/terumet_squish_place.0.ogg b/mods/terumet/sounds/terumet_squish_place.0.ogg new file mode 100644 index 0000000..f040deb Binary files /dev/null and b/mods/terumet/sounds/terumet_squish_place.0.ogg differ diff --git a/mods/terumet/sounds/terumet_squish_place.1.ogg b/mods/terumet/sounds/terumet_squish_place.1.ogg new file mode 100644 index 0000000..0624cdf Binary files /dev/null and b/mods/terumet/sounds/terumet_squish_place.1.ogg differ diff --git a/mods/terumet/sounds/terumet_squish_step.0.ogg b/mods/terumet/sounds/terumet_squish_step.0.ogg new file mode 100644 index 0000000..7757302 Binary files /dev/null and b/mods/terumet/sounds/terumet_squish_step.0.ogg differ diff --git a/mods/terumet/sounds/terumet_squish_step.1.ogg b/mods/terumet/sounds/terumet_squish_step.1.ogg new file mode 100644 index 0000000..791ad12 Binary files /dev/null and b/mods/terumet/sounds/terumet_squish_step.1.ogg differ diff --git a/mods/terumet/sounds/terumet_squish_step.2.ogg b/mods/terumet/sounds/terumet_squish_step.2.ogg new file mode 100644 index 0000000..ea0025d Binary files /dev/null and b/mods/terumet/sounds/terumet_squish_step.2.ogg differ diff --git a/mods/terumet/sounds/terumet_venting.ogg b/mods/terumet/sounds/terumet_venting.ogg new file mode 100644 index 0000000..618ecf1 Binary files /dev/null and b/mods/terumet/sounds/terumet_venting.ogg differ diff --git a/mods/terumet/textures/terumet_armboots_cgls.png b/mods/terumet/textures/terumet_armboots_cgls.png new file mode 100644 index 0000000..2f7b64a Binary files /dev/null and b/mods/terumet/textures/terumet_armboots_cgls.png differ diff --git a/mods/terumet/textures/terumet_armboots_rsuit.png b/mods/terumet/textures/terumet_armboots_rsuit.png new file mode 100644 index 0000000..7d5039c Binary files /dev/null and b/mods/terumet/textures/terumet_armboots_rsuit.png differ diff --git a/mods/terumet/textures/terumet_armboots_tcha.png b/mods/terumet/textures/terumet_armboots_tcha.png new file mode 100644 index 0000000..d69930a Binary files /dev/null and b/mods/terumet/textures/terumet_armboots_tcha.png differ diff --git a/mods/terumet/textures/terumet_armboots_tcop.png b/mods/terumet/textures/terumet_armboots_tcop.png new file mode 100644 index 0000000..5b7ed9b Binary files /dev/null and b/mods/terumet/textures/terumet_armboots_tcop.png differ diff --git a/mods/terumet/textures/terumet_armboots_tgol.png b/mods/terumet/textures/terumet_armboots_tgol.png new file mode 100644 index 0000000..4f44e72 Binary files /dev/null and b/mods/terumet/textures/terumet_armboots_tgol.png differ diff --git a/mods/terumet/textures/terumet_armboots_tste.png b/mods/terumet/textures/terumet_armboots_tste.png new file mode 100644 index 0000000..628df02 Binary files /dev/null and b/mods/terumet/textures/terumet_armboots_tste.png differ diff --git a/mods/terumet/textures/terumet_armboots_ttin.png b/mods/terumet/textures/terumet_armboots_ttin.png new file mode 100644 index 0000000..6a5710a Binary files /dev/null and b/mods/terumet/textures/terumet_armboots_ttin.png differ diff --git a/mods/terumet/textures/terumet_armbrcr_agv.png b/mods/terumet/textures/terumet_armbrcr_agv.png new file mode 100644 index 0000000..ef61199 Binary files /dev/null and b/mods/terumet/textures/terumet_armbrcr_agv.png differ diff --git a/mods/terumet/textures/terumet_armbrcr_aqua.png b/mods/terumet/textures/terumet_armbrcr_aqua.png new file mode 100644 index 0000000..4e92b0b Binary files /dev/null and b/mods/terumet/textures/terumet_armbrcr_aqua.png differ diff --git a/mods/terumet/textures/terumet_armbrcr_base.png b/mods/terumet/textures/terumet_armbrcr_base.png new file mode 100644 index 0000000..5c4b793 Binary files /dev/null and b/mods/terumet/textures/terumet_armbrcr_base.png differ diff --git a/mods/terumet/textures/terumet_armbrcr_def.png b/mods/terumet/textures/terumet_armbrcr_def.png new file mode 100644 index 0000000..c6d606d Binary files /dev/null and b/mods/terumet/textures/terumet_armbrcr_def.png differ diff --git a/mods/terumet/textures/terumet_armbrcr_fire.png b/mods/terumet/textures/terumet_armbrcr_fire.png new file mode 100644 index 0000000..05529ff Binary files /dev/null and b/mods/terumet/textures/terumet_armbrcr_fire.png differ diff --git a/mods/terumet/textures/terumet_armbrcr_heal.png b/mods/terumet/textures/terumet_armbrcr_heal.png new file mode 100644 index 0000000..e91dd89 Binary files /dev/null and b/mods/terumet/textures/terumet_armbrcr_heal.png differ diff --git a/mods/terumet/textures/terumet_armbrcr_jump.png b/mods/terumet/textures/terumet_armbrcr_jump.png new file mode 100644 index 0000000..06d86ce Binary files /dev/null and b/mods/terumet/textures/terumet_armbrcr_jump.png differ diff --git a/mods/terumet/textures/terumet_armbrcr_spd.png b/mods/terumet/textures/terumet_armbrcr_spd.png new file mode 100644 index 0000000..cda8ffc Binary files /dev/null and b/mods/terumet/textures/terumet_armbrcr_spd.png differ diff --git a/mods/terumet/textures/terumet_armchest_cgls.png b/mods/terumet/textures/terumet_armchest_cgls.png new file mode 100644 index 0000000..413302a Binary files /dev/null and b/mods/terumet/textures/terumet_armchest_cgls.png differ diff --git a/mods/terumet/textures/terumet_armchest_rsuit.png b/mods/terumet/textures/terumet_armchest_rsuit.png new file mode 100644 index 0000000..f7b8823 Binary files /dev/null and b/mods/terumet/textures/terumet_armchest_rsuit.png differ diff --git a/mods/terumet/textures/terumet_armchest_tcha.png b/mods/terumet/textures/terumet_armchest_tcha.png new file mode 100644 index 0000000..7461612 Binary files /dev/null and b/mods/terumet/textures/terumet_armchest_tcha.png differ diff --git a/mods/terumet/textures/terumet_armchest_tcop.png b/mods/terumet/textures/terumet_armchest_tcop.png new file mode 100644 index 0000000..8c391c3 Binary files /dev/null and b/mods/terumet/textures/terumet_armchest_tcop.png differ diff --git a/mods/terumet/textures/terumet_armchest_tgol.png b/mods/terumet/textures/terumet_armchest_tgol.png new file mode 100644 index 0000000..31e5484 Binary files /dev/null and b/mods/terumet/textures/terumet_armchest_tgol.png differ diff --git a/mods/terumet/textures/terumet_armchest_tste.png b/mods/terumet/textures/terumet_armchest_tste.png new file mode 100644 index 0000000..91c1e85 Binary files /dev/null and b/mods/terumet/textures/terumet_armchest_tste.png differ diff --git a/mods/terumet/textures/terumet_armchest_ttin.png b/mods/terumet/textures/terumet_armchest_ttin.png new file mode 100644 index 0000000..e7489bc Binary files /dev/null and b/mods/terumet/textures/terumet_armchest_ttin.png differ diff --git a/mods/terumet/textures/terumet_armhelm_cgls.png b/mods/terumet/textures/terumet_armhelm_cgls.png new file mode 100644 index 0000000..a5a06be Binary files /dev/null and b/mods/terumet/textures/terumet_armhelm_cgls.png differ diff --git a/mods/terumet/textures/terumet_armhelm_rsuit.png b/mods/terumet/textures/terumet_armhelm_rsuit.png new file mode 100644 index 0000000..d37137b Binary files /dev/null and b/mods/terumet/textures/terumet_armhelm_rsuit.png differ diff --git a/mods/terumet/textures/terumet_armhelm_tcha.png b/mods/terumet/textures/terumet_armhelm_tcha.png new file mode 100644 index 0000000..169a265 Binary files /dev/null and b/mods/terumet/textures/terumet_armhelm_tcha.png differ diff --git a/mods/terumet/textures/terumet_armhelm_tcop.png b/mods/terumet/textures/terumet_armhelm_tcop.png new file mode 100644 index 0000000..2de1343 Binary files /dev/null and b/mods/terumet/textures/terumet_armhelm_tcop.png differ diff --git a/mods/terumet/textures/terumet_armhelm_tgol.png b/mods/terumet/textures/terumet_armhelm_tgol.png new file mode 100644 index 0000000..4ffa966 Binary files /dev/null and b/mods/terumet/textures/terumet_armhelm_tgol.png differ diff --git a/mods/terumet/textures/terumet_armhelm_tste.png b/mods/terumet/textures/terumet_armhelm_tste.png new file mode 100644 index 0000000..bca08cc Binary files /dev/null and b/mods/terumet/textures/terumet_armhelm_tste.png differ diff --git a/mods/terumet/textures/terumet_armhelm_ttin.png b/mods/terumet/textures/terumet_armhelm_ttin.png new file mode 100644 index 0000000..0aeb395 Binary files /dev/null and b/mods/terumet/textures/terumet_armhelm_ttin.png differ diff --git a/mods/terumet/textures/terumet_armlegs_cgls.png b/mods/terumet/textures/terumet_armlegs_cgls.png new file mode 100644 index 0000000..607d92d Binary files /dev/null and b/mods/terumet/textures/terumet_armlegs_cgls.png differ diff --git a/mods/terumet/textures/terumet_armlegs_rsuit.png b/mods/terumet/textures/terumet_armlegs_rsuit.png new file mode 100644 index 0000000..7ac7d87 Binary files /dev/null and b/mods/terumet/textures/terumet_armlegs_rsuit.png differ diff --git a/mods/terumet/textures/terumet_armlegs_tcha.png b/mods/terumet/textures/terumet_armlegs_tcha.png new file mode 100644 index 0000000..296f0c0 Binary files /dev/null and b/mods/terumet/textures/terumet_armlegs_tcha.png differ diff --git a/mods/terumet/textures/terumet_armlegs_tcop.png b/mods/terumet/textures/terumet_armlegs_tcop.png new file mode 100644 index 0000000..2461780 Binary files /dev/null and b/mods/terumet/textures/terumet_armlegs_tcop.png differ diff --git a/mods/terumet/textures/terumet_armlegs_tgol.png b/mods/terumet/textures/terumet_armlegs_tgol.png new file mode 100644 index 0000000..a42882a Binary files /dev/null and b/mods/terumet/textures/terumet_armlegs_tgol.png differ diff --git a/mods/terumet/textures/terumet_armlegs_tste.png b/mods/terumet/textures/terumet_armlegs_tste.png new file mode 100644 index 0000000..d7ee6fb Binary files /dev/null and b/mods/terumet/textures/terumet_armlegs_tste.png differ diff --git a/mods/terumet/textures/terumet_armlegs_ttin.png b/mods/terumet/textures/terumet_armlegs_ttin.png new file mode 100644 index 0000000..5f95ba1 Binary files /dev/null and b/mods/terumet/textures/terumet_armlegs_ttin.png differ diff --git a/mods/terumet/textures/terumet_asmelt_front_lit.png b/mods/terumet/textures/terumet_asmelt_front_lit.png new file mode 100644 index 0000000..4fbc0f8 Binary files /dev/null and b/mods/terumet/textures/terumet_asmelt_front_lit.png differ diff --git a/mods/terumet/textures/terumet_asmelt_front_unlit.png b/mods/terumet/textures/terumet_asmelt_front_unlit.png new file mode 100644 index 0000000..30c71bb Binary files /dev/null and b/mods/terumet/textures/terumet_asmelt_front_unlit.png differ diff --git a/mods/terumet/textures/terumet_blank.png b/mods/terumet/textures/terumet_blank.png new file mode 100644 index 0000000..be4bdb7 Binary files /dev/null and b/mods/terumet/textures/terumet_blank.png differ diff --git a/mods/terumet/textures/terumet_block_asphalt.png b/mods/terumet/textures/terumet_block_asphalt.png new file mode 100644 index 0000000..31c3431 Binary files /dev/null and b/mods/terumet/textures/terumet_block_asphalt.png differ diff --git a/mods/terumet/textures/terumet_block_ceramic.png b/mods/terumet/textures/terumet_block_ceramic.png new file mode 100644 index 0000000..5ab8824 Binary files /dev/null and b/mods/terumet/textures/terumet_block_ceramic.png differ diff --git a/mods/terumet/textures/terumet_block_cgls.png b/mods/terumet/textures/terumet_block_cgls.png new file mode 100644 index 0000000..c9e66fe Binary files /dev/null and b/mods/terumet/textures/terumet_block_cgls.png differ diff --git a/mods/terumet/textures/terumet_block_coke.png b/mods/terumet/textures/terumet_block_coke.png new file mode 100644 index 0000000..da79b7e Binary files /dev/null and b/mods/terumet/textures/terumet_block_coke.png differ diff --git a/mods/terumet/textures/terumet_block_con.png b/mods/terumet/textures/terumet_block_con.png new file mode 100644 index 0000000..b3d47d0 Binary files /dev/null and b/mods/terumet/textures/terumet_block_con.png differ diff --git a/mods/terumet/textures/terumet_block_conmix.png b/mods/terumet/textures/terumet_block_conmix.png new file mode 100644 index 0000000..13922a6 Binary files /dev/null and b/mods/terumet/textures/terumet_block_conmix.png differ diff --git a/mods/terumet/textures/terumet_block_dust_bio.png b/mods/terumet/textures/terumet_block_dust_bio.png new file mode 100644 index 0000000..8cf6eae Binary files /dev/null and b/mods/terumet/textures/terumet_block_dust_bio.png differ diff --git a/mods/terumet/textures/terumet_block_entropy.png b/mods/terumet/textures/terumet_block_entropy.png new file mode 100644 index 0000000..0c11ddf Binary files /dev/null and b/mods/terumet/textures/terumet_block_entropy.png differ diff --git a/mods/terumet/textures/terumet_block_pwood.png b/mods/terumet/textures/terumet_block_pwood.png new file mode 100644 index 0000000..a213f63 Binary files /dev/null and b/mods/terumet/textures/terumet_block_pwood.png differ diff --git a/mods/terumet/textures/terumet_block_pwood_sides.png b/mods/terumet/textures/terumet_block_pwood_sides.png new file mode 100644 index 0000000..42b42a7 Binary files /dev/null and b/mods/terumet/textures/terumet_block_pwood_sides.png differ diff --git a/mods/terumet/textures/terumet_block_raw.png b/mods/terumet/textures/terumet_block_raw.png new file mode 100644 index 0000000..d8dd3e6 Binary files /dev/null and b/mods/terumet/textures/terumet_block_raw.png differ diff --git a/mods/terumet/textures/terumet_block_tar.png b/mods/terumet/textures/terumet_block_tar.png new file mode 100644 index 0000000..9791c74 Binary files /dev/null and b/mods/terumet/textures/terumet_block_tar.png differ diff --git a/mods/terumet/textures/terumet_block_tcha.png b/mods/terumet/textures/terumet_block_tcha.png new file mode 100644 index 0000000..1996f50 Binary files /dev/null and b/mods/terumet/textures/terumet_block_tcha.png differ diff --git a/mods/terumet/textures/terumet_block_tcop.png b/mods/terumet/textures/terumet_block_tcop.png new file mode 100644 index 0000000..f43fa93 Binary files /dev/null and b/mods/terumet/textures/terumet_block_tcop.png differ diff --git a/mods/terumet/textures/terumet_block_tglass_frame.png b/mods/terumet/textures/terumet_block_tglass_frame.png new file mode 100644 index 0000000..7b1bb12 Binary files /dev/null and b/mods/terumet/textures/terumet_block_tglass_frame.png differ diff --git a/mods/terumet/textures/terumet_block_tglass_streak.png b/mods/terumet/textures/terumet_block_tglass_streak.png new file mode 100644 index 0000000..e26e69c Binary files /dev/null and b/mods/terumet/textures/terumet_block_tglass_streak.png differ diff --git a/mods/terumet/textures/terumet_block_tglassglow_frame.png b/mods/terumet/textures/terumet_block_tglassglow_frame.png new file mode 100644 index 0000000..a865b31 Binary files /dev/null and b/mods/terumet/textures/terumet_block_tglassglow_frame.png differ diff --git a/mods/terumet/textures/terumet_block_tglassglow_streak.png b/mods/terumet/textures/terumet_block_tglassglow_streak.png new file mode 100644 index 0000000..61bbc09 Binary files /dev/null and b/mods/terumet/textures/terumet_block_tglassglow_streak.png differ diff --git a/mods/terumet/textures/terumet_block_tgol.png b/mods/terumet/textures/terumet_block_tgol.png new file mode 100644 index 0000000..fb23303 Binary files /dev/null and b/mods/terumet/textures/terumet_block_tgol.png differ diff --git a/mods/terumet/textures/terumet_block_thermese.png b/mods/terumet/textures/terumet_block_thermese.png new file mode 100644 index 0000000..ebdc98e Binary files /dev/null and b/mods/terumet/textures/terumet_block_thermese.png differ diff --git a/mods/terumet/textures/terumet_block_thermese_hot.png b/mods/terumet/textures/terumet_block_thermese_hot.png new file mode 100644 index 0000000..2c9bf68 Binary files /dev/null and b/mods/terumet/textures/terumet_block_thermese_hot.png differ diff --git a/mods/terumet/textures/terumet_block_tste.png b/mods/terumet/textures/terumet_block_tste.png new file mode 100644 index 0000000..cd36b5c Binary files /dev/null and b/mods/terumet/textures/terumet_block_tste.png differ diff --git a/mods/terumet/textures/terumet_block_ttin.png b/mods/terumet/textures/terumet_block_ttin.png new file mode 100644 index 0000000..57898ae Binary files /dev/null and b/mods/terumet/textures/terumet_block_ttin.png differ diff --git a/mods/terumet/textures/terumet_blockov_hline.png b/mods/terumet/textures/terumet_blockov_hline.png new file mode 100644 index 0000000..833d2f2 Binary files /dev/null and b/mods/terumet/textures/terumet_blockov_hline.png differ diff --git a/mods/terumet/textures/terumet_blockov_rebar1.png b/mods/terumet/textures/terumet_blockov_rebar1.png new file mode 100644 index 0000000..4509c33 Binary files /dev/null and b/mods/terumet/textures/terumet_blockov_rebar1.png differ diff --git a/mods/terumet/textures/terumet_blockov_rebar2.png b/mods/terumet/textures/terumet_blockov_rebar2.png new file mode 100644 index 0000000..6e5c29e Binary files /dev/null and b/mods/terumet/textures/terumet_blockov_rebar2.png differ diff --git a/mods/terumet/textures/terumet_blockov_rebar3.png b/mods/terumet/textures/terumet_blockov_rebar3.png new file mode 100644 index 0000000..4081851 Binary files /dev/null and b/mods/terumet/textures/terumet_blockov_rebar3.png differ diff --git a/mods/terumet/textures/terumet_cgls_heater_sides.png b/mods/terumet/textures/terumet_cgls_heater_sides.png new file mode 100644 index 0000000..71251f1 Binary files /dev/null and b/mods/terumet/textures/terumet_cgls_heater_sides.png differ diff --git a/mods/terumet/textures/terumet_crush_front.png b/mods/terumet/textures/terumet_crush_front.png new file mode 100644 index 0000000..c1c16c7 Binary files /dev/null and b/mods/terumet/textures/terumet_crush_front.png differ diff --git a/mods/terumet/textures/terumet_crush_front_lit.png b/mods/terumet/textures/terumet_crush_front_lit.png new file mode 100644 index 0000000..b6b141c Binary files /dev/null and b/mods/terumet/textures/terumet_crush_front_lit.png differ diff --git a/mods/terumet/textures/terumet_crush_front_unlit.png b/mods/terumet/textures/terumet_crush_front_unlit.png new file mode 100644 index 0000000..84e174b Binary files /dev/null and b/mods/terumet/textures/terumet_crush_front_unlit.png differ diff --git a/mods/terumet/textures/terumet_dinv_con.png b/mods/terumet/textures/terumet_dinv_con.png new file mode 100644 index 0000000..23efed9 Binary files /dev/null and b/mods/terumet/textures/terumet_dinv_con.png differ diff --git a/mods/terumet/textures/terumet_dinvfull_cgls.png b/mods/terumet/textures/terumet_dinvfull_cgls.png new file mode 100644 index 0000000..7d80d13 Binary files /dev/null and b/mods/terumet/textures/terumet_dinvfull_cgls.png differ diff --git a/mods/terumet/textures/terumet_dinvfull_tcha.png b/mods/terumet/textures/terumet_dinvfull_tcha.png new file mode 100644 index 0000000..07d9472 Binary files /dev/null and b/mods/terumet/textures/terumet_dinvfull_tcha.png differ diff --git a/mods/terumet/textures/terumet_dinvfull_tcop.png b/mods/terumet/textures/terumet_dinvfull_tcop.png new file mode 100644 index 0000000..0ed6b97 Binary files /dev/null and b/mods/terumet/textures/terumet_dinvfull_tcop.png differ diff --git a/mods/terumet/textures/terumet_dinvfull_tgol.png b/mods/terumet/textures/terumet_dinvfull_tgol.png new file mode 100644 index 0000000..fbe4fc1 Binary files /dev/null and b/mods/terumet/textures/terumet_dinvfull_tgol.png differ diff --git a/mods/terumet/textures/terumet_dinvfull_tste.png b/mods/terumet/textures/terumet_dinvfull_tste.png new file mode 100644 index 0000000..601372e Binary files /dev/null and b/mods/terumet/textures/terumet_dinvfull_tste.png differ diff --git a/mods/terumet/textures/terumet_dinvfull_ttin.png b/mods/terumet/textures/terumet_dinvfull_ttin.png new file mode 100644 index 0000000..69e7cd2 Binary files /dev/null and b/mods/terumet/textures/terumet_dinvfull_ttin.png differ diff --git a/mods/terumet/textures/terumet_dinvmesh_cgls.png b/mods/terumet/textures/terumet_dinvmesh_cgls.png new file mode 100644 index 0000000..4eb92bd Binary files /dev/null and b/mods/terumet/textures/terumet_dinvmesh_cgls.png differ diff --git a/mods/terumet/textures/terumet_dinvmesh_tcha.png b/mods/terumet/textures/terumet_dinvmesh_tcha.png new file mode 100644 index 0000000..889ba43 Binary files /dev/null and b/mods/terumet/textures/terumet_dinvmesh_tcha.png differ diff --git a/mods/terumet/textures/terumet_dinvmesh_tcop.png b/mods/terumet/textures/terumet_dinvmesh_tcop.png new file mode 100644 index 0000000..06266bb Binary files /dev/null and b/mods/terumet/textures/terumet_dinvmesh_tcop.png differ diff --git a/mods/terumet/textures/terumet_dinvmesh_tgol.png b/mods/terumet/textures/terumet_dinvmesh_tgol.png new file mode 100644 index 0000000..57918ae Binary files /dev/null and b/mods/terumet/textures/terumet_dinvmesh_tgol.png differ diff --git a/mods/terumet/textures/terumet_dinvmesh_tste.png b/mods/terumet/textures/terumet_dinvmesh_tste.png new file mode 100644 index 0000000..8df64b0 Binary files /dev/null and b/mods/terumet/textures/terumet_dinvmesh_tste.png differ diff --git a/mods/terumet/textures/terumet_dinvmesh_ttin.png b/mods/terumet/textures/terumet_dinvmesh_ttin.png new file mode 100644 index 0000000..6796b34 Binary files /dev/null and b/mods/terumet/textures/terumet_dinvmesh_ttin.png differ diff --git a/mods/terumet/textures/terumet_dinvslat_cgls.png b/mods/terumet/textures/terumet_dinvslat_cgls.png new file mode 100644 index 0000000..39b7364 Binary files /dev/null and b/mods/terumet/textures/terumet_dinvslat_cgls.png differ diff --git a/mods/terumet/textures/terumet_dinvslat_tcha.png b/mods/terumet/textures/terumet_dinvslat_tcha.png new file mode 100644 index 0000000..0254d83 Binary files /dev/null and b/mods/terumet/textures/terumet_dinvslat_tcha.png differ diff --git a/mods/terumet/textures/terumet_dinvslat_tcop.png b/mods/terumet/textures/terumet_dinvslat_tcop.png new file mode 100644 index 0000000..10fe4fa Binary files /dev/null and b/mods/terumet/textures/terumet_dinvslat_tcop.png differ diff --git a/mods/terumet/textures/terumet_dinvslat_tgol.png b/mods/terumet/textures/terumet_dinvslat_tgol.png new file mode 100644 index 0000000..e0bdc3c Binary files /dev/null and b/mods/terumet/textures/terumet_dinvslat_tgol.png differ diff --git a/mods/terumet/textures/terumet_dinvslat_tste.png b/mods/terumet/textures/terumet_dinvslat_tste.png new file mode 100644 index 0000000..630d461 Binary files /dev/null and b/mods/terumet/textures/terumet_dinvslat_tste.png differ diff --git a/mods/terumet/textures/terumet_dinvslat_ttin.png b/mods/terumet/textures/terumet_dinvslat_ttin.png new file mode 100644 index 0000000..fdc5ff4 Binary files /dev/null and b/mods/terumet/textures/terumet_dinvslat_ttin.png differ diff --git a/mods/terumet/textures/terumet_dinvvert_cgls.png b/mods/terumet/textures/terumet_dinvvert_cgls.png new file mode 100644 index 0000000..104ca44 Binary files /dev/null and b/mods/terumet/textures/terumet_dinvvert_cgls.png differ diff --git a/mods/terumet/textures/terumet_dinvvert_tcha.png b/mods/terumet/textures/terumet_dinvvert_tcha.png new file mode 100644 index 0000000..fca9cd5 Binary files /dev/null and b/mods/terumet/textures/terumet_dinvvert_tcha.png differ diff --git a/mods/terumet/textures/terumet_dinvvert_tcop.png b/mods/terumet/textures/terumet_dinvvert_tcop.png new file mode 100644 index 0000000..ff3ad2c Binary files /dev/null and b/mods/terumet/textures/terumet_dinvvert_tcop.png differ diff --git a/mods/terumet/textures/terumet_dinvvert_tgol.png b/mods/terumet/textures/terumet_dinvvert_tgol.png new file mode 100644 index 0000000..d59d041 Binary files /dev/null and b/mods/terumet/textures/terumet_dinvvert_tgol.png differ diff --git a/mods/terumet/textures/terumet_dinvvert_tste.png b/mods/terumet/textures/terumet_dinvvert_tste.png new file mode 100644 index 0000000..be33a11 Binary files /dev/null and b/mods/terumet/textures/terumet_dinvvert_tste.png differ diff --git a/mods/terumet/textures/terumet_dinvvert_ttin.png b/mods/terumet/textures/terumet_dinvvert_ttin.png new file mode 100644 index 0000000..9665d3f Binary files /dev/null and b/mods/terumet/textures/terumet_dinvvert_ttin.png differ diff --git a/mods/terumet/textures/terumet_door_con.png b/mods/terumet/textures/terumet_door_con.png new file mode 100644 index 0000000..7d4e4d5 Binary files /dev/null and b/mods/terumet/textures/terumet_door_con.png differ diff --git a/mods/terumet/textures/terumet_doorfull_cgls.png b/mods/terumet/textures/terumet_doorfull_cgls.png new file mode 100644 index 0000000..1ccb936 Binary files /dev/null and b/mods/terumet/textures/terumet_doorfull_cgls.png differ diff --git a/mods/terumet/textures/terumet_doorfull_tcha.png b/mods/terumet/textures/terumet_doorfull_tcha.png new file mode 100644 index 0000000..10db5e9 Binary files /dev/null and b/mods/terumet/textures/terumet_doorfull_tcha.png differ diff --git a/mods/terumet/textures/terumet_doorfull_tcop.png b/mods/terumet/textures/terumet_doorfull_tcop.png new file mode 100644 index 0000000..d9bf67e Binary files /dev/null and b/mods/terumet/textures/terumet_doorfull_tcop.png differ diff --git a/mods/terumet/textures/terumet_doorfull_tgol.png b/mods/terumet/textures/terumet_doorfull_tgol.png new file mode 100644 index 0000000..db0883d Binary files /dev/null and b/mods/terumet/textures/terumet_doorfull_tgol.png differ diff --git a/mods/terumet/textures/terumet_doorfull_tste.png b/mods/terumet/textures/terumet_doorfull_tste.png new file mode 100644 index 0000000..dc4bb1f Binary files /dev/null and b/mods/terumet/textures/terumet_doorfull_tste.png differ diff --git a/mods/terumet/textures/terumet_doorfull_ttin.png b/mods/terumet/textures/terumet_doorfull_ttin.png new file mode 100644 index 0000000..4c9a202 Binary files /dev/null and b/mods/terumet/textures/terumet_doorfull_ttin.png differ diff --git a/mods/terumet/textures/terumet_doormesh_cgls.png b/mods/terumet/textures/terumet_doormesh_cgls.png new file mode 100644 index 0000000..78524f3 Binary files /dev/null and b/mods/terumet/textures/terumet_doormesh_cgls.png differ diff --git a/mods/terumet/textures/terumet_doormesh_tcha.png b/mods/terumet/textures/terumet_doormesh_tcha.png new file mode 100644 index 0000000..55a1a51 Binary files /dev/null and b/mods/terumet/textures/terumet_doormesh_tcha.png differ diff --git a/mods/terumet/textures/terumet_doormesh_tcop.png b/mods/terumet/textures/terumet_doormesh_tcop.png new file mode 100644 index 0000000..dd4c188 Binary files /dev/null and b/mods/terumet/textures/terumet_doormesh_tcop.png differ diff --git a/mods/terumet/textures/terumet_doormesh_tgol.png b/mods/terumet/textures/terumet_doormesh_tgol.png new file mode 100644 index 0000000..82647bd Binary files /dev/null and b/mods/terumet/textures/terumet_doormesh_tgol.png differ diff --git a/mods/terumet/textures/terumet_doormesh_tste.png b/mods/terumet/textures/terumet_doormesh_tste.png new file mode 100644 index 0000000..5490f31 Binary files /dev/null and b/mods/terumet/textures/terumet_doormesh_tste.png differ diff --git a/mods/terumet/textures/terumet_doormesh_ttin.png b/mods/terumet/textures/terumet_doormesh_ttin.png new file mode 100644 index 0000000..81dcd58 Binary files /dev/null and b/mods/terumet/textures/terumet_doormesh_ttin.png differ diff --git a/mods/terumet/textures/terumet_doorslat_cgls.png b/mods/terumet/textures/terumet_doorslat_cgls.png new file mode 100644 index 0000000..4c4bf9f Binary files /dev/null and b/mods/terumet/textures/terumet_doorslat_cgls.png differ diff --git a/mods/terumet/textures/terumet_doorslat_tcha.png b/mods/terumet/textures/terumet_doorslat_tcha.png new file mode 100644 index 0000000..b54a0a5 Binary files /dev/null and b/mods/terumet/textures/terumet_doorslat_tcha.png differ diff --git a/mods/terumet/textures/terumet_doorslat_tcop.png b/mods/terumet/textures/terumet_doorslat_tcop.png new file mode 100644 index 0000000..632ab2e Binary files /dev/null and b/mods/terumet/textures/terumet_doorslat_tcop.png differ diff --git a/mods/terumet/textures/terumet_doorslat_tgol.png b/mods/terumet/textures/terumet_doorslat_tgol.png new file mode 100644 index 0000000..5b10687 Binary files /dev/null and b/mods/terumet/textures/terumet_doorslat_tgol.png differ diff --git a/mods/terumet/textures/terumet_doorslat_tste.png b/mods/terumet/textures/terumet_doorslat_tste.png new file mode 100644 index 0000000..8a143c7 Binary files /dev/null and b/mods/terumet/textures/terumet_doorslat_tste.png differ diff --git a/mods/terumet/textures/terumet_doorslat_ttin.png b/mods/terumet/textures/terumet_doorslat_ttin.png new file mode 100644 index 0000000..94a478e Binary files /dev/null and b/mods/terumet/textures/terumet_doorslat_ttin.png differ diff --git a/mods/terumet/textures/terumet_doorvert_cgls.png b/mods/terumet/textures/terumet_doorvert_cgls.png new file mode 100644 index 0000000..b3dc3a7 Binary files /dev/null and b/mods/terumet/textures/terumet_doorvert_cgls.png differ diff --git a/mods/terumet/textures/terumet_doorvert_tcha.png b/mods/terumet/textures/terumet_doorvert_tcha.png new file mode 100644 index 0000000..04a12fe Binary files /dev/null and b/mods/terumet/textures/terumet_doorvert_tcha.png differ diff --git a/mods/terumet/textures/terumet_doorvert_tcop.png b/mods/terumet/textures/terumet_doorvert_tcop.png new file mode 100644 index 0000000..d2902a8 Binary files /dev/null and b/mods/terumet/textures/terumet_doorvert_tcop.png differ diff --git a/mods/terumet/textures/terumet_doorvert_tgol.png b/mods/terumet/textures/terumet_doorvert_tgol.png new file mode 100644 index 0000000..5b64954 Binary files /dev/null and b/mods/terumet/textures/terumet_doorvert_tgol.png differ diff --git a/mods/terumet/textures/terumet_doorvert_tste.png b/mods/terumet/textures/terumet_doorvert_tste.png new file mode 100644 index 0000000..ef97736 Binary files /dev/null and b/mods/terumet/textures/terumet_doorvert_tste.png differ diff --git a/mods/terumet/textures/terumet_doorvert_ttin.png b/mods/terumet/textures/terumet_doorvert_ttin.png new file mode 100644 index 0000000..41cc8ba Binary files /dev/null and b/mods/terumet/textures/terumet_doorvert_ttin.png differ diff --git a/mods/terumet/textures/terumet_frame_cgls.png b/mods/terumet/textures/terumet_frame_cgls.png new file mode 100644 index 0000000..35c0913 Binary files /dev/null and b/mods/terumet/textures/terumet_frame_cgls.png differ diff --git a/mods/terumet/textures/terumet_frame_raw.png b/mods/terumet/textures/terumet_frame_raw.png new file mode 100644 index 0000000..12ac83e Binary files /dev/null and b/mods/terumet/textures/terumet_frame_raw.png differ diff --git a/mods/terumet/textures/terumet_frame_tste.png b/mods/terumet/textures/terumet_frame_tste.png new file mode 100644 index 0000000..4ac1ec8 Binary files /dev/null and b/mods/terumet/textures/terumet_frame_tste.png differ diff --git a/mods/terumet/textures/terumet_gui_back.png b/mods/terumet/textures/terumet_gui_back.png new file mode 100644 index 0000000..0463a40 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_back.png differ diff --git a/mods/terumet/textures/terumet_gui_back2.png b/mods/terumet/textures/terumet_gui_back2.png new file mode 100644 index 0000000..e0f7526 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_back2.png differ diff --git a/mods/terumet/textures/terumet_gui_back3.png b/mods/terumet/textures/terumet_gui_back3.png new file mode 100644 index 0000000..c6c291a Binary files /dev/null and b/mods/terumet/textures/terumet_gui_back3.png differ diff --git a/mods/terumet/textures/terumet_gui_backc.png b/mods/terumet/textures/terumet_gui_backc.png new file mode 100644 index 0000000..cfc720a Binary files /dev/null and b/mods/terumet/textures/terumet_gui_backc.png differ diff --git a/mods/terumet/textures/terumet_gui_bg_effc.png b/mods/terumet/textures/terumet_gui_bg_effc.png new file mode 100644 index 0000000..279c0ac Binary files /dev/null and b/mods/terumet/textures/terumet_gui_bg_effc.png differ diff --git a/mods/terumet/textures/terumet_gui_bg_flux.png b/mods/terumet/textures/terumet_gui_bg_flux.png new file mode 100644 index 0000000..ee62cc8 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_bg_flux.png differ diff --git a/mods/terumet/textures/terumet_gui_bg_heat.png b/mods/terumet/textures/terumet_gui_bg_heat.png new file mode 100644 index 0000000..8f2c990 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_bg_heat.png differ diff --git a/mods/terumet/textures/terumet_gui_bg_mese.png b/mods/terumet/textures/terumet_gui_bg_mese.png new file mode 100644 index 0000000..5105b1a Binary files /dev/null and b/mods/terumet/textures/terumet_gui_bg_mese.png differ diff --git a/mods/terumet/textures/terumet_gui_bg_rmat.png b/mods/terumet/textures/terumet_gui_bg_rmat.png new file mode 100644 index 0000000..67c2965 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_bg_rmat.png differ diff --git a/mods/terumet/textures/terumet_gui_bg_sun.png b/mods/terumet/textures/terumet_gui_bg_sun.png new file mode 100644 index 0000000..3e429c8 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_bg_sun.png differ diff --git a/mods/terumet/textures/terumet_gui_disabled.png b/mods/terumet/textures/terumet_gui_disabled.png new file mode 100644 index 0000000..82c7367 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_disabled.png differ diff --git a/mods/terumet/textures/terumet_gui_fg_effc.png b/mods/terumet/textures/terumet_gui_fg_effc.png new file mode 100644 index 0000000..c00553e Binary files /dev/null and b/mods/terumet/textures/terumet_gui_fg_effc.png differ diff --git a/mods/terumet/textures/terumet_gui_fg_flux.png b/mods/terumet/textures/terumet_gui_fg_flux.png new file mode 100644 index 0000000..61f2ae5 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_fg_flux.png differ diff --git a/mods/terumet/textures/terumet_gui_fg_heat.png b/mods/terumet/textures/terumet_gui_fg_heat.png new file mode 100644 index 0000000..1204b11 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_fg_heat.png differ diff --git a/mods/terumet/textures/terumet_gui_fg_interf.png b/mods/terumet/textures/terumet_gui_fg_interf.png new file mode 100644 index 0000000..55b9c2b Binary files /dev/null and b/mods/terumet/textures/terumet_gui_fg_interf.png differ diff --git a/mods/terumet/textures/terumet_gui_fg_mese.png b/mods/terumet/textures/terumet_gui_fg_mese.png new file mode 100644 index 0000000..f0028f9 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_fg_mese.png differ diff --git a/mods/terumet/textures/terumet_gui_fg_rmat.png b/mods/terumet/textures/terumet_gui_fg_rmat.png new file mode 100644 index 0000000..240e66e Binary files /dev/null and b/mods/terumet/textures/terumet_gui_fg_rmat.png differ diff --git a/mods/terumet/textures/terumet_gui_fg_sun.png b/mods/terumet/textures/terumet_gui_fg_sun.png new file mode 100644 index 0000000..3f6ca98 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_fg_sun.png differ diff --git a/mods/terumet/textures/terumet_gui_heatxfer.png b/mods/terumet/textures/terumet_gui_heatxfer.png new file mode 100644 index 0000000..a006a4a Binary files /dev/null and b/mods/terumet/textures/terumet_gui_heatxfer.png differ diff --git a/mods/terumet/textures/terumet_gui_idle_pres.png b/mods/terumet/textures/terumet_gui_idle_pres.png new file mode 100644 index 0000000..4fe9bd4 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_idle_pres.png differ diff --git a/mods/terumet/textures/terumet_gui_overheat.png b/mods/terumet/textures/terumet_gui_overheat.png new file mode 100644 index 0000000..1fc02d8 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_overheat.png differ diff --git a/mods/terumet/textures/terumet_gui_proc_alloy.png b/mods/terumet/textures/terumet_gui_proc_alloy.png new file mode 100644 index 0000000..7cd9887 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_proc_alloy.png differ diff --git a/mods/terumet/textures/terumet_gui_proc_cook.png b/mods/terumet/textures/terumet_gui_proc_cook.png new file mode 100644 index 0000000..75bf202 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_proc_cook.png differ diff --git a/mods/terumet/textures/terumet_gui_proc_gen.png b/mods/terumet/textures/terumet_gui_proc_gen.png new file mode 100644 index 0000000..7d6b238 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_proc_gen.png differ diff --git a/mods/terumet/textures/terumet_gui_proc_heat.png b/mods/terumet/textures/terumet_gui_proc_heat.png new file mode 100644 index 0000000..0257be7 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_proc_heat.png differ diff --git a/mods/terumet/textures/terumet_gui_proc_melt.png b/mods/terumet/textures/terumet_gui_proc_melt.png new file mode 100644 index 0000000..1986b2e Binary files /dev/null and b/mods/terumet/textures/terumet_gui_proc_melt.png differ diff --git a/mods/terumet/textures/terumet_gui_proc_pres1.png b/mods/terumet/textures/terumet_gui_proc_pres1.png new file mode 100644 index 0000000..5a02270 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_proc_pres1.png differ diff --git a/mods/terumet/textures/terumet_gui_proc_pres2.png b/mods/terumet/textures/terumet_gui_proc_pres2.png new file mode 100644 index 0000000..4f6f312 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_proc_pres2.png differ diff --git a/mods/terumet/textures/terumet_gui_side1.png b/mods/terumet/textures/terumet_gui_side1.png new file mode 100644 index 0000000..d3f0991 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_side1.png differ diff --git a/mods/terumet/textures/terumet_gui_side2.png b/mods/terumet/textures/terumet_gui_side2.png new file mode 100644 index 0000000..3f5ef75 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_side2.png differ diff --git a/mods/terumet/textures/terumet_gui_side3.png b/mods/terumet/textures/terumet_gui_side3.png new file mode 100644 index 0000000..d74551f Binary files /dev/null and b/mods/terumet/textures/terumet_gui_side3.png differ diff --git a/mods/terumet/textures/terumet_gui_side4.png b/mods/terumet/textures/terumet_gui_side4.png new file mode 100644 index 0000000..6e8b4f0 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_side4.png differ diff --git a/mods/terumet/textures/terumet_gui_side5.png b/mods/terumet/textures/terumet_gui_side5.png new file mode 100644 index 0000000..0a68088 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_side5.png differ diff --git a/mods/terumet/textures/terumet_gui_side6.png b/mods/terumet/textures/terumet_gui_side6.png new file mode 100644 index 0000000..1d5edd4 Binary files /dev/null and b/mods/terumet/textures/terumet_gui_side6.png differ diff --git a/mods/terumet/textures/terumet_hline.png b/mods/terumet/textures/terumet_hline.png new file mode 100644 index 0000000..f086b3b Binary files /dev/null and b/mods/terumet/textures/terumet_hline.png differ diff --git a/mods/terumet/textures/terumet_hline_in.png b/mods/terumet/textures/terumet_hline_in.png new file mode 100644 index 0000000..d0c9bf6 Binary files /dev/null and b/mods/terumet/textures/terumet_hline_in.png differ diff --git a/mods/terumet/textures/terumet_hray_back.png b/mods/terumet/textures/terumet_hray_back.png new file mode 100644 index 0000000..9a64e8e Binary files /dev/null and b/mods/terumet/textures/terumet_hray_back.png differ diff --git a/mods/terumet/textures/terumet_hray_front.png b/mods/terumet/textures/terumet_hray_front.png new file mode 100644 index 0000000..8054e3d Binary files /dev/null and b/mods/terumet/textures/terumet_hray_front.png differ diff --git a/mods/terumet/textures/terumet_hray_sides.png b/mods/terumet/textures/terumet_hray_sides.png new file mode 100644 index 0000000..85eaca4 Binary files /dev/null and b/mods/terumet/textures/terumet_hray_sides.png differ diff --git a/mods/terumet/textures/terumet_htfurn_front.png b/mods/terumet/textures/terumet_htfurn_front.png new file mode 100644 index 0000000..000cc7f Binary files /dev/null and b/mods/terumet/textures/terumet_htfurn_front.png differ diff --git a/mods/terumet/textures/terumet_htfurn_sides.png b/mods/terumet/textures/terumet_htfurn_sides.png new file mode 100644 index 0000000..0b5f89f Binary files /dev/null and b/mods/terumet/textures/terumet_htfurn_sides.png differ diff --git a/mods/terumet/textures/terumet_htfurn_top_lit.png b/mods/terumet/textures/terumet_htfurn_top_lit.png new file mode 100644 index 0000000..6ec4da9 Binary files /dev/null and b/mods/terumet/textures/terumet_htfurn_top_lit.png differ diff --git a/mods/terumet/textures/terumet_htfurn_top_unlit.png b/mods/terumet/textures/terumet_htfurn_top_unlit.png new file mode 100644 index 0000000..d5f3104 Binary files /dev/null and b/mods/terumet/textures/terumet_htfurn_top_unlit.png differ diff --git a/mods/terumet/textures/terumet_htr_entropy_top.png b/mods/terumet/textures/terumet_htr_entropy_top.png new file mode 100644 index 0000000..b233861 Binary files /dev/null and b/mods/terumet/textures/terumet_htr_entropy_top.png differ diff --git a/mods/terumet/textures/terumet_htr_furnace_front_lit.png b/mods/terumet/textures/terumet_htr_furnace_front_lit.png new file mode 100644 index 0000000..fa42c7d Binary files /dev/null and b/mods/terumet/textures/terumet_htr_furnace_front_lit.png differ diff --git a/mods/terumet/textures/terumet_htr_furnace_front_unlit.png b/mods/terumet/textures/terumet_htr_furnace_front_unlit.png new file mode 100644 index 0000000..a176be5 Binary files /dev/null and b/mods/terumet/textures/terumet_htr_furnace_front_unlit.png differ diff --git a/mods/terumet/textures/terumet_htr_solar_top.png b/mods/terumet/textures/terumet_htr_solar_top.png new file mode 100644 index 0000000..ba86670 Binary files /dev/null and b/mods/terumet/textures/terumet_htr_solar_top.png differ diff --git a/mods/terumet/textures/terumet_ingot_cgls.png b/mods/terumet/textures/terumet_ingot_cgls.png new file mode 100644 index 0000000..2690fb1 Binary files /dev/null and b/mods/terumet/textures/terumet_ingot_cgls.png differ diff --git a/mods/terumet/textures/terumet_ingot_meson.png b/mods/terumet/textures/terumet_ingot_meson.png new file mode 100644 index 0000000..413923f Binary files /dev/null and b/mods/terumet/textures/terumet_ingot_meson.png differ diff --git a/mods/terumet/textures/terumet_ingot_raw.png b/mods/terumet/textures/terumet_ingot_raw.png new file mode 100644 index 0000000..5dfd578 Binary files /dev/null and b/mods/terumet/textures/terumet_ingot_raw.png differ diff --git a/mods/terumet/textures/terumet_ingot_tcha.png b/mods/terumet/textures/terumet_ingot_tcha.png new file mode 100644 index 0000000..ccfaaf1 Binary files /dev/null and b/mods/terumet/textures/terumet_ingot_tcha.png differ diff --git a/mods/terumet/textures/terumet_ingot_tcop.png b/mods/terumet/textures/terumet_ingot_tcop.png new file mode 100644 index 0000000..5c2d0cc Binary files /dev/null and b/mods/terumet/textures/terumet_ingot_tcop.png differ diff --git a/mods/terumet/textures/terumet_ingot_tgol.png b/mods/terumet/textures/terumet_ingot_tgol.png new file mode 100644 index 0000000..b9271cb Binary files /dev/null and b/mods/terumet/textures/terumet_ingot_tgol.png differ diff --git a/mods/terumet/textures/terumet_ingot_tste.png b/mods/terumet/textures/terumet_ingot_tste.png new file mode 100644 index 0000000..fce1e1e Binary files /dev/null and b/mods/terumet/textures/terumet_ingot_tste.png differ diff --git a/mods/terumet/textures/terumet_ingot_ttin.png b/mods/terumet/textures/terumet_ingot_ttin.png new file mode 100644 index 0000000..6a98532 Binary files /dev/null and b/mods/terumet/textures/terumet_ingot_ttin.png differ diff --git a/mods/terumet/textures/terumet_invboots_cgls.png b/mods/terumet/textures/terumet_invboots_cgls.png new file mode 100644 index 0000000..1bed31d Binary files /dev/null and b/mods/terumet/textures/terumet_invboots_cgls.png differ diff --git a/mods/terumet/textures/terumet_invboots_rsuit.png b/mods/terumet/textures/terumet_invboots_rsuit.png new file mode 100644 index 0000000..8120693 Binary files /dev/null and b/mods/terumet/textures/terumet_invboots_rsuit.png differ diff --git a/mods/terumet/textures/terumet_invboots_tcha.png b/mods/terumet/textures/terumet_invboots_tcha.png new file mode 100644 index 0000000..2d025d8 Binary files /dev/null and b/mods/terumet/textures/terumet_invboots_tcha.png differ diff --git a/mods/terumet/textures/terumet_invboots_tcop.png b/mods/terumet/textures/terumet_invboots_tcop.png new file mode 100644 index 0000000..ae1cfb0 Binary files /dev/null and b/mods/terumet/textures/terumet_invboots_tcop.png differ diff --git a/mods/terumet/textures/terumet_invboots_tgol.png b/mods/terumet/textures/terumet_invboots_tgol.png new file mode 100644 index 0000000..a17a6f3 Binary files /dev/null and b/mods/terumet/textures/terumet_invboots_tgol.png differ diff --git a/mods/terumet/textures/terumet_invboots_tste.png b/mods/terumet/textures/terumet_invboots_tste.png new file mode 100644 index 0000000..d235ffe Binary files /dev/null and b/mods/terumet/textures/terumet_invboots_tste.png differ diff --git a/mods/terumet/textures/terumet_invboots_ttin.png b/mods/terumet/textures/terumet_invboots_ttin.png new file mode 100644 index 0000000..7dc1706 Binary files /dev/null and b/mods/terumet/textures/terumet_invboots_ttin.png differ diff --git a/mods/terumet/textures/terumet_invbrcr_base.png b/mods/terumet/textures/terumet_invbrcr_base.png new file mode 100644 index 0000000..f442eb1 Binary files /dev/null and b/mods/terumet/textures/terumet_invbrcr_base.png differ diff --git a/mods/terumet/textures/terumet_invbrcr_color.png b/mods/terumet/textures/terumet_invbrcr_color.png new file mode 100644 index 0000000..25e7bf8 Binary files /dev/null and b/mods/terumet/textures/terumet_invbrcr_color.png differ diff --git a/mods/terumet/textures/terumet_invchest_cgls.png b/mods/terumet/textures/terumet_invchest_cgls.png new file mode 100644 index 0000000..4defa8d Binary files /dev/null and b/mods/terumet/textures/terumet_invchest_cgls.png differ diff --git a/mods/terumet/textures/terumet_invchest_rsuit.png b/mods/terumet/textures/terumet_invchest_rsuit.png new file mode 100644 index 0000000..2b8f571 Binary files /dev/null and b/mods/terumet/textures/terumet_invchest_rsuit.png differ diff --git a/mods/terumet/textures/terumet_invchest_tcha.png b/mods/terumet/textures/terumet_invchest_tcha.png new file mode 100644 index 0000000..138eac3 Binary files /dev/null and b/mods/terumet/textures/terumet_invchest_tcha.png differ diff --git a/mods/terumet/textures/terumet_invchest_tcop.png b/mods/terumet/textures/terumet_invchest_tcop.png new file mode 100644 index 0000000..c86ad66 Binary files /dev/null and b/mods/terumet/textures/terumet_invchest_tcop.png differ diff --git a/mods/terumet/textures/terumet_invchest_tgol.png b/mods/terumet/textures/terumet_invchest_tgol.png new file mode 100644 index 0000000..76a990a Binary files /dev/null and b/mods/terumet/textures/terumet_invchest_tgol.png differ diff --git a/mods/terumet/textures/terumet_invchest_tste.png b/mods/terumet/textures/terumet_invchest_tste.png new file mode 100644 index 0000000..1530b46 Binary files /dev/null and b/mods/terumet/textures/terumet_invchest_tste.png differ diff --git a/mods/terumet/textures/terumet_invchest_ttin.png b/mods/terumet/textures/terumet_invchest_ttin.png new file mode 100644 index 0000000..c83570e Binary files /dev/null and b/mods/terumet/textures/terumet_invchest_ttin.png differ diff --git a/mods/terumet/textures/terumet_invhelm_cgls.png b/mods/terumet/textures/terumet_invhelm_cgls.png new file mode 100644 index 0000000..9bea6c1 Binary files /dev/null and b/mods/terumet/textures/terumet_invhelm_cgls.png differ diff --git a/mods/terumet/textures/terumet_invhelm_rsuit.png b/mods/terumet/textures/terumet_invhelm_rsuit.png new file mode 100644 index 0000000..bc8ca0d Binary files /dev/null and b/mods/terumet/textures/terumet_invhelm_rsuit.png differ diff --git a/mods/terumet/textures/terumet_invhelm_tcha.png b/mods/terumet/textures/terumet_invhelm_tcha.png new file mode 100644 index 0000000..84916f7 Binary files /dev/null and b/mods/terumet/textures/terumet_invhelm_tcha.png differ diff --git a/mods/terumet/textures/terumet_invhelm_tcop.png b/mods/terumet/textures/terumet_invhelm_tcop.png new file mode 100644 index 0000000..77632ab Binary files /dev/null and b/mods/terumet/textures/terumet_invhelm_tcop.png differ diff --git a/mods/terumet/textures/terumet_invhelm_tgol.png b/mods/terumet/textures/terumet_invhelm_tgol.png new file mode 100644 index 0000000..5bbed86 Binary files /dev/null and b/mods/terumet/textures/terumet_invhelm_tgol.png differ diff --git a/mods/terumet/textures/terumet_invhelm_tste.png b/mods/terumet/textures/terumet_invhelm_tste.png new file mode 100644 index 0000000..4a2c330 Binary files /dev/null and b/mods/terumet/textures/terumet_invhelm_tste.png differ diff --git a/mods/terumet/textures/terumet_invhelm_ttin.png b/mods/terumet/textures/terumet_invhelm_ttin.png new file mode 100644 index 0000000..e67bd02 Binary files /dev/null and b/mods/terumet/textures/terumet_invhelm_ttin.png differ diff --git a/mods/terumet/textures/terumet_invlegs_cgls.png b/mods/terumet/textures/terumet_invlegs_cgls.png new file mode 100644 index 0000000..d80e3a3 Binary files /dev/null and b/mods/terumet/textures/terumet_invlegs_cgls.png differ diff --git a/mods/terumet/textures/terumet_invlegs_rsuit.png b/mods/terumet/textures/terumet_invlegs_rsuit.png new file mode 100644 index 0000000..05dd162 Binary files /dev/null and b/mods/terumet/textures/terumet_invlegs_rsuit.png differ diff --git a/mods/terumet/textures/terumet_invlegs_tcha.png b/mods/terumet/textures/terumet_invlegs_tcha.png new file mode 100644 index 0000000..4154e6c Binary files /dev/null and b/mods/terumet/textures/terumet_invlegs_tcha.png differ diff --git a/mods/terumet/textures/terumet_invlegs_tcop.png b/mods/terumet/textures/terumet_invlegs_tcop.png new file mode 100644 index 0000000..cf20856 Binary files /dev/null and b/mods/terumet/textures/terumet_invlegs_tcop.png differ diff --git a/mods/terumet/textures/terumet_invlegs_tgol.png b/mods/terumet/textures/terumet_invlegs_tgol.png new file mode 100644 index 0000000..f744073 Binary files /dev/null and b/mods/terumet/textures/terumet_invlegs_tgol.png differ diff --git a/mods/terumet/textures/terumet_invlegs_tste.png b/mods/terumet/textures/terumet_invlegs_tste.png new file mode 100644 index 0000000..76a9049 Binary files /dev/null and b/mods/terumet/textures/terumet_invlegs_tste.png differ diff --git a/mods/terumet/textures/terumet_invlegs_ttin.png b/mods/terumet/textures/terumet_invlegs_ttin.png new file mode 100644 index 0000000..aa328cb Binary files /dev/null and b/mods/terumet/textures/terumet_invlegs_ttin.png differ diff --git a/mods/terumet/textures/terumet_item_batt_cop.png b/mods/terumet/textures/terumet_item_batt_cop.png new file mode 100644 index 0000000..bb8d377 Binary files /dev/null and b/mods/terumet/textures/terumet_item_batt_cop.png differ diff --git a/mods/terumet/textures/terumet_item_batt_cop_full.png b/mods/terumet/textures/terumet_item_batt_cop_full.png new file mode 100644 index 0000000..9c65e2c Binary files /dev/null and b/mods/terumet/textures/terumet_item_batt_cop_full.png differ diff --git a/mods/terumet/textures/terumet_item_batt_therm.png b/mods/terumet/textures/terumet_item_batt_therm.png new file mode 100644 index 0000000..5717b07 Binary files /dev/null and b/mods/terumet/textures/terumet_item_batt_therm.png differ diff --git a/mods/terumet/textures/terumet_item_batt_therm_full.png b/mods/terumet/textures/terumet_item_batt_therm_full.png new file mode 100644 index 0000000..4c1ea4b Binary files /dev/null and b/mods/terumet/textures/terumet_item_batt_therm_full.png differ diff --git a/mods/terumet/textures/terumet_item_batt_void.png b/mods/terumet/textures/terumet_item_batt_void.png new file mode 100644 index 0000000..4da166a Binary files /dev/null and b/mods/terumet/textures/terumet_item_batt_void.png differ diff --git a/mods/terumet/textures/terumet_item_brcrcrys.png b/mods/terumet/textures/terumet_item_brcrcrys.png new file mode 100644 index 0000000..72cbc2d Binary files /dev/null and b/mods/terumet/textures/terumet_item_brcrcrys.png differ diff --git a/mods/terumet/textures/terumet_item_ceramic.png b/mods/terumet/textures/terumet_item_ceramic.png new file mode 100644 index 0000000..75c62d1 Binary files /dev/null and b/mods/terumet/textures/terumet_item_ceramic.png differ diff --git a/mods/terumet/textures/terumet_item_coil_raw.png b/mods/terumet/textures/terumet_item_coil_raw.png new file mode 100644 index 0000000..d971873 Binary files /dev/null and b/mods/terumet/textures/terumet_item_coil_raw.png differ diff --git a/mods/terumet/textures/terumet_item_coil_tcop.png b/mods/terumet/textures/terumet_item_coil_tcop.png new file mode 100644 index 0000000..686e288 Binary files /dev/null and b/mods/terumet/textures/terumet_item_coil_tcop.png differ diff --git a/mods/terumet/textures/terumet_item_coil_tgol.png b/mods/terumet/textures/terumet_item_coil_tgol.png new file mode 100644 index 0000000..4b4f847 Binary files /dev/null and b/mods/terumet/textures/terumet_item_coil_tgol.png differ diff --git a/mods/terumet/textures/terumet_item_coke.png b/mods/terumet/textures/terumet_item_coke.png new file mode 100644 index 0000000..17377e7 Binary files /dev/null and b/mods/terumet/textures/terumet_item_coke.png differ diff --git a/mods/terumet/textures/terumet_item_cryscham.png b/mods/terumet/textures/terumet_item_cryscham.png new file mode 100644 index 0000000..266d187 Binary files /dev/null and b/mods/terumet/textures/terumet_item_cryscham.png differ diff --git a/mods/terumet/textures/terumet_item_cryst.png b/mods/terumet/textures/terumet_item_cryst.png new file mode 100644 index 0000000..0137b4f Binary files /dev/null and b/mods/terumet/textures/terumet_item_cryst.png differ diff --git a/mods/terumet/textures/terumet_item_dust_bio.png b/mods/terumet/textures/terumet_item_dust_bio.png new file mode 100644 index 0000000..3b704f2 Binary files /dev/null and b/mods/terumet/textures/terumet_item_dust_bio.png differ diff --git a/mods/terumet/textures/terumet_item_dust_ob.png b/mods/terumet/textures/terumet_item_dust_ob.png new file mode 100644 index 0000000..35a4889 Binary files /dev/null and b/mods/terumet/textures/terumet_item_dust_ob.png differ diff --git a/mods/terumet/textures/terumet_item_dust_wood.png b/mods/terumet/textures/terumet_item_dust_wood.png new file mode 100644 index 0000000..493b769 Binary files /dev/null and b/mods/terumet/textures/terumet_item_dust_wood.png differ diff --git a/mods/terumet/textures/terumet_item_entropy.png b/mods/terumet/textures/terumet_item_entropy.png new file mode 100644 index 0000000..811cb9d Binary files /dev/null and b/mods/terumet/textures/terumet_item_entropy.png differ diff --git a/mods/terumet/textures/terumet_item_glue.png b/mods/terumet/textures/terumet_item_glue.png new file mode 100644 index 0000000..4db6482 Binary files /dev/null and b/mods/terumet/textures/terumet_item_glue.png differ diff --git a/mods/terumet/textures/terumet_item_heatunit.png b/mods/terumet/textures/terumet_item_heatunit.png new file mode 100644 index 0000000..c94053a Binary files /dev/null and b/mods/terumet/textures/terumet_item_heatunit.png differ diff --git a/mods/terumet/textures/terumet_item_htg.png b/mods/terumet/textures/terumet_item_htg.png new file mode 100644 index 0000000..2bc7eda Binary files /dev/null and b/mods/terumet/textures/terumet_item_htg.png differ diff --git a/mods/terumet/textures/terumet_item_htglass.png b/mods/terumet/textures/terumet_item_htglass.png new file mode 100644 index 0000000..e4fe3e9 Binary files /dev/null and b/mods/terumet/textures/terumet_item_htglass.png differ diff --git a/mods/terumet/textures/terumet_item_prerub.png b/mods/terumet/textures/terumet_item_prerub.png new file mode 100644 index 0000000..476d9ae Binary files /dev/null and b/mods/terumet/textures/terumet_item_prerub.png differ diff --git a/mods/terumet/textures/terumet_item_press.png b/mods/terumet/textures/terumet_item_press.png new file mode 100644 index 0000000..d3919a5 Binary files /dev/null and b/mods/terumet/textures/terumet_item_press.png differ diff --git a/mods/terumet/textures/terumet_item_rebar.png b/mods/terumet/textures/terumet_item_rebar.png new file mode 100644 index 0000000..44c34e0 Binary files /dev/null and b/mods/terumet/textures/terumet_item_rebar.png differ diff --git a/mods/terumet/textures/terumet_item_rsuitmat.png b/mods/terumet/textures/terumet_item_rsuitmat.png new file mode 100644 index 0000000..367ba0c Binary files /dev/null and b/mods/terumet/textures/terumet_item_rsuitmat.png differ diff --git a/mods/terumet/textures/terumet_item_rubber.png b/mods/terumet/textures/terumet_item_rubber.png new file mode 100644 index 0000000..84af038 Binary files /dev/null and b/mods/terumet/textures/terumet_item_rubber.png differ diff --git a/mods/terumet/textures/terumet_item_tarball.png b/mods/terumet/textures/terumet_item_tarball.png new file mode 100644 index 0000000..be78010 Binary files /dev/null and b/mods/terumet/textures/terumet_item_tarball.png differ diff --git a/mods/terumet/textures/terumet_item_thermese.png b/mods/terumet/textures/terumet_item_thermese.png new file mode 100644 index 0000000..ced5dd6 Binary files /dev/null and b/mods/terumet/textures/terumet_item_thermese.png differ diff --git a/mods/terumet/textures/terumet_item_vacfood.png b/mods/terumet/textures/terumet_item_vacfood.png new file mode 100644 index 0000000..9bebe5d Binary files /dev/null and b/mods/terumet/textures/terumet_item_vacfood.png differ diff --git a/mods/terumet/textures/terumet_lavam_front_lit.png b/mods/terumet/textures/terumet_lavam_front_lit.png new file mode 100644 index 0000000..c706dc2 Binary files /dev/null and b/mods/terumet/textures/terumet_lavam_front_lit.png differ diff --git a/mods/terumet/textures/terumet_lavam_front_unlit.png b/mods/terumet/textures/terumet_lavam_front_unlit.png new file mode 100644 index 0000000..983d3d5 Binary files /dev/null and b/mods/terumet/textures/terumet_lavam_front_unlit.png differ diff --git a/mods/terumet/textures/terumet_lavam_top.png b/mods/terumet/textures/terumet_lavam_top.png new file mode 100644 index 0000000..89db4e1 Binary files /dev/null and b/mods/terumet/textures/terumet_lavam_top.png differ diff --git a/mods/terumet/textures/terumet_lump_raw.png b/mods/terumet/textures/terumet_lump_raw.png new file mode 100644 index 0000000..8843f01 Binary files /dev/null and b/mods/terumet/textures/terumet_lump_raw.png differ diff --git a/mods/terumet/textures/terumet_meseg_top.png b/mods/terumet/textures/terumet_meseg_top.png new file mode 100644 index 0000000..70226fc Binary files /dev/null and b/mods/terumet/textures/terumet_meseg_top.png differ diff --git a/mods/terumet/textures/terumet_ore_dense_raw.png b/mods/terumet/textures/terumet_ore_dense_raw.png new file mode 100644 index 0000000..e8c65d1 Binary files /dev/null and b/mods/terumet/textures/terumet_ore_dense_raw.png differ diff --git a/mods/terumet/textures/terumet_ore_raw.png b/mods/terumet/textures/terumet_ore_raw.png new file mode 100644 index 0000000..0979279 Binary files /dev/null and b/mods/terumet/textures/terumet_ore_raw.png differ diff --git a/mods/terumet/textures/terumet_part_entropy.png b/mods/terumet/textures/terumet_part_entropy.png new file mode 100644 index 0000000..c99acbc Binary files /dev/null and b/mods/terumet/textures/terumet_part_entropy.png differ diff --git a/mods/terumet/textures/terumet_part_ray.png b/mods/terumet/textures/terumet_part_ray.png new file mode 100644 index 0000000..613aa88 Binary files /dev/null and b/mods/terumet/textures/terumet_part_ray.png differ diff --git a/mods/terumet/textures/terumet_part_seedbreak.png b/mods/terumet/textures/terumet_part_seedbreak.png new file mode 100644 index 0000000..13b40a4 Binary files /dev/null and b/mods/terumet/textures/terumet_part_seedbreak.png differ diff --git a/mods/terumet/textures/terumet_part_seek.png b/mods/terumet/textures/terumet_part_seek.png new file mode 100644 index 0000000..4ef7937 Binary files /dev/null and b/mods/terumet/textures/terumet_part_seek.png differ diff --git a/mods/terumet/textures/terumet_part_smoke1.png b/mods/terumet/textures/terumet_part_smoke1.png new file mode 100644 index 0000000..073922c Binary files /dev/null and b/mods/terumet/textures/terumet_part_smoke1.png differ diff --git a/mods/terumet/textures/terumet_part_smoke2.png b/mods/terumet/textures/terumet_part_smoke2.png new file mode 100644 index 0000000..995e577 Binary files /dev/null and b/mods/terumet/textures/terumet_part_smoke2.png differ diff --git a/mods/terumet/textures/terumet_part_smoke3.png b/mods/terumet/textures/terumet_part_smoke3.png new file mode 100644 index 0000000..7372156 Binary files /dev/null and b/mods/terumet/textures/terumet_part_smoke3.png differ diff --git a/mods/terumet/textures/terumet_pebble_tin.png b/mods/terumet/textures/terumet_pebble_tin.png new file mode 100644 index 0000000..39d009c Binary files /dev/null and b/mods/terumet/textures/terumet_pebble_tin.png differ diff --git a/mods/terumet/textures/terumet_prvboots_cgls.png b/mods/terumet/textures/terumet_prvboots_cgls.png new file mode 100644 index 0000000..c083a48 Binary files /dev/null and b/mods/terumet/textures/terumet_prvboots_cgls.png differ diff --git a/mods/terumet/textures/terumet_prvboots_rsuit.png b/mods/terumet/textures/terumet_prvboots_rsuit.png new file mode 100644 index 0000000..9d8be7c Binary files /dev/null and b/mods/terumet/textures/terumet_prvboots_rsuit.png differ diff --git a/mods/terumet/textures/terumet_prvboots_tcha.png b/mods/terumet/textures/terumet_prvboots_tcha.png new file mode 100644 index 0000000..a511f66 Binary files /dev/null and b/mods/terumet/textures/terumet_prvboots_tcha.png differ diff --git a/mods/terumet/textures/terumet_prvboots_tcop.png b/mods/terumet/textures/terumet_prvboots_tcop.png new file mode 100644 index 0000000..e1279f3 Binary files /dev/null and b/mods/terumet/textures/terumet_prvboots_tcop.png differ diff --git a/mods/terumet/textures/terumet_prvboots_tgol.png b/mods/terumet/textures/terumet_prvboots_tgol.png new file mode 100644 index 0000000..f77f9f3 Binary files /dev/null and b/mods/terumet/textures/terumet_prvboots_tgol.png differ diff --git a/mods/terumet/textures/terumet_prvboots_tste.png b/mods/terumet/textures/terumet_prvboots_tste.png new file mode 100644 index 0000000..5237d79 Binary files /dev/null and b/mods/terumet/textures/terumet_prvboots_tste.png differ diff --git a/mods/terumet/textures/terumet_prvboots_ttin.png b/mods/terumet/textures/terumet_prvboots_ttin.png new file mode 100644 index 0000000..eb8cd77 Binary files /dev/null and b/mods/terumet/textures/terumet_prvboots_ttin.png differ diff --git a/mods/terumet/textures/terumet_prvbrcr_agv.png b/mods/terumet/textures/terumet_prvbrcr_agv.png new file mode 100644 index 0000000..900c3b6 Binary files /dev/null and b/mods/terumet/textures/terumet_prvbrcr_agv.png differ diff --git a/mods/terumet/textures/terumet_prvbrcr_aqua.png b/mods/terumet/textures/terumet_prvbrcr_aqua.png new file mode 100644 index 0000000..eb3e1b8 Binary files /dev/null and b/mods/terumet/textures/terumet_prvbrcr_aqua.png differ diff --git a/mods/terumet/textures/terumet_prvbrcr_base.png b/mods/terumet/textures/terumet_prvbrcr_base.png new file mode 100644 index 0000000..b835b43 Binary files /dev/null and b/mods/terumet/textures/terumet_prvbrcr_base.png differ diff --git a/mods/terumet/textures/terumet_prvbrcr_def.png b/mods/terumet/textures/terumet_prvbrcr_def.png new file mode 100644 index 0000000..49835e9 Binary files /dev/null and b/mods/terumet/textures/terumet_prvbrcr_def.png differ diff --git a/mods/terumet/textures/terumet_prvbrcr_fire.png b/mods/terumet/textures/terumet_prvbrcr_fire.png new file mode 100644 index 0000000..7783e67 Binary files /dev/null and b/mods/terumet/textures/terumet_prvbrcr_fire.png differ diff --git a/mods/terumet/textures/terumet_prvbrcr_heal.png b/mods/terumet/textures/terumet_prvbrcr_heal.png new file mode 100644 index 0000000..15a9468 Binary files /dev/null and b/mods/terumet/textures/terumet_prvbrcr_heal.png differ diff --git a/mods/terumet/textures/terumet_prvbrcr_jump.png b/mods/terumet/textures/terumet_prvbrcr_jump.png new file mode 100644 index 0000000..dc761fd Binary files /dev/null and b/mods/terumet/textures/terumet_prvbrcr_jump.png differ diff --git a/mods/terumet/textures/terumet_prvbrcr_spd.png b/mods/terumet/textures/terumet_prvbrcr_spd.png new file mode 100644 index 0000000..c370770 Binary files /dev/null and b/mods/terumet/textures/terumet_prvbrcr_spd.png differ diff --git a/mods/terumet/textures/terumet_prvchest_cgls.png b/mods/terumet/textures/terumet_prvchest_cgls.png new file mode 100644 index 0000000..7263ba2 Binary files /dev/null and b/mods/terumet/textures/terumet_prvchest_cgls.png differ diff --git a/mods/terumet/textures/terumet_prvchest_rsuit.png b/mods/terumet/textures/terumet_prvchest_rsuit.png new file mode 100644 index 0000000..f7b865f Binary files /dev/null and b/mods/terumet/textures/terumet_prvchest_rsuit.png differ diff --git a/mods/terumet/textures/terumet_prvchest_tcha.png b/mods/terumet/textures/terumet_prvchest_tcha.png new file mode 100644 index 0000000..01087b4 Binary files /dev/null and b/mods/terumet/textures/terumet_prvchest_tcha.png differ diff --git a/mods/terumet/textures/terumet_prvchest_tcop.png b/mods/terumet/textures/terumet_prvchest_tcop.png new file mode 100644 index 0000000..64d36ae Binary files /dev/null and b/mods/terumet/textures/terumet_prvchest_tcop.png differ diff --git a/mods/terumet/textures/terumet_prvchest_tgol.png b/mods/terumet/textures/terumet_prvchest_tgol.png new file mode 100644 index 0000000..f3b121f Binary files /dev/null and b/mods/terumet/textures/terumet_prvchest_tgol.png differ diff --git a/mods/terumet/textures/terumet_prvchest_tste.png b/mods/terumet/textures/terumet_prvchest_tste.png new file mode 100644 index 0000000..1963f65 Binary files /dev/null and b/mods/terumet/textures/terumet_prvchest_tste.png differ diff --git a/mods/terumet/textures/terumet_prvchest_ttin.png b/mods/terumet/textures/terumet_prvchest_ttin.png new file mode 100644 index 0000000..5517f97 Binary files /dev/null and b/mods/terumet/textures/terumet_prvchest_ttin.png differ diff --git a/mods/terumet/textures/terumet_prvhelm_cgls.png b/mods/terumet/textures/terumet_prvhelm_cgls.png new file mode 100644 index 0000000..6cc6dff Binary files /dev/null and b/mods/terumet/textures/terumet_prvhelm_cgls.png differ diff --git a/mods/terumet/textures/terumet_prvhelm_rsuit.png b/mods/terumet/textures/terumet_prvhelm_rsuit.png new file mode 100644 index 0000000..4c7aa8f Binary files /dev/null and b/mods/terumet/textures/terumet_prvhelm_rsuit.png differ diff --git a/mods/terumet/textures/terumet_prvhelm_tcha.png b/mods/terumet/textures/terumet_prvhelm_tcha.png new file mode 100644 index 0000000..e31a0a1 Binary files /dev/null and b/mods/terumet/textures/terumet_prvhelm_tcha.png differ diff --git a/mods/terumet/textures/terumet_prvhelm_tcop.png b/mods/terumet/textures/terumet_prvhelm_tcop.png new file mode 100644 index 0000000..881a061 Binary files /dev/null and b/mods/terumet/textures/terumet_prvhelm_tcop.png differ diff --git a/mods/terumet/textures/terumet_prvhelm_tgol.png b/mods/terumet/textures/terumet_prvhelm_tgol.png new file mode 100644 index 0000000..e960ef8 Binary files /dev/null and b/mods/terumet/textures/terumet_prvhelm_tgol.png differ diff --git a/mods/terumet/textures/terumet_prvhelm_tste.png b/mods/terumet/textures/terumet_prvhelm_tste.png new file mode 100644 index 0000000..18bf9cb Binary files /dev/null and b/mods/terumet/textures/terumet_prvhelm_tste.png differ diff --git a/mods/terumet/textures/terumet_prvhelm_ttin.png b/mods/terumet/textures/terumet_prvhelm_ttin.png new file mode 100644 index 0000000..82f0dc8 Binary files /dev/null and b/mods/terumet/textures/terumet_prvhelm_ttin.png differ diff --git a/mods/terumet/textures/terumet_prvlegs_cgls.png b/mods/terumet/textures/terumet_prvlegs_cgls.png new file mode 100644 index 0000000..64ca0ba Binary files /dev/null and b/mods/terumet/textures/terumet_prvlegs_cgls.png differ diff --git a/mods/terumet/textures/terumet_prvlegs_rsuit.png b/mods/terumet/textures/terumet_prvlegs_rsuit.png new file mode 100644 index 0000000..5bbe1c7 Binary files /dev/null and b/mods/terumet/textures/terumet_prvlegs_rsuit.png differ diff --git a/mods/terumet/textures/terumet_prvlegs_tcha.png b/mods/terumet/textures/terumet_prvlegs_tcha.png new file mode 100644 index 0000000..f4c13cd Binary files /dev/null and b/mods/terumet/textures/terumet_prvlegs_tcha.png differ diff --git a/mods/terumet/textures/terumet_prvlegs_tcop.png b/mods/terumet/textures/terumet_prvlegs_tcop.png new file mode 100644 index 0000000..c1a9b2b Binary files /dev/null and b/mods/terumet/textures/terumet_prvlegs_tcop.png differ diff --git a/mods/terumet/textures/terumet_prvlegs_tgol.png b/mods/terumet/textures/terumet_prvlegs_tgol.png new file mode 100644 index 0000000..ba35789 Binary files /dev/null and b/mods/terumet/textures/terumet_prvlegs_tgol.png differ diff --git a/mods/terumet/textures/terumet_prvlegs_tste.png b/mods/terumet/textures/terumet_prvlegs_tste.png new file mode 100644 index 0000000..05772be Binary files /dev/null and b/mods/terumet/textures/terumet_prvlegs_tste.png differ diff --git a/mods/terumet/textures/terumet_prvlegs_ttin.png b/mods/terumet/textures/terumet_prvlegs_ttin.png new file mode 100644 index 0000000..5a90041 Binary files /dev/null and b/mods/terumet/textures/terumet_prvlegs_ttin.png differ diff --git a/mods/terumet/textures/terumet_raw_heater_sides.png b/mods/terumet/textures/terumet_raw_heater_sides.png new file mode 100644 index 0000000..7556829 Binary files /dev/null and b/mods/terumet/textures/terumet_raw_heater_sides.png differ diff --git a/mods/terumet/textures/terumet_raw_mach_bot.png b/mods/terumet/textures/terumet_raw_mach_bot.png new file mode 100644 index 0000000..ed0d975 Binary files /dev/null and b/mods/terumet/textures/terumet_raw_mach_bot.png differ diff --git a/mods/terumet/textures/terumet_raw_mach_top.png b/mods/terumet/textures/terumet_raw_mach_top.png new file mode 100644 index 0000000..12ac83e Binary files /dev/null and b/mods/terumet/textures/terumet_raw_mach_top.png differ diff --git a/mods/terumet/textures/terumet_raw_sides_lit.png b/mods/terumet/textures/terumet_raw_sides_lit.png new file mode 100644 index 0000000..489c19a Binary files /dev/null and b/mods/terumet/textures/terumet_raw_sides_lit.png differ diff --git a/mods/terumet/textures/terumet_raw_sides_unlit.png b/mods/terumet/textures/terumet_raw_sides_unlit.png new file mode 100644 index 0000000..822d4ac Binary files /dev/null and b/mods/terumet/textures/terumet_raw_sides_unlit.png differ diff --git a/mods/terumet/textures/terumet_rayref_back.png b/mods/terumet/textures/terumet_rayref_back.png new file mode 100644 index 0000000..aa89f5c Binary files /dev/null and b/mods/terumet/textures/terumet_rayref_back.png differ diff --git a/mods/terumet/textures/terumet_rayref_front.png b/mods/terumet/textures/terumet_rayref_front.png new file mode 100644 index 0000000..c37dd4f Binary files /dev/null and b/mods/terumet/textures/terumet_rayref_front.png differ diff --git a/mods/terumet/textures/terumet_rayref_sides.png b/mods/terumet/textures/terumet_rayref_sides.png new file mode 100644 index 0000000..209050a Binary files /dev/null and b/mods/terumet/textures/terumet_rayref_sides.png differ diff --git a/mods/terumet/textures/terumet_repm_front.png b/mods/terumet/textures/terumet_repm_front.png new file mode 100644 index 0000000..5f9a4c4 Binary files /dev/null and b/mods/terumet/textures/terumet_repm_front.png differ diff --git a/mods/terumet/textures/terumet_tbox_back.png b/mods/terumet/textures/terumet_tbox_back.png new file mode 100644 index 0000000..594c0de Binary files /dev/null and b/mods/terumet/textures/terumet_tbox_back.png differ diff --git a/mods/terumet/textures/terumet_tbox_front.png b/mods/terumet/textures/terumet_tbox_front.png new file mode 100644 index 0000000..e8e83ec Binary files /dev/null and b/mods/terumet/textures/terumet_tbox_front.png differ diff --git a/mods/terumet/textures/terumet_tbox_sides.png b/mods/terumet/textures/terumet_tbox_sides.png new file mode 100644 index 0000000..d47bf06 Binary files /dev/null and b/mods/terumet/textures/terumet_tbox_sides.png differ diff --git a/mods/terumet/textures/terumet_tdis_back.png b/mods/terumet/textures/terumet_tdis_back.png new file mode 100644 index 0000000..ac05a6f Binary files /dev/null and b/mods/terumet/textures/terumet_tdis_back.png differ diff --git a/mods/terumet/textures/terumet_tdis_front.png b/mods/terumet/textures/terumet_tdis_front.png new file mode 100644 index 0000000..3398ab9 Binary files /dev/null and b/mods/terumet/textures/terumet_tdis_front.png differ diff --git a/mods/terumet/textures/terumet_tdis_sides.png b/mods/terumet/textures/terumet_tdis_sides.png new file mode 100644 index 0000000..0d171e3 Binary files /dev/null and b/mods/terumet/textures/terumet_tdis_sides.png differ diff --git a/mods/terumet/textures/terumet_tool_axe_cgls.png b/mods/terumet/textures/terumet_tool_axe_cgls.png new file mode 100644 index 0000000..2ef85d2 Binary files /dev/null and b/mods/terumet/textures/terumet_tool_axe_cgls.png differ diff --git a/mods/terumet/textures/terumet_tool_axe_raw.png b/mods/terumet/textures/terumet_tool_axe_raw.png new file mode 100644 index 0000000..5ca76df Binary files /dev/null and b/mods/terumet/textures/terumet_tool_axe_raw.png differ diff --git a/mods/terumet/textures/terumet_tool_axe_tcha.png b/mods/terumet/textures/terumet_tool_axe_tcha.png new file mode 100644 index 0000000..4c82f06 Binary files /dev/null and b/mods/terumet/textures/terumet_tool_axe_tcha.png differ diff --git a/mods/terumet/textures/terumet_tool_axe_tcop.png b/mods/terumet/textures/terumet_tool_axe_tcop.png new file mode 100644 index 0000000..0af00c1 Binary files /dev/null and b/mods/terumet/textures/terumet_tool_axe_tcop.png differ diff --git a/mods/terumet/textures/terumet_tool_axe_tgol.png b/mods/terumet/textures/terumet_tool_axe_tgol.png new file mode 100644 index 0000000..e586974 Binary files /dev/null and b/mods/terumet/textures/terumet_tool_axe_tgol.png differ diff --git a/mods/terumet/textures/terumet_tool_axe_tste.png b/mods/terumet/textures/terumet_tool_axe_tste.png new file mode 100644 index 0000000..f0c64a3 Binary files /dev/null and b/mods/terumet/textures/terumet_tool_axe_tste.png differ diff --git a/mods/terumet/textures/terumet_tool_meson.png b/mods/terumet/textures/terumet_tool_meson.png new file mode 100644 index 0000000..9f122e0 Binary files /dev/null and b/mods/terumet/textures/terumet_tool_meson.png differ diff --git a/mods/terumet/textures/terumet_tool_ore_saw.png b/mods/terumet/textures/terumet_tool_ore_saw.png new file mode 100644 index 0000000..7e03230 Binary files /dev/null and b/mods/terumet/textures/terumet_tool_ore_saw.png differ diff --git a/mods/terumet/textures/terumet_tool_ore_saw_adv.png b/mods/terumet/textures/terumet_tool_ore_saw_adv.png new file mode 100644 index 0000000..daade60 Binary files /dev/null and b/mods/terumet/textures/terumet_tool_ore_saw_adv.png differ diff --git a/mods/terumet/textures/terumet_tool_pick_cgls.png b/mods/terumet/textures/terumet_tool_pick_cgls.png new file mode 100644 index 0000000..5755820 Binary files /dev/null and b/mods/terumet/textures/terumet_tool_pick_cgls.png differ diff --git a/mods/terumet/textures/terumet_tool_pick_raw.png b/mods/terumet/textures/terumet_tool_pick_raw.png new file mode 100644 index 0000000..4275a44 Binary files /dev/null and b/mods/terumet/textures/terumet_tool_pick_raw.png differ diff --git a/mods/terumet/textures/terumet_tool_pick_tcha.png b/mods/terumet/textures/terumet_tool_pick_tcha.png new file mode 100644 index 0000000..a3e88db Binary files /dev/null and b/mods/terumet/textures/terumet_tool_pick_tcha.png differ diff --git a/mods/terumet/textures/terumet_tool_pick_tcop.png b/mods/terumet/textures/terumet_tool_pick_tcop.png new file mode 100644 index 0000000..cba16a1 Binary files /dev/null and b/mods/terumet/textures/terumet_tool_pick_tcop.png differ diff --git a/mods/terumet/textures/terumet_tool_pick_tgol.png b/mods/terumet/textures/terumet_tool_pick_tgol.png new file mode 100644 index 0000000..275e970 Binary files /dev/null and b/mods/terumet/textures/terumet_tool_pick_tgol.png differ diff --git a/mods/terumet/textures/terumet_tool_pick_tste.png b/mods/terumet/textures/terumet_tool_pick_tste.png new file mode 100644 index 0000000..e6d7c1e Binary files /dev/null and b/mods/terumet/textures/terumet_tool_pick_tste.png differ diff --git a/mods/terumet/textures/terumet_tool_shovel_cgls.png b/mods/terumet/textures/terumet_tool_shovel_cgls.png new file mode 100644 index 0000000..e9e8b09 Binary files /dev/null and b/mods/terumet/textures/terumet_tool_shovel_cgls.png differ diff --git a/mods/terumet/textures/terumet_tool_shovel_raw.png b/mods/terumet/textures/terumet_tool_shovel_raw.png new file mode 100644 index 0000000..3fe665a Binary files /dev/null and b/mods/terumet/textures/terumet_tool_shovel_raw.png differ diff --git a/mods/terumet/textures/terumet_tool_shovel_tcha.png b/mods/terumet/textures/terumet_tool_shovel_tcha.png new file mode 100644 index 0000000..35cb857 Binary files /dev/null and b/mods/terumet/textures/terumet_tool_shovel_tcha.png differ diff --git a/mods/terumet/textures/terumet_tool_shovel_tcop.png b/mods/terumet/textures/terumet_tool_shovel_tcop.png new file mode 100644 index 0000000..0523730 Binary files /dev/null and b/mods/terumet/textures/terumet_tool_shovel_tcop.png differ diff --git a/mods/terumet/textures/terumet_tool_shovel_tgol.png b/mods/terumet/textures/terumet_tool_shovel_tgol.png new file mode 100644 index 0000000..685e047 Binary files /dev/null and b/mods/terumet/textures/terumet_tool_shovel_tgol.png differ diff --git a/mods/terumet/textures/terumet_tool_shovel_tste.png b/mods/terumet/textures/terumet_tool_shovel_tste.png new file mode 100644 index 0000000..af4fbab Binary files /dev/null and b/mods/terumet/textures/terumet_tool_shovel_tste.png differ diff --git a/mods/terumet/textures/terumet_tool_sword_cgls.png b/mods/terumet/textures/terumet_tool_sword_cgls.png new file mode 100644 index 0000000..11fcd50 Binary files /dev/null and b/mods/terumet/textures/terumet_tool_sword_cgls.png differ diff --git a/mods/terumet/textures/terumet_tool_sword_raw.png b/mods/terumet/textures/terumet_tool_sword_raw.png new file mode 100644 index 0000000..fdad39b Binary files /dev/null and b/mods/terumet/textures/terumet_tool_sword_raw.png differ diff --git a/mods/terumet/textures/terumet_tool_sword_tcha.png b/mods/terumet/textures/terumet_tool_sword_tcha.png new file mode 100644 index 0000000..b3b4cb5 Binary files /dev/null and b/mods/terumet/textures/terumet_tool_sword_tcha.png differ diff --git a/mods/terumet/textures/terumet_tool_sword_tcop.png b/mods/terumet/textures/terumet_tool_sword_tcop.png new file mode 100644 index 0000000..ed59632 Binary files /dev/null and b/mods/terumet/textures/terumet_tool_sword_tcop.png differ diff --git a/mods/terumet/textures/terumet_tool_sword_tgol.png b/mods/terumet/textures/terumet_tool_sword_tgol.png new file mode 100644 index 0000000..894f2d9 Binary files /dev/null and b/mods/terumet/textures/terumet_tool_sword_tgol.png differ diff --git a/mods/terumet/textures/terumet_tool_sword_tste.png b/mods/terumet/textures/terumet_tool_sword_tste.png new file mode 100644 index 0000000..10b57de Binary files /dev/null and b/mods/terumet/textures/terumet_tool_sword_tste.png differ diff --git a/mods/terumet/textures/terumet_toolup_axe_dur.png b/mods/terumet/textures/terumet_toolup_axe_dur.png new file mode 100644 index 0000000..1a75472 Binary files /dev/null and b/mods/terumet/textures/terumet_toolup_axe_dur.png differ diff --git a/mods/terumet/textures/terumet_toolup_axe_rng.png b/mods/terumet/textures/terumet_toolup_axe_rng.png new file mode 100644 index 0000000..87da87e Binary files /dev/null and b/mods/terumet/textures/terumet_toolup_axe_rng.png differ diff --git a/mods/terumet/textures/terumet_toolup_axe_spd.png b/mods/terumet/textures/terumet_toolup_axe_spd.png new file mode 100644 index 0000000..d93b699 Binary files /dev/null and b/mods/terumet/textures/terumet_toolup_axe_spd.png differ diff --git a/mods/terumet/textures/terumet_toolup_pick_dur.png b/mods/terumet/textures/terumet_toolup_pick_dur.png new file mode 100644 index 0000000..8ae2fa0 Binary files /dev/null and b/mods/terumet/textures/terumet_toolup_pick_dur.png differ diff --git a/mods/terumet/textures/terumet_toolup_pick_rng.png b/mods/terumet/textures/terumet_toolup_pick_rng.png new file mode 100644 index 0000000..e56c97b Binary files /dev/null and b/mods/terumet/textures/terumet_toolup_pick_rng.png differ diff --git a/mods/terumet/textures/terumet_toolup_pick_spd.png b/mods/terumet/textures/terumet_toolup_pick_spd.png new file mode 100644 index 0000000..a45c983 Binary files /dev/null and b/mods/terumet/textures/terumet_toolup_pick_spd.png differ diff --git a/mods/terumet/textures/terumet_toolup_shovel_dur.png b/mods/terumet/textures/terumet_toolup_shovel_dur.png new file mode 100644 index 0000000..56044f3 Binary files /dev/null and b/mods/terumet/textures/terumet_toolup_shovel_dur.png differ diff --git a/mods/terumet/textures/terumet_toolup_shovel_rng.png b/mods/terumet/textures/terumet_toolup_shovel_rng.png new file mode 100644 index 0000000..007c141 Binary files /dev/null and b/mods/terumet/textures/terumet_toolup_shovel_rng.png differ diff --git a/mods/terumet/textures/terumet_toolup_shovel_spd.png b/mods/terumet/textures/terumet_toolup_shovel_spd.png new file mode 100644 index 0000000..b27945c Binary files /dev/null and b/mods/terumet/textures/terumet_toolup_shovel_spd.png differ diff --git a/mods/terumet/textures/terumet_toolup_sword_dur.png b/mods/terumet/textures/terumet_toolup_sword_dur.png new file mode 100644 index 0000000..ab6c00c Binary files /dev/null and b/mods/terumet/textures/terumet_toolup_sword_dur.png differ diff --git a/mods/terumet/textures/terumet_toolup_sword_rng.png b/mods/terumet/textures/terumet_toolup_sword_rng.png new file mode 100644 index 0000000..33b8588 Binary files /dev/null and b/mods/terumet/textures/terumet_toolup_sword_rng.png differ diff --git a/mods/terumet/textures/terumet_toolup_sword_spd.png b/mods/terumet/textures/terumet_toolup_sword_spd.png new file mode 100644 index 0000000..a561c8e Binary files /dev/null and b/mods/terumet/textures/terumet_toolup_sword_spd.png differ diff --git a/mods/terumet/textures/terumet_tste_heater_sides.png b/mods/terumet/textures/terumet_tste_heater_sides.png new file mode 100644 index 0000000..471158a Binary files /dev/null and b/mods/terumet/textures/terumet_tste_heater_sides.png differ diff --git a/mods/terumet/textures/terumet_uninv_flux_req.png b/mods/terumet/textures/terumet_uninv_flux_req.png new file mode 100644 index 0000000..6861e7f Binary files /dev/null and b/mods/terumet/textures/terumet_uninv_flux_req.png differ diff --git a/mods/terumet/textures/terumet_uninv_repmat.png b/mods/terumet/textures/terumet_uninv_repmat.png new file mode 100644 index 0000000..4bf1a0d Binary files /dev/null and b/mods/terumet/textures/terumet_uninv_repmat.png differ diff --git a/mods/terumet/textures/terumet_uninv_time_req.png b/mods/terumet/textures/terumet_uninv_time_req.png new file mode 100644 index 0000000..126216f Binary files /dev/null and b/mods/terumet/textures/terumet_uninv_time_req.png differ diff --git a/mods/terumet/textures/terumet_upg_base.png b/mods/terumet/textures/terumet_upg_base.png new file mode 100644 index 0000000..bfe6cd2 Binary files /dev/null and b/mods/terumet/textures/terumet_upg_base.png differ diff --git a/mods/terumet/textures/terumet_upg_cheat.png b/mods/terumet/textures/terumet_upg_cheat.png new file mode 100644 index 0000000..b29ccc4 Binary files /dev/null and b/mods/terumet/textures/terumet_upg_cheat.png differ diff --git a/mods/terumet/textures/terumet_upg_cryst.png b/mods/terumet/textures/terumet_upg_cryst.png new file mode 100644 index 0000000..756df6d Binary files /dev/null and b/mods/terumet/textures/terumet_upg_cryst.png differ diff --git a/mods/terumet/textures/terumet_upg_ext_both.png b/mods/terumet/textures/terumet_upg_ext_both.png new file mode 100644 index 0000000..2cebfe7 Binary files /dev/null and b/mods/terumet/textures/terumet_upg_ext_both.png differ diff --git a/mods/terumet/textures/terumet_upg_ext_input.png b/mods/terumet/textures/terumet_upg_ext_input.png new file mode 100644 index 0000000..d147e21 Binary files /dev/null and b/mods/terumet/textures/terumet_upg_ext_input.png differ diff --git a/mods/terumet/textures/terumet_upg_ext_output.png b/mods/terumet/textures/terumet_upg_ext_output.png new file mode 100644 index 0000000..d3bcfc4 Binary files /dev/null and b/mods/terumet/textures/terumet_upg_ext_output.png differ diff --git a/mods/terumet/textures/terumet_upg_gen_up.png b/mods/terumet/textures/terumet_upg_gen_up.png new file mode 100644 index 0000000..95ce730 Binary files /dev/null and b/mods/terumet/textures/terumet_upg_gen_up.png differ diff --git a/mods/terumet/textures/terumet_upg_heat_xfer.png b/mods/terumet/textures/terumet_upg_heat_xfer.png new file mode 100644 index 0000000..91499a3 Binary files /dev/null and b/mods/terumet/textures/terumet_upg_heat_xfer.png differ diff --git a/mods/terumet/textures/terumet_upg_max_heat.png b/mods/terumet/textures/terumet_upg_max_heat.png new file mode 100644 index 0000000..f1fd853 Binary files /dev/null and b/mods/terumet/textures/terumet_upg_max_heat.png differ diff --git a/mods/terumet/textures/terumet_upg_speed_up.png b/mods/terumet/textures/terumet_upg_speed_up.png new file mode 100644 index 0000000..2d2a923 Binary files /dev/null and b/mods/terumet/textures/terumet_upg_speed_up.png differ diff --git a/mods/terumet/textures/terumet_upg_tmcrys.png b/mods/terumet/textures/terumet_upg_tmcrys.png new file mode 100644 index 0000000..ea6ea0f Binary files /dev/null and b/mods/terumet/textures/terumet_upg_tmcrys.png differ diff --git a/mods/terumet/textures/terumet_upg_tubelib.png b/mods/terumet/textures/terumet_upg_tubelib.png new file mode 100644 index 0000000..c4f015f Binary files /dev/null and b/mods/terumet/textures/terumet_upg_tubelib.png differ diff --git a/mods/terumet/textures/terumet_vacoven_front.png b/mods/terumet/textures/terumet_vacoven_front.png new file mode 100644 index 0000000..f713037 Binary files /dev/null and b/mods/terumet/textures/terumet_vacoven_front.png differ diff --git a/mods/terumet/textures/terumet_vacoven_sides.png b/mods/terumet/textures/terumet_vacoven_sides.png new file mode 100644 index 0000000..08d69c2 Binary files /dev/null and b/mods/terumet/textures/terumet_vacoven_sides.png differ diff --git a/mods/terumet/textures/terumet_vacoven_top.png b/mods/terumet/textures/terumet_vacoven_top.png new file mode 100644 index 0000000..f8767d9 Binary files /dev/null and b/mods/terumet/textures/terumet_vacoven_top.png differ diff --git a/mods/terumet/textures/terumet_vulcan_front.png b/mods/terumet/textures/terumet_vulcan_front.png new file mode 100644 index 0000000..76dea19 Binary files /dev/null and b/mods/terumet/textures/terumet_vulcan_front.png differ diff --git a/mods/terumet/textures/terumet_vulcan_sides.png b/mods/terumet/textures/terumet_vulcan_sides.png new file mode 100644 index 0000000..3dbdf0e Binary files /dev/null and b/mods/terumet/textures/terumet_vulcan_sides.png differ diff --git a/mods/terumet/textures/terumet_vulcan_top.png b/mods/terumet/textures/terumet_vulcan_top.png new file mode 100644 index 0000000..7ad265e Binary files /dev/null and b/mods/terumet/textures/terumet_vulcan_top.png differ diff --git a/mods/terumet/util3d.lua b/mods/terumet/util3d.lua new file mode 100644 index 0000000..94603ae --- /dev/null +++ b/mods/terumet/util3d.lua @@ -0,0 +1,75 @@ +-- Utility functions for dealing with 3D math and node rotations/facing directions + +-- "Facing" is the direction the top of the node points, i.e. the axis the node rotates around with a screwdriver. +-- "Rotation" is the direction the "front" of the node points, i.e. the face that rotates with a screwdriver. + +-- The 6th texture in "tiles" of a facedir-type node is considered the "front" since that +-- is the side that faces the player when placed. + +-- by Terumoc + +local THIS_VERSION = 2 +-- don't overwrite a later version if its already loaded +if minetest.global_exists('util3d') and util3d.version >= THIS_VERSION then return end + +util3d = {} +util3d.version = THIS_VERSION + +-- given a node pos plus another pos/offset, add them together +function util3d.pos_plus(pos, offset) + return { + x=pos.x + offset.x, + y=pos.y + offset.y, + z=pos.z + offset.z, + } +end + +-- given a node pos plus offset, return the offset pos and node there +function util3d.get_offset(pos, offset) + pos = util3d.pos_plus(pos, offset) + return pos, minetest.get_node_or_nil(pos) +end + +-- given a facedir node's param2, return the FACING index +function util3d.param2_to_facing(param2) + return math.floor(param2 / 4) +end + +-- given a facedir node's param2, return the ROTATION index +function util3d.param2_to_rotation(param2) + return param2 % 4 +end + +-- human-readable directions of facings +util3d.FACING_DIRECTION = { + [0]='up', [1]='north', [2]='south', [3]='east', [4]='west', [5]='down' +} + +-- x/y/z offsets for each human-readable direction +util3d.ADJACENT_OFFSETS = { + east={x=1,y=0,z=0}, west={x=-1,y=0,z=0}, + up={x=0,y=1,z=0}, down={x=0,y=-1,z=0}, + north={x=0,y=0,z=1}, south={x=0,y=0,z=-1} +} + +-- auto-generated constants for x/y/z offset in a facing index +-- ex: FACING_OFFSETS[1]: 1 = facing north so returns offset of {x=0,y=0,z=1} (+1 node north) +util3d.FACING_OFFSETS = {} +for facing,dir in pairs(util3d.FACING_DIRECTION) do + util3d.FACING_OFFSETS[facing] = util3d.ADJACENT_OFFSETS[dir] +end + +-- relative x/y/z offset for rotations +util3d.ROTATION_OFFSETS = { + [0]={left={x=-1,y=0,z=0}, right={x=1,y=0,z=0}, front={x=0,y=0,z=-1}, back={x=0,y=0,z=1}, top=util3d.ADJACENT_OFFSETS.up, bottom=util3d.ADJACENT_OFFSETS.down}, + [1]={left={x=0,y=0,z=1}, right={x=0,y=0,z=-1}, front={x=-1,y=0,z=0}, back={x=1,y=0,z=0}, top=util3d.ADJACENT_OFFSETS.up, bottom=util3d.ADJACENT_OFFSETS.down}, + [2]={left={x=1,y=0,z=0}, right={x=-1,y=0,z=0}, front={x=0,y=0,z=1}, back={x=0,y=0,z=-1}, top=util3d.ADJACENT_OFFSETS.up, bottom=util3d.ADJACENT_OFFSETS.down}, + [3]={left={x=0,y=0,z=-1}, right={x=0,y=0,z=1}, front={x=1,y=0,z=0}, back={x=-1,y=0,z=0}, top=util3d.ADJACENT_OFFSETS.up, bottom=util3d.ADJACENT_OFFSETS.down}, +} + +util3d.RELATIVE_SIDES = { 'top', 'bottom', 'left', 'right', 'front', 'back' } + +function util3d.get_relative_pos(rot, pos, rel) + if 'number'==type(rel) then rel = util3d.RELATIVE_SIDES[rel] end + return util3d.pos_plus(pos, util3d.ROTATION_OFFSETS[rot][rel]) +end diff --git a/mods/vessels/README.TXT b/mods/vessels/README.TXT new file mode 100644 index 0000000..873eee3 --- /dev/null +++ b/mods/vessels/README.TXT @@ -0,0 +1,26 @@ +Minetest Game mod: vessels +========================== +See license.txt for license information. + +Authors of source code +---------------------- +Originally by Vanessa Ezekowitz (LGPL v2.1+) +Modified by Perttu Ahola (LGPL v2.1+) +Modified by MCL Software (LGPL v2.1+) +Various Minetest developers and contributors (LGPL v2.1+) + +Authors of media (textures) +--------------------------- +All not listed below, Vanessa Ezekowitz (CC BY-SA 3.0) + +The following textures were modified by Thomas-S (CC BY-SA 3.0): + vessels_drinking_glass.png + vessels_drinking_glass_inv.png + vessels_glass_bottle.png + vessels_steel_bottle.png + +The following texture was created by Wuzzy (CC BY-SA 3.0): + vessels_shelf_slot.png (based on vessels_glass_bottle.png) + +The following texture was created by MCL (CC BY-SA 4.0 International): + vessels_shelf.png diff --git a/mods/vessels/init.lua b/mods/vessels/init.lua new file mode 100644 index 0000000..0ee24f4 --- /dev/null +++ b/mods/vessels/init.lua @@ -0,0 +1,118 @@ +-- vessels/init.lua + +-- Minetest 0.4 mod: vessels +-- See README.TXT for licensing and other information. + + + + + +local function update_vessels_shelf(pos) + local meta = minetest.get_meta(pos) + + + -- Inventory slots overlay + + + + +end + +local vessels_shelf_def = { + description = "Vessels Shelf", + tiles = {"main_planks_oak.png", "main_planks_oak.png", "main_planks_oak.png", + "main_planks_oak.png", "vessels_shelf.png", "main_planks_oak.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + --sounds = default.node_sound_wood_defaults(), + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + update_vessels_shelf(pos) + local inv = meta:get_inventory() + inv:set_size("vessels", 8 * 2) + end, + can_dig = function(pos,player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("vessels") + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if minetest.get_item_group(stack:get_name(), "vessel") ~= 0 then + return stack:get_count() + end + return 0 + end, + on_blast = function(pos) + local drops = {} + --default.get_inventory_drops(pos, "vessels", drops) + drops[#drops + 1] = "vessels:shelf" + minetest.remove_node(pos) + return drops + end, +} +--default.set_inventory_action_loggers(vessels_shelf_def, "vessels shelf") +minetest.register_node("vessels:shelf", vessels_shelf_def) + + +minetest.register_node("vessels:glass_bottle", { + description = "Empty Glass Bottle", + drawtype = "plantlike", + tiles = {"vessels_glass_bottle.png"}, + inventory_image = "vessels_glass_bottle.png", + wield_image = "vessels_glass_bottle.png", + paramtype = "light", + is_ground_content = false, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} + }, + groups = {vessel = 1, dig_immediate = 3, attached_node = 1}, + --sounds = default.node_sound_glass_defaults(), +}) + + +minetest.register_node("vessels:drinking_glass", { + description = "Empty Drinking Glass", + drawtype = "plantlike", + tiles = {"vessels_drinking_glass.png"}, + inventory_image = "vessels_drinking_glass_inv.png", + wield_image = "vessels_drinking_glass.png", + paramtype = "light", + is_ground_content = false, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} + }, + groups = {vessel = 1, dig_immediate = 3, attached_node = 1}, + --sounds = default.node_sound_glass_defaults(), +}) + + +minetest.register_node("vessels:steel_bottle", { + description = "Empty Heavy Steel Bottle", + drawtype = "plantlike", + tiles = {"vessels_steel_bottle.png"}, + inventory_image = "vessels_steel_bottle.png", + wield_image = "vessels_steel_bottle.png", + paramtype = "light", + is_ground_content = false, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} + }, + groups = {vessel = 1, dig_immediate = 3, attached_node = 1}, + --sounds = default.node_sound_defaults(), +}) + + + +-- Glass and steel recycling + +minetest.register_craftitem("vessels:glass_fragments", { + description = "Glass Fragments", + inventory_image = "vessels_glass_fragments.png", +}) diff --git a/mods/vessels/license.txt b/mods/vessels/license.txt new file mode 100644 index 0000000..e72d20c --- /dev/null +++ b/mods/vessels/license.txt @@ -0,0 +1,55 @@ +License of source code +---------------------- + +GNU Lesser General Public License, version 2.1 +Copyright (C) 2012-2016 Vanessa Ezekowitz +Copyright (C) 2012-2016 celeron55, Perttu Ahola +Copyright (C) 2012-2016 Various Minetest developers and contributors +Copyright (C) 2022 MCL + +This program is free software; you can redistribute it and/or modify it under the terms +of the GNU Lesser General Public License as published by the Free Software Foundation; +either version 2.1 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU Lesser General Public License for more details: +https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html + + +Licenses of media (textures) +---------------------------- + +Attribution-ShareAlike 4.0 International (CC BY-SA 4.0 Int'l) + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2012-2016 Vanessa Ezekowitz +Copyright (C) 2016 Thomas-S + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/mods/vessels/mod.conf b/mods/vessels/mod.conf new file mode 100644 index 0000000..49700bc --- /dev/null +++ b/mods/vessels/mod.conf @@ -0,0 +1,3 @@ +name = vessels +description = Vessels mod from MTG modified for Adsurv +depends = main diff --git a/mods/vessels/textures/vessels_drinking_glass.png b/mods/vessels/textures/vessels_drinking_glass.png new file mode 100644 index 0000000..aef7329 Binary files /dev/null and b/mods/vessels/textures/vessels_drinking_glass.png differ diff --git a/mods/vessels/textures/vessels_drinking_glass_inv.png b/mods/vessels/textures/vessels_drinking_glass_inv.png new file mode 100644 index 0000000..e50c8c7 Binary files /dev/null and b/mods/vessels/textures/vessels_drinking_glass_inv.png differ diff --git a/mods/vessels/textures/vessels_glass_bottle.png b/mods/vessels/textures/vessels_glass_bottle.png new file mode 100644 index 0000000..2a46aaf Binary files /dev/null and b/mods/vessels/textures/vessels_glass_bottle.png differ diff --git a/mods/vessels/textures/vessels_glass_fragments.png b/mods/vessels/textures/vessels_glass_fragments.png new file mode 100644 index 0000000..acf2d38 Binary files /dev/null and b/mods/vessels/textures/vessels_glass_fragments.png differ diff --git a/mods/vessels/textures/vessels_shelf.png b/mods/vessels/textures/vessels_shelf.png new file mode 100644 index 0000000..9dd41a1 Binary files /dev/null and b/mods/vessels/textures/vessels_shelf.png differ diff --git a/mods/vessels/textures/vessels_shelf_slot.png b/mods/vessels/textures/vessels_shelf_slot.png new file mode 100644 index 0000000..93a729e Binary files /dev/null and b/mods/vessels/textures/vessels_shelf_slot.png differ diff --git a/mods/vessels/textures/vessels_steel_bottle.png b/mods/vessels/textures/vessels_steel_bottle.png new file mode 100644 index 0000000..169930a Binary files /dev/null and b/mods/vessels/textures/vessels_steel_bottle.png differ diff --git a/mods/walls/README.txt b/mods/walls/README.txt new file mode 100644 index 0000000..ba33bd7 --- /dev/null +++ b/mods/walls/README.txt @@ -0,0 +1,7 @@ +Minetest Game mod: walls +======================== +See license.txt for license information. + +Authors of source code +---------------------- +Auke Kok (LGPLv2.1+) diff --git a/mods/walls/init.lua b/mods/walls/init.lua new file mode 100644 index 0000000..a7c6748 --- /dev/null +++ b/mods/walls/init.lua @@ -0,0 +1,67 @@ +-- walls/init.lua + +walls = {} + +local fence_collision_extra = minetest.settings:get_bool("enable_fence_tall") and 3/8 or 0 + +-- Load support for MT game translation. +local S = minetest.get_translator("walls") + +walls.register = function(wall_name, wall_desc, wall_texture_table, wall_mat, wall_sounds) + --make wall_texture_table paramenter backwards compatible for mods passing single texture + if type(wall_texture_table) ~= "table" then + wall_texture_table = { wall_texture_table } + end + -- inventory node, and pole-type wall start item + minetest.register_node(wall_name, { + description = wall_desc, + drawtype = "nodebox", + node_box = { + type = "connected", + fixed = {-1/4, -1/2, -1/4, 1/4, 1/2, 1/4}, + -- connect_bottom = + connect_front = {-3/16, -1/2, -1/2, 3/16, 3/8, -1/4}, + connect_left = {-1/2, -1/2, -3/16, -1/4, 3/8, 3/16}, + connect_back = {-3/16, -1/2, 1/4, 3/16, 3/8, 1/2}, + connect_right = { 1/4, -1/2, -3/16, 1/2, 3/8, 3/16}, + }, + collision_box = { + type = "connected", + fixed = {-1/4, -1/2, -1/4, 1/4, 1/2 + fence_collision_extra, 1/4}, + -- connect_top = + -- connect_bottom = + connect_front = {-1/4,-1/2,-1/2,1/4,1/2 + fence_collision_extra,-1/4}, + connect_left = {-1/2,-1/2,-1/4,-1/4,1/2 + fence_collision_extra,1/4}, + connect_back = {-1/4,-1/2,1/4,1/4,1/2 + fence_collision_extra,1/2}, + connect_right = {1/4,-1/2,-1/4,1/2,1/2 + fence_collision_extra,1/4}, + }, + connects_to = { "group:wall", "group:stone", "group:fence" }, + paramtype = "light", + is_ground_content = false, + tiles = wall_texture_table, + walkable = true, + groups = { cracky = 3, wall = 1, stone = 2 }, + sounds = wall_sounds, + }) + + -- crafting recipe + minetest.register_craft({ + output = wall_name .. " 6", + recipe = { + { "", "", "" }, + { wall_mat, wall_mat, wall_mat}, + { wall_mat, wall_mat, wall_mat}, + } + }) + +end +--[[ +walls.register("walls:cobble", S("Cobblestone Wall"), {"default_cobble.png"}, + "default:cobble", default.node_sound_stone_defaults()) + +walls.register("walls:mossycobble", S("Mossy Cobblestone Wall"), {"default_mossycobble.png"}, + "default:mossycobble", default.node_sound_stone_defaults()) + +walls.register("walls:desertcobble", S("Desert Cobblestone Wall"), {"default_desert_cobble.png"}, + "default:desert_cobble", default.node_sound_stone_defaults())]] + diff --git a/mods/walls/license.txt b/mods/walls/license.txt new file mode 100644 index 0000000..ccfaf1c --- /dev/null +++ b/mods/walls/license.txt @@ -0,0 +1,14 @@ +License of source code +---------------------- + +GNU Lesser General Public License, version 2.1 +Copyright (C) 2015 Auke Kok + +This program is free software; you can redistribute it and/or modify it under the terms +of the GNU Lesser General Public License as published by the Free Software Foundation; +either version 2.1 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU Lesser General Public License for more details: +https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html diff --git a/mods/walls/locale/template.txt b/mods/walls/locale/template.txt new file mode 100644 index 0000000..6721dc6 --- /dev/null +++ b/mods/walls/locale/template.txt @@ -0,0 +1,4 @@ +# textdomain: walls +Cobblestone Wall= +Mossy Cobblestone Wall= +Desert Cobblestone Wall= diff --git a/mods/walls/locale/walls.de.tr b/mods/walls/locale/walls.de.tr new file mode 100644 index 0000000..c31d4f6 --- /dev/null +++ b/mods/walls/locale/walls.de.tr @@ -0,0 +1,4 @@ +# textdomain: walls +Cobblestone Wall=Kopfsteinpflastermauer +Mossy Cobblestone Wall=Moosige Kopfsteinpflastermauer +Desert Cobblestone Wall=Wüstenkopfsteinpflastermauer diff --git a/mods/walls/locale/walls.eo.tr b/mods/walls/locale/walls.eo.tr new file mode 100644 index 0000000..85efcbf --- /dev/null +++ b/mods/walls/locale/walls.eo.tr @@ -0,0 +1,4 @@ +# textdomain: walls +Cobblestone Wall=Pavimŝtona Muro +Mossy Cobblestone Wall=Muska Pavimŝtona Muro +Desert Cobblestone Wall=Dezerta Pavimŝtona Muro diff --git a/mods/walls/locale/walls.es.tr b/mods/walls/locale/walls.es.tr new file mode 100644 index 0000000..796710f --- /dev/null +++ b/mods/walls/locale/walls.es.tr @@ -0,0 +1,4 @@ +# textdomain: walls +Cobblestone Wall=Pared de adoquines +Mossy Cobblestone Wall=Pared de adoquines musgosos +Desert Cobblestone Wall=Pared de adoquines desérticos diff --git a/mods/walls/locale/walls.fr.tr b/mods/walls/locale/walls.fr.tr new file mode 100644 index 0000000..8dcb625 --- /dev/null +++ b/mods/walls/locale/walls.fr.tr @@ -0,0 +1,4 @@ +# textdomain: walls +Cobblestone Wall=Mur en pavé +Mossy Cobblestone Wall=Mur en pavé moussu +Desert Cobblestone Wall=Mur en pavé du désert diff --git a/mods/walls/locale/walls.id.tr b/mods/walls/locale/walls.id.tr new file mode 100644 index 0000000..8bfd9c7 --- /dev/null +++ b/mods/walls/locale/walls.id.tr @@ -0,0 +1,4 @@ +# textdomain: walls +Cobblestone Wall=Tembok Bongkahan Batu +Mossy Cobblestone Wall=Tembok Bongkahan Batu Berlumut +Desert Cobblestone Wall=Tembok Bongkahan Batu Gurun diff --git a/mods/walls/locale/walls.it.tr b/mods/walls/locale/walls.it.tr new file mode 100644 index 0000000..4babad2 --- /dev/null +++ b/mods/walls/locale/walls.it.tr @@ -0,0 +1,4 @@ +# textdomain: walls +Cobblestone Wall=Muro di ciottoli +Mossy Cobblestone Wall=Muro di ciottoli muschiosi +Desert Cobblestone Wall=Muro di ciottoli del deserto diff --git a/mods/walls/locale/walls.ja.tr b/mods/walls/locale/walls.ja.tr new file mode 100644 index 0000000..66e497d --- /dev/null +++ b/mods/walls/locale/walls.ja.tr @@ -0,0 +1,4 @@ +# textdomain: walls +Cobblestone Wall=丸石の壁 +Mossy Cobblestone Wall=苔むした丸石の壁 +Desert Cobblestone Wall=砂漠の丸石の壁 diff --git a/mods/walls/locale/walls.jbo.tr b/mods/walls/locale/walls.jbo.tr new file mode 100644 index 0000000..aba765c --- /dev/null +++ b/mods/walls/locale/walls.jbo.tr @@ -0,0 +1,4 @@ +# textdomain: walls +Cobblestone Wall=lo lolro'iboi bitmu +Mossy Cobblestone Wall=lo clika lolro'iboi bitmu +Desert Cobblestone Wall=lo cantu'a lolro'iboi bitmu diff --git a/mods/walls/locale/walls.ms.tr b/mods/walls/locale/walls.ms.tr new file mode 100644 index 0000000..9375342 --- /dev/null +++ b/mods/walls/locale/walls.ms.tr @@ -0,0 +1,4 @@ +# textdomain: walls +Cobblestone Wall=Pagar Batu Buntar +Mossy Cobblestone Wall=Pagar Batu Buntar Berlumut +Desert Cobblestone Wall=Pagar Batu Buntar Gurun diff --git a/mods/walls/locale/walls.pl.tr b/mods/walls/locale/walls.pl.tr new file mode 100644 index 0000000..ff544e2 --- /dev/null +++ b/mods/walls/locale/walls.pl.tr @@ -0,0 +1,4 @@ +# textdomain: walls +Cobblestone Wall=Brukowa ściana +Mossy Cobblestone Wall=Brukowa ściana z mchem +Desert Cobblestone Wall=Pustynno-brukowa ściana diff --git a/mods/walls/locale/walls.pt_BR.tr b/mods/walls/locale/walls.pt_BR.tr new file mode 100644 index 0000000..58c3d12 --- /dev/null +++ b/mods/walls/locale/walls.pt_BR.tr @@ -0,0 +1,4 @@ +# textdomain: walls +Cobblestone Wall=Parede de Paralelepípedo +Mossy Cobblestone Wall=Parede de Paralelepípedo com Musgo +Desert Cobblestone Wall=Parede de Paralelepípedo do Deserto diff --git a/mods/walls/locale/walls.ru.tr b/mods/walls/locale/walls.ru.tr new file mode 100644 index 0000000..1ed653f --- /dev/null +++ b/mods/walls/locale/walls.ru.tr @@ -0,0 +1,4 @@ +# textdomain: walls +Cobblestone Wall=Булыжниковая Ограда +Mossy Cobblestone Wall=Мшистая Булыжниковая Ограда +Desert Cobblestone Wall=Ограда Из Пустынного Булыжника diff --git a/mods/walls/locale/walls.sk.tr b/mods/walls/locale/walls.sk.tr new file mode 100644 index 0000000..69cf3a9 --- /dev/null +++ b/mods/walls/locale/walls.sk.tr @@ -0,0 +1,4 @@ +# textdomain: walls +Cobblestone Wall=Múr z dlažbových kociek +Mossy Cobblestone Wall=Múr z dlažbových kociek obrastených machom +Desert Cobblestone Wall=Múr z púštnych dlažbových kociek diff --git a/mods/walls/locale/walls.sv.tr b/mods/walls/locale/walls.sv.tr new file mode 100644 index 0000000..1ad4a29 --- /dev/null +++ b/mods/walls/locale/walls.sv.tr @@ -0,0 +1,4 @@ +# textdomain: walls +Cobblestone Wall=Kullerstensvägg +Mossy Cobblestone Wall=Mossig kullerstensvägg +Desert Cobblestone Wall=Ökenkullerstensvägg diff --git a/mods/walls/locale/walls.uk.tr b/mods/walls/locale/walls.uk.tr new file mode 100644 index 0000000..f92d7cc --- /dev/null +++ b/mods/walls/locale/walls.uk.tr @@ -0,0 +1,4 @@ +# textdomain: walls +Cobblestone Wall=Паркан З Кругляку +Mossy Cobblestone Wall=Паркан З Мохового Кругляку +Desert Cobblestone Wall=Паркан З Пустельного Кругляку diff --git a/mods/walls/locale/walls.zh_CN.tr b/mods/walls/locale/walls.zh_CN.tr new file mode 100644 index 0000000..f590e82 --- /dev/null +++ b/mods/walls/locale/walls.zh_CN.tr @@ -0,0 +1,4 @@ +# textdomain: walls +Cobblestone Wall=鹅卵石墙 +Mossy Cobblestone Wall=苔藓覆盖的鹅卵石墙 +Desert Cobblestone Wall=沙漠鹅卵石墙 diff --git a/mods/walls/locale/walls.zh_TW.tr b/mods/walls/locale/walls.zh_TW.tr new file mode 100644 index 0000000..ba1285f --- /dev/null +++ b/mods/walls/locale/walls.zh_TW.tr @@ -0,0 +1,4 @@ +# textdomain: walls +Cobblestone Wall=鵝卵石牆 +Mossy Cobblestone Wall=苔蘚覆蓋的鵝卵石牆 +Desert Cobblestone Wall=沙漠鵝卵石牆 diff --git a/mods/walls/mod.conf b/mods/walls/mod.conf new file mode 100644 index 0000000..982e0d1 --- /dev/null +++ b/mods/walls/mod.conf @@ -0,0 +1,2 @@ +name = walls +description = Walls mod from Minetest game adapted for Insane Protestor diff --git a/mods/waterworks/.gitattributes b/mods/waterworks/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/mods/waterworks/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/mods/waterworks/.gitignore b/mods/waterworks/.gitignore new file mode 100644 index 0000000..6fd0a37 --- /dev/null +++ b/mods/waterworks/.gitignore @@ -0,0 +1,41 @@ +# Compiled Lua sources +luac.out + +# luarocks build files +*.src.rock +*.zip +*.tar.gz + +# Object files +*.o +*.os +*.ko +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo +*.def +*.exp + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + diff --git a/mods/waterworks/LICENSE.txt b/mods/waterworks/LICENSE.txt new file mode 100644 index 0000000..67cd8ac --- /dev/null +++ b/mods/waterworks/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 FaceDeer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/mods/waterworks/README.md b/mods/waterworks/README.md new file mode 100644 index 0000000..799971b --- /dev/null +++ b/mods/waterworks/README.md @@ -0,0 +1,56 @@ +This mod provides a set of nodes that allow large quantities of water to be pumped from one place to another, potentially over very long distances. + +**Important Note:** The default behaviour of water in Minetest does not actually lend itself well to this kind of activity. In particular, ``default:water_source`` has ``liquid_renewable = true`` set in its node definition, which often causes new water nodes to be created where old ones are removed. + +This mod includes an optional setting that disables ``liquid_renewable`` for default water, but for best effect it is highly recommended that this mod be used in conjunction with the [dynamic_liquid](https://github.com/minetest-mods/dynamic_liquid) mod. + +The [airtanks](https://github.com/minetest-mods/airtanks) mod can also be helpful for players who are interested in doing large-scale underwater construction projects. + +A pipe network is only active when a player is near one of the terminal nodes attached to it. The map blocks containing all terminal nodes for the network will be forceloaded as long as the pipe network is active, allowing water to be added or removed from remote locations, but note that water will be unable to flow into or out from those remote map blocks into adjoining blocks so it may behoove a player to visit these places from time to time to ensure continued flow. + +## Pipes + +The core node type introduced by this mod is the pipe. When pipes are laid adjacent to each other they connect up to form a pipe network, to which inlets, outlets, and pumps can be connected. All contiguous pipes are part of the same network, and all terminal nodes connected to that network will be able to interact with each other through the pipes. + +Pipes automatically connect to other pipes through any of their six faces. + +## Terminals + +Terminals can only be connected to a pipe network via one face, the side that by default is facing away from the player when they place the node in world. They interact with water only on the opposite face - the one facing toward the player when they place the node in world. Terminals require at least one pipe segment to connect to, they don't interact directly with each other. + +A screwdriver can be used to reorient terminals if you want one facing upward or downward. + +The types of terminals in this mod are: + +* Inlets let water enter the pipe but not leave +* Outlets let water out but not in +* Grates let water flow either way depending on pressure +* Pumps are inlets that force water into the network at a higher pressure than their elevation would normally give it. + +## Valves + +A valve can be used to connect or disconnect sections of a pipe network with a simple right-click. When a valve is "open" it acts like a pipe section, and when it's "closed" it does not act like a pipe. + +## Elevation and pressure + +The flow of water through the network is determined by two main factors; the directionality of each type of terminal, and the pressure of the water at that terminal. + +Water flows from high pressure terminals to low pressure terminals. The rise and fall of the pipe in between those two terminals doesn't really matter, just the pressure at the terminals themselves. + +The following figure illustrates the basics of how this works with a very simple three-terminal pipe network: + +![Figure 1](/screenshots/waterworks_figure_1.png) + +The two terminals on the left side are "inlets", only permitting water to enter the network, and the terminal on the right is a grate that allows water in or out. + +If terminal 1 were to be immersed in water, water nodes would be transferred from terminal 1 to terminal 2 because terminal 1's higher elevation gives it higher pressure than terminal 2. Water would *not* be transferred to terminal 3 as terminal 3 is an inlet only. + +If terminal 2 were to be immersed, likewise no water would be transferred because although terminal 2 can allow water to enter the pipe (it's a grate) there are no valid outlet terminals it could go to. + +If terminal 3 were immersed in water, no water would be transferred because terminal 2 is higher elevation and therefore there isn't enough pressure at terminal 3 to reach it. + +![Figure 2](/screenshots/waterworks_figure_2.png) + +In this example terminal 3 is a pump, which acts as if it were an inlet located at an elevation 100 meters higher than it actually is. There are two potential outlets for water entering the system. Water is preferentially emitted from the *lowest* pressure outlet, so if terminal 3 was immersed in water it would be sent to terminal 2. However, if terminal 2 was contained in an enclosed space that had run out of room for additional water, the water would then be sent to the next-lowest outlet and come out of terminal 1. + +If terminal 1 was immersed, then water would transfer from it to terminal 2. Terminal 3 is an inlet, so water wouldn't come out of it. \ No newline at end of file diff --git a/mods/waterworks/crafting.lua b/mods/waterworks/crafting.lua new file mode 100644 index 0000000..2271c94 --- /dev/null +++ b/mods/waterworks/crafting.lua @@ -0,0 +1,92 @@ +--"waterworks:pipe" +if minetest.get_modpath("pipeworks") then +minetest.register_craft( { + output = "waterworks:pipe 12", + recipe = { + { "default:steel_ingot", "", "default:steel_ingot" }, + { "default:steel_ingot", "", "default:steel_ingot" }, + { "default:steel_ingot", "", "default:steel_ingot" } + }, +}) +else +minetest.register_craft( { + output = "waterworks:pipe 12", + recipe = { + { "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" }, + { "", "", "" }, + { "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" } + }, +}) +end + +--"waterworks:valve_on" +minetest.register_craft( { + output = "waterworks:valve_on", + recipe = { + { "default:steel_ingot", "", "default:steel_ingot" }, + { "", "waterworks:pipe", "" }, + { "default:steel_ingot", "", "default:steel_ingot" } + }, +}) + +--"waterworks:inlet" +minetest.register_craft( { + output = "waterworks:inlet", + recipe = { + { "default:steel_ingot", "", "" }, + { "", "waterworks:pipe", "" }, + { "default:steel_ingot", "", "" } + }, +}) +--"waterworks:pumped_inlet" +minetest.register_craft( { + output = "waterworks:pumped_inlet", + recipe = { + { "default:steel_ingot", "", "" }, + { "default:mese_crystal_fragment", "waterworks:pipe", "" }, + { "default:steel_ingot", "", "" } + }, +}) +minetest.register_craft( { + output = "waterworks:pumped_inlet", + recipe = { + { "default:mese_crystal_fragment", "waterworks:inlet"}, + }, +}) + +--"waterworks:outlet" +minetest.register_craft( { + output = "waterworks:outlet", + recipe = { + { "", "", "default:steel_ingot" }, + { "", "waterworks:pipe", "" }, + { "", "", "default:steel_ingot" } + }, +}) + +--"waterworks:grate" +minetest.register_craft( { + output = "waterworks:grate", + recipe = { + { "", "default:steel_ingot", "" }, + { "", "waterworks:pipe", "" }, + { "", "default:steel_ingot", "" } + }, +}) + +-- Allow the basic connectors to be cycled through +minetest.register_craft( { + output = "waterworks:inlet", + type = "shapeless", + recipe = { "waterworks:outlet"}, +}) +minetest.register_craft( { + output = "waterworks:outlet", + type = "shapeless", + recipe = {"waterworks:grate"}, +}) +minetest.register_craft( { + output = "waterworks:grate", + type = "shapeless", + recipe = {"waterworks:inlet"}, +}) \ No newline at end of file diff --git a/mods/waterworks/execute.lua b/mods/waterworks/execute.lua new file mode 100644 index 0000000..72d7835 --- /dev/null +++ b/mods/waterworks/execute.lua @@ -0,0 +1,204 @@ +local pressure_margin = 20 + +local pipe_cache = {} + +local cardinal_dirs = { + {x= 0, y=0, z= 1}, + {x= 1, y=0, z= 0}, + {x= 0, y=0, z=-1}, + {x=-1, y=0, z= 0}, + {x= 0, y=-1, z= 0}, + {x= 0, y=1, z= 0}, +} + +local sort_by_pressure = function(first, second) + local first_pressure = first.pressure + local second_pressure = second.pressure + if first_pressure == nil or second_pressure == nil then + minetest.log("error", "[waterworks] attempted to sort something by pressure that had no pressure value: " .. dump(first) .. "\n" .. dump(second)) + return + end + + return first_pressure > second_pressure +end + +local valid_sink = function(node_name) + return node_name == "air" or node_name == "default:water_flowing" +end +local valid_source = function(node_name) + return node_name == "default:water_source" +end + +-- breadth-first search passing through water searching for air or flowing water, limited to y <= pressure. +-- I could try to be fancy about water flowing downward preferentially, let's leave that as a TODO for now. +local flood_search_outlet = function(start_pos, pressure) + local start_node = minetest.get_node(start_pos) + local start_node_name = start_node.name + if valid_sink(start_node_name) then + return start_pos + end + + local visited = {} + visited[minetest.hash_node_position(start_pos)] = true + local queue = {start_pos} + local queue_pointer = 1 + + while #queue >= queue_pointer do + local current_pos = queue[queue_pointer] + queue_pointer = queue_pointer + 1 + for _, cardinal_dir in ipairs(cardinal_dirs) do + local new_pos = vector.add(current_pos, cardinal_dir) + local new_hash = minetest.hash_node_position(new_pos) + if visited[new_hash] == nil and new_pos.y <= pressure then + local new_node = minetest.get_node(new_pos) + local new_node_name = new_node.name + if valid_sink(new_node_name) then + return new_pos + end + visited[new_hash] = true + if valid_source(new_node_name) then + table.insert(queue, new_pos) + end + end + end + end + return nil +end + + +local upward_dirs = { + {x= 0, y=0, z= 1}, + {x= 1, y=0, z= 0}, + {x= 0, y=0, z=-1}, + {x=-1, y=0, z= 0}, + {x= 0, y=1, z= 0}, +} + +local shuffle = function(tbl) + for i = #tbl, 2, -1 do + local rand = math.random(i) + tbl[i], tbl[rand] = tbl[rand], tbl[i] + end + return tbl +end + +-- depth-first random-walk search trending in an upward direction, returns when it gets cornered +local find_source = function(start_pos) + local current_node = minetest.get_node(start_pos) + local current_node_name = current_node.name + if not valid_source(current_node_name) then + return nil + end + + local visited = {[minetest.hash_node_position(start_pos)] = true} + local current_pos = start_pos + + local continue = true + while continue do + continue = false + shuffle(upward_dirs) + for _, dir in ipairs(upward_dirs) do + local next_pos = vector.add(current_pos, dir) + local next_hash = minetest.hash_node_position(next_pos) + if visited[next_hash] == nil then + visited[next_hash] = true + local next_node = minetest.get_node(next_pos) + local next_node_name = next_node.name + if valid_source(next_node_name) then + current_pos = next_pos + continue = true + break + end + end + end + end + return current_pos +end + + +waterworks.execute_pipes = function(net_index, net_capacity) + local net = waterworks.pipe_networks[net_index] + if net == nil then + minetest.log("error", "[waterworks] Invalid net index given to execute: " .. tostring(net_index)) + return + end + + local inlets + local outlets + + if net.cache_valid then + -- We don't need to recalculate, nothing about the pipe network has changed since last time + inlets = pipe_cache[net_index].inlets + outlets = pipe_cache[net_index].outlets + else + -- Find all the inlets and outlets and sort them by pressure + inlets = {} + if net.connected.inlet ~= nil then + for _, inlet_set in pairs(net.connected.inlet) do + for _, inlet in pairs(inlet_set) do + table.insert(inlets, inlet) + end + end + end + table.sort(inlets, sort_by_pressure) + + outlets = {} + if net.connected.outlet ~= nil then + for _, outlet_set in pairs(net.connected.outlet) do + for _, outlet in pairs(outlet_set) do + table.insert(outlets, outlet) + end + end + end + table.sort(outlets, sort_by_pressure) + + -- Cache the results + pipe_cache[net_index] = {} + pipe_cache[net_index].inlets = inlets + pipe_cache[net_index].outlets = outlets + + net.cache_valid = true + end + + local inlet_index = 1 + local outlet_index = #outlets + local inlet_count = #inlets + + local count = 0 + + -- Starting with the highest-pressure inlet and the lowest-pressure outlet, attempt to move water. + -- We then proceed to steadily lower-pressure inlets and higher-pressure outlets until we meet in the middle, at which point + -- the system is in equilibrium. + while inlet_index <= inlet_count and outlet_index > 0 and count < net_capacity do + local source = inlets[inlet_index] + local sink = outlets[outlet_index] + + --minetest.debug("source: " .. dump(source)) + --minetest.debug("sink: " .. dump(sink)) + + -- pressure_margin allows us to check sources that are a little bit below sinks, + -- in case the extra pressure from their water depth is sufficient to force water through + if source.pressure + pressure_margin >= sink.pressure then + local source_pos = find_source(source.target) + local sink_pos + if source_pos ~= nil then + sink_pos = flood_search_outlet(sink.target, math.max(source.pressure, source_pos.y)) + if sink_pos ~= nil then + minetest.swap_node(sink_pos, {name="default:water_source"}) + minetest.swap_node(source_pos, {name="air"}) + count = count + 1 + end + end + + if source_pos == nil then + -- the outlet had available space but the inlet didn't provide + inlet_index = inlet_index + 1 + elseif sink_pos == nil then + -- the inlet provided but the outlet didn't have space + outlet_index = outlet_index - 1 + end + else + break + end + end +end diff --git a/mods/waterworks/globalstep.lua b/mods/waterworks/globalstep.lua new file mode 100644 index 0000000..d2ba569 --- /dev/null +++ b/mods/waterworks/globalstep.lua @@ -0,0 +1,112 @@ +local worldpath = minetest.get_worldpath() +local network_filename = worldpath.."/waterworks_network.json" + +-- Json storage + +local save_data = function() + if waterworks.dirty_data ~= true then + return + end + local file = io.open(network_filename, "w") + if file then + file:write(minetest.serialize(waterworks.pipe_networks)) + file:close() + waterworks.dirty_data = false + end +end + +local read_data = function() + local file = io.open(network_filename, "r") + if file then + waterworks.pipe_networks = minetest.deserialize(file:read("*all")) -- note: any cached references to pipe_networks is invalidated here, so do this once at the beginning of the run and never again thereafter. + file:close() + else + waterworks.pipe_networks = {} + end + waterworks.dirty_data = false + for _, net in ipairs(waterworks.pipe_networks) do + net.cache_valid = false + end +end + +read_data() + +---------------------------------------------- + +local nets_near_players = {} + +minetest.register_abm ({ + label = "Active connected node tracking", + nodenames = {"group:waterworks_connected"}, + interval = 1.0, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local player_close = false + for _, player in ipairs(minetest.get_connected_players()) do + local player_pos = player:get_pos() + if math.abs(player_pos.x - pos.x) < 161 and math.abs(player_pos.z - pos.z) < 161 and math.abs(player_pos.y - pos.y) < 161 then + player_close = true + break + end + end + + if not player_close then return end + + local hash = minetest.hash_node_position(pos) + waterworks.facedir_to_hash(node.param2) + local net_index = waterworks.find_network_for_pipe_hash(hash) + if net_index < 0 then return end + --minetest.chat_send_all("net near player " .. tostring(net_index)) + nets_near_players[net_index] = 5.0 + end, +}) + +local forceloads = {} +local timer = 0 +minetest.register_globalstep(function(dtime) + timer = timer + dtime + if timer > 1.0 then + + if waterworks.dirty_data then + -- it's possible that a pipe network was split or merged, invalidating the nets_near_players values here. + -- Best to clear them and do nothing for one globalstep, they'll be repopulated shortly. + nets_near_players = {} + end + + -- find connected node positions for all networks with connected nodes near players + local ensure_forceload = {} + for index, live_time in pairs(nets_near_players) do + local new_time = live_time - timer + --minetest.chat_send_all("new time " .. tostring(new_time)) + if new_time < 0 then + nets_near_players[index] = nil + else + nets_near_players[index] = new_time + for connection_type, connections in pairs(waterworks.pipe_networks[index].connected) do + for hash, _ in pairs(connections) do + ensure_forceload[hash] = true + end + end + end + end + + -- clear forceloads that are no longer needed + for hash, _ in pairs(forceloads) do + if not ensure_forceload[hash] then + minetest.forceload_free_block(minetest.get_position_from_hash(hash), true) + end + end + forceloads = ensure_forceload + -- enable forceloads that are needed + for hash, _ in pairs(forceloads) do + minetest.forceload_block(minetest.get_position_from_hash(hash), true) + end + + timer = timer - 1.0 + save_data() + for index, _ in pairs(nets_near_players) do + --minetest.chat_send_all("executing index " .. tostring(index)) + waterworks.execute_pipes(index, 8) + end + end +end) + diff --git a/mods/waterworks/init.lua b/mods/waterworks/init.lua new file mode 100644 index 0000000..ab2b149 --- /dev/null +++ b/mods/waterworks/init.lua @@ -0,0 +1,70 @@ +waterworks = {} + +local modpath = minetest.get_modpath(minetest.get_current_modname()) + +dofile(modpath .. "/globalstep.lua") +dofile(modpath .. "/network.lua") +dofile(modpath .. "/execute.lua") +dofile(modpath .. "/nodes.lua") +dofile(modpath .. "/crafting.lua") + +if minetest.settings:get_bool("waterworks_make_default_water_non_renewable") then + local override_def = {liquid_renewable = false} + minetest.override_item("default:water_source", override_def) + minetest.override_item("default:water_flowing", override_def) + +end + +-- This rebuilds pipe networks whenever the map block is loaded. +-- May be useful for fixing broken stuff. +-- Note that this doesn't *remove* pipes that are inappropriately listed in the network, +-- that may be tricky. +--minetest.register_lbm({ +-- label = "Validate waterworks pipe networks", +-- name = "waterworks:validate_pipe_networks", +-- nodenames = {"group:waterworks_pipe"}, +-- run_at_every_load = true, +-- action = function(pos, node) +-- local hash_pos = minetest.hash_node_position(pos) +-- local found = false +-- for i, net in ipairs(waterworks.pipe_networks) do +-- if net.pipes[hash_pos] then +-- found = true +-- break +-- end +-- end +-- if not found then +-- local new_net_index = waterworks.place_pipe(pos) +-- minetest.log("warning", "[waterworks] detected an unregistered pipe at " .. +-- minetest.pos_to_string(pos) .. ", added it to pipe network " .. +-- tostring(new_net_index)) +-- end +-- end, +--}) + +--minetest.register_chatcommand("dump_pipes", { +---- params = "pos", -- Short parameter description +-- description = "dump pipe network to debug log", +-- func = function(name, param) +-- --minetest.debug(dump(pipe_networks)) +-- +-- for i, net in ipairs(waterworks.pipe_networks) do +-- minetest.debug("net #" .. tostring(i) .. " cache valid: " .. dump(net.cache_valid)) +-- minetest.debug("\tpipes:") +-- local count = 0 +-- for hash_pos, _ in pairs(net.pipes) do +-- minetest.debug("\t\t"..minetest.pos_to_string(minetest.get_position_from_hash(hash_pos))) +-- count = count + 1 +-- end +-- minetest.debug("\tpipe count: " .. tostring(count)) +-- minetest.debug("\tconnections:") +-- for connection_type, connection_list in pairs(net.connected) do +-- minetest.debug("\t\t"..connection_type..":") +-- for connection_hash, data in pairs(connection_list) do +-- minetest.debug("\t\t\t"..minetest.pos_to_string(minetest.get_position_from_hash(connection_hash))..": "..string.gsub(string.gsub(dump(data), "\t", ""), "\n", " ")) +-- end +-- end +-- end +-- +-- end, +--}) diff --git a/mods/waterworks/mod.conf b/mods/waterworks/mod.conf new file mode 100644 index 0000000..a3f46df --- /dev/null +++ b/mods/waterworks/mod.conf @@ -0,0 +1,3 @@ +name = waterworks +description = Provides pipes, pumps, and valves for moving water over long distances +optional_dependencies = default \ No newline at end of file diff --git a/mods/waterworks/network.lua b/mods/waterworks/network.lua new file mode 100644 index 0000000..fd2fbf4 --- /dev/null +++ b/mods/waterworks/network.lua @@ -0,0 +1,386 @@ +local pipe_networks = waterworks.pipe_networks + +local invalidate_cache = function(pipe_network) + pipe_network.cache_valid = false + waterworks.dirty_data = true +end + +local cardinal_dirs = { + {x= 0, y=0, z= 1}, + {x= 1, y=0, z= 0}, + {x= 0, y=0, z=-1}, + {x=-1, y=0, z= 0}, + {x= 0, y=-1, z= 0}, + {x= 0, y=1, z= 0}, +} +-- Mapping from facedir value to index in cardinal_dirs. +local facedir_to_dir_map = { + [0]=1, 2, 3, 4, + 5, 2, 6, 4, + 6, 2, 5, 4, + 1, 5, 3, 6, + 1, 6, 3, 5, + 1, 4, 3, 2, +} + +-- Turn the cardinal directions into a set of integers you can add to a hash to step in that direction. +local cardinal_dirs_hash = {} +for i, dir in ipairs(cardinal_dirs) do + cardinal_dirs_hash[i] = minetest.hash_node_position(dir) - minetest.hash_node_position({x=0, y=0, z=0}) +end + +local facedir_to_dir_index = function(param2) + return facedir_to_dir_map[param2 % 32] +end + +local facedir_to_cardinal_hash = function(dir_index) + return cardinal_dirs_hash[dir_index] +end + +waterworks.facedir_to_hash = function(param2) + return facedir_to_cardinal_hash(facedir_to_dir_index(param2)) +end + +local init_new_network = function(hash_pos) + waterworks.dirty_data = true + return {pipes = {[hash_pos] = true}, connected = {}, cache_valid = false} +end + +local get_neighbor_pipes = function(pos) + local neighbor_pipes = {} + local neighbor_connected = {} + for _, dir in ipairs(cardinal_dirs) do + local potential_pipe_pos = vector.add(pos, dir) + local neighbor = minetest.get_node(potential_pipe_pos) + if minetest.get_item_group(neighbor.name, "waterworks_pipe") > 0 then + table.insert(neighbor_pipes, potential_pipe_pos) + elseif minetest.get_item_group(neighbor.name, "waterworks_connected") > 0 then + table.insert(neighbor_connected, potential_pipe_pos) + end + end + return neighbor_pipes, neighbor_connected +end + +local merge_networks = function(index_list) + table.sort(index_list) + local first_index = table.remove(index_list, 1) + local merged_network = pipe_networks[first_index] + -- remove in reverse order so that indices of earlier tables to remove don't get disrupted + for i = #index_list, 1, -1 do + local index = index_list[i] + local net_to_merge = pipe_networks[index] + for pipe_hash, _ in pairs(net_to_merge.pipes) do + merged_network.pipes[pipe_hash] = true + end + for item_type, item_list in pairs(net_to_merge.connected) do + merged_network.connected[item_type] = merged_network.connected[item_type] or {} + for connection_hash, connection_data in pairs(item_list) do + merged_network.connected[item_type][connection_hash] = connection_data + end + end + table.remove(pipe_networks, index) + end + invalidate_cache(merged_network) + return first_index +end + +local handle_connected = function(connected_positions) + for _, pos in ipairs(connected_positions) do + local node = minetest.get_node(pos) + local node_def = minetest.registered_nodes[node.name] + if node_def._waterworks_update_connected then + node_def._waterworks_update_connected(pos) + else + minetest.log("error", "[waterworks] Node def for " .. node.name .. " had no _waterworks_update_connected defined") + end + end +end + + +-- When placing a pipe at pos, identifies what pipe network to add it to and updates the network map. +-- Note that this can result in fusing multiple networks together into one network. +waterworks.place_pipe = function(pos) + local hash_pos = minetest.hash_node_position(pos) + local neighbor_pipes, neighbor_connected = get_neighbor_pipes(pos) + local neighbor_count = #neighbor_pipes + + if neighbor_count == 0 then + -- this newly-placed pipe has no other pipes next to it, so make a new network for it. + local new_net = init_new_network(hash_pos) + table.insert(pipe_networks, new_net) + handle_connected(neighbor_connected) + return #pipe_networks + elseif neighbor_count == 1 then + -- there's only one pipe neighbor. Look up what network it belongs to and add this pipe to it too. + local neighbor_pos_hash = minetest.hash_node_position(neighbor_pipes[1]) + for i, net in ipairs(pipe_networks) do + local pipes = net.pipes + if pipes[neighbor_pos_hash] then + pipes[hash_pos] = true + invalidate_cache(net) + handle_connected(neighbor_connected) + return i + end + end + else + local neighbor_index_set = {} -- set of indices for networks that neighbors belong to + local neighbor_index_list = {} -- list version of above + for _, neighbor_pos in ipairs(neighbor_pipes) do + local neighbor_hash = minetest.hash_node_position(neighbor_pos) + for i, net in ipairs(pipe_networks) do + if net.pipes[neighbor_hash] then + if not neighbor_index_set[i] then + table.insert(neighbor_index_list, i) + neighbor_index_set[i] = true + end + end + end + end + + if #neighbor_index_list == 1 then -- all neighbors belong to one network. Add this node to that network. + local target_network_index = neighbor_index_list[1] + pipe_networks[target_network_index]["pipes"][hash_pos] = true + invalidate_cache(pipe_networks[target_network_index]) + handle_connected(neighbor_connected) + return target_network_index + end + + -- The most complicated case, this new pipe segment bridges multiple networks. + if #neighbor_index_list > 1 then + local new_index = merge_networks(neighbor_index_list) + pipe_networks[new_index]["pipes"][hash_pos] = true + handle_connected(neighbor_connected) + return new_index + end + end + + -- if we get here we're in a strange state - there are neighbor pipe nodes but none are registered in a network. + -- We could be trying to recover from corruption, so pretend the neighbors don't exist and start a new network. + -- The unregistered neighbors may join it soon. + local new_net = init_new_network(hash_pos) + table.insert(pipe_networks, new_net) + handle_connected(neighbor_connected) + return #pipe_networks + +end + +waterworks.remove_pipe = function(pos) + local hash_pos = minetest.hash_node_position(pos) + local neighbor_pipes = get_neighbor_pipes(pos) + local neighbor_count = #neighbor_pipes + + if neighbor_count == 0 then + -- no neighbors, so this is the last of its network. + for i, net in ipairs(pipe_networks) do + if net.pipes[hash_pos] then + table.remove(pipe_networks, i) + waterworks.dirty_data = true + return i + end + end + + minetest.log("error", "[waterworks] pipe removed from pos " .. minetest.pos_to_string(pos) .. + " didn't belong to any networks. Something went wrong to get to this state.") + return -1 + elseif neighbor_count == 1 then + -- there's only one pipe neighbor. This pipe is at the end of a line, so just remove it. + for i, net in ipairs(pipe_networks) do + local pipes = net.pipes + if pipes[hash_pos] then + pipes[hash_pos] = nil + invalidate_cache(net) + -- If there's anything connected to the pipe here, remove it from the network too + for _, connected_items in pairs(net.connected) do + connected_items[hash_pos] = nil + end + return i + end + end + minetest.log("error", "[waterworks] pipe removed from pos " .. minetest.pos_to_string(pos) .. + " didn't belong to any networks, despite being neighbor to one at " .. + minetest.pos_to_string(neighbor_pipes[1]) .. + ". Something went wrong to get to this state.") + return -1 + else + -- we may be splitting networks. This is complicated. + -- find the network we currently belong to. Remove ourselves from it. + local old_net + local old_pipes + local old_connected + local old_index + for i, net in ipairs(pipe_networks) do + local pipes = net.pipes + if pipes[hash_pos] then + old_connected = net.connected + old_net = net + old_pipes = pipes + old_index = i + old_pipes[hash_pos] = nil + -- if there's anything connected to the pipe here, remove it + for _, connected_items in pairs(old_connected) do + connected_items[hash_pos] = nil + end + end + end + if old_index == nil then + minetest.log("error", "[waterworks] pipe removed from pos " .. minetest.pos_to_string(pos) .. + " didn't belong to any networks, despite being neighbor to several. Something went wrong to get to this state.") + return -1 + end + + -- get the hashes of the neighbor positions. + -- We're maintaining a set as well as a list because they're + -- efficient for different purposes. The list is easy to count, + -- the set is easy to test membership of. + local neighbor_hashes_list = {} + local neighbor_hashes_set = {} + for i, neighbor_pos in ipairs(neighbor_pipes) do + local neighbor_hash = minetest.hash_node_position(neighbor_pos) + neighbor_hashes_list[i] = neighbor_hash + neighbor_hashes_set[neighbor_hash] = true + end + + -- We're going to need to traverse through the old network, starting from each of our neighbors, + -- to establish what's still connected. + local to_visit = {} + local visited = {[hash_pos] = true} -- set of hashes we've visited already. We know the starting point is not valid. + local new_nets = {} -- this will be where we put new sets of connected nodes. + while #neighbor_hashes_list > 0 do + local current_neighbor = table.remove(neighbor_hashes_list) -- pop neighbor hash and push it into the to_visit list. + neighbor_hashes_set[current_neighbor] = nil + table.insert(to_visit, current_neighbor) -- file that neighbor hash as our starting point. + local new_net = init_new_network(current_neighbor) -- we know that hash is in old_net, so initialize the new_net with it. + local new_pipes = new_net.pipes + while #to_visit > 0 do + local current_hash = table.remove(to_visit) + for _, cardinal_hash in ipairs(cardinal_dirs_hash) do + local test_hash = cardinal_hash + current_hash + if not visited[test_hash] then + if old_pipes[test_hash] then + -- we've traversed to a node that was in the old network + old_pipes[test_hash] = nil -- remove from old network + new_pipes[test_hash] = true -- add to one we're building + table.insert(to_visit, test_hash) -- flag it as next one to traverse from + if neighbor_hashes_set[test_hash] then + --we've encountered another neighbor while traversing + --eliminate it from future consideration as a starting point. + neighbor_hashes_set[test_hash] = nil + for i, neighbor_hash_in_list in ipairs(neighbor_hashes_list) do + if neighbor_hash_in_list == test_hash then + table.remove(neighbor_hashes_list, i) + break + end + end + if #neighbor_hashes_list == 0 then + --Huzzah! We encountered all neighbors. The rest of the nodes in old_net should belong to new_net. + --We can skip all remaining pathfinding flood-fill and connected testing + for remaining_hash, _ in pairs(old_pipes) do + new_pipes[remaining_hash] = true + to_visit = {} + end + break + end + end + end + end + end + visited[current_hash] = true + end + table.insert(new_nets, new_net) + end + + -- distribute connected items to the new nets + if #new_nets == 1 then + -- net didn't split, just keep the old stuff + new_nets[1].connected = old_connected + else + for _, new_net in ipairs(new_nets) do + local new_pipes = new_net.pipes + for item_type, item_list in pairs(old_connected) do + new_net.connected[item_type] = new_net.connected[item_type] or {} + for connection_hash, connection_data in pairs(item_list) do + if new_pipes[connection_hash] then + new_net.connected[item_type][connection_hash] = connection_data + end + end + end + end + end + + -- replace the old net with one of the new nets + pipe_networks[old_index] = table.remove(new_nets) + -- if there are any additional nets left, add those as brand new ones. + for _, new_net in ipairs(new_nets) do + table.insert(pipe_networks, new_net) + end + return old_index + end +end + +waterworks.place_connected = function(pos, item_type, data) + local node = minetest.get_node(pos) + local dir_index = facedir_to_dir_index(node.param2) + local dir_hash = facedir_to_cardinal_hash(dir_index) + local pos_hash = minetest.hash_node_position(pos) + local connection_hash = pos_hash + dir_hash + + for i, net in ipairs(pipe_networks) do + if net.pipes[connection_hash] then + net.connected[item_type] = net.connected[item_type] or {} + net.connected[item_type][connection_hash] = net.connected[item_type][connection_hash] or {} + net.connected[item_type][connection_hash][dir_index] = data + invalidate_cache(net) + return i + end + end + + return -1 +end + +waterworks.remove_connected = function(pos, item_type) + local node = minetest.get_node(pos) + local dir_index = facedir_to_dir_index(node.param2) + local dir_hash = facedir_to_cardinal_hash(dir_index) + local pos_hash = minetest.hash_node_position(pos) + local connection_hash = pos_hash + dir_hash + + for i, net in ipairs(pipe_networks) do + if net.pipes[connection_hash] then + local item_list = net.connected[item_type] + if item_list then + if item_list[connection_hash] ~= nil then + local connected_items = item_list[connection_hash] + connected_items[dir_index] = nil + local count = 0 + for _, data in pairs(connected_items) do + count = count + 1 + end + if count == 0 then + item_list[connection_hash] = nil + end + count = 0 + for _, item in pairs(item_list) do + count = count + 1 + end + if count == 0 then + net.connected[item_type] = nil + end + invalidate_cache(net) + return i + end + end + break -- If we get here, we didn't find the connected node even though we should have. + end + end + + return -1 +end + +waterworks.find_network_for_pipe_hash = function(hash) + for i, net in ipairs(pipe_networks) do + if net.pipes[hash] then + return i + end + end + return -1 +end \ No newline at end of file diff --git a/mods/waterworks/nodes.lua b/mods/waterworks/nodes.lua new file mode 100644 index 0000000..365bd14 --- /dev/null +++ b/mods/waterworks/nodes.lua @@ -0,0 +1,280 @@ + +minetest.register_node("waterworks:pipe", { + description = "Waterworks Pipe", + tiles = { + {name="waterworks_pipe.png^waterworks_pipe_rivets_offset.png", scale=4, align_style="world"}, + {name="waterworks_pipe.png^waterworks_pipe_rivets_offset_2.png", scale=4, align_style="world"}, + {name="waterworks_pipe.png^waterworks_pipe_rivets.png", scale=4, align_style="world"}, + {name="waterworks_pipe.png^waterworks_pipe_rivets_offset_2.png", scale=4, align_style="world"}, + {name="waterworks_pipe.png^waterworks_pipe_rivets.png", scale=4, align_style="world"}, + {name="waterworks_pipe.png^waterworks_pipe_rivets_offset_2.png", scale=4, align_style="world"}, + }, + connects_to = {"group:waterworks_pipe", "group:waterworks_connected", "group:waterworks_inert"}, + connect_sides = { "top", "bottom", "front", "left", "back", "right" }, + drawtype = "nodebox", + node_box = { + type = "connected", + fixed = {-0.25,-0.25,-0.25,0.25,0.25,0.25}, + connect_top = {-0.375, 0, -0.375, 0.375, 0.5, 0.375}, + connect_bottom = {-0.375, -0.5, -0.375, 0.375, 0, 0.375}, + connect_back = {-0.375, -0.375, 0, 0.375, 0.375, 0.5}, + connect_right = {0, -0.375, -0.375, 0.5, 0.375, 0.375}, + connect_front = {-0.375, -0.375, -0.5, 0.375, 0.375, 0}, + connect_left = {-0.5, -0.375, -0.375, 0, 0.375, 0.375}, + disconnected = {-0.375,-0.375,-0.375,0.375,0.375,0.375}, + }, + paramtype = "light", + + is_ground_content = false, + groups = {oddly_breakable_by_hand = 1, waterworks_pipe = 1}, + --sounds = default.node_sound_metal_defaults(), + on_construct = function(pos) + waterworks.place_pipe(pos) + end, + on_destruct = function(pos) + waterworks.remove_pipe(pos) + end, +}) + +----------------------------------------------------------------- + +minetest.register_node("waterworks:valve_on", { + description = "Waterworks Valve (open)", + tiles = {"waterworks_metal.png^waterworks_valve_seam.png^waterworks_valve_on.png",}, + connects_to = {"group:waterworks_pipe", "group:waterworks_connected", "group:waterworks_inert"}, + connect_sides = { "top", "bottom", "front", "left", "back", "right" }, + drawtype = "nodebox", + node_box = { + type = "connected", + fixed = {-0.4375,-0.4375,-0.4375,0.4375,0.4375,0.4375}, + connect_top = {-0.375, 0.4375, -0.375, 0.375, 0.5, 0.375}, + connect_bottom = {-0.375, -0.5, -0.375, 0.375, -0.4375, 0.375}, + connect_back = {-0.375, -0.375, 0.4375, 0.375, 0.375, 0.5}, + connect_right = {0.4375, -0.375, -0.375, 0.5, 0.375, 0.375}, + connect_front = {-0.375, -0.375, -0.5, 0.375, 0.375, -0.4375}, + connect_left = {-0.5, -0.375, -0.375, -0.4375, 0.375, 0.375}, + }, + paramtype = "light", + + is_ground_content = false, + groups = {oddly_breakable_by_hand = 1, waterworks_pipe = 1}, + --sounds = default.node_sound_metal_defaults(), + on_construct = function(pos) + waterworks.place_pipe(pos) + end, + on_destruct = function(pos) + waterworks.remove_pipe(pos) + end, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + node.name = "waterworks:valve_off" + minetest.set_node(pos, node) + end, +}) + +minetest.register_node("waterworks:valve_off", { + description = "Waterworks Valve (closed)", + tiles = {"waterworks_metal.png^waterworks_valve_seam.png^waterworks_valve_off.png",}, + connects_to = {"group:waterworks_pipe", "group:waterworks_connected", "group:waterworks_inert"}, + connect_sides = { "top", "bottom", "front", "left", "back", "right" }, + drawtype = "nodebox", + node_box = { + type = "connected", + fixed = {-0.4375,-0.4375,-0.4375,0.4375,0.4375,0.4375}, + connect_top = {-0.375, 0.4375, -0.375, 0.375, 0.5, 0.375}, + connect_bottom = {-0.375, -0.5, -0.375, 0.375, -0.4375, 0.375}, + connect_back = {-0.375, -0.375, 0.4375, 0.375, 0.375, 0.5}, + connect_right = {0.4375, -0.375, -0.375, 0.5, 0.375, 0.375}, + connect_front = {-0.375, -0.375, -0.5, 0.375, 0.375, -0.4375}, + connect_left = {-0.5, -0.375, -0.375, -0.4375, 0.375, 0.375}, + }, + paramtype = "light", + drops = "waterworks:valve_on", + + is_ground_content = false, + groups = {oddly_breakable_by_hand = 1, waterworks_inert = 1, not_in_creative_inventory = 1}, + --sounds = default.node_sound_metal_defaults(), + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + node.name = "waterworks:valve_on" + minetest.set_node(pos, node) + end, +}) + +----------------------------------------------------------------- + +local place_inlet = function(pos) + local node = minetest.get_node(pos) + local dir = minetest.facedir_to_dir(node.param2) + local target = vector.subtract(pos, dir) + waterworks.place_connected(pos, "inlet", {pos = pos, target = target, pressure = target.y}) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", "Inlet elevation " .. tostring(target.y)) +end +minetest.register_node("waterworks:inlet", { + description = "Waterworks Inlet", + tiles = { + "waterworks_metal.png", + "waterworks_metal.png", + "waterworks_metal.png", + "waterworks_metal.png", + "waterworks_metal.png^waterworks_connected_back.png", + "waterworks_metal.png^waterworks_inlet.png", + }, + paramtype2 = "facedir", + is_ground_content = false, + groups = {oddly_breakable_by_hand = 1, waterworks_connected = 1}, + --sounds = default.node_sound_metal_defaults(), + paramtype = "light", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = {{-0.375, -0.375, -0.375, 0.375, 0.375, 0.5}, {-0.5, -0.5, -0.5, 0.5, 0.5, -0.375}}, + }, + _waterworks_update_connected = place_inlet, + on_construct = function(pos) + place_inlet(pos) + end, + on_destruct = function(pos) + waterworks.remove_connected(pos, "inlet") + end, + on_rotate = function(pos, node, user, mode, new_param2) + waterworks.remove_connected(pos, "inlet") + node.param2 = new_param2 + minetest.swap_node(pos, node) + place_inlet(pos) + return true + end, +}) + +local place_pumped_inlet = function(pos) + local node = minetest.get_node(pos) + local dir = minetest.facedir_to_dir(node.param2) + local target = vector.subtract(pos, dir) + waterworks.place_connected(pos, "inlet", {pos = pos, target = target, pressure = target.y + 100}) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", "Pump effective elevation " .. tostring(target.y + 100)) +end +minetest.register_node("waterworks:pumped_inlet", { + description = "Waterworks Pumped Inlet", + tiles = { + "waterworks_turbine_base.png", + "waterworks_turbine_base.png", + "waterworks_turbine_side.png^[transformFX", + "waterworks_turbine_side.png", + "waterworks_metal.png^waterworks_connected_back.png", + "waterworks_turbine_base.png^waterworks_turbine.png", + }, + paramtype2 = "facedir", + is_ground_content = false, + groups = {oddly_breakable_by_hand = 1, waterworks_connected = 1}, + --sounds = default.node_sound_metal_defaults(), + paramtype = "light", + drawtype = "normal", + _waterworks_update_connected = place_pumped_inlet, + on_construct = function(pos) + place_pumped_inlet(pos) + end, + on_destruct = function(pos) + waterworks.remove_connected(pos, "inlet") + end, + on_rotate = function(pos, node, user, mode, new_param2) + waterworks.remove_connected(pos, "inlet") + node.param2 = new_param2 + minetest.swap_node(pos, node) + place_pumped_inlet(pos) + return true + end, +}) + +local place_outlet = function(pos) + local node = minetest.get_node(pos) + local dir = minetest.facedir_to_dir(node.param2) + local target = vector.subtract(pos, dir) + waterworks.place_connected(pos, "outlet", {pos = pos, target = target, pressure = target.y}) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", "Outlet elevation " .. tostring(target.y)) +end +minetest.register_node("waterworks:outlet", { + description = "Waterworks Outlet", + tiles = { + "waterworks_metal.png", + "waterworks_metal.png", + "waterworks_metal.png", + "waterworks_metal.png", + "waterworks_metal.png^waterworks_connected_back.png", + "waterworks_metal.png^waterworks_outlet.png", + }, + paramtype2 = "facedir", + is_ground_content = false, + groups = {oddly_breakable_by_hand = 1, waterworks_connected = 1}, + + paramtype = "light", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = {{-0.375, -0.375, -0.375, 0.375, 0.375, 0.5}, {-0.5, -0.5, -0.5, 0.5, 0.5, -0.375}}, + }, + + --sounds = default.node_sound_metal_defaults(), + _waterworks_update_connected = place_outlet, + on_construct = function(pos) + place_outlet(pos) + end, + on_destruct = function(pos) + waterworks.remove_connected(pos, "outlet") + end, + on_rotate = function(pos, node, user, mode, new_param2) + waterworks.remove_connected(pos, "outlet") + node.param2 = new_param2 + minetest.swap_node(pos, node) + place_outlet(pos) + return true + end, +}) + +local place_grate = function(pos) + local node = minetest.get_node(pos) + local dir = minetest.facedir_to_dir(node.param2) + local target = vector.subtract(pos, dir) + waterworks.place_connected(pos, "outlet", {pos = pos, target = target, pressure = target.y}) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", "Grate elevation " .. tostring(target.y)) +end +minetest.register_node("waterworks:grate", { + description = "Waterworks Grate", + tiles = { + "waterworks_metal.png", + "waterworks_metal.png", + "waterworks_metal.png", + "waterworks_metal.png", + "waterworks_metal.png^waterworks_connected_back.png", + "waterworks_metal.png^waterworks_grate.png", + }, + paramtype2 = "facedir", + is_ground_content = false, + groups = {oddly_breakable_by_hand = 1, waterworks_connected = 1}, + + paramtype = "light", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = {{-0.375, -0.375, -0.375, 0.375, 0.375, 0.5}, {-0.5, -0.5, -0.5, 0.5, 0.5, -0.375}}, + }, + + --sounds = default.node_sound_metal_defaults(), + _waterworks_update_connected = place_outlet, + on_construct = function(pos) + place_outlet(pos) + end, + on_destruct = function(pos) + waterworks.remove_connected(pos, "outlet") + waterworks.remove_connected(pos, "inlet") + end, + on_rotate = function(pos, node, user, mode, new_param2) + waterworks.remove_connected(pos, "outlet") + waterworks.remove_connected(pos, "inlet") + node.param2 = new_param2 + minetest.swap_node(pos, node) + place_outlet(pos) + return true + end, +}) \ No newline at end of file diff --git a/mods/waterworks/screenshot.png b/mods/waterworks/screenshot.png new file mode 100644 index 0000000..523c7f8 Binary files /dev/null and b/mods/waterworks/screenshot.png differ diff --git a/mods/waterworks/screenshots/waterworks_figure_1.png b/mods/waterworks/screenshots/waterworks_figure_1.png new file mode 100644 index 0000000..c8a4b58 Binary files /dev/null and b/mods/waterworks/screenshots/waterworks_figure_1.png differ diff --git a/mods/waterworks/screenshots/waterworks_figure_2.png b/mods/waterworks/screenshots/waterworks_figure_2.png new file mode 100644 index 0000000..e3cf747 Binary files /dev/null and b/mods/waterworks/screenshots/waterworks_figure_2.png differ diff --git a/mods/waterworks/settingtypes.txt b/mods/waterworks/settingtypes.txt new file mode 100644 index 0000000..4d1e632 --- /dev/null +++ b/mods/waterworks/settingtypes.txt @@ -0,0 +1 @@ +waterworks_make_default_water_non_renewable (Disable self-replication of default water) bool false \ No newline at end of file diff --git a/mods/waterworks/textures/LICENSE.txt b/mods/waterworks/textures/LICENSE.txt new file mode 100644 index 0000000..41950b4 --- /dev/null +++ b/mods/waterworks/textures/LICENSE.txt @@ -0,0 +1,17 @@ +The following textures are licensed under the MIT and CC0 licenses by FaceDeer: + +waterworks_connected_back +waterworks_grate +waterworks_inlet +waterworks_metal +waterworks_outlet +waterworks_pipe +waterworks_pipe_rivets +waterworks_pipe_rivets_offset +waterworks_pipe_rivets_offset_2 +waterworks_turbine +waterworks_turbine_base +waterworks_turbine_side +waterworks_valve_off +waterworks_valve_on +waterworks_valve_seam \ No newline at end of file diff --git a/mods/waterworks/textures/waterworks_connected_back.png b/mods/waterworks/textures/waterworks_connected_back.png new file mode 100644 index 0000000..7779155 Binary files /dev/null and b/mods/waterworks/textures/waterworks_connected_back.png differ diff --git a/mods/waterworks/textures/waterworks_grate.png b/mods/waterworks/textures/waterworks_grate.png new file mode 100644 index 0000000..f878f32 Binary files /dev/null and b/mods/waterworks/textures/waterworks_grate.png differ diff --git a/mods/waterworks/textures/waterworks_inlet.png b/mods/waterworks/textures/waterworks_inlet.png new file mode 100644 index 0000000..0ac79b2 Binary files /dev/null and b/mods/waterworks/textures/waterworks_inlet.png differ diff --git a/mods/waterworks/textures/waterworks_metal.png b/mods/waterworks/textures/waterworks_metal.png new file mode 100644 index 0000000..74e6014 Binary files /dev/null and b/mods/waterworks/textures/waterworks_metal.png differ diff --git a/mods/waterworks/textures/waterworks_outlet.png b/mods/waterworks/textures/waterworks_outlet.png new file mode 100644 index 0000000..9f38450 Binary files /dev/null and b/mods/waterworks/textures/waterworks_outlet.png differ diff --git a/mods/waterworks/textures/waterworks_pipe.png b/mods/waterworks/textures/waterworks_pipe.png new file mode 100644 index 0000000..c3d6dff Binary files /dev/null and b/mods/waterworks/textures/waterworks_pipe.png differ diff --git a/mods/waterworks/textures/waterworks_pipe_rivets.png b/mods/waterworks/textures/waterworks_pipe_rivets.png new file mode 100644 index 0000000..4462136 Binary files /dev/null and b/mods/waterworks/textures/waterworks_pipe_rivets.png differ diff --git a/mods/waterworks/textures/waterworks_pipe_rivets_offset.png b/mods/waterworks/textures/waterworks_pipe_rivets_offset.png new file mode 100644 index 0000000..a53bf4d Binary files /dev/null and b/mods/waterworks/textures/waterworks_pipe_rivets_offset.png differ diff --git a/mods/waterworks/textures/waterworks_pipe_rivets_offset_2.png b/mods/waterworks/textures/waterworks_pipe_rivets_offset_2.png new file mode 100644 index 0000000..70d966f Binary files /dev/null and b/mods/waterworks/textures/waterworks_pipe_rivets_offset_2.png differ diff --git a/mods/waterworks/textures/waterworks_turbine.png b/mods/waterworks/textures/waterworks_turbine.png new file mode 100644 index 0000000..43ce420 Binary files /dev/null and b/mods/waterworks/textures/waterworks_turbine.png differ diff --git a/mods/waterworks/textures/waterworks_turbine_base.png b/mods/waterworks/textures/waterworks_turbine_base.png new file mode 100644 index 0000000..715d242 Binary files /dev/null and b/mods/waterworks/textures/waterworks_turbine_base.png differ diff --git a/mods/waterworks/textures/waterworks_turbine_side.png b/mods/waterworks/textures/waterworks_turbine_side.png new file mode 100644 index 0000000..fed9d63 Binary files /dev/null and b/mods/waterworks/textures/waterworks_turbine_side.png differ diff --git a/mods/waterworks/textures/waterworks_valve_off.png b/mods/waterworks/textures/waterworks_valve_off.png new file mode 100644 index 0000000..c870df8 Binary files /dev/null and b/mods/waterworks/textures/waterworks_valve_off.png differ diff --git a/mods/waterworks/textures/waterworks_valve_on.png b/mods/waterworks/textures/waterworks_valve_on.png new file mode 100644 index 0000000..9fda87f Binary files /dev/null and b/mods/waterworks/textures/waterworks_valve_on.png differ diff --git a/mods/waterworks/textures/waterworks_valve_seam.png b/mods/waterworks/textures/waterworks_valve_seam.png new file mode 100644 index 0000000..f7e712c Binary files /dev/null and b/mods/waterworks/textures/waterworks_valve_seam.png differ diff --git a/mods/xdecor/.gitignore b/mods/xdecor/.gitignore new file mode 100644 index 0000000..ef02689 --- /dev/null +++ b/mods/xdecor/.gitignore @@ -0,0 +1,22 @@ +## Files related to minetest development cycle +/*.patch +# GNU Patch reject file +*.rej + +## Editors and Development environments +*~ +*.swp +*.bak* +*.orig +# Vim +*.vim +# Kate +.*.kate-swp +.swp.* +# Eclipse (LDT) +.project +.settings/ +.buildpath +.metadata +# Idea IDE +.idea/* diff --git a/mods/xdecor/.luacheckrc b/mods/xdecor/.luacheckrc new file mode 100644 index 0000000..8cdd8c3 --- /dev/null +++ b/mods/xdecor/.luacheckrc @@ -0,0 +1,14 @@ +allow_defined_top = true + +read_globals = { + "minetest", + "vector", "ItemStack", + "default", + "stairs", "doors", "xpanes", + "xdecor", "xbg", + table = {fields = {"copy"}}, + string = {fields = {"split"}}, + "unpack", + "stairsplus", + "mesecon" +} diff --git a/mods/xdecor/LICENSE b/mods/xdecor/LICENSE new file mode 100644 index 0000000..7a7294b --- /dev/null +++ b/mods/xdecor/LICENSE @@ -0,0 +1,49 @@ +┌──────────────────────────────────────────────────────────────────────┐ +│ Copyright (c) 2015-2021 kilbith │ +│ │ +│ Code: BSD │ +│ Textures: WTFPL (credits: Gambit, kilbith, Cisoun) │ +│ │ +│ Textures (radio and speaker) by │ +│ MCL (CC BY 4.0 Int'l) │ +│ │ +│ Textures (rooster) by │ +│ sirrobzeroone (CC0) │ +│ │ +│ Textures (hanging candle) by │ +│ gigomaf (CC BY-NC 3.0) │ +│ │ +│ Sounds: │ +│ - xdecor_boiling_water.ogg - by Audionautics - CC BY-SA │ +│ freesound.org/people/Audionautics/sounds/133901/ │ +│ - xdecor_enchanting.ogg - by Timbre - CC BY-SA-NC │ +│ freesound.org/people/Timbre/sounds/221683/ │ +│ - xdecor_bouncy.ogg - by Blender Foundation - CC BY 3.0 │ +│ opengameart.org/content/funny-comic-cartoon-bounce-sound │ +└──────────────────────────────────────────────────────────────────────┘ + + +Copyright (c) 1998, Regents of the University of California +All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of the University of California, Berkeley nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/mods/xdecor/README.md b/mods/xdecor/README.md new file mode 100644 index 0000000..05340a2 --- /dev/null +++ b/mods/xdecor/README.md @@ -0,0 +1,17 @@ +## X-Decor ## + +[![ContentDB](https://content.minetest.net/packages/jp/xdecor/shields/downloads/)](https://content.minetest.net/packages/jp/xdecor/) + +A decoration mod meant to be simple and well-featured. +It adds a bunch of cute cubes, various mechanisms and stuff for [cutting](https://forum.minetest.net/viewtopic.php?f=11&t=14085), [enchanting](https://forum.minetest.net/viewtopic.php?f=11&t=14087), cooking, etc. +This mod is a lightweight alternative to HomeDecor and MoreBlocks. + +### Requirements ### +This mod requires at least version 5.1 of Minetest. + +### Credits ### + +Special thanks to Gambit for the textures from the PixelBOX pack for Minetest. +Thanks to all contributors who keep this mod alive. + +![Preview](http://i.imgur.com/AVoyCQy.png) diff --git a/mods/xdecor/handlers/animations.lua b/mods/xdecor/handlers/animations.lua new file mode 100644 index 0000000..2849667 --- /dev/null +++ b/mods/xdecor/handlers/animations.lua @@ -0,0 +1,57 @@ +local function top_face(pointed_thing) + if not pointed_thing then return end + return pointed_thing.above.y > pointed_thing.under.y +end + +function xdecor.sit(pos, node, clicker, pointed_thing) + if not top_face(pointed_thing) then return end + local player_name = clicker:get_player_name() + local objs = minetest.get_objects_inside_radius(pos, 0.1) + local vel = clicker:get_player_velocity() + local ctrl = clicker:get_player_control() + + for _, obj in pairs(objs) do + if obj:is_player() and obj:get_player_name() ~= player_name then + return + end + end + + if default.player_attached[player_name] then + pos.y = pos.y - 0.5 + clicker:set_pos(pos) + clicker:set_eye_offset(vector.new(), vector.new()) + clicker:set_physics_override({speed = 1, jump = 1, gravity = 1}) + default.player_attached[player_name] = false + default.player_set_animation(clicker, "stand", 30) + + elseif not default.player_attached[player_name] and node.param2 <= 3 and + not ctrl.sneak and vector.equals(vel, vector.new()) then + + clicker:set_eye_offset({x = 0, y = -7, z = 2}, vector.new()) + clicker:set_physics_override({speed = 0, jump = 0, gravity = 1}) + clicker:set_pos(pos) + default.player_attached[player_name] = true + default.player_set_animation(clicker, "sit", 30) + + if node.param2 == 0 then + clicker:set_look_yaw(3.15) + elseif node.param2 == 1 then + clicker:set_look_yaw(7.9) + elseif node.param2 == 2 then + clicker:set_look_yaw(6.28) + elseif node.param2 == 3 then + clicker:set_look_yaw(4.75) + end + end +end + +function xdecor.sit_dig(pos, digger) + for _, player in pairs(minetest.get_objects_inside_radius(pos, 0.1)) do + if player:is_player() and + default.player_attached[player:get_player_name()] then + return false + end + end + + return true +end diff --git a/mods/xdecor/handlers/helpers.lua b/mods/xdecor/handlers/helpers.lua new file mode 100644 index 0000000..dc14b24 --- /dev/null +++ b/mods/xdecor/handlers/helpers.lua @@ -0,0 +1,60 @@ +-- Returns the greatest numeric key in a table. +function xdecor.maxn(T) + local n = 0 + for k in pairs(T) do + if k > n then + n = k + end + end + + return n +end + +-- Returns the length of an hash table. +function xdecor.tablelen(T) + local n = 0 + + for _ in pairs(T) do + n = n + 1 + end + + return n +end + +-- Deep copy of a table. Borrowed from mesecons mod (https://github.com/Jeija/minetest-mod-mesecons). +function xdecor.tablecopy(T) + if type(T) ~= "table" then + return T -- No need to copy. + end + + local new = {} + + for k, v in pairs(T) do + if type(v) == "table" then + new[k] = xdecor.tablecopy(v) + else + new[k] = v + end + end + + return new +end + +function xdecor.stairs_valid_def(def) + return (def.drawtype == "normal" or def.drawtype:sub(1,5) == "glass") and + (def.groups.cracky or def.groups.choppy) and + not def.on_construct and + not def.after_place_node and + not def.on_rightclick and + not def.on_blast and + not def.allow_metadata_inventory_take and + not (def.groups.not_in_creative_inventory == 1) and + not (def.groups.not_cuttable == 1) and + not def.groups.wool and + (def.tiles and type(def.tiles[1]) == "string" and not + def.tiles[1]:find("default_mineral")) and + not def.mesecons and + def.description and + def.description ~= "" and + def.light_source == 0 +end diff --git a/mods/xdecor/handlers/nodeboxes.lua b/mods/xdecor/handlers/nodeboxes.lua new file mode 100644 index 0000000..4a3d8ca --- /dev/null +++ b/mods/xdecor/handlers/nodeboxes.lua @@ -0,0 +1,67 @@ +xdecor.box = { + slab_y = function(height, shift) + return { + -0.5, + -0.5 + (shift or 0), + -0.5, + 0.5, + -0.5 + height + (shift or 0), + 0.5 + } + end, + slab_z = function(depth) + return {-0.5, -0.5, -0.5 + depth, 0.5, 0.5, 0.5} + end, + bar_y = function(radius) + return {-radius, -0.5, -radius, radius, 0.5, radius} + end, + cuboid = function(radius_x, radius_y, radius_z) + return {-radius_x, -radius_y, -radius_z, radius_x, radius_y, radius_z} + end +} + +xdecor.nodebox = { + regular = {type = "regular"}, + null = { + type = "fixed", fixed = {0,0,0,0,0,0} + } +} + +xdecor.pixelbox = function(size, boxes) + local fixed = {} + for _, box in ipairs(boxes) do + -- `unpack` has been changed to `table.unpack` in newest Lua versions. + local x, y, z, w, h, l = unpack(box) + fixed[#fixed + 1] = { + (x / size) - 0.5, + (y / size) - 0.5, + (z / size) - 0.5, + ((x + w) / size) - 0.5, + ((y + h) / size) - 0.5, + ((z + l) / size) - 0.5 + } + end + + return {type = "fixed", fixed = fixed} +end + +local mt = {} + +mt.__index = function(table, key) + local ref = xdecor.box[key] + local ref_type = type(ref) + + if ref_type == "function" then + return function(...) + return {type = "fixed", fixed = ref(...)} + end + elseif ref_type == "table" then + return {type = "fixed", fixed = ref} + elseif ref_type == "nil" then + error(key .. "could not be found among nodebox presets and functions") + end + + error("unexpected datatype " .. tostring(type(ref)) .. " while looking for " .. key) +end + +setmetatable(xdecor.nodebox, mt) diff --git a/mods/xdecor/handlers/registration.lua b/mods/xdecor/handlers/registration.lua new file mode 100644 index 0000000..c421b86 --- /dev/null +++ b/mods/xdecor/handlers/registration.lua @@ -0,0 +1,78 @@ + + +local default_can_dig = function(pos) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("main") +end + +local function xdecor_stairs_alternative(nodename, def) + local mod, name = nodename:match("(.*):(.*)") + + for groupname, value in pairs(def.groups) do + if groupname ~= "cracky" and groupname ~= "choppy" and + groupname ~= "flammable" and groupname ~= "crumbly" and + groupname ~= "snappy" then + def.groups.groupname = nil + end + end + + if minetest.get_modpath("moreblocks") then + stairsplus:register_all( + mod, + name, + nodename, + { + description = def.description, + tiles = def.tiles, + groups = def.groups, + sounds = def.sounds, + } + ) + elseif minetest.get_modpath("stairs") then + stairs.register_stair_and_slab(name,nodename, + def.groups, + def.tiles, + ("%s Stair"):format(def.description), + ("%s Slab"):format(def.description), + def.sounds + ) + end + end + +function xdecor.register(name, def) + def.drawtype = def.drawtype or (def.mesh and "mesh") or (def.node_box and "nodebox") + def.sounds = def.sounds or default.node_sound_defaults() + + if not (def.drawtype == "normal" or def.drawtype == "signlike" or + def.drawtype == "plantlike" or def.drawtype == "glasslike_framed" or + def.drawtype == "glasslike_framed_optional") then + def.paramtype2 = def.paramtype2 or "facedir" + end + + if def.sunlight_propagates ~= false and + (def.drawtype == "plantlike" or def.drawtype == "torchlike" or + def.drawtype == "signlike" or def.drawtype == "fencelike") then + def.sunlight_propagates = true + end + + if not def.paramtype and + (def.light_source or def.sunlight_propagates or + def.drawtype == "nodebox" or def.drawtype == "mesh") then + def.paramtype = "light" + end + + local infotext = def.infotext + local inventory = def.inventory + + + minetest.register_node("xdecor:" .. name, def) + + local workbench = minetest.settings:get_bool("enable_xdecor_workbench") + + if workbench == false and + (minetest.get_modpath("moreblocks") or minetest.get_modpath("stairs")) then + if xdecor.stairs_valid_def(def) then + xdecor_stairs_alternative("xdecor:"..name, def) + end + end +end diff --git a/mods/xdecor/init.lua b/mods/xdecor/init.lua new file mode 100644 index 0000000..98867f0 --- /dev/null +++ b/mods/xdecor/init.lua @@ -0,0 +1,30 @@ +--local t = os.clock() + +xdecor = {} +local modpath = minetest.get_modpath("xdecor") + +dofile(modpath .. "/handlers/animations.lua") +dofile(modpath .. "/handlers/helpers.lua") +dofile(modpath .. "/handlers/nodeboxes.lua") +dofile(modpath .. "/handlers/registration.lua") + +dofile(modpath .. "/src/nodes.lua") + + +local subpart = { + "cooking", + "itemframe", + "mailbox", + "mechanisms", + "rope", + "workbench", +} + +for _, name in ipairs(subpart) do + local enable = minetest.settings:get_bool("enable_xdecor_" .. name) + if enable or enable == nil then + dofile(modpath .. "/src/" .. name .. ".lua") + end +end + +--print(string.format("[xdecor] loaded in %.2f ms", (os.clock()-t)*1000)) diff --git a/mods/xdecor/locale/template.txt b/mods/xdecor/locale/template.txt new file mode 100644 index 0000000..4addddd --- /dev/null +++ b/mods/xdecor/locale/template.txt @@ -0,0 +1,155 @@ +# textdomain: xdecor + + +### chess.lua ### + +Black Bishop= +Black King= +Black Knight= +Black Pawn= +Black Queen= +Black Rook= +Chess= +Chess Board= +Dumb AI= +Multiplayer= +New game= +Select a mode:= +Singleplayer= +Someone else plays black pieces!= +Someone else plays white pieces!= +White Bishop= +White King= +White Knight= +White Pawn= +White Queen= +White Rook= + +You can't dig the chessboard, a game has been started. Reset it first if you're a current player, or dig it again in @1= + +You can't reset the chessboard, a game has been started. If you aren't a current player, try again in @1= + +check= + +### cooking.lua ### + +Bowl= +Bowl of soup= +Cauldron= +Cauldron (active)= +Cauldron (active) - Drop foods inside to make a soup= +Cauldron (active) - Use a bowl to eat the soup= +Cauldron (empty)= +Cauldron (idle)= +No room in your inventory to add a bowl of soup.= +No room in your inventory to add a bucket of water.= + +### enchanting.lua ### + +Axe= +Bronze= +Diamond= +Durability= +Efficiency= +Enchanted @1 @2 @3= +Enchantment Table= +Mese= +Pickaxe= +Sharpness= +Shovel= +Steel= +Sword= +Your tool digs faster= +Your tool last longer= +Your weapon inflicts more damages= + +### hive.lua ### + +Artificial Hive= +Bees are busy making honey…= +Honey= + +### itemframe.lua ### + +@1 (owned by @2)= +Item Frame= + +### mailbox.lua ### + +@1's Mailbox= +Last donators= +Mailbox= +Send your goods to@n@1= +The mailbox is full.= + +### mechanisms.lua ### + +Lever= +Stone Pressure Plate= +Wooden Pressure Plate= + +### nodes.lua ### + +Bamboo Frame= +Baricade= +Barrel= +Cactus Brick= +Candle= +Chainlink= +Chair= +Coal Stone Tile= +Cobweb= +Cushion= +Cushion Block= +Desert Stone Tile= +Empty Shelf= +Ender Chest= +Garden Stone Path= +Half Wooden Cabinet= +Hardened Clay= +Iron Light Box= +Ivy= +Japanese Door= +Lantern= +Moon Brick= +Multi Shelf= +Packed Ice= +Painting= +Potted Geranium= +Potted Rose= +Potted Tulip= +Potted Viola= +Potted White Dandelion= +Potted Yellow Dandelion= +Prison Door= +Red Curtain= +Runestone= +Rusty Iron Bars= +Rusty Prison Door= +Screen Door= +Slide Door= +Stone Tile= +Table= +Tatami= +Television= +Trampoline= +Wood Frame= +Wood Framed Glass= +Wooden Cabinet= +Wooden Light Box= +Wooden Tile= +Woodglass Door= + +### rope.lua ### + +Rope= + +### workbench.lua ### + +Back= +Crafting= +Cut= +Hammer= +Repair= +Storage= +Work Bench= diff --git a/mods/xdecor/locale/xdecor.de.tr b/mods/xdecor/locale/xdecor.de.tr new file mode 100644 index 0000000..bdff769 --- /dev/null +++ b/mods/xdecor/locale/xdecor.de.tr @@ -0,0 +1,153 @@ +# textdomain: xdecor + + +### chess.lua ### + +Black Bishop=schwarzer Läufer +Black King=schwarter König +Black Knight=schwarzes Pferd +Black Pawn=schwarzer Bauer +Black Queen=schwarze Dame +Black Rook=schwarzer Turm +Chess=Schach +Chess Board=Schachbrett +Dumb AI=dumme KI +Multiplayer=Mehrspieler +New game=neues Spiel +Select a mode:=Wähle einen Modus: +Singleplayer=Einzelspieler +Someone else plays black pieces!=Jemand anderes spielt Schwarz! +Someone else plays white pieces!=Jemand anderes spielt Weiß! +White Bishop=weißer Läufer +White King=weißer König +White Knight=weißes Pferd +White Pawn=weißer Bauer +White Queen=weiße Dame +White Rook=weißer Turm +You can't dig the chessboard, a game has been started. Reset it first if you're a current player, or dig it again in @1=Das Schachbrett ist während eines Schachspieles nicht abbaubar. Setze das Spiel zurück, falls du ein Mitspieler bist oder versuche es in @1 erneut. +You can't reset the chessboard, a game has been started. If you aren't a current player, try again in @1=Das Schachbrett kann nicht zurückgesetzt werden, da ein Spiel im Gang ist. Versuche es in @1 erneut, falls du kein Mitspieler bist. + +check=Schach + +### cooking.lua ### + +Bowl=Schüssel +Bowl of soup=Suppenschüssel +Cauldron=Kessel +Cauldron (active)=Kessel (aktiv) +Cauldron (active) - Drop foods inside to make a soup=Kessel (aktiv) - Nahrungsmittel einwerfen, um Suppe zu machen. +Cauldron (active) - Use a bowl to eat the soup=Kessel (aktiv) - Benutze eine Schüssel, um die Suppe zu essen +Cauldron (empty)=Kessel (leer) +Cauldron (idle)=Kessel (untätig) +No room in your inventory to add a bowl of soup.=Zu wenig Platz im Inventar für eine Schüssel voll Suppe. +No room in your inventory to add a bucket of water.=Zu wenig Platz im Inventar für einen Eimer Wasser. + +### enchanting.lua ### + +Axe=axt +Bronze=Bronze +Diamond=Diamant +Durability=Haltbarkeit +Efficiency=Effizienz +Enchanted @1 @2 @3=verzauberte(s) @1@2 @3 +Enchantment Table=Zaubertisch +Mese=Mese +Pickaxe=Spitzhacke +Sharpness=Schärfe +Shovel=Schaufel +Steel=Eisen +Sword=Schwert +Your tool digs faster=Dein Werkzeug arbeitet schneller +Your tool last longer=Dein Werkzeug hält länger +Your weapon inflicts more damages=Deine Waffe erzeugt mehr Schaden + +### hive.lua ### + +Artificial Hive=künstlicher Bienenstock +Bees are busy making honey…=Bienen sind beschäftigt, Honig herzustellen. +Honey=Honig + +### itemframe.lua ### + +@1 (owned by @2)=@1 (gehört @2) +Item Frame=Objektrahmen + +### mailbox.lua ### + +@1's Mailbox=Briefkasten von @1 +Last donators=letzte Spender +Mailbox=Briefkasten +Send your goods to@n@1=Sende deine Waren an@n@1 +The mailbox is full.=Der Briefkasten ist voll. + +### mechanisms.lua ### + +Lever=Schalthebel +Stone Pressure Plate=steinerne Druckplatte +Wooden Pressure Plate=hölzerne Druckplatte + +### nodes.lua ### + +Bamboo Frame=Bambusgerüst +Baricade=Barrikade +Barrel=Fass +Cactus Brick=Kaktusstein +Candle=Kerze +Chainlink=Kettenvorhang +Chair=einfacher Stuhl +Coal Stone Tile=Kohle-Stein-Block +Cobweb=Spinnenwebe +Cushion=Sitzkissen +Cushion Block=Sitzkissenblock +Desert Stone Tile=Wüstensteinblock +Empty Shelf=leeres Regal +Ender Chest=Endertruhe +Garden Stone Path=Steingartenweg +Half Wooden Cabinet=halber Holzschrank +Hardened Clay=gehärteter Ton +Iron Light Box=eiseneingefasster Lichtblock +Ivy=Efeu +Japanese Door=japanische Tür +Lantern=Laterne +Moon Brick=Naturziegelwand +Multi Shelf=Mehrzweckregal +Packed Ice=Packeis +Painting=Gemälde +Potted Geranium=Geranien im Topf +Potted Rose=Rosen im Topf +Potted Tulip=Tulpen im Topf +Potted Viola=Veilchen im Topf +Potted White Dandelion=weißer Löwenzahn im Topf +Potted Yellow Dandelion=gelber Löwenzahn im Topf +Prison Door=Verliestür +Red Curtain=roter Vorhang +Runestone=Runensteinblock +Rusty Iron Bars=rostige Eisenstäbe +Rusty Prison Door=rostige Verliestür +Screen Door=französische Glastür +Slide Door=Schiebetür +Stone Tile=steinerner Block +Table=einfacher Tisch +Tatami=Tatamimatte +Television=Fernseher +Trampoline=Trampolin +Wood Frame=hölzerner Zierrahmen +Wood Framed Glass=holzeingefasstes Glas +Wooden Cabinet=Holzschrank +Wooden Light Box=holzeingefasster Lichtblock +Wooden Tile=hölzerner Dekorblock +Woodglass Door=Tür mit Lichtausschnitt + +### rope.lua ### + +Rope=Seil + +### workbench.lua ### + +Back=Zurück +Crafting=Fertigung +Cut=Zuschnitt +Hammer=Hämmerchen +Repair=Reparatur +Storage=Aufbewahrung +Work Bench=Werkbank diff --git a/mods/xdecor/locale/xdecor.fr.tr b/mods/xdecor/locale/xdecor.fr.tr new file mode 100644 index 0000000..52ae158 --- /dev/null +++ b/mods/xdecor/locale/xdecor.fr.tr @@ -0,0 +1,155 @@ +# textdomain: xdecor + + +### chess.lua ### + +Black Bishop=Fou noir +Black King=Roi noir +Black Knight=Cavalier noir +Black Pawn=Pion noir +Black Queen=Reine noire +Black Rook=Tour noire +Chess=Echecs +Chess Board=Echiquier +Dumb AI=IA stupide +Multiplayer=Multijoueur +New game=Nouvelle partie +Select a mode:=Sélectionnez un mode de jeu: +Singleplayer=Solo +Someone else plays black pieces!=Quelqu’un d’autre joue les pièces noires ! +Someone else plays white pieces!=Quelqu’un d’autre joue les pièces blanches ! +White Bishop=Fou blanc +White King=Roi blanc +White Knight=Cavalier blanc +White Pawn=Pion blanc +White Queen=Reine blanche +White Rook=Tour blanche + +You can't dig the chessboard, a game has been started. Reset it first if you're a current player, or dig it again in @1=Vous ne pouvez pas récupérer l’échiquier, une partie à été commencée. Remettez le à zéro si vous c’est votre tour de jouer, ou réessayez dans @1 + +You can't reset the chessboard, a game has been started. If you aren't a current player, try again in @1=Vous ne pouvez pas mettre à zéro l’échiquier, une partie a été commencée. Si ce n’est pas votre tour de jouer, réessayez dans @1 + +check=échec + +### cooking.lua ### + +Bowl=Bol +Bowl of soup=Bol de soupe +Cauldron=Chaudron +Cauldron (active)=Chaudron (actif) +Cauldron (active) - Drop foods inside to make a soup=Chaudron (actif) - Placez des ingrédients à l’intérieur pour faire une soupe +Cauldron (active) - Use a bowl to eat the soup=Chaudron (actif) - Utilisez un bol pour boire la soupe +Cauldron (empty)=Chaudron (vide) +Cauldron (idle)=Chaudron (inactif) +No room in your inventory to add a bowl of soup.=Pas de place dans votre inventaire pour ajouter un bol de soupe. +No room in your inventory to add a bucket of water.=Pas de place dans votre inventaire pour ajouter un seau d’eau. + +### enchanting.lua ### + +Axe=Hache +Bronze=Bronze +Diamond=Diamant +Durability=Durabilité +Efficiency=Efficacité +Enchanted @1 @2 @3=@2 en @1 enchantée @3 +Enchantment Table=Table d’enchantements +Mese=Mese +Pickaxe=Pioche +Sharpness=Tranchant +Shovel=Pelle +Steel=Fer +Sword=Épée +Your tool digs faster=Votre outil creuse plus vite +Your tool last longer=Votre outil dure plus longtemps +Your weapon inflicts more damages=Votre arme inflige plus de dégâts + +### hive.lua ### + +Artificial Hive=Ruche artificielle +Bees are busy making honey…=Les abeilles sont occupées à fabriquer du miel… +Honey=Miel + +### itemframe.lua ### + +@1 (owned by @2)=@1 (propriété de @2) +Item Frame=Cadre + +### mailbox.lua ### + +@1's Mailbox=Boite aux lettres de @1 +Last donators=Derniers donateurs +Mailbox=Boite aux lettres +Send your goods to@n@1=Envoyer vos biens à@n@1 +The mailbox is full.=La boite aux lettres est pleine. + +### mechanisms.lua ### + +Lever=Levier +Stone Pressure Plate=Plaque de pression en pierre +Wooden Pressure Plate=Plaque de pression en bois + +### nodes.lua ### + +Bamboo Frame=Cadre en bambou +Baricade=Barricade +Barrel=Tonneau +Cactus Brick=Brique en cactus +Candle=Bougie +Chainlink=Maillon de chaîne +Chair=Chaise +Coal Stone Tile=Carreau en charbon et pierre +Cobweb=Toile d’araignée +Cushion=Coussin +Cushion Block=Bloc de coussin +Desert Stone Tile=Carreau en pierre du désert +Empty Shelf=Étagère vide +Ender Chest=Coffre de l’End +Garden Stone Path=Chemin de pierres de jardin +Half Wooden Cabinet=Demi meuble en bois +Hardened Clay=Argile durcie +Iron Light Box=Boite lumineuse en fer +Ivy=Lierre +Japanese Door=Porte japonaise +Lantern=Lanterne +Moon Brick=Brique lunaire +Multi Shelf=Étagères multiple +Packed Ice=Glace compactée +Painting=Tableau +Potted Geranium=Géranium en pot +Potted Rose=Rose en pot +Potted Tulip=Tulipe en pot +Potted Viola=Violette en pot +Potted White Dandelion=Pissenlit blanc en pot +Potted Yellow Dandelion=Pissenlit jaune en pot +Prison Door=Porte de prison +Red Curtain=Rideaux rouge +Runestone=Pierre runique +Rusty Iron Bars=Barreaux en fer rouillé +Rusty Prison Door=Barreaux de prison rouillés +Screen Door=Porte avec moustiquaire +Slide Door=Porte coulissante +Stone Tile=Carreau en pierre +Table=Table +Tatami=Tatami +Television=Télévision +Trampoline=Trampoline +Wood Frame=Cadre en bois +Wood Framed Glass=Verre encadré par du bois +Wooden Cabinet=Meuble en bois +Wooden Light Box=Boite lumineuse en bois +Wooden Tile=Carreau en bois +Woodglass Door=Porte vitrée + +### rope.lua ### + +Rope=Corde + +### workbench.lua ### + +Back=Retour +Crafting=Fabrication +Cut=Couper +Hammer=Marteau +Repair=Réparer +Storage=Stockage +Work Bench=Atelier diff --git a/mods/xdecor/locale/xdecor.it.tr b/mods/xdecor/locale/xdecor.it.tr new file mode 100644 index 0000000..f88655b --- /dev/null +++ b/mods/xdecor/locale/xdecor.it.tr @@ -0,0 +1,155 @@ +# textdomain: xdecor +# Author: Salvo 'LtWorf' Tomaselli + +### chess.lua ### + +Black Bishop=Alfiere nero +Black King=Re nero +Black Knight=Cavallo nero +Black Pawn=Pedone nero +Black Queen=Regina nera +Black Rook=Torre nera +Chess=Scacchi +Chess Board=Scacchiera +Dumb AI=AI stupida +Multiplayer=Multigiocatore +New game=Nuova partita +Select a mode:=Selezionare una modalità +Singleplayer=Singolo giocatore +Someone else plays black pieces!=Qualcun altro gioca con il nero! +Someone else plays white pieces!=Qualcun altro gioca con il bianco! +White Bishop=Alfiere bianco +White King=Re bianco +White Knight=Cavallo bianco +White Pawn=Pedone bianco +White Queen=Regina bianca +White Rook=Torre bianca + +You can't dig the chessboard, a game has been started. Reset it first if you're a current player, or dig it again in @1=Non si può scavare la scacchiera, una partita è in corso. Resettarla se si è uno dei giocatori, o riprovare in @1 + +You can't reset the chessboard, a game has been started. If you aren't a current player, try again in @1=Non si può resettare la partita, un gioco è in corso. Se non si è uno dei giocatori, riprovare in @1 + +check=scacco + +### cooking.lua ### + +Bowl=Ciotola +Bowl of soup=Ciotola di zuppa +Cauldron=Calderone +Cauldron (active)=Calderone (attivo) +Cauldron (active) - Drop foods inside to make a soup=Calderone (attivo) - Mettere gli ingredienti all'interno per fare una zuppa. +Cauldron (active) - Use a bowl to eat the soup=Calderone (actif) - Utilizzare una ciotola per mangiare la zuppa +Cauldron (empty)=Calderone (vuoto) +Cauldron (idle)=Calderone (inattivo) +No room in your inventory to add a bowl of soup.=Non c'è spazio nell'inventario per aggiungere una ciotola di zuppa. +No room in your inventory to add a bucket of water.=Non c'è spazio nell'inventario per aggiungere un secchio di acqua. + +### enchanting.lua ### + +Axe=Ascia +Bronze=Bronzo +Diamond=Diamante +Durability=Durabilità +Efficiency=Efficacia +Enchanted @1 @2 @3=@2 su @1 incantesimo @3 +Enchantment Table=Tavolo per migliorie +Mese=Mese +Pickaxe=Piccone +Sharpness=Affilatezza +Shovel=Pala +Steel=Acciaio +Sword=Spada +Your tool digs faster=Il tuo utensile scava più rapidamente +Your tool last longer=Il tuo utensile dura di più +Your weapon inflicts more damages=La tua arma infligge più danno + +### hive.lua ### + +Artificial Hive=Favo artificiale +Bees are busy making honey…=Le api sono occupate a fare il miele… +Honey=Miele + +### itemframe.lua ### + +@1 (owned by @2)=@1 (proprietà di @2) +Item Frame=Teca + +### mailbox.lua ### + +@1's Mailbox=Cassetta delle lettere di @1 +Last donators=Ultimi donatori +Mailbox=Cassetta delle lettere +Send your goods to@n@1=Invia i tuoi item a@n@1 +The mailbox is full.=La cassetta delle lettere è piena + +### mechanisms.lua ### + +Lever=Leva +Stone Pressure Plate=Placca di pressione di pietra +Wooden Pressure Plate=Placca di pressione di legno + +### nodes.lua ### + +Bamboo Frame=Cornice di bambù +Baricade=Barricata +Barrel=Barile +Cactus Brick=Mattone di cactus +Candle=Candela +Chainlink=Cotta di maglia +Chair=Sedia +Coal Stone Tile=Mattonella di pietra di carbone +Cobweb=Ragnatela +Cushion=Cuscino +Cushion Block=Blocco di cuscini +Desert Stone Tile=Mattonella di pietra del deserto +Empty Shelf=Mensola vuota +Ender Chest=Baule ender +Garden Stone Path=Sentiero da giardino in pietra +Half Wooden Cabinet=Stipo di legno a metà +Hardened Clay=Argilla indurita +Iron Light Box=Scatola luminosa di ferro +Ivy=Edera +Japanese Door=Porta giapponese +Lantern=Lanterna +Moon Brick=Mattone lunare +Multi Shelf=Mensole +Packed Ice=Ghiaccio compatto +Painting=Dipinto +Potted Geranium=Geranio in vaso +Potted Rose=Rosa in vaso +Potted Tulip=Tulipano in vaso +Potted Viola=Violetta in vaso +Potted White Dandelion=Soffione bianco in vaso +Potted Yellow Dandelion=Soffione giallo in vaso +Prison Door=Porta di prigione +Red Curtain=Tenda rossa +Runestone=Pietra runica +Rusty Iron Bars=Sbarre di prigione arrugginite +Rusty Prison Door=Porta di prigione arrugginita +Screen Door=Porta a schermo +Slide Door=Porta scorrevole +Stone Tile=Mattonella di pietra +Table=Tavolo +Tatami=Tatami +Television=Televisione +Trampoline=Trampolino +Wood Frame=Cornice in legno +Wood Framed Glass=Cornice in legno con vetro +Wooden Cabinet=Stipo di legno +Wooden Light Box=Mattonella luminosa di legno +Wooden Tile=Mattonella di legno +Woodglass Door=Porta di vetro + +### rope.lua ### + +Rope=Corda + +### workbench.lua ### + +Back=Indietro +Crafting=Fabbricare +Cut=Tagliare +Hammer=Martello +Repair=Riparare +Storage=Conservare +Work Bench=Banco da lavoro diff --git a/mods/xdecor/mod.conf b/mods/xdecor/mod.conf new file mode 100644 index 0000000..17a11a1 --- /dev/null +++ b/mods/xdecor/mod.conf @@ -0,0 +1,5 @@ +name = xdecor +description = A decoration mod meant to be simple and well-featured. +depends = doors, stairs, xpanes +optional_depends = fire, oresplus, moreblocks, mesecons +min_minetest_version = 5.1.0 diff --git a/mods/xdecor/screenshot.png b/mods/xdecor/screenshot.png new file mode 100644 index 0000000..ae0c2e1 Binary files /dev/null and b/mods/xdecor/screenshot.png differ diff --git a/mods/xdecor/settingtypes.txt b/mods/xdecor/settingtypes.txt new file mode 100644 index 0000000..f75d75c --- /dev/null +++ b/mods/xdecor/settingtypes.txt @@ -0,0 +1,11 @@ +#For enabling a subpart of X-Decor. + +enable_xdecor_chess (Enable Chess) bool true +enable_xdecor_cooking (Enable Cooking) bool true +enable_xdecor_enchanting (Enable Enchanting) bool true +enable_xdecor_hive (Enable Hive) bool true +enable_xdecor_itemframe (Enable Itemframe) bool true +enable_xdecor_mailbox (Enable Mailbox) bool true +enable_xdecor_mechanisms (Enable Mechanisms) bool true +enable_xdecor_rope (Enable Rope) bool true +enable_xdecor_workbench (Enable Workbench) bool true \ No newline at end of file diff --git a/mods/xdecor/sounds/xdecor_boiling_water.ogg b/mods/xdecor/sounds/xdecor_boiling_water.ogg new file mode 100644 index 0000000..cc1e7a5 Binary files /dev/null and b/mods/xdecor/sounds/xdecor_boiling_water.ogg differ diff --git a/mods/xdecor/sounds/xdecor_bouncy.ogg b/mods/xdecor/sounds/xdecor_bouncy.ogg new file mode 100644 index 0000000..779e825 Binary files /dev/null and b/mods/xdecor/sounds/xdecor_bouncy.ogg differ diff --git a/mods/xdecor/sounds/xdecor_enchanting.ogg b/mods/xdecor/sounds/xdecor_enchanting.ogg new file mode 100644 index 0000000..882e9ee Binary files /dev/null and b/mods/xdecor/sounds/xdecor_enchanting.ogg differ diff --git a/mods/xdecor/src/cooking.lua b/mods/xdecor/src/cooking.lua new file mode 100644 index 0000000..8abcb14 --- /dev/null +++ b/mods/xdecor/src/cooking.lua @@ -0,0 +1,267 @@ +local cauldron, sounds = {}, {} +local S = minetest.get_translator("xdecor") + +-- Add more ingredients here that make a soup. +local ingredients_list = { + "apple", "mushroom", "honey", "pumpkin", "egg", "bread", "meat", + "chicken", "carrot", "potato", "melon", "rhubarb", "cucumber", + "corn", "beans", "berries", "grapes", "tomato", "wheat" +} + +cauldron.cbox = { + {0, 0, 0, 16, 16, 0}, + {0, 0, 16, 16, 16, 0}, + {0, 0, 0, 0, 16, 16}, + {16, 0, 0, 0, 16, 16}, + {0, 0, 0, 16, 8, 16} +} + +function cauldron.stop_sound(pos) + local spos = minetest.hash_node_position(pos) + if sounds[spos] then + minetest.sound_stop(sounds[spos]) + end +end + +function cauldron.idle_construct(pos) + local timer = minetest.get_node_timer(pos) + timer:start(10.0) + cauldron.stop_sound(pos) +end + +function cauldron.boiling_construct(pos) + local spos = minetest.hash_node_position(pos) + sounds[spos] = minetest.sound_play("xdecor_boiling_water", { + pos = pos, + max_hear_distance = 5, + gain = 0.8, + loop = true + }) + + local meta = minetest.get_meta(pos) + meta:set_string("infotext", S("Cauldron (active) - Drop foods inside to make a soup")) + + local timer = minetest.get_node_timer(pos) + timer:start(5.0) +end + +function cauldron.filling(pos, node, clicker, itemstack) + local inv = clicker:get_inventory() + local wield_item = clicker:get_wielded_item():get_name() + + if wield_item:sub(1,7) == "bucket:" then + if wield_item:sub(-6) == "_empty" and not (node.name:sub(-6) == "_empty") then + if itemstack:get_count() > 1 then + if inv:room_for_item("main", "bucket:bucket_water 1") then + itemstack:take_item() + inv:add_item("main", "bucket:bucket_water 1") + else + minetest.chat_send_player(clicker:get_player_name(), + S("No room in your inventory to add a bucket of water.")) + return itemstack + end + else + itemstack:replace("bucket:bucket_water") + end + minetest.set_node(pos, {name = "xdecor:cauldron_empty", param2 = node.param2}) + + elseif wield_item:sub(-6) == "_water" and node.name:sub(-6) == "_empty" then + minetest.set_node(pos, {name = "xdecor:cauldron_idle", param2 = node.param2}) + itemstack:replace("bucket:bucket_empty") + end + + return itemstack + end +end + +function cauldron.idle_timer(pos) + local below_node = {x = pos.x, y = pos.y - 1, z = pos.z} + if not minetest.get_node(below_node).name:find("fire") then + return true + end + + local node = minetest.get_node(pos) + minetest.set_node(pos, {name = "xdecor:cauldron_boiling", param2 = node.param2}) + return true +end + +-- Ugly hack to determine if an item has the function `minetest.item_eat` in its definition. +local function eatable(itemstring) + local item = itemstring:match("[%w_:]+") + local on_use_def = minetest.registered_items[item].on_use + if not on_use_def then return end + + return string.format("%q", string.dump(on_use_def)):find("item_eat") +end + +function cauldron.boiling_timer(pos) + local node = minetest.get_node(pos) + local objs = minetest.get_objects_inside_radius(pos, 0.5) + + if not next(objs) then + return true + end + + local ingredients = {} + for _, obj in pairs(objs) do + if obj and not obj:is_player() and obj:get_luaentity().itemstring then + local itemstring = obj:get_luaentity().itemstring + local food = itemstring:match(":([%w_]+)") + + for _, ingredient in ipairs(ingredients_list) do + if food and (eatable(itemstring) or food:find(ingredient)) then + ingredients[#ingredients + 1] = food + break + end + end + end + end + + if #ingredients >= 2 then + for _, obj in pairs(objs) do + obj:remove() + end + + minetest.set_node(pos, {name = "xdecor:cauldron_soup", param2 = node.param2}) + end + + local node_under = {x = pos.x, y = pos.y - 1, z = pos.z} + + if not minetest.get_node(node_under).name:find("fire") then + minetest.set_node(pos, {name = "xdecor:cauldron_idle", param2 = node.param2}) + end + + return true +end + +function cauldron.take_soup(pos, node, clicker, itemstack) + local inv = clicker:get_inventory() + local wield_item = clicker:get_wielded_item() + local item_name = wield_item:get_name() + + if item_name == "xdecor:bowl" or item_name == "farming:bowl" then + if wield_item:get_count() > 1 then + if inv:room_for_item("main", "xdecor:bowl_soup 1") then + itemstack:take_item() + inv:add_item("main", "xdecor:bowl_soup 1") + else + minetest.chat_send_player(clicker:get_player_name(), + S("No room in your inventory to add a bowl of soup.")) + return itemstack + end + else + itemstack:replace("xdecor:bowl_soup 1") + end + + minetest.set_node(pos, {name = "xdecor:cauldron_empty", param2 = node.param2}) + end + + return itemstack +end + +xdecor.register("cauldron_empty", { + description = S("Cauldron"), + groups = {cracky=2, oddly_breakable_by_hand=1}, + on_rotate = screwdriver.rotate_simple, + tiles = {"xdecor_cauldron_top_empty.png", "xdecor_cauldron_sides.png"}, + infotext = S("Cauldron (empty)"), + collision_box = xdecor.pixelbox(16, cauldron.cbox), + on_rightclick = cauldron.filling, + on_construct = function(pos) + cauldron.stop_sound(pos) + end, +}) + +xdecor.register("cauldron_idle", { + description = S("Cauldron (idle)"), + groups = {cracky=2, oddly_breakable_by_hand=1, not_in_creative_inventory=1}, + on_rotate = screwdriver.rotate_simple, + tiles = {"xdecor_cauldron_top_idle.png", "xdecor_cauldron_sides.png"}, + drop = "xdecor:cauldron_empty", + infotext = S("Cauldron (idle)"), + collision_box = xdecor.pixelbox(16, cauldron.cbox), + on_rightclick = cauldron.filling, + on_construct = cauldron.idle_construct, + on_timer = cauldron.idle_timer, +}) + +xdecor.register("cauldron_boiling", { + description = S("Cauldron (active)"), + groups = {cracky=2, oddly_breakable_by_hand=1, not_in_creative_inventory=1}, + on_rotate = screwdriver.rotate_simple, + drop = "xdecor:cauldron_empty", + infotext = S("Cauldron (active) - Drop foods inside to make a soup"), + damage_per_second = 2, + tiles = { + { + name = "xdecor_cauldron_top_anim_boiling_water.png", + animation = {type = "vertical_frames", length = 3.0} + }, + "xdecor_cauldron_sides.png" + }, + collision_box = xdecor.pixelbox(16, cauldron.cbox), + on_rightclick = cauldron.filling, + on_construct = cauldron.boiling_construct, + on_timer = cauldron.boiling_timer, + on_destruct = function(pos) + cauldron.stop_sound(pos) + end, +}) + +xdecor.register("cauldron_soup", { + description = S("Cauldron (active)"), + groups = {cracky = 2, oddly_breakable_by_hand = 1, not_in_creative_inventory = 1}, + on_rotate = screwdriver.rotate_simple, + drop = "xdecor:cauldron_empty", + infotext = S("Cauldron (active) - Use a bowl to eat the soup"), + damage_per_second = 2, + tiles = { + { + name = "xdecor_cauldron_top_anim_soup.png", + animation = {type = "vertical_frames", length = 3.0} + }, + "xdecor_cauldron_sides.png" + }, + collision_box = xdecor.pixelbox(16, cauldron.cbox), + on_rightclick = cauldron.take_soup, + on_destruct = function(pos) + cauldron.stop_sound(pos) + end, +}) + +-- Craft items + +minetest.register_craftitem("xdecor:bowl", { + description = S("Bowl"), + inventory_image = "xdecor_bowl.png", + wield_image = "xdecor_bowl.png", + groups = {food_bowl = 1, flammable = 2}, +}) + +minetest.register_craftitem("xdecor:bowl_soup", { + description = S("Bowl of soup"), + inventory_image = "xdecor_bowl_soup.png", + wield_image = "xdecor_bowl_soup.png", + groups = {not_in_creative_inventory=1}, + stack_max = 1, + on_use = minetest.item_eat(30, "xdecor:bowl") +}) + +-- Recipes + +minetest.register_craft({ + output = "xdecor:bowl 3", + recipe = { + {"group:wood", "", "group:wood"}, + {"", "group:wood", ""} + } +}) + +minetest.register_craft({ + output = "xdecor:cauldron_empty", + recipe = { + {"default:iron_lump", "", "default:iron_lump"}, + {"default:iron_lump", "", "default:iron_lump"}, + {"default:iron_lump", "default:iron_lump", "default:iron_lump"} + } +}) diff --git a/mods/xdecor/src/enchanting.lua b/mods/xdecor/src/enchanting.lua new file mode 100644 index 0000000..fd07336 --- /dev/null +++ b/mods/xdecor/src/enchanting.lua @@ -0,0 +1,336 @@ +screwdriver = screwdriver or {} +local S = minetest.get_translator("xdecor") +local FS = function(...) return minetest.formspec_escape(S(...)) end +local ceil, abs, random = math.ceil, math.abs, math.random +local reg_tools = minetest.registered_tools + +-- Cost in Mese crystal(s) for enchanting. +local mese_cost = 1 + +-- Force of the enchantments. +local enchanting = { + uses = 1.2, -- Durability + times = 0.1, -- Efficiency + damages = 1, -- Sharpness +} + +local function cap(str) return + str:gsub("^%l", string.upper) +end + +local function to_percent(orig_value, final_value) + return abs(ceil(((final_value - orig_value) / orig_value) * 100)) +end + +function enchanting:get_tooltip(enchant, orig_caps, fleshy) + local bonus = {durable = 0, efficiency = 0, damages = 0} + + if orig_caps then + bonus.durable = to_percent(orig_caps.uses, orig_caps.uses * enchanting.uses) + local sum_caps_times = 0 + for i=1, #orig_caps.times do + sum_caps_times = sum_caps_times + orig_caps.times[i] + end + local average_caps_time = sum_caps_times / #orig_caps.times + bonus.efficiency = to_percent(average_caps_time, average_caps_time - + enchanting.times) + end + + if fleshy then + bonus.damages = to_percent(fleshy, fleshy + enchanting.damages) + end + + local specs = { -- not finished, to complete + durable = {"#00baff", " (+" .. bonus.durable .. "%)"}, + fast = {"#74ff49", " (+" .. bonus.efficiency .. "%)"}, + sharp = {"#ffff00", " (+" .. bonus.damages .. "%)"}, + } + + local enchant_loc = { + fast = S("Efficiency"), + durable = S("Durability"), + sharp = S("Sharpness"), + } + + return minetest.colorize and minetest.colorize(specs[enchant][1], + "\n" .. enchant_loc[enchant] .. specs[enchant][2]) or + "\n" .. enchant_loc[enchant] .. specs[enchant][2] +end + +local enchant_buttons = { + "image_button[3.9,0.85;4,0.92;bg_btn.png;fast;"..FS("Efficiency").."]" .. + "image_button[3.9,1.77;4,1.12;bg_btn.png;durable;"..FS("Durability").."]", + "image_button[3.9,2.9;4,0.92;bg_btn.png;sharp;"..FS("Sharpness").."]", +} + +function enchanting.formspec(pos, num) + local meta = minetest.get_meta(pos) + local formspec = [[ + size[9,8.6;] + no_prepend[] + bgcolor[#080808BB;true] + listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF] + background9[0,0;9,9;ench_ui.png;6] + list[context;tool;0.9,2.9;1,1;] + list[context;mese;2,2.9;1,1;] + list[current_player;main;0.55,4.5;8,4;] + listring[current_player;main] + listring[context;tool] + listring[current_player;main] + listring[context;mese] + image[2,2.9;1,1;mese_layout.png] + ]] + .."tooltip[sharp;"..FS("Your weapon inflicts more damages").."]" + .."tooltip[durable;"..FS("Your tool last longer").."]" + .."tooltip[fast;"..FS("Your tool digs faster").."]" + ..default.gui_slots .. default.get_hotbar_bg(0.55, 4.5) + + formspec = formspec .. (enchant_buttons[num] or "") + meta:set_string("formspec", formspec) +end + +function enchanting.on_put(pos, listname, _, stack) + if listname == "tool" then + local stackname = stack:get_name() + local tool_groups = { + "axe, pick, shovel", + "sword", + } + + for idx, tools in ipairs(tool_groups) do + if tools:find(stackname:match(":(%w+)")) then + enchanting.formspec(pos, idx) + end + end + end +end + +function enchanting.fields(pos, _, fields, sender) + if not next(fields) or fields.quit then return end + local inv = minetest.get_meta(pos):get_inventory() + local tool = inv:get_stack("tool", 1) + local mese = inv:get_stack("mese", 1) + local orig_wear = tool:get_wear() + local mod, name = tool:get_name():match("(.*):(.*)") + local enchanted_tool = (mod or "") .. ":enchanted_" .. (name or "") .. "_" .. next(fields) + + if mese:get_count() >= mese_cost and reg_tools[enchanted_tool] then + minetest.sound_play("xdecor_enchanting", { + to_player = sender:get_player_name(), + gain = 0.8 + }) + + tool:replace(enchanted_tool) + tool:add_wear(orig_wear) + mese:take_item(mese_cost) + inv:set_stack("mese", 1, mese) + inv:set_stack("tool", 1, tool) + end +end + +function enchanting.dig(pos) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("tool") and inv:is_empty("mese") +end + +local function allowed(tool) + if not tool then return end + + for item in pairs(reg_tools) do + if item:find("enchanted_" .. tool) then + return true + end + end +end + +function enchanting.put(_, listname, _, stack) + local stackname = stack:get_name() + if listname == "mese" and (stackname == "default:mese_crystal" or + stackname == "imese:industrial_mese_crystal") then + return stack:get_count() + elseif listname == "tool" and allowed(stackname:match("[^:]+$")) then + return 1 + end + + return 0 +end + +function enchanting.on_take(pos, listname) + if listname == "tool" then + enchanting.formspec(pos) + end +end + +function enchanting.construct(pos) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", S("Enchantment Table")) + enchanting.formspec(pos) + + local inv = meta:get_inventory() + inv:set_size("tool", 1) + inv:set_size("mese", 1) + + minetest.add_entity({x = pos.x, y = pos.y + 0.85, z = pos.z}, "xdecor:book_open") + local timer = minetest.get_node_timer(pos) + timer:start(0.5) +end + +function enchanting.destruct(pos) + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0.9)) do + if obj and obj:get_luaentity() and + obj:get_luaentity().name == "xdecor:book_open" then + obj:remove() + break + end + end +end + +function enchanting.timer(pos) + local minp = {x = pos.x - 2, y = pos.y, z = pos.z - 2} + local maxp = {x = pos.x + 2, y = pos.y + 1, z = pos.z + 2} + + local bookshelves = minetest.find_nodes_in_area(minp, maxp, "default:bookshelf") + if #bookshelves == 0 then + return true + end + + local bookshelf_pos = bookshelves[random(1, #bookshelves)] + local x = pos.x - bookshelf_pos.x + local y = bookshelf_pos.y - pos.y + local z = pos.z - bookshelf_pos.z + + if tostring(x .. z):find(2) then + minetest.add_particle({ + pos = bookshelf_pos, + velocity = {x = x, y = 2 - y, z = z}, + acceleration = {x = 0, y = -2.2, z = 0}, + expirationtime = 1, + size = 1.5, + glow = 5, + texture = "xdecor_glyph" .. random(1,18) .. ".png" + }) + end + + return true +end + +xdecor.register("enchantment_table", { + description = S("Enchantment Table"), + tiles = { + "xdecor_enchantment_top.png", "xdecor_enchantment_bottom.png", + "xdecor_enchantment_side.png", "xdecor_enchantment_side.png", + "xdecor_enchantment_side.png", "xdecor_enchantment_side.png" + }, + groups = {cracky = 1, level = 1}, + light_source = 6, + sounds = default.node_sound_stone_defaults(), + on_rotate = screwdriver.rotate_simple, + can_dig = enchanting.dig, + on_timer = enchanting.timer, + on_construct = enchanting.construct, + on_destruct = enchanting.destruct, + on_receive_fields = enchanting.fields, + on_metadata_inventory_put = enchanting.on_put, + on_metadata_inventory_take = enchanting.on_take, + allow_metadata_inventory_put = enchanting.put, + allow_metadata_inventory_move = function() + return 0 + end, +}) + +minetest.register_entity("xdecor:book_open", { + visual = "sprite", + visual_size = {x=0.75, y=0.75}, + collisionbox = {0}, + physical = false, + textures = {"xdecor_book_open.png"}, + static_save = false, +}) + +minetest.register_lbm({ + label = "recreate book entity", + name = "xdecor:create_book_entity", + nodenames = {"xdecor:enchantment_table"}, + run_at_every_load = true, + action = function(pos, node) + local objs = minetest.get_objects_inside_radius(pos, 0.9) + + for _, obj in ipairs(objs) do + local e = obj:get_luaentity() + if e and e.name == "xdecor:book_open" then + return + end + end + + minetest.add_entity({x = pos.x, y = pos.y + 0.85, z = pos.z}, "xdecor:book_open") + end, +}) + +function enchanting:register_tools(mod, def) + for tool in pairs(def.tools) do + for material in def.materials:gmatch("[%w_]+") do + for enchant in def.tools[tool].enchants:gmatch("[%w_]+") do + local original_tool = reg_tools[mod .. ":" .. tool .. "_" .. material] + if not original_tool then break end + local original_toolcaps = original_tool.tool_capabilities + + if original_toolcaps then + local original_damage_groups = original_toolcaps.damage_groups + local original_groupcaps = original_toolcaps.groupcaps + local groupcaps = table.copy(original_groupcaps) + local fleshy = original_damage_groups.fleshy + local full_punch_interval = original_toolcaps.full_punch_interval + local max_drop_level = original_toolcaps.max_drop_level + local group = next(original_groupcaps) + + if enchant == "durable" then + groupcaps[group].uses = ceil(original_groupcaps[group].uses * + enchanting.uses) + elseif enchant == "fast" then + for i, time in pairs(original_groupcaps[group].times) do + groupcaps[group].times[i] = time - enchanting.times + end + elseif enchant == "sharp" then + fleshy = fleshy + enchanting.damages + end + + minetest.register_tool(":" .. mod .. ":enchanted_" .. tool .. "_" .. material .. "_" .. enchant, { + description = S("Enchanted @1 @2 @3", + def.material_desc[material] or cap(material), def.tools[tool].desc or cap(tool), + self:get_tooltip(enchant, original_groupcaps[group], fleshy)), + inventory_image = original_tool.inventory_image .. "^[colorize:violet:50", + wield_image = original_tool.wield_image, + groups = {not_in_creative_inventory = 1}, + tool_capabilities = { + groupcaps = groupcaps, damage_groups = {fleshy = fleshy}, + full_punch_interval = full_punch_interval, + max_drop_level = max_drop_level + } + }) + end + end + end + end +end + +enchanting:register_tools("default", { + materials = "steel, bronze, mese, diamond", + material_desc = {steel = S("Steel"), bronze = S("Bronze"), mese = S("Mese"), diamond = S("Diamond")}, + tools = { + axe = {enchants = "durable, fast", desc = S("Axe")}, + pick = {enchants = "durable, fast", desc = S("Pickaxe")}, + shovel = {enchants = "durable, fast", desc = S("Shovel")}, + sword = {enchants = "sharp", desc = S("Sword")} + }, +}) + +-- Recipes + +minetest.register_craft({ + output = "xdecor:enchantment_table", + recipe = { + {"", "default:book", ""}, + {"default:diamond", "default:obsidian", "default:diamond"}, + {"default:obsidian", "default:obsidian", "default:obsidian"} + } +}) diff --git a/mods/xdecor/src/hive.lua b/mods/xdecor/src/hive.lua new file mode 100644 index 0000000..2aa9910 --- /dev/null +++ b/mods/xdecor/src/hive.lua @@ -0,0 +1,108 @@ +local hive = {} +local S = minetest.get_translator("xdecor") +local FS = function(...) return minetest.formspec_escape(S(...)) end +local honey_max = 16 + +function hive.construct(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + local formspec = "size[8,6;]" + .."label[0.5,0;"..FS("Bees are busy making honey…").."]" + ..[[ image[6,1;1,1;hive_bee.png] + image[5,1;1,1;hive_layout.png] + list[context;honey;5,1;1,1;] + list[current_player;main;0,2.35;8,4;] + listring[current_player;main] + listring[context;honey] ]] .. + xbg .. default.get_hotbar_bg(0,2.35) + + meta:set_string("formspec", formspec) + meta:set_string("infotext", S("Artificial Hive")) + inv:set_size("honey", 1) + + local timer = minetest.get_node_timer(pos) + timer:start(math.random(64, 128)) +end + +function hive.timer(pos) + local time = (minetest.get_timeofday() or 0) * 24000 + if time < 5500 or time > 18500 then + return true + end + + local inv = minetest.get_meta(pos):get_inventory() + local honeystack = inv:get_stack("honey", 1) + local honey = honeystack:get_count() + + local radius = 4 + local minp = vector.add(pos, -radius) + local maxp = vector.add(pos, radius) + local flowers = minetest.find_nodes_in_area_under_air(minp, maxp, "group:flower") + + if #flowers > 2 and honey < honey_max then + inv:add_item("honey", "xdecor:honey") + elseif honey == honey_max then + local timer = minetest.get_node_timer(pos) + timer:stop() + return true + end + + return true +end + +xdecor.register("hive", { + description = S("Artificial Hive"), + tiles = {"xdecor_hive_top.png", "xdecor_hive_top.png", + "xdecor_hive_side.png", "xdecor_hive_side.png", + "xdecor_hive_side.png", "xdecor_hive_front.png"}, + groups = {choppy=3, oddly_breakable_by_hand=2, flammable=1}, + on_construct = hive.construct, + on_timer = hive.timer, + + can_dig = function(pos) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("honey") + end, + + on_punch = function(_, _, puncher) + puncher:set_hp(puncher:get_hp() - 2) + end, + + allow_metadata_inventory_put = function() + return 0 + end, + + on_metadata_inventory_take = function(pos, _, _, stack) + if stack:get_count() == honey_max then + local timer = minetest.get_node_timer(pos) + timer:start(math.random(64, 128)) + end + end +}) + +-- Craft items + +minetest.register_craftitem("xdecor:honey", { + description = S("Honey"), + inventory_image = "xdecor_honey.png", + wield_image = "xdecor_honey.png", + on_use = minetest.item_eat(2), + groups = { + food_honey = 1, + food_sugar = 1, + flammable = 2, + not_in_creative_inventory = 1, + }, +}) + +-- Recipes + +minetest.register_craft({ + output = "xdecor:hive", + recipe = { + {"group:stick", "group:stick", "group:stick"}, + {"default:paper", "default:paper", "default:paper"}, + {"group:stick", "group:stick", "group:stick"} + } +}) diff --git a/mods/xdecor/src/itemframe.lua b/mods/xdecor/src/itemframe.lua new file mode 100644 index 0000000..38dcc0a --- /dev/null +++ b/mods/xdecor/src/itemframe.lua @@ -0,0 +1,186 @@ +local itemframe, tmp = {}, {} +local S = minetest.get_translator("xdecor") +screwdriver = screwdriver or {} + +local function remove_item(pos, node) + local objs = minetest.get_objects_inside_radius(pos, 0.5) + if not objs then return end + + for _, obj in pairs(objs) do + local ent = obj:get_luaentity() + if obj and ent and ent.name == "xdecor:f_item" then + obj:remove() break + end + end +end + +local facedir = { + [0] = {x = 0, y = 0, z = 1}, + {x = 1, y = 0, z = 0}, + {x = 0, y = 0, z = -1}, + {x = -1, y = 0, z = 0} +} + +local function update_item(pos, node) + remove_item(pos, node) + local meta = minetest.get_meta(pos) + local itemstring = meta:get_string("item") + local posad = facedir[node.param2] + if not posad or itemstring == "" then return end + + pos = vector.add(pos, vector.multiply(posad, 6.5/16)) + tmp.nodename = node.name + tmp.texture = ItemStack(itemstring):get_name() + + local entity = minetest.add_entity(pos, "xdecor:f_item") + local yaw = (math.pi * 2) - node.param2 * (math.pi / 2) + entity:set_yaw(yaw) + + local timer = minetest.get_node_timer(pos) + timer:start(15.0) +end + +local function drop_item(pos, node) + local meta = minetest.get_meta(pos) + local item = meta:get_string("item") + if item == "" then return end + + minetest.add_item(pos, item) + meta:set_string("item", "") + remove_item(pos, node) + + local timer = minetest.get_node_timer(pos) + timer:stop() +end + +function itemframe.after_place(pos, placer, itemstack) + local meta = minetest.get_meta(pos) + local name = placer:get_player_name() + meta:set_string("owner", name) + meta:set_string("infotext", S("@1 (owned by @2)", S("Item Frame"), name)) +end + +function itemframe.timer(pos) + local node = minetest.get_node(pos) + local meta = minetest.get_meta(pos) + local num = #minetest.get_objects_inside_radius(pos, 0.5) + + if num == 0 and meta:get_string("item") ~= "" then + update_item(pos, node) + end + + return true +end + +function itemframe.rightclick(pos, node, clicker, itemstack) + local meta = minetest.get_meta(pos) + local player_name = clicker:get_player_name() + local owner = meta:get_string("owner") + local admin = minetest.check_player_privs(player_name, "protection_bypass") + + if not admin and (player_name ~= owner or not itemstack) then + return itemstack + end + + drop_item(pos, node) + local itemstring = itemstack:take_item():to_string() + meta:set_string("item", itemstring) + update_item(pos, node) + if itemstring == "" then + meta:set_string("infotext", S("@1 (owned by @2)", S("Item Frame"), owner)) + else + meta:set_string("infotext", S("@1 (owned by @2)", itemstring, owner)) + end + return itemstack +end + +function itemframe.punch(pos, node, puncher) + local meta = minetest.get_meta(pos) + local player_name = puncher:get_player_name() + local owner = meta:get_string("owner") + local admin = minetest.check_player_privs(player_name, "protection_bypass") + + if admin and player_name == owner then + drop_item(pos, node) + end +end + +function itemframe.dig(pos, player) + if not player then return end + local meta = minetest.get_meta(pos) + local player_name = player and player:get_player_name() + local owner = meta:get_string("owner") + local admin = minetest.check_player_privs(player_name, "protection_bypass") + + return admin or player_name == owner +end + +xdecor.register("itemframe", { + description = S("Item Frame"), + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = default.node_sound_wood_defaults(), + on_rotate = screwdriver.disallow, + sunlight_propagates = true, + inventory_image = "xdecor_itemframe.png", + node_box = xdecor.nodebox.slab_z(0.9375), + tiles = { + "xdecor_wood.png", "xdecor_wood.png", "xdecor_wood.png", + "xdecor_wood.png", "xdecor_wood.png", "xdecor_itemframe.png" + }, + after_place_node = itemframe.after_place, + on_timer = itemframe.timer, + on_rightclick = itemframe.rightclick, + on_punch = itemframe.punch, + can_dig = itemframe.dig, + after_destruct = remove_item +}) + +minetest.register_entity("xdecor:f_item", { + visual = "wielditem", + visual_size = {x = 0.33, y = 0.33}, + collisionbox = {0}, + physical = false, + textures = {"air"}, + on_activate = function(self, staticdata) + local pos = self.object:get_pos() + if minetest.get_node(pos).name ~= "xdecor:itemframe" then + self.object:remove() + end + + if tmp.nodename and tmp.texture then + self.nodename = tmp.nodename + tmp.nodename = nil + self.texture = tmp.texture + tmp.texture = nil + elseif staticdata and staticdata ~= "" then + local data = staticdata:split(";") + if data and data[1] and data[2] then + self.nodename = data[1] + self.texture = data[2] + end + end + if self.texture then + self.object:set_properties({ + textures = {self.texture} + }) + end + end, + get_staticdata = function(self) + if self.nodename and self.texture then + return self.nodename .. ";" .. self.texture + end + + return "" + end +}) + +-- Recipes + +minetest.register_craft({ + output = "xdecor:itemframe", + recipe = { + {"group:stick", "group:stick", "group:stick"}, + {"group:stick", "default:paper", "group:stick"}, + {"group:stick", "group:stick", "group:stick"} + } +}) diff --git a/mods/xdecor/src/mailbox.lua b/mods/xdecor/src/mailbox.lua new file mode 100644 index 0000000..78a3ed3 --- /dev/null +++ b/mods/xdecor/src/mailbox.lua @@ -0,0 +1,192 @@ +local mailbox = {} +screwdriver = screwdriver or {} +local S = minetest.get_translator("xdecor") +local FS = function(...) return minetest.formspec_escape(S(...)) end + +local function get_img(img) + if not img then return end + local img_name = img:match("(.*)%.png") + + if img_name then + return img_name .. ".png" + end +end + +local function img_col(stack) + local def = minetest.registered_items[stack] + if not def then + return "" + end + + if def.inventory_image ~= "" then + local img = get_img(def.inventory_image) + if img then + return img + end + end + + if def.tiles then + local tile, img = def.tiles[1] + if type(tile) == "table" then + img = get_img(tile.name) + elseif type(tile) == "string" then + img = get_img(tile) + end + + if img then + return img + end + end + + return "" +end + +function mailbox:formspec(pos, owner, is_owner) + local spos = pos.x .. "," .. pos.y .. "," .. pos.z + local meta = minetest.get_meta(pos) + local giver, img = "", "" + + if is_owner then + for i = 1, 7 do + local giving = meta:get_string("giver" .. i) + if giving ~= "" then + local stack = meta:get_string("stack" .. i) + local giver_name = giving:sub(1,12) + local stack_name = stack:match("[%w_:]+") + local stack_count = stack:match("%s(%d+)") or 1 + + giver = giver .. "#FFFF00," .. giver_name .. "," .. i .. + ",#FFFFFF,x " .. stack_count .. "," + + img = img .. i .. "=" .. + img_col(stack_name) .. "^\\[resize:16x16," + end + end + + return "size[9.5,9]" + .."label[0,0;"..FS("Mailbox").."]" + .."label[6,0;"..FS("Last donators").."]" + ..[[ box[6,0.72;3.3,3.5;#555555] + listring[current_player;main] + list[current_player;main;0.75,5.25;8,4;] + tableoptions[background=#00000000;highlight=#00000000;border=false] ]] .. + "tablecolumns[color;text;image," .. img .. "0;color;text]" .. + "table[6,0.75;3.3,4;givers;" .. giver .. "]" .. + "list[nodemeta:" .. spos .. ";mailbox;0,0.75;6,4;]" .. + "listring[nodemeta:" .. spos .. ";mailbox]" .. + xbg .. default.get_hotbar_bg(0.75, 5.25) + end + + return "size[8,5]" .. + "list[current_player;main;0,1.25;8,4;]" .. + "label[0,0;"..FS("Send your goods to\n@1", + (minetest.colorize and + minetest.colorize("#FFFF00", owner) or owner)) .. "]" .. + "list[nodemeta:" .. spos .. ";drop;3.5,0;1,1;]" .. + xbg .. default.get_hotbar_bg(0, 1.25) +end + +function mailbox.dig(pos, player) + local meta = minetest.get_meta(pos) + local owner = meta:get_string("owner") + local player_name = player and player:get_player_name() + local inv = meta:get_inventory() + + return inv:is_empty("mailbox") and player_name == owner +end + +function mailbox.after_place_node(pos, placer) + local meta = minetest.get_meta(pos) + local player_name = placer:get_player_name() + + meta:set_string("owner", player_name) + meta:set_string("infotext", S("@1's Mailbox", player_name)) + + local inv = meta:get_inventory() + inv:set_size("mailbox", 6 * 4) + inv:set_size("drop", 1) +end + +function mailbox.rightclick(pos, node, clicker, itemstack, pointed_thing) + local meta = minetest.get_meta(pos) + local player = clicker:get_player_name() + local owner = meta:get_string("owner") + + minetest.show_formspec(player, "xdecor:mailbox", + mailbox:formspec(pos, owner, (player == owner))) + + return itemstack +end + +function mailbox.put(pos, listname, _, stack, player) + if listname == "drop" then + local inv = minetest.get_meta(pos):get_inventory() + if inv:room_for_item("mailbox", stack) then + return -1 + else + minetest.chat_send_player(player:get_player_name(), + S("The mailbox is full.")) + end + end + + return 0 +end + +function mailbox.on_put(pos, listname, _, stack, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + if listname == "drop" and inv:room_for_item("mailbox", stack) then + inv:set_list("drop", {}) + inv:add_item("mailbox", stack) + + for i = 7, 2, -1 do + meta:set_string("giver" .. i, meta:get_string("giver" .. (i - 1))) + meta:set_string("stack" .. i, meta:get_string("stack" .. (i - 1))) + end + + meta:set_string("giver1", player:get_player_name()) + meta:set_string("stack1", stack:to_string()) + end +end + +function mailbox.allow_take(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + + if player:get_player_name() ~= meta:get_string("owner") then + return 0 + end + + return stack:get_count() +end + +function mailbox.allow_move(pos) + return 0 +end + +xdecor.register("mailbox", { + description = S("Mailbox"), + tiles = {"xdecor_mailbox_top.png", "xdecor_mailbox_bottom.png", + "xdecor_mailbox_side.png", "xdecor_mailbox_side.png", + "xdecor_mailbox.png", "xdecor_mailbox.png"}, + groups = {cracky = 3, oddly_breakable_by_hand = 1}, + on_rotate = screwdriver.rotate_simple, + can_dig = mailbox.dig, + on_rightclick = mailbox.rightclick, + allow_metadata_inventory_take = mailbox.allow_take, + allow_metadata_inventory_move = mailbox.allow_move, + on_metadata_inventory_put = mailbox.on_put, + allow_metadata_inventory_put = mailbox.put, + after_place_node = mailbox.after_place_node +}) + +-- Recipes + +minetest.register_craft({ + output = "xdecor:mailbox", + recipe = { + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"dye:red", "default:paper", "dye:red"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"} + } +}) diff --git a/mods/xdecor/src/mechanisms.lua b/mods/xdecor/src/mechanisms.lua new file mode 100644 index 0000000..a758f45 --- /dev/null +++ b/mods/xdecor/src/mechanisms.lua @@ -0,0 +1,153 @@ +-- Thanks to sofar for helping with that code. + +local plate = {} +screwdriver = screwdriver or {} + +local S = minetest.get_translator("xdecor") +local ALPHA_OPAQUE = minetest.features.use_texture_alpha_string_modes and "opaque" or false + +local function door_toggle(pos_actuator, pos_door, player) + local player_name = player:get_player_name() + local actuator = minetest.get_node(pos_actuator) + local door = doors.get(pos_door) + if not door then return end + + if actuator.name:sub(-4) == "_off" then + minetest.set_node(pos_actuator, + {name = actuator.name:gsub("_off", "_on"), param2 = actuator.param2}) + end + door:open(player) + + minetest.after(2, function() + if minetest.get_node(pos_actuator).name:sub(-3) == "_on" then + minetest.set_node(pos_actuator, + {name = actuator.name, param2 = actuator.param2}) + end + -- Re-get player object (or nil) because 'player' could + -- be an invalid object at this time (player left) + door:close(minetest.get_player_by_name(player_name)) + end) +end + +function plate.construct(pos) + local timer = minetest.get_node_timer(pos) + timer:start(0.1) +end + +function plate.timer(pos) + local objs = minetest.get_objects_inside_radius(pos, 0.8) + if not next(objs) or not doors.get then return true end + + local minp = {x = pos.x - 2, y = pos.y, z = pos.z - 2} + local maxp = {x = pos.x + 2, y = pos.y, z = pos.z + 2} + local doors = minetest.find_nodes_in_area(minp, maxp, "group:door") + + for _, player in pairs(objs) do + if player:is_player() then + for i = 1, #doors do + door_toggle(pos, doors[i], player) + end + break + end + end + + return true +end + +function plate.register(material, desc, def) + xdecor.register("pressure_" .. material .. "_off", { + description = def.description or (desc .. " Pressure Plate"), + tiles = {"xdecor_pressure_" .. material .. ".png"}, + use_texture_alpha = ALPHA_OPAQUE, + drawtype = "nodebox", + node_box = xdecor.pixelbox(16, {{1, 0, 1, 14, 1, 14}}), + groups = def.groups, + sounds = def.sounds, + sunlight_propagates = true, + on_rotate = screwdriver.rotate_simple, + on_construct = plate.construct, + on_timer = plate.timer + }) + xdecor.register("pressure_" .. material .. "_on", { + tiles = {"xdecor_pressure_" .. material .. ".png"}, + use_texture_alpha = ALPHA_OPAQUE, + drawtype = "nodebox", + node_box = xdecor.pixelbox(16, {{1, 0, 1, 14, 0.4, 14}}), + groups = def.groups, + sounds = def.sounds, + drop = "xdecor:pressure_" .. material .. "_off", + sunlight_propagates = true, + on_rotate = screwdriver.rotate_simple + }) +end + +plate.register("wood", "Wooden", { + sounds = default.node_sound_wood_defaults(), + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 2}, + description = S("Wooden Pressure Plate"), +}) + +plate.register("stone", "Stone", { + sounds = default.node_sound_stone_defaults(), + groups = {cracky = 3, oddly_breakable_by_hand = 2}, + description = S("Stone Pressure Plate"), +}) + +xdecor.register("lever_off", { + description = S("Lever"), + tiles = {"xdecor_lever_off.png"}, + use_texture_alpha = ALPHA_OPAQUE, + drawtype = "nodebox", + node_box = xdecor.pixelbox(16, {{2, 1, 15, 12, 14, 1}}), + groups = {cracky = 3, oddly_breakable_by_hand = 2}, + sounds = default.node_sound_stone_defaults(), + sunlight_propagates = true, + on_rotate = screwdriver.rotate_simple, + + on_rightclick = function(pos, node, clicker, itemstack) + if not doors.get then return itemstack end + local minp = {x = pos.x - 2, y = pos.y - 1, z = pos.z - 2} + local maxp = {x = pos.x + 2, y = pos.y + 1, z = pos.z + 2} + local doors = minetest.find_nodes_in_area(minp, maxp, "group:door") + + for i = 1, #doors do + door_toggle(pos, doors[i], clicker) + end + + return itemstack + end +}) + +xdecor.register("lever_on", { + tiles = {"xdecor_lever_on.png"}, + use_texture_alpha = ALPHA_OPAQUE, + drawtype = "nodebox", + node_box = xdecor.pixelbox(16, {{2, 1, 15, 12, 14, 1}}), + groups = {cracky = 3, oddly_breakable_by_hand = 2, not_in_creative_inventory = 1}, + sounds = default.node_sound_stone_defaults(), + sunlight_propagates = true, + on_rotate = screwdriver.rotate_simple, + drop = "xdecor:lever_off" +}) + +-- Recipes + +minetest.register_craft({ + output = "xdecor:pressure_stone_off", + type = "shapeless", + recipe = {"group:stone", "group:stone"} +}) + +minetest.register_craft({ + output = "xdecor:pressure_wood_off", + type = "shapeless", + recipe = {"group:wood", "group:wood"} +}) + +minetest.register_craft({ + output = "xdecor:lever_off", + recipe = { + {"group:stick"}, + {"group:stone"} + } +}) diff --git a/mods/xdecor/src/nodes.lua b/mods/xdecor/src/nodes.lua new file mode 100644 index 0000000..f4d9308 --- /dev/null +++ b/mods/xdecor/src/nodes.lua @@ -0,0 +1,744 @@ +screwdriver = screwdriver or {} +local S = minetest.get_translator("xdecor") +local ALPHA_CLIP = minetest.features.use_texture_alpha_string_modes and "clip" or true +local ALPHA_OPAQUE = minetest.features.use_texture_alpha_string_modes and "opaque" or false + +local function register_pane(name, desc, def) + xpanes.register_pane(name, { + description = desc, + tiles = {"xdecor_" .. name .. ".png"}, + drawtype = "airlike", + paramtype = "light", + textures = {"xdecor_" .. name .. ".png", "" ,"xdecor_" .. name .. ".png"}, + inventory_image = "xdecor_" .. name .. ".png", + wield_image = "xdecor_" .. name .. ".png", + groups = def.groups, + sounds = def.sounds or default.node_sound_defaults(), + recipe = def.recipe + }) +end + +register_pane("bamboo_frame", S("Bamboo Frame"), { + groups = {choppy = 3, oddly_breakable_by_hand = 2, pane = 1, flammable = 2}, + recipe = { + {"default:papyrus", "default:papyrus", "default:papyrus"}, + {"default:papyrus", "farming:cotton", "default:papyrus"}, + {"default:papyrus", "default:papyrus", "default:papyrus"} + } +}) + +register_pane("chainlink", S("Chainlink"), { + groups = {cracky = 3, oddly_breakable_by_hand = 2, pane = 1}, + recipe = { + {"default:steel_ingot", "", "default:steel_ingot"}, + {"", "default:steel_ingot", ""}, + {"default:steel_ingot", "", "default:steel_ingot"} + } +}) + +register_pane("rusty_bar", S("Rusty Iron Bars"), { + sounds = default.node_sound_stone_defaults(), + groups = {cracky = 2, pane = 1}, + recipe = { + {"", "default:dirt", ""}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"} + } +}) + +register_pane("wood_frame", S("Wood Frame"), { + sounds = default.node_sound_wood_defaults(), + groups = {choppy = 2, pane = 1, flammable = 2}, + recipe = { + {"group:wood", "group:stick", "group:wood"}, + {"group:stick", "group:stick", "group:stick"}, + {"group:wood", "group:stick", "group:wood"} + } +}) + +xdecor.register("baricade", { + description = S("Baricade"), + drawtype = "plantlike", + paramtype2 = "facedir", + inventory_image = "xdecor_baricade.png", + tiles = {"xdecor_baricade.png"}, + groups = {choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + damage_per_second = 4, + selection_box = xdecor.nodebox.slab_y(0.3), + collision_box = xdecor.pixelbox(2, {{0, 0, 1, 2, 2, 0}}) +}) + +xdecor.register("barrel", { + description = S("Barrel"), + tiles = {"xdecor_barrel_top.png", "xdecor_barrel_top.png", "xdecor_barrel_sides.png"}, + on_place = minetest.rotate_node, + groups = {choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = default.node_sound_wood_defaults() +}) + +local function register_storage(name, desc, def) + xdecor.register(name, { + description = desc, + inventory = {size = def.inv_size or 24}, + infotext = desc, + tiles = def.tiles, + use_texture_alpha = ALPHA_OPAQUE, + node_box = def.node_box, + on_rotate = def.on_rotate, + on_place = def.on_place, + groups = def.groups or {choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = default.node_sound_wood_defaults() + }) +end + +register_storage("cabinet", S("Wooden Cabinet"), { + on_rotate = screwdriver.rotate_simple, + tiles = { + "xdecor_cabinet_sides.png", "xdecor_cabinet_sides.png", + "xdecor_cabinet_sides.png", "xdecor_cabinet_sides.png", + "xdecor_cabinet_sides.png", "xdecor_cabinet_front.png" + } +}) + +register_storage("cabinet_half", S("Half Wooden Cabinet"), { + inv_size = 8, + node_box = xdecor.nodebox.slab_y(0.5, 0.5), + on_rotate = screwdriver.rotate_simple, + tiles = { + "xdecor_cabinet_sides.png", "xdecor_cabinet_sides.png", + "xdecor_half_cabinet_sides.png", "xdecor_half_cabinet_sides.png", + "xdecor_half_cabinet_sides.png", "xdecor_half_cabinet_front.png" + } +}) + + +register_storage("empty_shelf", S("Empty Shelf"), { + on_rotate = screwdriver.rotate_simple, + tiles = { + "main_planks_oak.png", "main_planks_oak.png", "main_planks_oak.png", + "main_planks_oak.png", "main_planks_oak.png^xdecor_empty_shelf.png" + } +}) + + +register_storage("multishelf", S("Multi Shelf"), { + on_rotate = screwdriver.rotate_simple, + tiles = { + "main_planks_oak.png", "main_planks_oak.png", "main_planks_oak.png", + "main_planks_oak.png", "main_planks_oak.png^xdecor_multishelf.png" + }, +}) + +register_storage("bookshelf", S("Bookshelf"), { + on_rotate = screwdriver.rotate_simple, + tiles = { + "main_planks_oak.png", "main_planks_oak.png", "main_planks_oak.png", + "main_planks_oak.png", "main_planks_oak.png^xdecor_bookshelf.png" + }, +}) + +register_storage("binder_shelf", S("Binder Shelf"), { + on_rotate = screwdriver.rotate_simple, + tiles = { + "main_planks_oak.png", "main_planks_oak.png", "main_planks_oak.png", + "main_planks_oak.png", "main_planks_oak.png^xdecor_bindershelf.png" + }, +}) + +register_storage("vhs_shelf", S("VHS Shelf"), { + on_rotate = screwdriver.rotate_simple, + tiles = { + "main_planks_oak.png", "main_planks_oak.png", "main_planks_oak.png", + "main_planks_oak.png", "main_planks_oak.png^xdecor_vhsshelf.png" + }, +}) + +xdecor.register("candle", { + description = S("Candle"), + light_source = 12, + drawtype = "torchlike", + inventory_image = "xdecor_candle_inv.png", + wield_image = "xdecor_candle_wield.png", + paramtype2 = "wallmounted", + walkable = false, + groups = {dig_immediate = 3, attached_node = 1}, + tiles = { + { + name = "xdecor_candle_floor.png", + animation = {type="vertical_frames", length = 1.5} + }, + { + name = "xdecor_candle_hanging.png", + animation = {type="vertical_frames", length = 1.5} + }, + { + name = "xdecor_candle_wall.png", + animation = {type="vertical_frames", length = 1.5} + } + }, + selection_box = { + type = "wallmounted", + wall_top = {-0.25, -0.3, -0.25, 0.25, 0.5, 0.25}, + wall_bottom = {-0.25, -0.5, -0.25, 0.25, 0.1, 0.25}, + wall_side = {-0.5, -0.35, -0.15, -0.15, 0.4, 0.15} + } +}) + +xdecor.register("chair", { + description = S("Chair"), + tiles = {"xdecor_wood.png"}, + sounds = default.node_sound_wood_defaults(), + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 2}, + on_rotate = screwdriver.rotate_simple, + node_box = xdecor.pixelbox(16, { + {3, 0, 11, 2, 16, 2}, + {11, 0, 11, 2, 16, 2}, + {5, 9, 11.5, 6, 6, 1}, + {3, 0, 3, 2, 6, 2}, + {11, 0, 3, 2, 6, 2}, + {3, 6, 3, 10, 2, 8} + }), +}) + +xdecor.register("stacking_chair", { + description = S("Stacking Chair"), + tiles = {"xdecor_stacking_chair_topbottom.png", "xdecor_stacking_chair_topbottom.png", "xdecor_stacking_chair.png", "xdecor_stacking_chair.png", "xdecor_stacking_chair.png", "xdecor_stacking_chair.png"}, + sounds = default.node_sound_wood_defaults(), + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 2}, + on_rotate = screwdriver.rotate_simple, + node_box = { + type = "fixed", + fixed = { + {-0.25, -0.0625, -0.25, 0.25, 0, 0.25}, + {-0.25, 0, -0.25, 0.25, 0.5, -0.1875}, + {-0.25, -0.5, 0.1875, -0.1875, -0.0625, 0.25}, + {-0.25, -0.125, -0.1875, -0.1875, -0.0625, 0.1875}, + {0.1875, -0.125, -0.1875, 0.25, -0.0625, 0.1875}, + {-0.25, -0.5, -0.25, -0.1875, -0.0625, -0.1875}, + {0.1875, -0.5, -0.25, 0.25, -0.0625, -0.1875}, + {0.1875, -0.5, 0.1875, 0.25, -0.0625, 0.25}, + } + } +}) + + + +xdecor.register("cobweb", { + description = S("Cobweb"), + drawtype = "plantlike", + tiles = {"xdecor_cobweb.png"}, + inventory_image = "xdecor_cobweb.png", + liquid_viscosity = 8, + liquidtype = "source", + liquid_alternative_flowing = "xdecor:cobweb", + liquid_alternative_source = "xdecor:cobweb", + liquid_renewable = false, + liquid_range = 0, + walkable = false, + selection_box = {type = "regular"}, + groups = {snappy = 3, liquid = 3, flammable = 3}, + sounds = default.node_sound_leaves_defaults() +}) + +local curtain_colors = { + red = S("Red Curtain"), +} + +for c, desc in pairs(curtain_colors) do + xdecor.register("curtain_" .. c, { + description = desc, + walkable = false, + tiles = {"wool_white.png"}, + color = c, + inventory_image = "wool_white.png^[colorize:" .. c .. + ":170^xdecor_curtain_open_overlay.png^[makealpha:255,126,126", + wield_image = "wool_white.png^[colorize:" .. c .. ":170", + drawtype = "signlike", + paramtype2 = "colorwallmounted", + groups = {dig_immediate = 3, flammable = 3}, + selection_box = {type = "wallmounted"}, + on_rightclick = function(pos, node, _, itemstack) + minetest.set_node(pos, {name = "xdecor:curtain_open_" .. c, param2 = node.param2}) + return itemstack + end + }) + + xdecor.register("curtain_open_" .. c, { + tiles = {"wool_white.png^xdecor_curtain_open_overlay.png^[makealpha:255,126,126"}, + color = c, + drawtype = "signlike", + paramtype2 = "colorwallmounted", + walkable = false, + groups = {dig_immediate = 3, flammable = 3, not_in_creative_inventory = 1}, + selection_box = {type="wallmounted"}, + drop = "xdecor:curtain_" .. c, + on_rightclick = function(pos, node, _, itemstack) + minetest.set_node(pos, {name="xdecor:curtain_" .. c, param2 = node.param2}) + return itemstack + end + }) + + minetest.register_craft({ + output = "xdecor:curtain_" .. c .. " 4", + recipe = { + {"", "wool:" .. c, ""}, + {"", "wool:" .. c, ""} + } + }) +end + +xdecor.register("cushion", { + description = S("Cushion"), + tiles = {"xdecor_cushion.png"}, + groups = {snappy = 3, flammable = 3, fall_damage_add_percent = -50}, + on_place = minetest.rotate_node, + node_box = xdecor.nodebox.slab_y(0.5), + can_dig = xdecor.sit_dig, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + pos.y = pos.y + 0 -- Sitting position + xdecor.sit(pos, node, clicker, pointed_thing) + return itemstack + end +}) + +xdecor.register("cushion_block", { + description = S("Cushion Block"), + tiles = {"xdecor_cushion.png"}, + groups = {snappy = 3, flammable = 3, fall_damage_add_percent = -75, not_in_creative_inventory = 1} +}) + +local function door_access(name) + return name:find("prison") +end + +local xdecor_doors = { + japanese = { + recipe = { + {"group:wood", "default:paper"}, + {"default:paper", "group:wood"}, + {"group:wood", "default:paper"} + }, + desc = S("Japanese Door"), + }, + prison = { + recipe = { + {"xpanes:bar_flat", "xpanes:bar_flat",}, + {"xpanes:bar_flat", "xpanes:bar_flat",}, + {"xpanes:bar_flat", "xpanes:bar_flat"} + }, + desc = S("Prison Door"), + }, + rusty_prison = { + recipe = { + {"xpanes:rusty_bar_flat", "xpanes:rusty_bar_flat",}, + {"xpanes:rusty_bar_flat", "xpanes:rusty_bar_flat",}, + {"xpanes:rusty_bar_flat", "xpanes:rusty_bar_flat"} + }, + desc = S("Rusty Prison Door"), + }, + screen = { + recipe = { + {"group:wood", "group:wood"}, + {"xpanes:chainlink_flat", "xpanes:chainlink_flat"}, + {"group:wood", "group:wood"} + }, + desc = S("Screen Door"), + }, + slide = { + recipe = { + {"default:paper", "default:paper"}, + {"default:paper", "default:paper"}, + {"group:wood", "group:wood"} + }, + desc = S("Slide Door"), + }, + woodglass = { + recipe = { + {"default:glass", "default:glass"}, + {"group:wood", "group:wood"}, + {"group:wood", "group:wood"} + }, + desc = S("Woodglass Door"), + }, +} + +local mesecons_register + +if minetest.global_exists("mesecon") then + mesecons_register = { effector = { + action_on = function(pos, node) + local door = doors.get(pos) + if door then + door:open() + end + end, + action_off = function(pos, node) + local door = doors.get(pos) + if door then + door:close() + end + end, + rules = mesecon.rules.pplate + }} +end + +for name, def in pairs(xdecor_doors) do + if not doors.register then break end + doors.register(name .. "_door", { + tiles = { + {name = "xdecor_" .. name .. "_door.png", backface_culling = true} + }, + description = def.desc, + inventory_image = "xdecor_" .. name .. "_door_inv.png", + protected = door_access(name), + groups = {choppy = 2, cracky = 2, oddly_breakable_by_hand = 1, door = 1}, + recipe = def.recipe, + mesecons = mesecons_register, + }) +end + +xdecor.register("enderchest", { + description = S("Ender Chest"), + tiles = { + "xdecor_enderchest_top.png", "xdecor_enderchest_top.png", + "xdecor_enderchest_side.png", "xdecor_enderchest_side.png", + "xdecor_enderchest_side.png", "xdecor_enderchest_front.png" + }, + groups = {cracky = 1, choppy = 1}, + sounds = default.node_sound_stone_defaults(), + on_rotate = screwdriver.rotate_simple, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", [[ size[8,9] + list[current_player;enderchest;0,0;8,4;] + list[current_player;main;0,5;8,4;] + listring[current_player;enderchest] + listring[current_player;main] ]] + .. xbg .. default.get_hotbar_bg(0,5)) + + meta:set_string("infotext", S("Ender Chest")) + end +}) + +minetest.register_on_joinplayer(function(player) + local inv = player:get_inventory() + inv:set_size("enderchest", 8*4) +end) + +xdecor.register("ivy", { + description = S("Ivy"), + drawtype = "signlike", + walkable = false, + climbable = true, + groups = {snappy = 3, flora = 1, attached_node = 1, plant = 1, flammable = 3}, + paramtype2 = "wallmounted", + selection_box = {type="wallmounted"}, + tiles = {"xdecor_ivy.png"}, + inventory_image = "xdecor_ivy.png", + wield_image = "xdecor_ivy.png", + sounds = default.node_sound_leaves_defaults() +}) + +xdecor.register("rooster", { + description = S("Rooster"), + drawtype = "torchlike", + inventory_image = "xdecor_rooster.png", + walkable = false, + groups = {snappy = 3, attached_node = 1}, + tiles = {"xdecor_rooster.png"}, +}) + +xdecor.register("lantern", { + description = S("Lantern"), + light_source = 13, + drawtype = "plantlike", + inventory_image = "xdecor_lantern_inv.png", + wield_image = "xdecor_lantern_inv.png", + paramtype2 = "wallmounted", + walkable = false, + groups = {snappy = 3, attached_node = 1}, + tiles = { + { + name = "xdecor_lantern.png", + animation = {type="vertical_frames", length = 1.5} + } + }, + selection_box = xdecor.pixelbox(16, {{4, 0, 4, 8, 16, 8}}) +}) + +local xdecor_lightbox = { + iron = S("Iron Light Box"), + wooden = S("Wooden Light Box"), + wooden2 = S("Wooden Light Box 2"), +} + +for l, desc in pairs(xdecor_lightbox) do + xdecor.register(l .. "_lightbox", { + description = desc, + tiles = {"xdecor_" .. l .. "_lightbox.png"}, + groups = {cracky = 3, choppy = 3, oddly_breakable_by_hand = 2}, + light_source = 13, + sounds = default.node_sound_glass_defaults() + }) +end + +local xdecor_potted = { + dandelion_white = S("Potted White Dandelion"), + dandelion_yellow = S("Potted Yellow Dandelion"), + geranium = S("Potted Geranium"), + rose = S("Potted Rose"), + tulip = S("Potted Tulip"), + viola = S("Potted Viola"), +} + +for f, desc in pairs(xdecor_potted) do + xdecor.register("potted_" .. f, { + description = desc, + walkable = false, + groups = {snappy = 3, flammable = 3, plant = 1, flower = 1}, + tiles = {"xdecor_" .. f .. "_pot.png"}, + inventory_image = "xdecor_" .. f .. "_pot.png", + drawtype = "plantlike", + sounds = default.node_sound_leaves_defaults(), + selection_box = xdecor.nodebox.slab_y(0.3) + }) + + minetest.register_craft({ + output = "xdecor:potted_" .. f, + recipe = { + {"default:clay_brick", "flowers:" .. f, "default:clay_brick"}, + {"", "default:clay_brick", ""} + } + }) +end + +local painting_box = { + type = "wallmounted", + wall_top = {-0.4375, 0.4375, -0.3125, 0.4375, 0.5, 0.3125}, + wall_bottom = {-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125}, + wall_side = {-0.5, -0.3125, -0.4375, -0.4375, 0.3125, 0.4375} +} + +xdecor.register("painting_1", { + description = S("Painting"), + tiles = {"xdecor_painting_1.png"}, + use_texture_alpha = ALPHA_OPAQUE, + inventory_image = "xdecor_painting_empty.png", + wield_image = "xdecor_painting_empty.png", + paramtype2 = "wallmounted", + sunlight_propagates = true, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 2, attached_node = 1}, + sounds = default.node_sound_wood_defaults(), + node_box = painting_box, + node_placement_prediction = "", + on_place = function(itemstack, placer, pointed_thing) + local num = math.random(4) + local leftover = minetest.item_place_node( + ItemStack("xdecor:painting_" .. num), placer, pointed_thing) + + if leftover:get_count() == 0 and + not minetest.setting_getbool("creative_mode") then + itemstack:take_item() + end + + return itemstack + end +}) + +for i = 2, 4 do + xdecor.register("painting_" .. i, { + tiles = {"xdecor_painting_" .. i .. ".png"}, + use_texture_alpha = ALPHA_OPAQUE, + paramtype2 = "wallmounted", + drop = "xdecor:painting_1", + sunlight_propagates = true, + groups = { + choppy = 3, + oddly_breakable_by_hand = 2, + flammable = 2, + attached_node = 1, + not_in_creative_inventory = 1 + }, + sounds = default.node_sound_wood_defaults(), + node_box = painting_box + }) +end + +xdecor.register("stonepath", { + description = S("Garden Stone Path"), + tiles = {"main_stone.png"}, + groups = {snappy = 3}, + on_rotate = screwdriver.rotate_simple, + sounds = default.node_sound_stone_defaults(), + sunlight_propagates = true, + node_box = xdecor.pixelbox(16, { + {8, 0, 8, 6, .5, 6}, {1, 0, 1, 6, .5, 6}, + {1, 0, 10, 5, .5, 5}, {10, 0, 2, 4, .5, 4} + }), + selection_box = xdecor.nodebox.slab_y(0.05) +}) + +local function register_hard_node(name, desc, def) + def = def or {} + xdecor.register(name, { + description = desc, + tiles = {"xdecor_" .. name .. ".png"}, + groups = def.groups or {cracky = 1}, + sounds = def.sounds or default.node_sound_stone_defaults() + }) +end + +register_hard_node("cactusbrick", S("Cactus Brick")) +register_hard_node("coalstone_tile", S("Coal Stone Tile")) +register_hard_node("desertstone_tile", S("Desert Stone Tile")) +register_hard_node("hard_clay", S("Hardened Clay")) +register_hard_node("moonbrick", S("Moon Brick")) +register_hard_node("stone_tile", S("Stone Tile")) +register_hard_node("stone_rune", S("Runestone")) + +register_hard_node("packed_ice", S("Packed Ice"), { + groups = {cracky = 1, puts_out_fire = 1, slippery = 3}, + sounds = default.node_sound_glass_defaults() +}) + +register_hard_node("wood_tile", S("Wooden Tile"), { + groups = {choppy = 1, wood = 1, flammable = 2}, + sounds = default.node_sound_wood_defaults() +}) + +register_hard_node("wood", S("XDecor Wood"), { + groups = {choppy = 1, wood = 1, flammable = 2}, + sounds = default.node_sound_wood_defaults(), + paramtype2 = "none", +}) + +xdecor.register("table", { + description = S("Table"), + tiles = {"xdecor_wood.png"}, + groups = {choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = default.node_sound_wood_defaults(), + node_box = xdecor.pixelbox(16, { + {0, 14, 0, 16, 2, 16}, {5.5, 0, 5.5, 5, 14, 6} + }) +}) + +xdecor.register("tatami", { + description = S("Tatami"), + tiles = {"xdecor_tatami.png"}, + wield_image = "xdecor_tatami.png", + groups = {snappy = 3, flammable = 3}, + sunlight_propagates = true, + node_box = xdecor.nodebox.slab_y(0.0625) +}) + +xdecor.register("trampoline", { + description = S("Trampoline"), + tiles = {"xdecor_trampoline.png", "mailbox_blank16.png", "xdecor_trampoline_sides.png"}, + use_texture_alpha = ALPHA_CLIP, + groups = {cracky = 3, oddly_breakable_by_hand = 1, fall_damage_add_percent = -80, bouncy = 90}, + node_box = xdecor.nodebox.slab_y(0.5), + sounds = { + footstep = { + name = "xdecor_bouncy", + gain = 0.8 + } + } +}) + +xdecor.register("tv", { + description = S("Television"), + light_source = 11, + groups = {cracky = 3, oddly_breakable_by_hand = 2}, + on_rotate = screwdriver.rotate_simple, + tiles = { + "xdecor_television_left.png^[transformR270", + "xdecor_television_left.png^[transformR90", + "xdecor_television_left.png^[transformFX", + "xdecor_television_left.png", + "xdecor_television_back.png", + { + name = "xdecor_television_front_animated.png", + animation = {type = "vertical_frames", length = 80.0} + } + } +}) + +xdecor.register("tv_av", { + description = S("Television (AV)"), + light_source = 7, + groups = {cracky = 3, oddly_breakable_by_hand = 2}, + on_rotate = screwdriver.rotate_simple, + tiles = { + "xdecor_television_left.png^[transformR270", + "xdecor_television_left.png^[transformR90", + "xdecor_television_left.png^[transformFX", + "xdecor_television_left.png", + "xdecor_television_back.png", + { + name = "xdecor_television_av_front_animated.png", + animation = {type = "vertical_frames", length = 1.0} + } + } +}) + +xdecor.register("tv1_imploded", { + description = S("Imploded Television"), + groups = {cracky = 3, oddly_breakable_by_hand = 2}, + on_rotate = screwdriver.rotate_simple, + tiles = { + "xdecor_television_left.png^[transformR270", + "xdecor_television_left.png^[transformR90", + "xdecor_television_left.png^[transformFX", + "xdecor_television_left.png", + "xdecor_television_back.png", + "xdecor_television1_imploded.png", + } +}) + +xdecor.register("woodframed_glass", { + description = S("Wood Framed Glass"), + drawtype = "glasslike_framed", + sunlight_propagates = true, + tiles = {"xdecor_woodframed_glass.png", "xdecor_woodframed_glass_detail.png"}, + use_texture_alpha = ALPHA_CLIP, + groups = {cracky = 2, oddly_breakable_by_hand = 1}, + sounds = default.node_sound_glass_defaults() +}) + +minetest.register_node("xdecor:toilet", { + description = "Toilet", + tiles = { + "soviet_machine.png", + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 2}, + node_box = + { + type = "fixed", + fixed = + { + {-0.25, -0.5, -0.3125, 0.25, -0.3125, 0.3125}, + {-0.3125, -0.3125, -0.375, 0.3125, -0.1875, 0.4375}, + {-0.3125, -0.1875, -0.4375, 0.3125, 0, 0.5}, + {-0.25, 0, 0.1875, 0.25, 0.5, 0.5}, + } + } +}) + +for _, v in ipairs({"radio", "speaker"}) do + xdecor.register(v, { + description = v:gsub("^%l", string.upper), + on_rotate = screwdriver.rotate_simple, + tiles = { + "xdecor_" .. v .. "_top.png", + "xdecor_" .. v .. "_side.png", + "xdecor_" .. v .. "_side.png", + "xdecor_" .. v .. "_side.png", + "xdecor_" .. v .. "_back.png", + "xdecor_" .. v .. "_front.png", + }, + groups = {cracky = 2, not_cuttable = 1}, + }) +end diff --git a/mods/xdecor/src/rope.lua b/mods/xdecor/src/rope.lua new file mode 100644 index 0000000..4380205 --- /dev/null +++ b/mods/xdecor/src/rope.lua @@ -0,0 +1,75 @@ +local rope = {} +local S = minetest.get_translator("xdecor") + +-- Code by Mirko K. (modified by Temperest, Wulfsdad and kilbith) (License: GPL). +function rope.place(itemstack, placer, pointed_thing) + if pointed_thing.type == "node" then + local pos = pointed_thing.above + local oldnode = minetest.get_node(pos) + local stackname = itemstack:get_name() + + if minetest.is_protected(pos, placer:get_player_name()) then + return itemstack + end + + while oldnode.name == "air" and not itemstack:is_empty() do + local newnode = {name = stackname, param1 = 0} + minetest.set_node(pos, newnode) + itemstack:take_item() + pos.y = pos.y - 1 + oldnode = minetest.get_node(pos) + end + end + + return itemstack +end + +function rope.remove(pos, oldnode, digger, rope_name) + local num = 0 + local below = {x = pos.x, y = pos.y, z = pos.z} + local digger_inv = digger:get_inventory() + + while minetest.get_node(below).name == rope_name do + minetest.remove_node(below) + below.y = below.y - 1 + num = num + 1 + end + + if num == 0 then return end + digger_inv:add_item("main", rope_name.." "..num) + + return true +end + +xdecor.register("rope", { + description = S("Rope"), + drawtype = "plantlike", + walkable = false, + climbable = true, + groups = {snappy = 3, flammable = 3}, + tiles = {"xdecor_rope.png"}, + inventory_image = "xdecor_rope_inv.png", + wield_image = "xdecor_rope_inv.png", + selection_box = xdecor.pixelbox(8, {{3, 0, 3, 2, 8, 2}}), + on_place = rope.place, + + on_punch = function(pos, node, puncher, pointed_thing) + local player_name = puncher:get_player_name() + + if not minetest.is_protected(pos, player_name) or + minetest.get_player_privs(player_name).protection_bypass then + rope.remove(pos, node, puncher, "xdecor:rope") + end + end +}) + +-- Recipes + +minetest.register_craft({ + output = "xdecor:rope", + recipe = { + {"farming:string"}, + {"farming:string"}, + {"farming:string"} + } +}) diff --git a/mods/xdecor/src/workbench.lua b/mods/xdecor/src/workbench.lua new file mode 100644 index 0000000..4c87c3e --- /dev/null +++ b/mods/xdecor/src/workbench.lua @@ -0,0 +1,361 @@ +local workbench = {} +local nodes = {} + +screwdriver = screwdriver or {} +local min, ceil = math.min, math.ceil +local S = minetest.get_translator("xdecor") +local FS = function(...) return minetest.formspec_escape(S(...)) end + +-- Nodes allowed to be cut +-- Only the regular, solid blocks without metas or explosivity can be cut +for node, def in pairs(minetest.registered_nodes) do + if xdecor.stairs_valid_def(def) then + nodes[#nodes + 1] = node + end +end + +-- Nodeboxes definitions +workbench.defs = { + -- Name YieldX YZ WH L + {"nanoslab", 16, { 0, 0, 0, 8, 1, 8 }}, + {"micropanel", 16, { 0, 0, 0, 16, 1, 8 }}, + {"microslab", 8, { 0, 0, 0, 16, 1, 16 }}, + {"thinstair", 8, { 0, 7, 0, 16, 1, 8 }, + { 0, 15, 8, 16, 1, 8 }}, + {"cube", 4, { 0, 0, 0, 8, 8, 8 }}, + {"panel", 4, { 0, 0, 0, 16, 8, 8 }}, + {"slab", 2, nil }, + {"doublepanel", 2, { 0, 0, 0, 16, 8, 8 }, + { 0, 8, 8, 16, 8, 8 }}, + {"halfstair", 2, { 0, 0, 0, 8, 8, 16 }, + { 0, 8, 8, 8, 8, 8 }}, + {"stair_outer", 1, nil }, + {"stair", 1, nil }, + {"stair_inner", 1, nil } +} + +local repairable_tools = {"pick", "axe", "shovel", "sword", "hoe", "armor", "shield"} + +local custom_repairable = {} +function xdecor:register_repairable(item) + custom_repairable[item] = true +end + +-- Tools allowed to be repaired +function workbench:repairable(stack) + if custom_repairable[stack] then return true end + + for _, t in ipairs(repairable_tools) do + if stack:find(t) then + return true + end + end +end + +-- method to allow other mods to check if an item is repairable +function xdecor:is_repairable(stack) + return workbench:repairable(stack) +end + +function workbench:get_output(inv, input, name) + local output = {} + for i = 1, #self.defs do + local nbox = self.defs[i] + local count = min(nbox[2] * input:get_count(), input:get_stack_max()) + local item = name .. "_" .. nbox[1] + + item = nbox[3] and item or "stairs:" .. nbox[1] .. "_" .. name:match(":(.*)") + output[i] = item .. " " .. count + end + + inv:set_list("forms", output) +end + +local main_fs = "label[0.9,1.23;"..FS("Cut").."]" + .."label[0.9,2.23;"..FS("Repair").."]" + ..[[ box[-0.05,1;2.05,0.9;#555555] + box[-0.05,2;2.05,0.9;#555555] ]] + .."button[0,0;2,1;craft;"..FS("Crafting").."]" + .."button[2,0;2,1;storage;"..FS("Storage").."]" + ..[[ image[3,1;1,1;gui_arrow.png] + image[0,1;1,1;worktable_saw.png] + image[0,2;1,1;worktable_anvil.png] + image[3,2;1,1;hammer_layout.png] + list[context;input;2,1;1,1;] + list[context;tool;2,2;1,1;] + list[context;hammer;3,2;1,1;] + list[context;forms;4,0;4,3;] + listring[current_player;main] + listring[context;tool] + listring[current_player;main] + listring[context;hammer] + listring[current_player;main] + listring[context;forms] + listring[current_player;main] + listring[context;input] +]] + +local crafting_fs = "image[5,1;1,1;gui_furnace_arrow_bg.png^[transformR270]" + .."button[0,0;1.5,1;back;< "..FS("Back").."]" + ..[[ list[current_player;craft;2,0;3,3;] + list[current_player;craftpreview;6,1;1,1;] + listring[current_player;main] + listring[current_player;craft] +]] + +local storage_fs = "list[context;storage;0,1;8,2;]" + .."button[0,0;1.5,1;back;< "..FS("Back").."]" + ..[[listring[context;storage] + listring[current_player;main] +]] + +local formspecs = { + -- Main formspec + main_fs, + + -- Crafting formspec + crafting_fs, + + -- Storage formspec + storage_fs, +} + +function workbench:set_formspec(meta, id) + meta:set_string("formspec", + "size[8,7;]list[current_player;main;0,3.25;8,4;]" .. + formspecs[id] .. xbg .. default.get_hotbar_bg(0,3.25)) +end + +function workbench.construct(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + inv:set_size("tool", 1) + inv:set_size("input", 1) + inv:set_size("hammer", 1) + inv:set_size("forms", 4*3) + inv:set_size("storage", 8*2) + + meta:set_string("infotext", S("Work Bench")) + workbench:set_formspec(meta, 1) +end + +function workbench.fields(pos, _, fields) + if fields.quit then return end + + local meta = minetest.get_meta(pos) + local id = fields.back and 1 or fields.craft and 2 or fields.storage and 3 + if not id then return end + + workbench:set_formspec(meta, id) +end + +function workbench.dig(pos) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("input") and inv:is_empty("hammer") and + inv:is_empty("tool") and inv:is_empty("storage") +end + +function workbench.timer(pos) + local timer = minetest.get_node_timer(pos) + local inv = minetest.get_meta(pos):get_inventory() + local tool = inv:get_stack("tool", 1) + local hammer = inv:get_stack("hammer", 1) + + if tool:is_empty() or hammer:is_empty() or tool:get_wear() == 0 then + timer:stop() + return + end + + -- Tool's wearing range: 0-65535; 0 = new condition + tool:add_wear(-500) + hammer:add_wear(700) + + inv:set_stack("tool", 1, tool) + inv:set_stack("hammer", 1, hammer) + + return true +end + +function workbench.allow_put(pos, listname, index, stack, player) + local stackname = stack:get_name() + if (listname == "tool" and stack:get_wear() > 0 and + workbench:repairable(stackname)) or + (listname == "input" and minetest.registered_nodes[stackname .. "_cube"]) or + (listname == "hammer" and stackname == "xdecor:hammer") or + listname == "storage" then + return stack:get_count() + end + + return 0 +end + +function workbench.on_put(pos, listname, index, stack, player) + local inv = minetest.get_meta(pos):get_inventory() + if listname == "input" then + local input = inv:get_stack("input", 1) + workbench:get_output(inv, input, stack:get_name()) + elseif listname == "tool" or listname == "hammer" then + local timer = minetest.get_node_timer(pos) + timer:start(3.0) + end +end + +function workbench.allow_move(pos, from_list, from_index, to_list, to_index, count, player) + return (to_list == "storage" and from_list ~= "forms") and count or 0 +end + +function workbench.on_move(pos, from_list, from_index, to_list, to_index, count, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local from_stack = inv:get_stack(from_list, from_index) + local to_stack = inv:get_stack(to_list, to_index) + + workbench.on_take(pos, from_list, from_index, from_stack, player) + workbench.on_put(pos, to_list, to_index, to_stack, player) +end + +function workbench.allow_take(pos, listname, index, stack, player) + return stack:get_count() +end + +function workbench.on_take(pos, listname, index, stack, player) + local inv = minetest.get_meta(pos):get_inventory() + local input = inv:get_stack("input", 1) + local inputname = input:get_name() + local stackname = stack:get_name() + + if listname == "input" then + if stackname == inputname and minetest.registered_nodes[inputname .. "_cube"] then + workbench:get_output(inv, input, stackname) + else + inv:set_list("forms", {}) + end + elseif listname == "forms" then + local fromstack = inv:get_stack(listname, index) + if not fromstack:is_empty() and fromstack:get_name() ~= stackname then + local player_inv = player:get_inventory() + if player_inv:room_for_item("main", fromstack) then + player_inv:add_item("main", fromstack) + end + end + + input:take_item(ceil(stack:get_count() / workbench.defs[index][2])) + inv:set_stack("input", 1, input) + workbench:get_output(inv, input, inputname) + end +end + +xdecor.register("workbench", { + description = S("Work Bench"), + groups = {cracky = 2, choppy = 2, oddly_breakable_by_hand = 1}, + sounds = default.node_sound_wood_defaults(), + tiles = { + "xdecor_workbench_top.png","xdecor_workbench_top.png", + "xdecor_workbench_sides.png", "xdecor_workbench_sides.png", + "xdecor_workbench_front.png", "xdecor_workbench_front.png" + }, + on_rotate = screwdriver.rotate_simple, + can_dig = workbench.dig, + on_timer = workbench.timer, + on_construct = workbench.construct, + on_receive_fields = workbench.fields, + on_metadata_inventory_put = workbench.on_put, + on_metadata_inventory_take = workbench.on_take, + on_metadata_inventory_move = workbench.on_move, + allow_metadata_inventory_put = workbench.allow_put, + allow_metadata_inventory_take = workbench.allow_take, + allow_metadata_inventory_move = workbench.allow_move +}) + +for _, d in ipairs(workbench.defs) do +for i = 1, #nodes do + local node = nodes[i] + local mod_name, item_name = node:match("^(.-):(.*)") + local def = minetest.registered_nodes[node] + + if item_name and d[3] then + local groups = {} + local tiles + groups.not_in_creative_inventory = 1 + + for k, v in pairs(def.groups) do + if k ~= "wood" and k ~= "stone" and k ~= "level" then + groups[k] = v + end + end + + if def.tiles then + if #def.tiles > 1 and (def.drawtype:sub(1,5) ~= "glass") then + tiles = def.tiles + else + tiles = {def.tiles[1]} + end + else + tiles = {def.tile_images[1]} + end + + --TODO: Translation support for Stairs/Slab + if not minetest.registered_nodes["stairs:slab_" .. item_name] then + stairs.register_stair_and_slab(item_name, node, + groups, tiles, def.description .. " Stair", + def.description .. " Slab", def.sounds) + end + + minetest.register_node(":" .. node .. "_" .. d[1], { + --TODO: Translation support + description = def.description .. " " .. d[1]:gsub("^%l", string.upper), + paramtype = "light", + paramtype2 = "facedir", + drawtype = "nodebox", + sounds = def.sounds, + tiles = tiles, + use_texture_alpha = def.use_texture_alpha, + groups = groups, + -- `unpack` has been changed to `table.unpack` in newest Lua versions + node_box = xdecor.pixelbox(16, {unpack(d, 3)}), + sunlight_propagates = true, + on_place = minetest.rotate_node + }) + + elseif item_name and mod_name then + minetest.register_alias_force( + ("%s:%s_innerstair"):format(mod_name, item_name), + ("stairs:stair_inner_%s"):format(item_name) + ) + minetest.register_alias_force( + ("%s:%s_outerstair"):format(mod_name, item_name), + ("stairs:stair_outer_%s"):format(item_name) + ) + end +end +end + +-- Craft items + +minetest.register_tool("xdecor:hammer", { + description = S("Hammer"), + inventory_image = "xdecor_hammer.png", + wield_image = "xdecor_hammer.png", + on_use = function() do + return end + end +}) + +-- Recipes + +minetest.register_craft({ + output = "xdecor:hammer", + recipe = { + {"default:steel_ingot", "group:stick", "default:steel_ingot"}, + {"", "group:stick", ""} + } +}) + +minetest.register_craft({ + output = "xdecor:workbench", + recipe = { + {"group:wood", "group:wood"}, + {"group:wood", "group:wood"} + } +}) diff --git a/mods/xdecor/textures/bg_btn.png b/mods/xdecor/textures/bg_btn.png new file mode 100644 index 0000000..5815572 Binary files /dev/null and b/mods/xdecor/textures/bg_btn.png differ diff --git a/mods/xdecor/textures/bishop_black.png b/mods/xdecor/textures/bishop_black.png new file mode 100644 index 0000000..388a622 Binary files /dev/null and b/mods/xdecor/textures/bishop_black.png differ diff --git a/mods/xdecor/textures/bishop_white.png b/mods/xdecor/textures/bishop_white.png new file mode 100644 index 0000000..2819a58 Binary files /dev/null and b/mods/xdecor/textures/bishop_white.png differ diff --git a/mods/xdecor/textures/chess_bg.png b/mods/xdecor/textures/chess_bg.png new file mode 100644 index 0000000..41ee603 Binary files /dev/null and b/mods/xdecor/textures/chess_bg.png differ diff --git a/mods/xdecor/textures/chessboard_sides.png b/mods/xdecor/textures/chessboard_sides.png new file mode 100644 index 0000000..1498b1d Binary files /dev/null and b/mods/xdecor/textures/chessboard_sides.png differ diff --git a/mods/xdecor/textures/chessboard_top.png b/mods/xdecor/textures/chessboard_top.png new file mode 100644 index 0000000..d6db051 Binary files /dev/null and b/mods/xdecor/textures/chessboard_top.png differ diff --git a/mods/xdecor/textures/ench_ui.png b/mods/xdecor/textures/ench_ui.png new file mode 100644 index 0000000..8a2f4a0 Binary files /dev/null and b/mods/xdecor/textures/ench_ui.png differ diff --git a/mods/xdecor/textures/gui_arrow.png b/mods/xdecor/textures/gui_arrow.png new file mode 100644 index 0000000..df1bbdb Binary files /dev/null and b/mods/xdecor/textures/gui_arrow.png differ diff --git a/mods/xdecor/textures/hammer_layout.png b/mods/xdecor/textures/hammer_layout.png new file mode 100644 index 0000000..355ceab Binary files /dev/null and b/mods/xdecor/textures/hammer_layout.png differ diff --git a/mods/xdecor/textures/hive_bee.png b/mods/xdecor/textures/hive_bee.png new file mode 100644 index 0000000..e221f1f Binary files /dev/null and b/mods/xdecor/textures/hive_bee.png differ diff --git a/mods/xdecor/textures/hive_layout.png b/mods/xdecor/textures/hive_layout.png new file mode 100644 index 0000000..27794f4 Binary files /dev/null and b/mods/xdecor/textures/hive_layout.png differ diff --git a/mods/xdecor/textures/king_black.png b/mods/xdecor/textures/king_black.png new file mode 100644 index 0000000..06cfc30 Binary files /dev/null and b/mods/xdecor/textures/king_black.png differ diff --git a/mods/xdecor/textures/king_white.png b/mods/xdecor/textures/king_white.png new file mode 100644 index 0000000..60621c4 Binary files /dev/null and b/mods/xdecor/textures/king_white.png differ diff --git a/mods/xdecor/textures/knight_black.png b/mods/xdecor/textures/knight_black.png new file mode 100644 index 0000000..44de5f1 Binary files /dev/null and b/mods/xdecor/textures/knight_black.png differ diff --git a/mods/xdecor/textures/knight_white.png b/mods/xdecor/textures/knight_white.png new file mode 100644 index 0000000..1de460f Binary files /dev/null and b/mods/xdecor/textures/knight_white.png differ diff --git a/mods/xdecor/textures/mailbox_blank16.png b/mods/xdecor/textures/mailbox_blank16.png new file mode 100644 index 0000000..017d4f9 Binary files /dev/null and b/mods/xdecor/textures/mailbox_blank16.png differ diff --git a/mods/xdecor/textures/mese_layout.png b/mods/xdecor/textures/mese_layout.png new file mode 100644 index 0000000..154a6bc Binary files /dev/null and b/mods/xdecor/textures/mese_layout.png differ diff --git a/mods/xdecor/textures/pawn_black.png b/mods/xdecor/textures/pawn_black.png new file mode 100644 index 0000000..7cb5fc8 Binary files /dev/null and b/mods/xdecor/textures/pawn_black.png differ diff --git a/mods/xdecor/textures/pawn_white.png b/mods/xdecor/textures/pawn_white.png new file mode 100644 index 0000000..f7a8dec Binary files /dev/null and b/mods/xdecor/textures/pawn_white.png differ diff --git a/mods/xdecor/textures/queen_black.png b/mods/xdecor/textures/queen_black.png new file mode 100644 index 0000000..d59e312 Binary files /dev/null and b/mods/xdecor/textures/queen_black.png differ diff --git a/mods/xdecor/textures/queen_white.png b/mods/xdecor/textures/queen_white.png new file mode 100644 index 0000000..d923f05 Binary files /dev/null and b/mods/xdecor/textures/queen_white.png differ diff --git a/mods/xdecor/textures/rook_black.png b/mods/xdecor/textures/rook_black.png new file mode 100644 index 0000000..fa87141 Binary files /dev/null and b/mods/xdecor/textures/rook_black.png differ diff --git a/mods/xdecor/textures/rook_white.png b/mods/xdecor/textures/rook_white.png new file mode 100644 index 0000000..6703452 Binary files /dev/null and b/mods/xdecor/textures/rook_white.png differ diff --git a/mods/xdecor/textures/worktable_anvil.png b/mods/xdecor/textures/worktable_anvil.png new file mode 100644 index 0000000..afca15e Binary files /dev/null and b/mods/xdecor/textures/worktable_anvil.png differ diff --git a/mods/xdecor/textures/worktable_saw.png b/mods/xdecor/textures/worktable_saw.png new file mode 100644 index 0000000..73246ca Binary files /dev/null and b/mods/xdecor/textures/worktable_saw.png differ diff --git a/mods/xdecor/textures/xdecor_bamboo_frame.png b/mods/xdecor/textures/xdecor_bamboo_frame.png new file mode 100644 index 0000000..6a0d863 Binary files /dev/null and b/mods/xdecor/textures/xdecor_bamboo_frame.png differ diff --git a/mods/xdecor/textures/xdecor_baricade.png b/mods/xdecor/textures/xdecor_baricade.png new file mode 100644 index 0000000..87109bb Binary files /dev/null and b/mods/xdecor/textures/xdecor_baricade.png differ diff --git a/mods/xdecor/textures/xdecor_barrel_sides.png b/mods/xdecor/textures/xdecor_barrel_sides.png new file mode 100644 index 0000000..4172b81 Binary files /dev/null and b/mods/xdecor/textures/xdecor_barrel_sides.png differ diff --git a/mods/xdecor/textures/xdecor_barrel_top.png b/mods/xdecor/textures/xdecor_barrel_top.png new file mode 100644 index 0000000..014b00a Binary files /dev/null and b/mods/xdecor/textures/xdecor_barrel_top.png differ diff --git a/mods/xdecor/textures/xdecor_bindershelf.png b/mods/xdecor/textures/xdecor_bindershelf.png new file mode 100644 index 0000000..237d0a3 Binary files /dev/null and b/mods/xdecor/textures/xdecor_bindershelf.png differ diff --git a/mods/xdecor/textures/xdecor_book_open.png b/mods/xdecor/textures/xdecor_book_open.png new file mode 100644 index 0000000..206b11c Binary files /dev/null and b/mods/xdecor/textures/xdecor_book_open.png differ diff --git a/mods/xdecor/textures/xdecor_bookshelf.png b/mods/xdecor/textures/xdecor_bookshelf.png new file mode 100644 index 0000000..374a7b1 Binary files /dev/null and b/mods/xdecor/textures/xdecor_bookshelf.png differ diff --git a/mods/xdecor/textures/xdecor_bowl.png b/mods/xdecor/textures/xdecor_bowl.png new file mode 100644 index 0000000..9197da9 Binary files /dev/null and b/mods/xdecor/textures/xdecor_bowl.png differ diff --git a/mods/xdecor/textures/xdecor_bowl_soup.png b/mods/xdecor/textures/xdecor_bowl_soup.png new file mode 100644 index 0000000..54d87ae Binary files /dev/null and b/mods/xdecor/textures/xdecor_bowl_soup.png differ diff --git a/mods/xdecor/textures/xdecor_cabinet_front.png b/mods/xdecor/textures/xdecor_cabinet_front.png new file mode 100644 index 0000000..6380968 Binary files /dev/null and b/mods/xdecor/textures/xdecor_cabinet_front.png differ diff --git a/mods/xdecor/textures/xdecor_cabinet_sides.png b/mods/xdecor/textures/xdecor_cabinet_sides.png new file mode 100644 index 0000000..32ab257 Binary files /dev/null and b/mods/xdecor/textures/xdecor_cabinet_sides.png differ diff --git a/mods/xdecor/textures/xdecor_cactusbrick.png b/mods/xdecor/textures/xdecor_cactusbrick.png new file mode 100644 index 0000000..4856f09 Binary files /dev/null and b/mods/xdecor/textures/xdecor_cactusbrick.png differ diff --git a/mods/xdecor/textures/xdecor_candle_floor.png b/mods/xdecor/textures/xdecor_candle_floor.png new file mode 100644 index 0000000..c1bc4e3 Binary files /dev/null and b/mods/xdecor/textures/xdecor_candle_floor.png differ diff --git a/mods/xdecor/textures/xdecor_candle_hanging.png b/mods/xdecor/textures/xdecor_candle_hanging.png new file mode 100644 index 0000000..b8595a7 Binary files /dev/null and b/mods/xdecor/textures/xdecor_candle_hanging.png differ diff --git a/mods/xdecor/textures/xdecor_candle_inv.png b/mods/xdecor/textures/xdecor_candle_inv.png new file mode 100644 index 0000000..90a479e Binary files /dev/null and b/mods/xdecor/textures/xdecor_candle_inv.png differ diff --git a/mods/xdecor/textures/xdecor_candle_wall.png b/mods/xdecor/textures/xdecor_candle_wall.png new file mode 100644 index 0000000..b8a4b50 Binary files /dev/null and b/mods/xdecor/textures/xdecor_candle_wall.png differ diff --git a/mods/xdecor/textures/xdecor_candle_wield.png b/mods/xdecor/textures/xdecor_candle_wield.png new file mode 100644 index 0000000..60bdede Binary files /dev/null and b/mods/xdecor/textures/xdecor_candle_wield.png differ diff --git a/mods/xdecor/textures/xdecor_cauldron_sides.png b/mods/xdecor/textures/xdecor_cauldron_sides.png new file mode 100644 index 0000000..6644edb Binary files /dev/null and b/mods/xdecor/textures/xdecor_cauldron_sides.png differ diff --git a/mods/xdecor/textures/xdecor_cauldron_top_anim_boiling_water.png b/mods/xdecor/textures/xdecor_cauldron_top_anim_boiling_water.png new file mode 100644 index 0000000..48584d5 Binary files /dev/null and b/mods/xdecor/textures/xdecor_cauldron_top_anim_boiling_water.png differ diff --git a/mods/xdecor/textures/xdecor_cauldron_top_anim_soup.png b/mods/xdecor/textures/xdecor_cauldron_top_anim_soup.png new file mode 100644 index 0000000..f6d5258 Binary files /dev/null and b/mods/xdecor/textures/xdecor_cauldron_top_anim_soup.png differ diff --git a/mods/xdecor/textures/xdecor_cauldron_top_empty.png b/mods/xdecor/textures/xdecor_cauldron_top_empty.png new file mode 100644 index 0000000..5cdf5fd Binary files /dev/null and b/mods/xdecor/textures/xdecor_cauldron_top_empty.png differ diff --git a/mods/xdecor/textures/xdecor_cauldron_top_idle.png b/mods/xdecor/textures/xdecor_cauldron_top_idle.png new file mode 100644 index 0000000..69ec2ab Binary files /dev/null and b/mods/xdecor/textures/xdecor_cauldron_top_idle.png differ diff --git a/mods/xdecor/textures/xdecor_chainlink.png b/mods/xdecor/textures/xdecor_chainlink.png new file mode 100644 index 0000000..1aba3c0 Binary files /dev/null and b/mods/xdecor/textures/xdecor_chainlink.png differ diff --git a/mods/xdecor/textures/xdecor_coalstone_tile.png b/mods/xdecor/textures/xdecor_coalstone_tile.png new file mode 100644 index 0000000..3122db0 Binary files /dev/null and b/mods/xdecor/textures/xdecor_coalstone_tile.png differ diff --git a/mods/xdecor/textures/xdecor_cobweb.png b/mods/xdecor/textures/xdecor_cobweb.png new file mode 100644 index 0000000..bb1ecea Binary files /dev/null and b/mods/xdecor/textures/xdecor_cobweb.png differ diff --git a/mods/xdecor/textures/xdecor_curtain_open_overlay.png b/mods/xdecor/textures/xdecor_curtain_open_overlay.png new file mode 100644 index 0000000..e6eea41 Binary files /dev/null and b/mods/xdecor/textures/xdecor_curtain_open_overlay.png differ diff --git a/mods/xdecor/textures/xdecor_cushion.png b/mods/xdecor/textures/xdecor_cushion.png new file mode 100644 index 0000000..ad4674c Binary files /dev/null and b/mods/xdecor/textures/xdecor_cushion.png differ diff --git a/mods/xdecor/textures/xdecor_dandelion_white_pot.png b/mods/xdecor/textures/xdecor_dandelion_white_pot.png new file mode 100644 index 0000000..ccb91ee Binary files /dev/null and b/mods/xdecor/textures/xdecor_dandelion_white_pot.png differ diff --git a/mods/xdecor/textures/xdecor_dandelion_yellow_pot.png b/mods/xdecor/textures/xdecor_dandelion_yellow_pot.png new file mode 100644 index 0000000..f303475 Binary files /dev/null and b/mods/xdecor/textures/xdecor_dandelion_yellow_pot.png differ diff --git a/mods/xdecor/textures/xdecor_desertstone_tile.png b/mods/xdecor/textures/xdecor_desertstone_tile.png new file mode 100644 index 0000000..094437f Binary files /dev/null and b/mods/xdecor/textures/xdecor_desertstone_tile.png differ diff --git a/mods/xdecor/textures/xdecor_empty_shelf.png b/mods/xdecor/textures/xdecor_empty_shelf.png new file mode 100644 index 0000000..a8363c0 Binary files /dev/null and b/mods/xdecor/textures/xdecor_empty_shelf.png differ diff --git a/mods/xdecor/textures/xdecor_enchantment_bottom.png b/mods/xdecor/textures/xdecor_enchantment_bottom.png new file mode 100644 index 0000000..65a8639 Binary files /dev/null and b/mods/xdecor/textures/xdecor_enchantment_bottom.png differ diff --git a/mods/xdecor/textures/xdecor_enchantment_side.png b/mods/xdecor/textures/xdecor_enchantment_side.png new file mode 100644 index 0000000..9bbd5a2 Binary files /dev/null and b/mods/xdecor/textures/xdecor_enchantment_side.png differ diff --git a/mods/xdecor/textures/xdecor_enchantment_top.png b/mods/xdecor/textures/xdecor_enchantment_top.png new file mode 100644 index 0000000..cc79b35 Binary files /dev/null and b/mods/xdecor/textures/xdecor_enchantment_top.png differ diff --git a/mods/xdecor/textures/xdecor_enderchest_front.png b/mods/xdecor/textures/xdecor_enderchest_front.png new file mode 100644 index 0000000..e7286ce Binary files /dev/null and b/mods/xdecor/textures/xdecor_enderchest_front.png differ diff --git a/mods/xdecor/textures/xdecor_enderchest_side.png b/mods/xdecor/textures/xdecor_enderchest_side.png new file mode 100644 index 0000000..4691247 Binary files /dev/null and b/mods/xdecor/textures/xdecor_enderchest_side.png differ diff --git a/mods/xdecor/textures/xdecor_enderchest_top.png b/mods/xdecor/textures/xdecor_enderchest_top.png new file mode 100644 index 0000000..1f6676c Binary files /dev/null and b/mods/xdecor/textures/xdecor_enderchest_top.png differ diff --git a/mods/xdecor/textures/xdecor_geranium_pot.png b/mods/xdecor/textures/xdecor_geranium_pot.png new file mode 100644 index 0000000..0a68204 Binary files /dev/null and b/mods/xdecor/textures/xdecor_geranium_pot.png differ diff --git a/mods/xdecor/textures/xdecor_glyph1.png b/mods/xdecor/textures/xdecor_glyph1.png new file mode 100644 index 0000000..645abac Binary files /dev/null and b/mods/xdecor/textures/xdecor_glyph1.png differ diff --git a/mods/xdecor/textures/xdecor_glyph10.png b/mods/xdecor/textures/xdecor_glyph10.png new file mode 100644 index 0000000..06bd074 Binary files /dev/null and b/mods/xdecor/textures/xdecor_glyph10.png differ diff --git a/mods/xdecor/textures/xdecor_glyph11.png b/mods/xdecor/textures/xdecor_glyph11.png new file mode 100644 index 0000000..532d25c Binary files /dev/null and b/mods/xdecor/textures/xdecor_glyph11.png differ diff --git a/mods/xdecor/textures/xdecor_glyph12.png b/mods/xdecor/textures/xdecor_glyph12.png new file mode 100644 index 0000000..1f6be21 Binary files /dev/null and b/mods/xdecor/textures/xdecor_glyph12.png differ diff --git a/mods/xdecor/textures/xdecor_glyph13.png b/mods/xdecor/textures/xdecor_glyph13.png new file mode 100644 index 0000000..4678f7f Binary files /dev/null and b/mods/xdecor/textures/xdecor_glyph13.png differ diff --git a/mods/xdecor/textures/xdecor_glyph14.png b/mods/xdecor/textures/xdecor_glyph14.png new file mode 100644 index 0000000..bf095bb Binary files /dev/null and b/mods/xdecor/textures/xdecor_glyph14.png differ diff --git a/mods/xdecor/textures/xdecor_glyph15.png b/mods/xdecor/textures/xdecor_glyph15.png new file mode 100644 index 0000000..27199bb Binary files /dev/null and b/mods/xdecor/textures/xdecor_glyph15.png differ diff --git a/mods/xdecor/textures/xdecor_glyph16.png b/mods/xdecor/textures/xdecor_glyph16.png new file mode 100644 index 0000000..27e1807 Binary files /dev/null and b/mods/xdecor/textures/xdecor_glyph16.png differ diff --git a/mods/xdecor/textures/xdecor_glyph17.png b/mods/xdecor/textures/xdecor_glyph17.png new file mode 100644 index 0000000..7ed2bd4 Binary files /dev/null and b/mods/xdecor/textures/xdecor_glyph17.png differ diff --git a/mods/xdecor/textures/xdecor_glyph18.png b/mods/xdecor/textures/xdecor_glyph18.png new file mode 100644 index 0000000..f03b73a Binary files /dev/null and b/mods/xdecor/textures/xdecor_glyph18.png differ diff --git a/mods/xdecor/textures/xdecor_glyph2.png b/mods/xdecor/textures/xdecor_glyph2.png new file mode 100644 index 0000000..81b2061 Binary files /dev/null and b/mods/xdecor/textures/xdecor_glyph2.png differ diff --git a/mods/xdecor/textures/xdecor_glyph3.png b/mods/xdecor/textures/xdecor_glyph3.png new file mode 100644 index 0000000..24b8cf4 Binary files /dev/null and b/mods/xdecor/textures/xdecor_glyph3.png differ diff --git a/mods/xdecor/textures/xdecor_glyph4.png b/mods/xdecor/textures/xdecor_glyph4.png new file mode 100644 index 0000000..dc1909b Binary files /dev/null and b/mods/xdecor/textures/xdecor_glyph4.png differ diff --git a/mods/xdecor/textures/xdecor_glyph5.png b/mods/xdecor/textures/xdecor_glyph5.png new file mode 100644 index 0000000..1473ea4 Binary files /dev/null and b/mods/xdecor/textures/xdecor_glyph5.png differ diff --git a/mods/xdecor/textures/xdecor_glyph6.png b/mods/xdecor/textures/xdecor_glyph6.png new file mode 100644 index 0000000..45c0c9a Binary files /dev/null and b/mods/xdecor/textures/xdecor_glyph6.png differ diff --git a/mods/xdecor/textures/xdecor_glyph7.png b/mods/xdecor/textures/xdecor_glyph7.png new file mode 100644 index 0000000..5708623 Binary files /dev/null and b/mods/xdecor/textures/xdecor_glyph7.png differ diff --git a/mods/xdecor/textures/xdecor_glyph8.png b/mods/xdecor/textures/xdecor_glyph8.png new file mode 100644 index 0000000..c5ae1c3 Binary files /dev/null and b/mods/xdecor/textures/xdecor_glyph8.png differ diff --git a/mods/xdecor/textures/xdecor_glyph9.png b/mods/xdecor/textures/xdecor_glyph9.png new file mode 100644 index 0000000..148b03d Binary files /dev/null and b/mods/xdecor/textures/xdecor_glyph9.png differ diff --git a/mods/xdecor/textures/xdecor_half_cabinet_front.png b/mods/xdecor/textures/xdecor_half_cabinet_front.png new file mode 100644 index 0000000..ea9c389 Binary files /dev/null and b/mods/xdecor/textures/xdecor_half_cabinet_front.png differ diff --git a/mods/xdecor/textures/xdecor_half_cabinet_sides.png b/mods/xdecor/textures/xdecor_half_cabinet_sides.png new file mode 100644 index 0000000..6f274b8 Binary files /dev/null and b/mods/xdecor/textures/xdecor_half_cabinet_sides.png differ diff --git a/mods/xdecor/textures/xdecor_hammer.png b/mods/xdecor/textures/xdecor_hammer.png new file mode 100644 index 0000000..17b9856 Binary files /dev/null and b/mods/xdecor/textures/xdecor_hammer.png differ diff --git a/mods/xdecor/textures/xdecor_hard_clay.png b/mods/xdecor/textures/xdecor_hard_clay.png new file mode 100644 index 0000000..8abe666 Binary files /dev/null and b/mods/xdecor/textures/xdecor_hard_clay.png differ diff --git a/mods/xdecor/textures/xdecor_hive_front.png b/mods/xdecor/textures/xdecor_hive_front.png new file mode 100644 index 0000000..4515551 Binary files /dev/null and b/mods/xdecor/textures/xdecor_hive_front.png differ diff --git a/mods/xdecor/textures/xdecor_hive_side.png b/mods/xdecor/textures/xdecor_hive_side.png new file mode 100644 index 0000000..7fd26ad Binary files /dev/null and b/mods/xdecor/textures/xdecor_hive_side.png differ diff --git a/mods/xdecor/textures/xdecor_hive_top.png b/mods/xdecor/textures/xdecor_hive_top.png new file mode 100644 index 0000000..43203e1 Binary files /dev/null and b/mods/xdecor/textures/xdecor_hive_top.png differ diff --git a/mods/xdecor/textures/xdecor_honey.png b/mods/xdecor/textures/xdecor_honey.png new file mode 100644 index 0000000..04c404c Binary files /dev/null and b/mods/xdecor/textures/xdecor_honey.png differ diff --git a/mods/xdecor/textures/xdecor_iron_lightbox.png b/mods/xdecor/textures/xdecor_iron_lightbox.png new file mode 100644 index 0000000..45146f9 Binary files /dev/null and b/mods/xdecor/textures/xdecor_iron_lightbox.png differ diff --git a/mods/xdecor/textures/xdecor_itemframe.png b/mods/xdecor/textures/xdecor_itemframe.png new file mode 100644 index 0000000..088ba15 Binary files /dev/null and b/mods/xdecor/textures/xdecor_itemframe.png differ diff --git a/mods/xdecor/textures/xdecor_ivy.png b/mods/xdecor/textures/xdecor_ivy.png new file mode 100644 index 0000000..b85e112 Binary files /dev/null and b/mods/xdecor/textures/xdecor_ivy.png differ diff --git a/mods/xdecor/textures/xdecor_japanese_door.png b/mods/xdecor/textures/xdecor_japanese_door.png new file mode 100644 index 0000000..35f77ec Binary files /dev/null and b/mods/xdecor/textures/xdecor_japanese_door.png differ diff --git a/mods/xdecor/textures/xdecor_japanese_door_inv.png b/mods/xdecor/textures/xdecor_japanese_door_inv.png new file mode 100644 index 0000000..4d3ec64 Binary files /dev/null and b/mods/xdecor/textures/xdecor_japanese_door_inv.png differ diff --git a/mods/xdecor/textures/xdecor_lantern.png b/mods/xdecor/textures/xdecor_lantern.png new file mode 100644 index 0000000..18c9ce2 Binary files /dev/null and b/mods/xdecor/textures/xdecor_lantern.png differ diff --git a/mods/xdecor/textures/xdecor_lantern_inv.png b/mods/xdecor/textures/xdecor_lantern_inv.png new file mode 100644 index 0000000..71cef66 Binary files /dev/null and b/mods/xdecor/textures/xdecor_lantern_inv.png differ diff --git a/mods/xdecor/textures/xdecor_lever_off.png b/mods/xdecor/textures/xdecor_lever_off.png new file mode 100644 index 0000000..6d8bb49 Binary files /dev/null and b/mods/xdecor/textures/xdecor_lever_off.png differ diff --git a/mods/xdecor/textures/xdecor_lever_on.png b/mods/xdecor/textures/xdecor_lever_on.png new file mode 100644 index 0000000..c64d27f Binary files /dev/null and b/mods/xdecor/textures/xdecor_lever_on.png differ diff --git a/mods/xdecor/textures/xdecor_mailbox.png b/mods/xdecor/textures/xdecor_mailbox.png new file mode 100644 index 0000000..8289884 Binary files /dev/null and b/mods/xdecor/textures/xdecor_mailbox.png differ diff --git a/mods/xdecor/textures/xdecor_mailbox_bottom.png b/mods/xdecor/textures/xdecor_mailbox_bottom.png new file mode 100644 index 0000000..b613863 Binary files /dev/null and b/mods/xdecor/textures/xdecor_mailbox_bottom.png differ diff --git a/mods/xdecor/textures/xdecor_mailbox_side.png b/mods/xdecor/textures/xdecor_mailbox_side.png new file mode 100644 index 0000000..44b2a2f Binary files /dev/null and b/mods/xdecor/textures/xdecor_mailbox_side.png differ diff --git a/mods/xdecor/textures/xdecor_mailbox_top.png b/mods/xdecor/textures/xdecor_mailbox_top.png new file mode 100644 index 0000000..3584c53 Binary files /dev/null and b/mods/xdecor/textures/xdecor_mailbox_top.png differ diff --git a/mods/xdecor/textures/xdecor_moonbrick.png b/mods/xdecor/textures/xdecor_moonbrick.png new file mode 100644 index 0000000..efdac14 Binary files /dev/null and b/mods/xdecor/textures/xdecor_moonbrick.png differ diff --git a/mods/xdecor/textures/xdecor_multishelf.png b/mods/xdecor/textures/xdecor_multishelf.png new file mode 100644 index 0000000..e6c9d15 Binary files /dev/null and b/mods/xdecor/textures/xdecor_multishelf.png differ diff --git a/mods/xdecor/textures/xdecor_packed_ice.png b/mods/xdecor/textures/xdecor_packed_ice.png new file mode 100644 index 0000000..8c44eaf Binary files /dev/null and b/mods/xdecor/textures/xdecor_packed_ice.png differ diff --git a/mods/xdecor/textures/xdecor_painting_1.png b/mods/xdecor/textures/xdecor_painting_1.png new file mode 100644 index 0000000..7609c2b Binary files /dev/null and b/mods/xdecor/textures/xdecor_painting_1.png differ diff --git a/mods/xdecor/textures/xdecor_painting_2.png b/mods/xdecor/textures/xdecor_painting_2.png new file mode 100644 index 0000000..8a9cf4a Binary files /dev/null and b/mods/xdecor/textures/xdecor_painting_2.png differ diff --git a/mods/xdecor/textures/xdecor_painting_3.png b/mods/xdecor/textures/xdecor_painting_3.png new file mode 100644 index 0000000..d094d3d Binary files /dev/null and b/mods/xdecor/textures/xdecor_painting_3.png differ diff --git a/mods/xdecor/textures/xdecor_painting_4.png b/mods/xdecor/textures/xdecor_painting_4.png new file mode 100644 index 0000000..5ccb141 Binary files /dev/null and b/mods/xdecor/textures/xdecor_painting_4.png differ diff --git a/mods/xdecor/textures/xdecor_painting_empty.png b/mods/xdecor/textures/xdecor_painting_empty.png new file mode 100644 index 0000000..216429a Binary files /dev/null and b/mods/xdecor/textures/xdecor_painting_empty.png differ diff --git a/mods/xdecor/textures/xdecor_pressure_stone.png b/mods/xdecor/textures/xdecor_pressure_stone.png new file mode 100644 index 0000000..faf3ae0 Binary files /dev/null and b/mods/xdecor/textures/xdecor_pressure_stone.png differ diff --git a/mods/xdecor/textures/xdecor_pressure_wood.png b/mods/xdecor/textures/xdecor_pressure_wood.png new file mode 100644 index 0000000..504113a Binary files /dev/null and b/mods/xdecor/textures/xdecor_pressure_wood.png differ diff --git a/mods/xdecor/textures/xdecor_prison_door.png b/mods/xdecor/textures/xdecor_prison_door.png new file mode 100644 index 0000000..2f7e66f Binary files /dev/null and b/mods/xdecor/textures/xdecor_prison_door.png differ diff --git a/mods/xdecor/textures/xdecor_prison_door_inv.png b/mods/xdecor/textures/xdecor_prison_door_inv.png new file mode 100644 index 0000000..0751caf Binary files /dev/null and b/mods/xdecor/textures/xdecor_prison_door_inv.png differ diff --git a/mods/xdecor/textures/xdecor_radio_back.png b/mods/xdecor/textures/xdecor_radio_back.png new file mode 100644 index 0000000..78b28c4 Binary files /dev/null and b/mods/xdecor/textures/xdecor_radio_back.png differ diff --git a/mods/xdecor/textures/xdecor_radio_front.png b/mods/xdecor/textures/xdecor_radio_front.png new file mode 100644 index 0000000..0202114 Binary files /dev/null and b/mods/xdecor/textures/xdecor_radio_front.png differ diff --git a/mods/xdecor/textures/xdecor_radio_side.png b/mods/xdecor/textures/xdecor_radio_side.png new file mode 100644 index 0000000..441ae30 Binary files /dev/null and b/mods/xdecor/textures/xdecor_radio_side.png differ diff --git a/mods/xdecor/textures/xdecor_radio_top.png b/mods/xdecor/textures/xdecor_radio_top.png new file mode 100644 index 0000000..b8c1280 Binary files /dev/null and b/mods/xdecor/textures/xdecor_radio_top.png differ diff --git a/mods/xdecor/textures/xdecor_rooster.png b/mods/xdecor/textures/xdecor_rooster.png new file mode 100644 index 0000000..41ab699 Binary files /dev/null and b/mods/xdecor/textures/xdecor_rooster.png differ diff --git a/mods/xdecor/textures/xdecor_rope.png b/mods/xdecor/textures/xdecor_rope.png new file mode 100644 index 0000000..bcfaba2 Binary files /dev/null and b/mods/xdecor/textures/xdecor_rope.png differ diff --git a/mods/xdecor/textures/xdecor_rope_inv.png b/mods/xdecor/textures/xdecor_rope_inv.png new file mode 100644 index 0000000..51a24a8 Binary files /dev/null and b/mods/xdecor/textures/xdecor_rope_inv.png differ diff --git a/mods/xdecor/textures/xdecor_rope_wield.png b/mods/xdecor/textures/xdecor_rope_wield.png new file mode 100644 index 0000000..3ca8fef Binary files /dev/null and b/mods/xdecor/textures/xdecor_rope_wield.png differ diff --git a/mods/xdecor/textures/xdecor_rose_pot.png b/mods/xdecor/textures/xdecor_rose_pot.png new file mode 100644 index 0000000..12923ac Binary files /dev/null and b/mods/xdecor/textures/xdecor_rose_pot.png differ diff --git a/mods/xdecor/textures/xdecor_rusty_bar.png b/mods/xdecor/textures/xdecor_rusty_bar.png new file mode 100644 index 0000000..d2d5866 Binary files /dev/null and b/mods/xdecor/textures/xdecor_rusty_bar.png differ diff --git a/mods/xdecor/textures/xdecor_rusty_prison_door.png b/mods/xdecor/textures/xdecor_rusty_prison_door.png new file mode 100644 index 0000000..3b1dd1a Binary files /dev/null and b/mods/xdecor/textures/xdecor_rusty_prison_door.png differ diff --git a/mods/xdecor/textures/xdecor_rusty_prison_door_inv.png b/mods/xdecor/textures/xdecor_rusty_prison_door_inv.png new file mode 100644 index 0000000..486486b Binary files /dev/null and b/mods/xdecor/textures/xdecor_rusty_prison_door_inv.png differ diff --git a/mods/xdecor/textures/xdecor_screen_door.png b/mods/xdecor/textures/xdecor_screen_door.png new file mode 100644 index 0000000..a00ebb3 Binary files /dev/null and b/mods/xdecor/textures/xdecor_screen_door.png differ diff --git a/mods/xdecor/textures/xdecor_screen_door_inv.png b/mods/xdecor/textures/xdecor_screen_door_inv.png new file mode 100644 index 0000000..6c9633e Binary files /dev/null and b/mods/xdecor/textures/xdecor_screen_door_inv.png differ diff --git a/mods/xdecor/textures/xdecor_slide_door.png b/mods/xdecor/textures/xdecor_slide_door.png new file mode 100644 index 0000000..1810ccd Binary files /dev/null and b/mods/xdecor/textures/xdecor_slide_door.png differ diff --git a/mods/xdecor/textures/xdecor_slide_door_inv.png b/mods/xdecor/textures/xdecor_slide_door_inv.png new file mode 100644 index 0000000..4ea2154 Binary files /dev/null and b/mods/xdecor/textures/xdecor_slide_door_inv.png differ diff --git a/mods/xdecor/textures/xdecor_speaker_back.png b/mods/xdecor/textures/xdecor_speaker_back.png new file mode 100644 index 0000000..0696d9f Binary files /dev/null and b/mods/xdecor/textures/xdecor_speaker_back.png differ diff --git a/mods/xdecor/textures/xdecor_speaker_front.png b/mods/xdecor/textures/xdecor_speaker_front.png new file mode 100644 index 0000000..7d3b085 Binary files /dev/null and b/mods/xdecor/textures/xdecor_speaker_front.png differ diff --git a/mods/xdecor/textures/xdecor_speaker_side.png b/mods/xdecor/textures/xdecor_speaker_side.png new file mode 100644 index 0000000..319dbf6 Binary files /dev/null and b/mods/xdecor/textures/xdecor_speaker_side.png differ diff --git a/mods/xdecor/textures/xdecor_speaker_top.png b/mods/xdecor/textures/xdecor_speaker_top.png new file mode 100644 index 0000000..b510a2e Binary files /dev/null and b/mods/xdecor/textures/xdecor_speaker_top.png differ diff --git a/mods/xdecor/textures/xdecor_stacking_chair.png b/mods/xdecor/textures/xdecor_stacking_chair.png new file mode 100644 index 0000000..fc0728a Binary files /dev/null and b/mods/xdecor/textures/xdecor_stacking_chair.png differ diff --git a/mods/xdecor/textures/xdecor_stacking_chair_topbottom.png b/mods/xdecor/textures/xdecor_stacking_chair_topbottom.png new file mode 100644 index 0000000..204b028 Binary files /dev/null and b/mods/xdecor/textures/xdecor_stacking_chair_topbottom.png differ diff --git a/mods/xdecor/textures/xdecor_stone_rune.png b/mods/xdecor/textures/xdecor_stone_rune.png new file mode 100644 index 0000000..319a2df Binary files /dev/null and b/mods/xdecor/textures/xdecor_stone_rune.png differ diff --git a/mods/xdecor/textures/xdecor_stone_tile.png b/mods/xdecor/textures/xdecor_stone_tile.png new file mode 100644 index 0000000..4346783 Binary files /dev/null and b/mods/xdecor/textures/xdecor_stone_tile.png differ diff --git a/mods/xdecor/textures/xdecor_tatami.png b/mods/xdecor/textures/xdecor_tatami.png new file mode 100644 index 0000000..e1998f7 Binary files /dev/null and b/mods/xdecor/textures/xdecor_tatami.png differ diff --git a/mods/xdecor/textures/xdecor_television1_imploded.png b/mods/xdecor/textures/xdecor_television1_imploded.png new file mode 100644 index 0000000..425c4f6 Binary files /dev/null and b/mods/xdecor/textures/xdecor_television1_imploded.png differ diff --git a/mods/xdecor/textures/xdecor_television_av_front_animated.png b/mods/xdecor/textures/xdecor_television_av_front_animated.png new file mode 100644 index 0000000..57e800c Binary files /dev/null and b/mods/xdecor/textures/xdecor_television_av_front_animated.png differ diff --git a/mods/xdecor/textures/xdecor_television_back.png b/mods/xdecor/textures/xdecor_television_back.png new file mode 100644 index 0000000..e882111 Binary files /dev/null and b/mods/xdecor/textures/xdecor_television_back.png differ diff --git a/mods/xdecor/textures/xdecor_television_front_animated.png b/mods/xdecor/textures/xdecor_television_front_animated.png new file mode 100644 index 0000000..96b62e9 Binary files /dev/null and b/mods/xdecor/textures/xdecor_television_front_animated.png differ diff --git a/mods/xdecor/textures/xdecor_television_left.png b/mods/xdecor/textures/xdecor_television_left.png new file mode 100644 index 0000000..65444fb Binary files /dev/null and b/mods/xdecor/textures/xdecor_television_left.png differ diff --git a/mods/xdecor/textures/xdecor_trampoline.png b/mods/xdecor/textures/xdecor_trampoline.png new file mode 100644 index 0000000..a8536c2 Binary files /dev/null and b/mods/xdecor/textures/xdecor_trampoline.png differ diff --git a/mods/xdecor/textures/xdecor_trampoline_sides.png b/mods/xdecor/textures/xdecor_trampoline_sides.png new file mode 100644 index 0000000..497a86a Binary files /dev/null and b/mods/xdecor/textures/xdecor_trampoline_sides.png differ diff --git a/mods/xdecor/textures/xdecor_tulip_pot.png b/mods/xdecor/textures/xdecor_tulip_pot.png new file mode 100644 index 0000000..d339ef6 Binary files /dev/null and b/mods/xdecor/textures/xdecor_tulip_pot.png differ diff --git a/mods/xdecor/textures/xdecor_vhsshelf.png b/mods/xdecor/textures/xdecor_vhsshelf.png new file mode 100644 index 0000000..ad6b8af Binary files /dev/null and b/mods/xdecor/textures/xdecor_vhsshelf.png differ diff --git a/mods/xdecor/textures/xdecor_viola_pot.png b/mods/xdecor/textures/xdecor_viola_pot.png new file mode 100644 index 0000000..7549c4c Binary files /dev/null and b/mods/xdecor/textures/xdecor_viola_pot.png differ diff --git a/mods/xdecor/textures/xdecor_wood.png b/mods/xdecor/textures/xdecor_wood.png new file mode 100644 index 0000000..426e5bf Binary files /dev/null and b/mods/xdecor/textures/xdecor_wood.png differ diff --git a/mods/xdecor/textures/xdecor_wood_frame.png b/mods/xdecor/textures/xdecor_wood_frame.png new file mode 100644 index 0000000..f528f5a Binary files /dev/null and b/mods/xdecor/textures/xdecor_wood_frame.png differ diff --git a/mods/xdecor/textures/xdecor_wood_tile.png b/mods/xdecor/textures/xdecor_wood_tile.png new file mode 100644 index 0000000..272df2c Binary files /dev/null and b/mods/xdecor/textures/xdecor_wood_tile.png differ diff --git a/mods/xdecor/textures/xdecor_wooden2_lightbox.png b/mods/xdecor/textures/xdecor_wooden2_lightbox.png new file mode 100644 index 0000000..a53ad96 Binary files /dev/null and b/mods/xdecor/textures/xdecor_wooden2_lightbox.png differ diff --git a/mods/xdecor/textures/xdecor_wooden_lightbox.png b/mods/xdecor/textures/xdecor_wooden_lightbox.png new file mode 100644 index 0000000..c5a6b52 Binary files /dev/null and b/mods/xdecor/textures/xdecor_wooden_lightbox.png differ diff --git a/mods/xdecor/textures/xdecor_woodframed_glass.png b/mods/xdecor/textures/xdecor_woodframed_glass.png new file mode 100644 index 0000000..9fd6ea8 Binary files /dev/null and b/mods/xdecor/textures/xdecor_woodframed_glass.png differ diff --git a/mods/xdecor/textures/xdecor_woodframed_glass_detail.png b/mods/xdecor/textures/xdecor_woodframed_glass_detail.png new file mode 100644 index 0000000..9b5d141 Binary files /dev/null and b/mods/xdecor/textures/xdecor_woodframed_glass_detail.png differ diff --git a/mods/xdecor/textures/xdecor_woodglass_door.png b/mods/xdecor/textures/xdecor_woodglass_door.png new file mode 100644 index 0000000..51209e2 Binary files /dev/null and b/mods/xdecor/textures/xdecor_woodglass_door.png differ diff --git a/mods/xdecor/textures/xdecor_woodglass_door_inv.png b/mods/xdecor/textures/xdecor_woodglass_door_inv.png new file mode 100644 index 0000000..e5b3293 Binary files /dev/null and b/mods/xdecor/textures/xdecor_woodglass_door_inv.png differ diff --git a/mods/xdecor/textures/xdecor_workbench_front.png b/mods/xdecor/textures/xdecor_workbench_front.png new file mode 100644 index 0000000..3ef7236 Binary files /dev/null and b/mods/xdecor/textures/xdecor_workbench_front.png differ diff --git a/mods/xdecor/textures/xdecor_workbench_sides.png b/mods/xdecor/textures/xdecor_workbench_sides.png new file mode 100644 index 0000000..24521ad Binary files /dev/null and b/mods/xdecor/textures/xdecor_workbench_sides.png differ diff --git a/mods/xdecor/textures/xdecor_workbench_top.png b/mods/xdecor/textures/xdecor_workbench_top.png new file mode 100644 index 0000000..852a83d Binary files /dev/null and b/mods/xdecor/textures/xdecor_workbench_top.png differ diff --git a/mods/xpanes/README.txt b/mods/xpanes/README.txt new file mode 100644 index 0000000..33fa13e --- /dev/null +++ b/mods/xpanes/README.txt @@ -0,0 +1,33 @@ +Minetest Game mod: xpanes +========================= +See license.txt for license information. + +Authors of source code +---------------------- +Originally by xyz (MIT) +BlockMen (MIT) +sofar (MIT) +Modified by MCL for Adsurv (MIT) +Various Minetest developers and contributors (MIT) + +Authors of media (textures) +--------------------------- +xyz (CC BY-SA 3.0): + All textures not mentioned below. + +Gambit (CC BY-SA 3.0): + xpanes_bar.png + +paramat (CC BY-SA 3.0): + xpanes_bar_top.png + +Krock (CC0 1.0): + xpanes_edge.png + +TumeniNodes (CC BY-SA 3.0): + xpanes_door_steel_bar.png + xpanes_item_steel_bar.png + xpanes_trapdoor_steel_bar.png + xpanes_trapdoor_steel_bar_side.png + xpanes_steel_bar_door_close.ogg + xpanes_steel_bar_door_open.ogg diff --git a/mods/xpanes/init.lua b/mods/xpanes/init.lua new file mode 100644 index 0000000..9dafe1d --- /dev/null +++ b/mods/xpanes/init.lua @@ -0,0 +1,234 @@ +-- xpanes/init.lua + +-- Load support for MT game translation. +local S = minetest.get_translator("xpanes") + + +local function is_pane(pos) + return minetest.get_item_group(minetest.get_node(pos).name, "pane") > 0 +end + +local function connects_dir(pos, name, dir) + local aside = vector.add(pos, minetest.facedir_to_dir(dir)) + if is_pane(aside) then + return true + end + + local connects_to = minetest.registered_nodes[name].connects_to + if not connects_to then + return false + end + local list = minetest.find_nodes_in_area(aside, aside, connects_to) + + if #list > 0 then + return true + end + + return false +end + +local function swap(pos, node, name, param2) + if node.name == name and node.param2 == param2 then + return + end + + minetest.swap_node(pos, {name = name, param2 = param2}) +end + +local function update_pane(pos) + if not is_pane(pos) then + return + end + local node = minetest.get_node(pos) + local name = node.name + if name:sub(-5) == "_flat" then + name = name:sub(1, -6) + end + + local any = node.param2 + local c = {} + local count = 0 + for dir = 0, 3 do + c[dir] = connects_dir(pos, name, dir) + if c[dir] then + any = dir + count = count + 1 + end + end + + if count == 0 then + swap(pos, node, name .. "_flat", any) + elseif count == 1 then + swap(pos, node, name .. "_flat", (any + 1) % 4) + elseif count == 2 then + if (c[0] and c[2]) or (c[1] and c[3]) then + swap(pos, node, name .. "_flat", (any + 1) % 4) + else + swap(pos, node, name, 0) + end + else + swap(pos, node, name, 0) + end +end + +minetest.register_on_placenode(function(pos, node) + if minetest.get_item_group(node, "pane") then + update_pane(pos) + end + for i = 0, 3 do + local dir = minetest.facedir_to_dir(i) + update_pane(vector.add(pos, dir)) + end +end) + +minetest.register_on_dignode(function(pos) + for i = 0, 3 do + local dir = minetest.facedir_to_dir(i) + update_pane(vector.add(pos, dir)) + end +end) + +xpanes = {} +function xpanes.register_pane(name, def) + for i = 1, 15 do + minetest.register_alias("xpanes:" .. name .. "_" .. i, "xpanes:" .. name .. "_flat") + end + + local flatgroups = table.copy(def.groups) + flatgroups.pane = 1 + minetest.register_node(":xpanes:" .. name .. "_flat", { + description = def.description, + drawtype = "nodebox", + paramtype = "light", + is_ground_content = false, + sunlight_propagates = true, + inventory_image = def.inventory_image, + wield_image = def.wield_image, + paramtype2 = "facedir", + tiles = { + def.textures[3], + def.textures[3], + def.textures[3], + def.textures[3], + def.textures[1], + def.textures[1] + }, + groups = flatgroups, + drop = "xpanes:" .. name .. "_flat", + sounds = def.sounds, + use_texture_alpha = def.use_texture_alpha and "blend" or "clip", + node_box = { + type = "fixed", + fixed = {{-1/2, -1/2, -1/32, 1/2, 1/2, 1/32}}, + }, + selection_box = { + type = "fixed", + fixed = {{-1/2, -1/2, -1/32, 1/2, 1/2, 1/32}}, + }, + connect_sides = { "left", "right" }, + }) + + local groups = table.copy(def.groups) + groups.pane = 1 + groups.not_in_creative_inventory = 1 + minetest.register_node(":xpanes:" .. name, { + drawtype = "nodebox", + paramtype = "light", + is_ground_content = false, + sunlight_propagates = true, + description = def.description, + tiles = { + def.textures[3], + def.textures[3], + def.textures[1] + }, + groups = groups, + drop = "xpanes:" .. name .. "_flat", + sounds = def.sounds, + use_texture_alpha = def.use_texture_alpha and "blend" or "clip", + node_box = { + type = "connected", + fixed = {{-1/32, -1/2, -1/32, 1/32, 1/2, 1/32}}, + connect_front = {{-1/32, -1/2, -1/2, 1/32, 1/2, -1/32}}, + connect_left = {{-1/2, -1/2, -1/32, -1/32, 1/2, 1/32}}, + connect_back = {{-1/32, -1/2, 1/32, 1/32, 1/2, 1/2}}, + connect_right = {{1/32, -1/2, -1/32, 1/2, 1/2, 1/32}}, + }, + connects_to = {"group:pane", "group:stone", "group:glass", "group:wood", "group:tree"}, + }) + + +end + +xpanes.register_pane("pane", { + description = S("Glass Pane"), + textures = {"main_glass.png", "", "xpanes_edge.png"}, + inventory_image = "main_glass.png", + wield_image = "main_glass.png", + --sounds = default.node_sound_glass_defaults(), + groups = {snappy=2, cracky=3, oddly_breakable_by_hand=3}, + +}) + + +xpanes.register_pane("bar", { + description = S("Steel Bars"), + textures = {"xpanes_bar.png", "", "xpanes_bar_top.png"}, + inventory_image = "xpanes_bar.png", + wield_image = "xpanes_bar.png", + groups = {cracky=2}, + --sounds = default.node_sound_metal_defaults(), + +}) + +minetest.register_lbm({ + name = "xpanes:gen2", + nodenames = {"group:pane"}, + action = function(pos, node) + update_pane(pos) + for i = 0, 3 do + local dir = minetest.facedir_to_dir(i) + update_pane(vector.add(pos, dir)) + end + end +}) + +-- Register steel bar doors and trapdoors + +if minetest.get_modpath("doors") then + + doors.register("xpanes:door_steel_bar", { + tiles = {{name = "xpanes_door_steel_bar.png", backface_culling = true}}, + description = S("Steel Bar Door"), + inventory_image = "xpanes_item_steel_bar.png", + protected = true, + groups = {node = 1, cracky = 1, level = 2}, + --sounds = default.node_sound_metal_defaults(), + sound_open = "xpanes_steel_bar_door_open", + sound_close = "xpanes_steel_bar_door_close", + gain_open = 0.15, + gain_close = 0.13, + recipe = { + {"xpanes:bar_flat", "xpanes:bar_flat"}, + {"xpanes:bar_flat", "xpanes:bar_flat"}, + {"xpanes:bar_flat", "xpanes:bar_flat"}, + }, + }) + + doors.register_trapdoor("xpanes:trapdoor_steel_bar", { + description = S("Steel Bar Trapdoor"), + inventory_image = "xpanes_trapdoor_steel_bar.png", + wield_image = "xpanes_trapdoor_steel_bar.png", + tile_front = "xpanes_trapdoor_steel_bar.png", + tile_side = "xpanes_trapdoor_steel_bar_side.png", + protected = true, + groups = {node = 1, cracky = 1, level = 2, door = 1}, + --sounds = default.node_sound_metal_defaults(), + sound_open = "xpanes_steel_bar_door_open", + sound_close = "xpanes_steel_bar_door_close", + gain_open = 0.15, + gain_close = 0.13, + }) + + +end diff --git a/mods/xpanes/license.txt b/mods/xpanes/license.txt new file mode 100644 index 0000000..1d2ebf9 --- /dev/null +++ b/mods/xpanes/license.txt @@ -0,0 +1,66 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2014-2016 xyz +Copyright (C) 2014-2016 BlockMen +Copyright (C) 2016 Auke Kok +Copyright (C) 2014-2016 Various Minetest developers and contributors +Copyright (C) 2022 MCL + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media (textures) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2014-2016 xyz +Copyright (C) 2013-2016 Gambit +Copyright (C) 2016 paramat +Copyright (C) 2019 TumeniNodes + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/mods/xpanes/mod.conf b/mods/xpanes/mod.conf new file mode 100644 index 0000000..94619b7 --- /dev/null +++ b/mods/xpanes/mod.conf @@ -0,0 +1,3 @@ +name = xpanes +description = Minetest Game mod: xpanes +optional_depends = doors diff --git a/mods/xpanes/sounds/xpanes_steel_bar_door_close.ogg b/mods/xpanes/sounds/xpanes_steel_bar_door_close.ogg new file mode 100644 index 0000000..0620bfb Binary files /dev/null and b/mods/xpanes/sounds/xpanes_steel_bar_door_close.ogg differ diff --git a/mods/xpanes/sounds/xpanes_steel_bar_door_open.ogg b/mods/xpanes/sounds/xpanes_steel_bar_door_open.ogg new file mode 100644 index 0000000..d159be9 Binary files /dev/null and b/mods/xpanes/sounds/xpanes_steel_bar_door_open.ogg differ diff --git a/mods/xpanes/textures/xpanes_bar.png b/mods/xpanes/textures/xpanes_bar.png new file mode 100644 index 0000000..3ea62a9 Binary files /dev/null and b/mods/xpanes/textures/xpanes_bar.png differ diff --git a/mods/xpanes/textures/xpanes_bar_top.png b/mods/xpanes/textures/xpanes_bar_top.png new file mode 100644 index 0000000..2955d72 Binary files /dev/null and b/mods/xpanes/textures/xpanes_bar_top.png differ diff --git a/mods/xpanes/textures/xpanes_door_steel_bar.png b/mods/xpanes/textures/xpanes_door_steel_bar.png new file mode 100644 index 0000000..39f45c3 Binary files /dev/null and b/mods/xpanes/textures/xpanes_door_steel_bar.png differ diff --git a/mods/xpanes/textures/xpanes_edge.png b/mods/xpanes/textures/xpanes_edge.png new file mode 100644 index 0000000..5768d66 Binary files /dev/null and b/mods/xpanes/textures/xpanes_edge.png differ diff --git a/mods/xpanes/textures/xpanes_edge_obsidian.png b/mods/xpanes/textures/xpanes_edge_obsidian.png new file mode 100644 index 0000000..abdd14e Binary files /dev/null and b/mods/xpanes/textures/xpanes_edge_obsidian.png differ diff --git a/mods/xpanes/textures/xpanes_item_steel_bar.png b/mods/xpanes/textures/xpanes_item_steel_bar.png new file mode 100644 index 0000000..46e4d9c Binary files /dev/null and b/mods/xpanes/textures/xpanes_item_steel_bar.png differ diff --git a/mods/xpanes/textures/xpanes_trapdoor_steel_bar.png b/mods/xpanes/textures/xpanes_trapdoor_steel_bar.png new file mode 100644 index 0000000..a56c5ee Binary files /dev/null and b/mods/xpanes/textures/xpanes_trapdoor_steel_bar.png differ diff --git a/mods/xpanes/textures/xpanes_trapdoor_steel_bar_side.png b/mods/xpanes/textures/xpanes_trapdoor_steel_bar_side.png new file mode 100644 index 0000000..a71231e Binary files /dev/null and b/mods/xpanes/textures/xpanes_trapdoor_steel_bar_side.png differ