From de3adb5859bf2817c5a46e052200759e7a491213 Mon Sep 17 00:00:00 2001 From: paramat Date: Sat, 30 Apr 2016 20:11:08 +0100 Subject: [PATCH 001/121] Default: Lower grass_side and snow_side textures Half coverage for a more grassy appearance Make snow_side universal by removing green pixels Move KevDoy's heart texture credit to above sound credits --- mods/default/README.txt | 10 +++++----- .../default/textures/default_dry_grass_side.png | Bin 285 -> 890 bytes mods/default/textures/default_grass_side.png | Bin 771 -> 779 bytes mods/default/textures/default_snow_side.png | Bin 360 -> 376 bytes 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mods/default/README.txt b/mods/default/README.txt index 15a7f5af..8e72ca5e 100644 --- a/mods/default/README.txt +++ b/mods/default/README.txt @@ -87,7 +87,6 @@ InfinityProject (WTFPL): Splizard (CC BY-SA 3.0): default_snow.png - default_snow_side.png default_pine_sapling.png Zeg9 (CC BY-SA 3.0): @@ -98,7 +97,7 @@ Zeg9 (CC BY-SA 3.0): default_gold_block.png paramat (CC BY-SA 3.0): - wieldhand.png copied from character.png by Jordach (CC BY-SA 3.0) + wieldhand.png -- Copied from character.png by Jordach (CC BY-SA 3.0) default_pinetree.png default_pinetree_top.png default_pinewood.png @@ -121,6 +120,7 @@ paramat (CC BY-SA 3.0): default_dry_grass_*.png default_grass.png default_grass_side.png + default_snow_side.png brunob.santos (CC BY-SA 4.0): default_desert_cobble.png @@ -182,6 +182,9 @@ Gambit (WTFPL): asl97 (WTFPL): default_ice.png +KevDoy (CC BY-SA 3.0) + heart.png + Glass breaking sounds (CC BY 3.0): 1: http://www.freesound.org/people/cmusounddesign/sounds/71947/ 2: http://www.freesound.org/people/Tomlija/sounds/97669/ @@ -221,6 +224,3 @@ Mito551 (sounds) (CC BY-SA): default_dirt_footstep.1.ogg default_dirt_footstep.2.ogg default_glass_footstep.ogg - -KevDoy (CC BY-SA 3.0) - heart.png diff --git a/mods/default/textures/default_dry_grass_side.png b/mods/default/textures/default_dry_grass_side.png index 27f4d9604f672ba30fb4eda036057c889c0b2072..ef375b7fc388c6a1a6d2ed45ca6de773680094e5 100644 GIT binary patch delta 852 zcmV-a1FQU<0{RA!85#xv001BJ|6u?C00v@9M??Vs0RI60puMM)k%=CE-~=8LCnx{A zM_vE`0|!Y&K~y-)O_M!r8+91QfA``0-}m{>XXo0=g|w~^3PU9%6d|ExKuBd^Kp=JM z1`|ugjtn~+QyExLg@nYwKqbV`h=s8WEhIEboVY%_cAWcgoIBewLzJk`^h(e0NWbTO zq@TW7UkX*=hcz761E8~iyNe&z&~=?or$bN;5JFHC1+&?VvMjMIi!4o0J;$fnY_hZc zFN&nFSS|?b4YD+0I+_HKkp3sz|`z{&Q@9+X0|aZy)vAx@dZbxO??n&WwUJw^Ek@~xUcZMSEav5$FbEls#yGA=Q52NLDVAlC=Q+cp zA@g$1w3whs3Ua5@p|#rL>}<};l@^A@BYw^;}|uts{oJR|Kit8 z;JhZGvwrVk`^T@}X}{`SwDjSZzi(dL60q^dcOPwKX+l_kZ}8q{KX34g{`~&aEz_|% z$#Q((=dDj3Z2b1^2V0V?aOeJ`4e9ZNkC{%U_%)xSmqR33!LSU*!x4U113-}!Oy?Zx zNtRO-1zDPK{l*Pc$Mu*_rc^Y6CiKf>-7pyp1_adrC-fNfVzNmFK)EQny>^@Nc#Jye z#Wb5u@{=5YAp`&wQ2}6iwm{X?%MWZ^i8#q}7Rv>395b8EP%D)RaU4??r_AOHidjLU z(ZF#%4ts}~j!jV%^m~1>(~PJVA%tLXJm6;Q7IKy*sG5r7dRUf)s0fmA!p`&8y!ZM|;m`@MHg^4&GX zXZuv&JyZM+PW3-BJ>bBspd+(=j?eQyvmog5^1z#GLLYAkf3P*;)y}9xoF3vp(-=#F z{DK)Ap4~_Tagw~leK~y-)O_M!uTtyUypEEOeX7^t9!!`;r zU;#?OuK-7(K;nl`P(eopTc(31QbfV8ph*GB%2IwsB$GH%kim|<>)rb`Gl$~h6;q8g z?|XF4dESxFzCO}-?~M@={(iot+;H(Uo(@tv1Ds0LPzybF`ct1};u(p8fjznE#yz-+r`=-H?e;S)M#R zJ^u3hPnOL(v3&IMSibt<9<~sgRixb{M1_a27?BWQ-2%~3K_S39RC0S0+2~WK~y-)O_R@V97Pa^zv}MknVpH({~}1F z7=bwO5=3huMR^i(;f%y_;e^C35(shN#4CV=I3!La4m?A^m=GljcH(%wJ3BqyT^!mr z^tHQ6UBB-uxqWX>ufIP*MEK{)igw3QO)SHCB#nx#gkhO*-ha^TR-7F6SZ`>z9C1)w zvuQa$4#YvJH!J{Sp9rgrv4Un0k*nfrQr-ZBK4I32gt0)8)u8MtYSiB63eZl~|{(DWcY5C==Kj$fC(x9~46#)Hdp?!kJIc>L|tncV&CJ$z>g%YTIRhQ*73IM593mLrWyPRh0G zp5s4OSZ@$hMsk9vBQpOyIgbS;TskP#7Fw_9N=DcqZaXIy30XOWx=nP$VXev_app2Se@ zr#C#VKYuOVW4OTN4UtTWg|lXO^L$|Xc1=!748_pt4S(^zHLPAmd{_K;Q=#rE7NcGT zS$CE+YB8@8Ty1E#tFkK}e6)-6Lg;h(>UlzQ@gasx3W}c?oHw*P#m;e^$x&Io9)sV(wp$Hf!eq){Zm8D!d(n3UX~rW4BA%0 i@?=C+ao(_bv*uqRVO01IoT|zI0000P+<%J diff --git a/mods/default/textures/default_snow_side.png b/mods/default/textures/default_snow_side.png index 3e98915131310783a3632d7622c61bdc0ca107b2..f13ec94041f30abf1c8953778008a790957ad3b8 100644 GIT binary patch delta 350 zcmV-k0ipir0{8-uBYyw}VoOIv0RI600RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_ z000McNliru-~|K#1|@(@+Qa|=0R>4!K~y-)eN)+ugfI+!M*Ndd0mBqBbhgvl6v9zK z!c_3~BQiK%SWA(7#MiSec_%{$>|X!?QU=DM$SI?uKGwQE0)LGPp*xk9#-Y4BxdrO% zeFT>63}ktgEw#Q(TamY^Y%36w)Cxj(W*CRR**peE3l>BhU7f7m;*>Jb?BCP4Y=!rk zJ=s>8lz|xJoigxz$lHQ74#l=?#VLlb6O;o=1TX!`&4Q8E{nyc;VW9?|i>-ALyHqh19 w*<;h&k$L59pS~r3Xek4&I_PKR?{M(CU*$QV;Ea2rG5`Po07*qoM6N<$f&@99rvLx| delta 334 zcmV-U0kQu00_XyeBYy!eNklM|AjkO|LrcZgE^ z&o9c62NX;6t1|i@*=6?M&{u8&gIB!re_boltw4!38FjuS9XrtyMn(o5AYUDbIe^$R zxzg~zO^~v^ibt`iACPa$00gcvD*qW78GAwOG?1x4%ml=YP?`-1s{ye91S0^HFTy|! gfE$1VjDk@B0GM6^Le-f=SO5S307*qoM6N<$f^Pq&sQ>@~ From 8d3d558e424f8b5221834bed3780a440ac6b75ab Mon Sep 17 00:00:00 2001 From: Foz Date: Mon, 2 May 2016 22:36:29 -0400 Subject: [PATCH 002/121] Tnt: Fix bug in dropped item counting --- mods/tnt/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/tnt/init.lua b/mods/tnt/init.lua index f939d612..2f0ffdc4 100644 --- a/mods/tnt/init.lua +++ b/mods/tnt/init.lua @@ -51,7 +51,7 @@ local function eject_drops(drops, pos, radius) local count = item:get_count() while count > 0 do local take = math.max(1,math.min(radius * radius, - item:get_count(), + count, item:get_stack_max())) rand_pos(pos, drop_pos, radius) local dropitem = ItemStack(item) From 8c3f96d738eed2f0edcb375ffd6acd574e758a01 Mon Sep 17 00:00:00 2001 From: paramat Date: Thu, 5 May 2016 00:22:57 +0100 Subject: [PATCH 003/121] Stairs/default: Make sandstone(brick) groups consistent Sandstone is crumbly = 1 cracky = 3 to be slowly diggable by hand Sandstonebrick(stair/slab) is cracky = 2 --- mods/default/nodes.lua | 2 +- mods/stairs/init.lua | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua index 9af3131e..d494e1af 100644 --- a/mods/default/nodes.lua +++ b/mods/default/nodes.lua @@ -246,7 +246,7 @@ minetest.register_node("default:desert_stonebrick", { minetest.register_node("default:sandstone", { description = "Sandstone", tiles = {"default_sandstone.png"}, - groups = {crumbly = 2, cracky = 3}, + groups = {crumbly = 1, cracky = 3}, sounds = default.node_sound_stone_defaults(), }) diff --git a/mods/stairs/init.lua b/mods/stairs/init.lua index 7688d905..7c28fa4f 100644 --- a/mods/stairs/init.lua +++ b/mods/stairs/init.lua @@ -339,14 +339,14 @@ stairs.register_stair_and_slab("desert_stonebrick", "default:desert_stonebrick", default.node_sound_stone_defaults()) stairs.register_stair_and_slab("sandstone", "default:sandstone", - {crumbly = 2, cracky = 2}, + {crumbly = 1, cracky = 3}, {"default_sandstone.png"}, "Sandstone Stair", "Sandstone Slab", default.node_sound_stone_defaults()) stairs.register_stair_and_slab("sandstonebrick", "default:sandstonebrick", - {crumbly = 2, cracky = 2}, + {cracky = 2}, {"default_sandstone_brick.png"}, "Sandstone Brick Stair", "Sandstone Brick Slab", From 8ea031ef775d77b4837153f1c889916855b255c0 Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Thu, 21 Apr 2016 21:25:51 +0100 Subject: [PATCH 004/121] Creative: Add global variable creative.formspec_add This pull adds a new global variable called creative.formspec_add that will allow mods to add to the creative inventory screen without the need to fork the mod altogether. Simple solution that works already for inventory_plus' BACK button --- mods/creative/init.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mods/creative/init.lua b/mods/creative/init.lua index c842efd3..a2c8858d 100644 --- a/mods/creative/init.lua +++ b/mods/creative/init.lua @@ -98,6 +98,8 @@ local trash = minetest.create_detached_inventory("creative_trash", { }) trash:set_size("main", 1) +creative.formspec_add = "" + creative.set_creative_formspec = function(player, start_i) local player_name = player:get_player_name() local inv = player_inventory[player_name] @@ -128,6 +130,7 @@ creative.set_creative_formspec = function(player, start_i) "table[6.05,3.35;1.15,0.5;pagenum;#FFFF00," .. tostring(pagenum) .. ",#FFFFFF,/ " .. tostring(pagemax) .. "]" .. default.get_hotbar_bg(0,4.7) .. default.gui_bg .. default.gui_bg_img .. default.gui_slots + .. creative.formspec_add ) end From 3976dc6a5b044cd4a07337ba95848e3ab3d41985 Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Fri, 6 May 2016 15:14:38 +0100 Subject: [PATCH 005/121] Creative: Fix '-' glitch in playername Fix the glitch when players use the '-' character in their username on a server, causing creative inventory to not pass page 2 --- mods/creative/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/creative/init.lua b/mods/creative/init.lua index a2c8858d..5ef8dcf0 100644 --- a/mods/creative/init.lua +++ b/mods/creative/init.lua @@ -194,8 +194,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) creative.set_creative_formspec(player, 0) else local formspec = player:get_inventory_formspec() - local start_i = formspec:match("list%[.-" .. player_name .. ";.-;(%d+)%]") - start_i = tonumber(start_i) or 0 + local start_i = player_inventory[player_name].start_i or 0 if fields.creative_prev then start_i = start_i - 3*8 @@ -212,6 +211,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end end + player_inventory[player_name].start_i = start_i creative.set_creative_formspec(player, start_i) end end) From b36b154257bed99cdda2f90b99aca7af0047e73a Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Sat, 7 May 2016 10:12:58 +0100 Subject: [PATCH 006/121] Creative: Fix inventory crash after toggling creative mode in-game --- mods/creative/init.lua | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/mods/creative/init.lua b/mods/creative/init.lua index 5ef8dcf0..bc4687f7 100644 --- a/mods/creative/init.lua +++ b/mods/creative/init.lua @@ -2,6 +2,7 @@ creative = {} local player_inventory = {} +local creative_mode = minetest.setting_getbool("creative_mode") -- Create detached creative inventory after loading all mods creative.init_creative_inventory = function(player) @@ -14,7 +15,7 @@ creative.init_creative_inventory = function(player) minetest.create_detached_inventory("creative_" .. player_name, { allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) - if minetest.setting_getbool("creative_mode") and not to_list == "main" then + if creative_mode and not to_list == "main" then return count else return 0 @@ -24,7 +25,7 @@ creative.init_creative_inventory = function(player) return 0 end, allow_take = function(inv, listname, index, stack, player) - if minetest.setting_getbool("creative_mode") then + if creative_mode then return -1 else return 0 @@ -86,7 +87,7 @@ local trash = minetest.create_detached_inventory("creative_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) - if minetest.setting_getbool("creative_mode") then + if creative_mode then return stack:get_count() else return 0 @@ -155,7 +156,7 @@ end minetest.register_on_joinplayer(function(player) -- If in creative mode, modify player's inventory forms - if not minetest.setting_getbool("creative_mode") then + if not creative_mode then return end creative.init_creative_inventory(player) @@ -163,7 +164,7 @@ minetest.register_on_joinplayer(function(player) end) minetest.register_on_player_receive_fields(function(player, formname, fields) - if formname ~= "" or not minetest.setting_getbool("creative_mode") then + if formname ~= "" or not creative_mode then return end @@ -216,7 +217,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end end) -if minetest.setting_getbool("creative_mode") then +if creative_mode then local digtime = 0.5 local caps = {times = {digtime, digtime, digtime}, uses = 0, maxlevel = 3} From e7a55734d3de051d6565ebe28a9dd53043f9b352 Mon Sep 17 00:00:00 2001 From: paramat Date: Sun, 8 May 2016 22:26:18 +0100 Subject: [PATCH 007/121] Tnt: Avoid divide-by-zero errors in calc_velocity() --- mods/tnt/init.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mods/tnt/init.lua b/mods/tnt/init.lua index 2f0ffdc4..9fd97f49 100644 --- a/mods/tnt/init.lua +++ b/mods/tnt/init.lua @@ -110,6 +110,11 @@ 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) From 90f24e312d41b59b98fe78e2ed0979aacb17eeb9 Mon Sep 17 00:00:00 2001 From: paramat Date: Tue, 17 May 2016 01:34:52 +0100 Subject: [PATCH 008/121] Default: Remove unnecessary infotexts for chests and signs --- mods/default/nodes.lua | 3 --- 1 file changed, 3 deletions(-) diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua index d494e1af..a97a30fa 100644 --- a/mods/default/nodes.lua +++ b/mods/default/nodes.lua @@ -1447,7 +1447,6 @@ minetest.register_node("default:chest", { on_construct = function(pos) local meta = minetest.get_meta(pos) meta:set_string("formspec", chest_formspec) - meta:set_string("infotext", "Chest") local inv = meta:get_inventory() inv:set_size("main", 8*4) end, @@ -1498,7 +1497,6 @@ minetest.register_node("default:chest_locked", { end, on_construct = function(pos) local meta = minetest.get_meta(pos) - meta:set_string("infotext", "Locked Chest") meta:set_string("owner", "") local inv = meta:get_inventory() inv:set_size("main", 8 * 4) @@ -1636,7 +1634,6 @@ local function register_sign(material, desc, def) --local n = minetest.get_node(pos) local meta = minetest.get_meta(pos) meta:set_string("formspec", "field[text;;${text}]") - meta:set_string("infotext", "\"\"") end, on_receive_fields = function(pos, formname, fields, sender) --print("Sign at "..minetest.pos_to_string(pos).." got "..dump(fields)) From b1e0864cf195d65142ef361fc287c09eaa8f2667 Mon Sep 17 00:00:00 2001 From: red-001 Date: Thu, 19 May 2016 19:40:13 +0100 Subject: [PATCH 009/121] Creative: Reset 'start_i' to 1 when the inventory filter is changed --- mods/creative/init.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mods/creative/init.lua b/mods/creative/init.lua index bc4687f7..0f5bd364 100644 --- a/mods/creative/init.lua +++ b/mods/creative/init.lua @@ -178,6 +178,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) elseif fields.creative_tabs then local tab = tonumber(fields.creative_tabs) inv.tab_id = tab + player_inventory[player_name].start_i = 1 if tab == 1 then creative.set_crafting_formspec(player) @@ -186,10 +187,12 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) creative.set_creative_formspec(player, 0) end elseif fields.creative_clear then + player_inventory[player_name].start_i = 1 inv.filter = "" creative.update_creative_inventory(player_name) creative.set_creative_formspec(player, 0) elseif fields.creative_search then + player_inventory[player_name].start_i = 1 inv.filter = fields.creative_filter:lower() creative.update_creative_inventory(player_name) creative.set_creative_formspec(player, 0) From b9422ed44e0a175278cd7e49909b385a94380e11 Mon Sep 17 00:00:00 2001 From: Thomas--S Date: Thu, 19 May 2016 20:43:46 +0200 Subject: [PATCH 010/121] Vessels: Smaller/improved textures, remove duplicated 'inv' textures Removed unnecessary inventory textures The drinking glass inventory texture now differs from the node texture to be more clearly a drinking glass Smaller textures to reduce size as nodes --- mods/vessels/README.txt | 5 +++++ mods/vessels/init.lua | 10 +++++----- .../vessels/textures/vessels_drinking_glass.png | Bin 188 -> 371 bytes .../textures/vessels_drinking_glass_inv.png | Bin 188 -> 313 bytes mods/vessels/textures/vessels_glass_bottle.png | Bin 200 -> 229 bytes .../textures/vessels_glass_bottle_inv.png | Bin 200 -> 0 bytes mods/vessels/textures/vessels_steel_bottle.png | Bin 257 -> 348 bytes .../textures/vessels_steel_bottle_inv.png | Bin 257 -> 0 bytes 8 files changed, 10 insertions(+), 5 deletions(-) delete mode 100644 mods/vessels/textures/vessels_glass_bottle_inv.png delete mode 100644 mods/vessels/textures/vessels_steel_bottle_inv.png diff --git a/mods/vessels/README.txt b/mods/vessels/README.txt index d5c3da84..c2a802f4 100644 --- a/mods/vessels/README.txt +++ b/mods/vessels/README.txt @@ -43,3 +43,8 @@ Authors of media files Unless specifically noted, Copyright (C) 2012 Vanessa Ezekowitz +The following textures were modified by Thomas-S (License is CC0): + vessels_drinking_glass.png + vessels_drinking_glass_inv.png (Paramat helped to improve this texture) + vessels_glass_bottle.png + vessels_steel_bottle.png diff --git a/mods/vessels/init.lua b/mods/vessels/init.lua index 165efbd5..b36eea20 100644 --- a/mods/vessels/init.lua +++ b/mods/vessels/init.lua @@ -70,14 +70,14 @@ minetest.register_node("vessels:glass_bottle", { description = "Glass Bottle (empty)", drawtype = "plantlike", tiles = {"vessels_glass_bottle.png"}, - inventory_image = "vessels_glass_bottle_inv.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.4, 0.25} + 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(), @@ -103,7 +103,7 @@ minetest.register_node("vessels:drinking_glass", { walkable = false, selection_box = { type = "fixed", - fixed = {-0.25, -0.5, -0.25, 0.25, 0.4, 0.25} + 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(), @@ -122,14 +122,14 @@ minetest.register_node("vessels:steel_bottle", { description = "Heavy Steel Bottle (empty)", drawtype = "plantlike", tiles = {"vessels_steel_bottle.png"}, - inventory_image = "vessels_steel_bottle_inv.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.4, 0.25} + 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/vessels/textures/vessels_drinking_glass.png b/mods/vessels/textures/vessels_drinking_glass.png index 4cff308c29f7618471f41ed3bd249344def22ed1..d5037b8579ee9b712e6a281ee22432f5697b74b2 100644 GIT binary patch delta 356 zcmV-q0h|830rLWo7=H)`0000V^Z#K0000JJOGiWi{{a60|De66lK=n!32;bRa{vGf z6951U69E94oEQKA00(qQO+^Rb1rrfE3W!8F0{{R38FWQhbVF}#ZDnqB07G(RVRU6= zAa`kWXdp*PO;A^X4i^9b0NY7KK~y-)?UJzy!Y~v?Z`4vGD1W7pp@X1{f;jpEet=)= z2Z*z7ieLp597HN2tx-#nxTL|S&5LsP9$aJ~a^g`Ac@mNGWCbB)XT!)gw=^{K<$xo1$$Exr* zfdD{2ZJ925@m*D^ zjaQ&$3*q?&eoe$=w#8x{eEvv-;oLaJ)Zg#5HQ@oYa$^KD+ulh40000|8-G$*l2rk&Wd@@jkv%n*=n1O*?7=#%aX3dcR z3bL1Y`ns||U=?8#5?FKe(R`qgWQl7;iF1B#Zfaf$gL6@8Vo7R>LV0FMhJw4NZ$Nk> zpEyv_LQfaR5R22v2@ qFRVPB&+PsFHdC!y*{udwm>E=2hTN delta 172 zcmdnVw1;tmL_G^L0|Ud`yN`l^lxToYh%1o3_2BiHD~~ttzjpBSz2~n#z5DRhzedmt zD8X0~^&i3WrL7Pl)U4zVeAWiuICgGDjI07#K@}{DK)Ap4~_Tagw~Fdh=fK^zCS34}n%m654<>}%W!f`!0L4mKpzu|(; z!ER=SH7`yEtYk@(XqI&{HZrhqknjm`Yi9BgIFgXiWGEsLC~7RJqR%SCFgKLlpr<+Y QG|(6ZPgg&ebxsLQ0OZ#!^#A|> delta 142 zcmaFLc!F_)3Ws`tPlzi61H(ie#p>04pYuKzopr0Q4Rzf&c&j diff --git a/mods/vessels/textures/vessels_glass_bottle_inv.png b/mods/vessels/textures/vessels_glass_bottle_inv.png deleted file mode 100644 index e9dc6837810f8133d91dcb462c1893769335a46e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv5AX?b1=3sgoV|7H>G{j|_a3=? z?97d=ThAOkcxCn06CJs+m##mY*_gY!ue?aO{0UGgV@Z%-FoVOh8)-m}zo(012*>qg z2BvwOJOT%JQ#Y{a^EGT(r0%>_XhtGW*$OGPHYN$?MG*~-jjV?fk{FCFBt#ly6qW^Jujk`do|E#22WQ%mvv4FO#rZdMCTq8=H^K)}k^GX<;i&7IyQd1PlGfOfQ+&z5*!W;R- zfr^fJx;TbdoPImWHm^BApvAst`;wOK`T{1cDQ$MS?3wu$d%;c2OowsQ|yrk~sST(~4Q zU6Eyy3Zp})px`H){yNi)+t)VfDEB41urvrT-QITbyRB>B8B9HvHsJ%Yn`s|<=9*awpFWk bJ&b3}s_?n+=!bp?&_@iOu6{1-oD!McJ-(n)R<-0S z&_tG!AirRSXZJ44&0SayhG%*>^dt)xy zD>M84MXCRcKAMUZqHG7^qP3TbZ+zL5@?0-$rbO?ir)+v#IS*!>luuA#*$}^QH{-hV l%Dw3gXKsJmYZdNp&1kilr9fBZY7x*X22WQ%mvv4FO#pqXZNdNm diff --git a/mods/vessels/textures/vessels_steel_bottle_inv.png b/mods/vessels/textures/vessels_steel_bottle_inv.png deleted file mode 100644 index 834a3d5a062f37faa598e9c95bb3c59dd8da4fff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 257 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!Uw}`DE0Ep^1ILda2QsHjnR4;s z#pTPFU%h(u#EBC(Zrs?vfB*dX^Ba;pA3b_>_wL=ZXU}fhv}w_zMYCqjnlNEPXJ_Z^ z(#Q-C)8h*&WmQYQ0!?Ho3GxeOcy{ly+}wrbKz^L3i(`ny<+bO``5FvFm@iD3e^0yM zf47oI6O-}0H|CPPGPCbrl={!;qp4US%61?wT6?MZ#+OYg&-KD)O7w1e%BHuK^I*nF x`2+=)4e<+iGp;+Y+?(ET=Juz(R^jf}j8= Date: Sat, 21 May 2016 08:45:55 -0500 Subject: [PATCH 011/121] Doors: Fix uninitialized state variable --- mods/doors/init.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index 90ddcc3d..302eb08f 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -140,6 +140,8 @@ function _doors.door_toggle(pos, clicker) -- fix up lvm-placed right-hinged doors, default closed if minetest.get_node(pos).name:sub(-2) == "_b" then state = 2 + else + state = 0 end else state = tonumber(state) From d8daee7e477ad23affe0b510a86663802099e711 Mon Sep 17 00:00:00 2001 From: paramat Date: Sat, 21 May 2016 03:32:50 +0100 Subject: [PATCH 012/121] Vessels: Make shelf open on 2 sides not impossible 4 sides Make shelf facedir rotatable as is now required --- mods/vessels/init.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mods/vessels/init.lua b/mods/vessels/init.lua index b36eea20..025a5c7c 100644 --- a/mods/vessels/init.lua +++ b/mods/vessels/init.lua @@ -15,7 +15,9 @@ local vessels_shelf_formspec = minetest.register_node("vessels:shelf", { description = "Vessels shelf", - tiles = {"default_wood.png", "default_wood.png", "vessels_shelf.png"}, + tiles = {"default_wood.png", "default_wood.png", "default_wood.png", + "default_wood.png", "vessels_shelf.png", "vessels_shelf.png"}, + paramtype2 = "facedir", is_ground_content = false, groups = {choppy=3,oddly_breakable_by_hand=2,flammable=3}, sounds = default.node_sound_wood_defaults(), From 3e5f3f28d2dea61f0bebd11785d9f1f139441904 Mon Sep 17 00:00:00 2001 From: paramat Date: Sat, 21 May 2016 03:49:28 +0100 Subject: [PATCH 013/121] Vessels: Improve code style --- mods/vessels/init.lua | 61 +++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/mods/vessels/init.lua b/mods/vessels/init.lua index 025a5c7c..e56cc284 100644 --- a/mods/vessels/init.lua +++ b/mods/vessels/init.lua @@ -2,24 +2,24 @@ -- See README.txt for licensing and other information. local vessels_shelf_formspec = - "size[8,7;]".. - default.gui_bg.. - default.gui_bg_img.. - default.gui_slots.. - "list[context;vessels;0,0.3;8,2;]".. - "list[current_player;main;0,2.85;8,1;]".. - "list[current_player;main;0,4.08;8,3;8]".. - "listring[context;vessels]".. - "listring[current_player;main]".. - default.get_hotbar_bg(0,2.85) + "size[8,7;]" .. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "list[context;vessels;0,0.3;8,2;]" .. + "list[current_player;main;0,2.85;8,1;]" .. + "list[current_player;main;0,4.08;8,3;8]" .. + "listring[context;vessels]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0, 2.85) minetest.register_node("vessels:shelf", { - description = "Vessels shelf", + description = "Vessels Shelf", tiles = {"default_wood.png", "default_wood.png", "default_wood.png", "default_wood.png", "vessels_shelf.png", "vessels_shelf.png"}, paramtype2 = "facedir", is_ground_content = false, - groups = {choppy=3,oddly_breakable_by_hand=2,flammable=3}, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, sounds = default.node_sound_wood_defaults(), on_construct = function(pos) @@ -53,18 +53,18 @@ minetest.register_node("vessels:shelf", { on_blast = function(pos) local drops = {} default.get_inventory_drops(pos, "vessels", drops) - drops[#drops+1] = "vessels:shelf" + drops[#drops + 1] = "vessels:shelf" minetest.remove_node(pos) return drops end, }) minetest.register_craft({ - output = 'vessels:shelf', + output = "vessels:shelf", recipe = { - {'group:wood', 'group:wood', 'group:wood'}, - {'group:vessel', 'group:vessel', 'group:vessel'}, - {'group:wood', 'group:wood', 'group:wood'}, + {"group:wood", "group:wood", "group:wood"}, + {"group:vessel", "group:vessel", "group:vessel"}, + {"group:wood", "group:wood", "group:wood"}, } }) @@ -81,16 +81,16 @@ minetest.register_node("vessels:glass_bottle", { type = "fixed", fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} }, - groups = {vessel=1,dig_immediate=3,attached_node=1}, + groups = {vessel = 1, dig_immediate = 3, attached_node = 1}, sounds = default.node_sound_glass_defaults(), }) minetest.register_craft( { output = "vessels:glass_bottle 10", recipe = { - { "default:glass", "", "default:glass" }, - { "default:glass", "", "default:glass" }, - { "", "default:glass", "" } + {"default:glass", "", "default:glass"}, + {"default:glass", "", "default:glass"}, + {"", "default:glass", ""} } }) @@ -107,16 +107,16 @@ minetest.register_node("vessels:drinking_glass", { type = "fixed", fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} }, - groups = {vessel=1,dig_immediate=3,attached_node=1}, + groups = {vessel = 1, dig_immediate = 3, attached_node = 1}, sounds = default.node_sound_glass_defaults(), }) minetest.register_craft( { output = "vessels:drinking_glass 14", recipe = { - { "default:glass", "", "default:glass" }, - { "default:glass", "", "default:glass" }, - { "default:glass", "default:glass", "default:glass" } + {"default:glass", "", "default:glass"}, + {"default:glass", "", "default:glass"}, + {"default:glass", "default:glass", "default:glass"} } }) @@ -133,21 +133,21 @@ minetest.register_node("vessels:steel_bottle", { type = "fixed", fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} }, - groups = {vessel=1,dig_immediate=3,attached_node=1}, + groups = {vessel = 1, dig_immediate = 3, attached_node = 1}, sounds = default.node_sound_defaults(), }) minetest.register_craft( { output = "vessels:steel_bottle 5", 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", "", "default:steel_ingot"}, + {"", "default:steel_ingot", ""} } }) --- Make sure we can recycle them +-- Glass and steel recycling minetest.register_craftitem("vessels:glass_fragments", { description = "Pile of Glass Fragments", @@ -183,4 +183,3 @@ minetest.register_craft( { output = "default:steel_ingot", recipe = "vessels:steel_bottle", }) - From fc902a77de1e54b85076b2a0682fb30dd70359dc Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Sat, 21 May 2016 23:15:59 -0700 Subject: [PATCH 014/121] Boats: Lower boat collision box top Standing on a boat makes you appear to "hover" over it since this collision box is way too high. Lower it so that it's low enough to look normal when walking on top of a boat --- mods/boats/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/boats/init.lua b/mods/boats/init.lua index f8d0ccb4..f481b2a3 100644 --- a/mods/boats/init.lua +++ b/mods/boats/init.lua @@ -34,7 +34,7 @@ end local boat = { physical = true, - collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5}, + collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.15, 0.5}, visual = "mesh", mesh = "boats_boat.obj", textures = {"default_wood.png"}, From 70ef7864c1533cc50ef1da95985ff6b741778066 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Mon, 22 Feb 2016 22:28:17 -0800 Subject: [PATCH 015/121] Farming: Convert plants to use node timers This PR requires @minetest/minetest#3677 Farming and plant growth has traditionally in minetest been implemented using ABM's. These ABM's periodically tick and cause plants to grow. The way these ABM's work has several side effects that can be considered harmful. Not to mention a comprehensive list of downsides here, but ABM's are chance-dependent. That results in the chance that some nodes potentially never get processed by the ABM action, and others get processed always. One can easily find this effect by planting a large field of crops, and seeing that some nodes are fully grown really fast, and some just won't make it to fully grown status even after hours or play time. One could solve the problem by making the ABM's slower, and giving them a 100% of action, but this would cause the entire field to grow a step instantly at ABM intervals, and is both ugly, and a large number of node updates that needs to be sent out to each client. Very un-ideal. With NodeTimers though, each node will see a separate node timer event, and they will likely not coalesce. This means that we can stop relying on chance to distribute plant growth, and assign a single timer event to grow the plant to the next phase. Due to the timer implementation, we won't ever miss a growth event, and we can re-scehdule them until the plant has reached full size. Previously, plants would attempt to grow every 9 seconds, with a chance of 1/20. This means typically, a plant would need 9*20 seconds to grow 1 phase, and since there are 8 steps, a typical plant growth would require 9*20*8 ABM node events. (spread out over 9*8 ABM actual underlying events per block, roughly). because plants are likely not growing to full for a very long time due to statistics working against it (5% of the crops take 20x longer than the median to grow to full, we'd be seeing ABMs fire possibly up to 9*20*8*20 with a 95% confidence interval (the actual math is likely off, but the scale should be correct). That's incredibly wasteful. We'd reach those conditions easily with 20 plant nodes. Now, after we convert to NodeTimers, each plant node will see exactly 8 NodeTimer events, and no more. This scales lineairly per plant. I've tuned the growth rate of crops to be mature in just under 3 whole days. That's about 1hr of game time. Previously, about half the crops would grow to full in under 2 days, but many plants would still not be mature by the end of day 3. This is more consistent. An additional problem in the farming mod was that the final fully-grown plant was also included in the ABM, causing infinite more ABM's even after the entire field had grown to completion. Now, we're left with the problem that none of the pre-existing plants have actual node timers started on them, and we do not want a new ABM to fix this issue, since that would be wasteful. Fortunately, there is now an LBM concept, and we can use it to assure that NodeTimers on crop nodes are properly started, and only have to do the actual conversion once per block, ever. We want to provide a fairly similar growth rate after this conversion and as such I've resorted to modelling some statistical data. For this I created a virtual 32x32 crop field with 9 steps (8 transitions) as is the default wheat crop. We then apply a step where 1 in 20 plants in the field grows a step (randomly chosen) and count the number of steps needed to get to 25%, 50, 75% and 95% grown. The resulting data looks as follows: 25% - ~120 steps * 9 sec / abm = 1080s 50% - ~152 steps = 1368s 75% - ~194 steps = 1746s 95% - ~255 steps = 2295s Next, we want to create a model where the chance that a crop grows is 100% every node timer. Since there will only be 8 steps ever, we want the slowest crops to grow in intervals of ~ 2300 / 8 seconds and the fastest 1/4 of crops to grow 1080 / 8 seconds intervals. We can roughly compare this to a normal distribution with a median of 1400 with a stddev of ~350 (thick fingering this one here). The rest is a bit of thick-fingering to get similar growth rates, taking into account that ABM's fire regularly so if they're missed it's fairly painless, but our timers are going to be 1-2 minutes apart at minimum. I calculate the timer should be around 150s median, and experimented with several jitter ranges. Eventually I settled for now on [80,200] with a redo of [40,80], meaning that each growth step at minimum takes (80 to 200) seconds, and if a negative growth condition was found (darkness, soil not wet, etc), then the growth step is retried every (40 to 80) seconds. The end result is a growth period from seed to full in ~ 2.25 minetest days. This is a little bit shorter than the current growth rate but the chances you'll miss timer ticks is a bit larger, so in normal gameplay it should be fairly comparable. A side effect is that fields grow to full yield fairly quickly after crops make it to mature growth, and no crops are mature a very long time before the majority grows to full. The spread and view over a growing field is also fairly even, there's no large updates with plenty of nodes. Just a node here or there every second or so in large fields. Ultimately, we get rid of ABM rollercoasters that cause tens of node updates every 9 seconds. This will help multiplayer servers likely a lot. --- mods/farming/api.lua | 172 ++++++++++++++++++++++++++----------------- 1 file changed, 105 insertions(+), 67 deletions(-) diff --git a/mods/farming/api.lua b/mods/farming/api.lua index 68f7be75..e25d5b91 100644 --- a/mods/farming/api.lua +++ b/mods/farming/api.lua @@ -1,3 +1,4 @@ + -- Wear out hoes, place soil -- TODO Ignore group:flower farming.hoe_on_use = function(itemstack, user, pointed_thing, uses) @@ -9,11 +10,11 @@ farming.hoe_on_use = function(itemstack, user, pointed_thing, uses) if pt.type ~= "node" then return end - + local under = minetest.get_node(pt.under) local p = {x=pt.under.x, y=pt.under.y+1, z=pt.under.z} local above = minetest.get_node(p) - + -- return if any of the nodes is not registered if not minetest.registered_nodes[under.name] then return @@ -21,23 +22,23 @@ farming.hoe_on_use = function(itemstack, user, pointed_thing, uses) if not minetest.registered_nodes[above.name] then return end - + -- check if the node above the pointed thing is air if above.name ~= "air" then return end - + -- check if pointing at soil if minetest.get_item_group(under.name, "soil") ~= 1 then return end - + -- check if (wet) soil defined local regN = minetest.registered_nodes if regN[under.name].soil == nil or regN[under.name].soil.wet == nil or regN[under.name].soil.dry == nil then return end - + if minetest.is_protected(pt.under, user:get_player_name()) then minetest.record_protection_violation(pt.under, user:get_player_name()) return @@ -47,14 +48,13 @@ farming.hoe_on_use = function(itemstack, user, pointed_thing, uses) return end - -- turn the node into soil, wear out item and play sound minetest.set_node(pt.under, {name = regN[under.name].soil.dry}) minetest.sound_play("default_dig_crumbly", { pos = pt.under, gain = 0.5, }) - + if not minetest.setting_getbool("creative_mode") then itemstack:add_wear(65535/(uses-1)) end @@ -119,6 +119,15 @@ farming.register_hoe = function(name, def) end end +-- how often node timers for plants will tick, +/- some random value +local function tick(pos) + minetest.get_node_timer(pos):start(math.random(166, 286)) +end +-- how often a growth failure tick is retried (e.g. too dark) +local function tick_again(pos) + minetest.get_node_timer(pos):start(math.random(40, 80)) +end + -- Seed placement farming.place_seed = function(itemstack, placer, pointed_thing, plantname) local pt = pointed_thing @@ -129,10 +138,10 @@ farming.place_seed = function(itemstack, placer, pointed_thing, plantname) if pt.type ~= "node" then return end - + local under = minetest.get_node(pt.under) local above = minetest.get_node(pt.above) - + if minetest.is_protected(pt.under, placer:get_player_name()) then minetest.record_protection_violation(pt.under, placer:get_player_name()) return @@ -142,7 +151,6 @@ farming.place_seed = function(itemstack, placer, pointed_thing, plantname) return end - -- return if any of the nodes is not registered if not minetest.registered_nodes[under.name] then return @@ -150,30 +158,86 @@ farming.place_seed = function(itemstack, placer, pointed_thing, plantname) if not minetest.registered_nodes[above.name] then return end - + -- check if pointing at the top of the node if pt.above.y ~= pt.under.y+1 then return end - + -- check if you can replace the node above the pointed node if not minetest.registered_nodes[above.name].buildable_to then return end - + -- check if pointing at soil if minetest.get_item_group(under.name, "soil") < 2 then return end - + -- add the node and remove 1 item from the itemstack minetest.add_node(pt.above, {name = plantname, param2 = 1}) + tick(pt.above) if not minetest.setting_getbool("creative_mode") then itemstack:take_item() end return itemstack end +farming.grow_plant = function(pos, elapsed) + local node = minetest.get_node(pos) + local name = node.name + local def = minetest.registered_nodes[name] + + if not def.next_plant then + -- disable timer for fully grown plant + return + end + + -- grow seed + if minetest.get_item_group(node.name, "seed") and def.fertility then + local soil_node = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z}) + if not soil_node then + tick_again(pos) + return + end + -- omitted is a check for light, we assume seeds can germinate in the dark. + for _, v in pairs(def.fertility) do + if minetest.get_item_group(soil_node.name, v) ~= 0 then + minetest.swap_node(pos, {name = def.next_plant}) + if minetest.registered_nodes[def.next_plant].next_plant then + tick(pos) + return + end + end + end + + return + end + + -- check if on wet soil + local below = minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z}) + if minetest.get_item_group(below.name, "soil") < 3 then + tick_again(pos) + return + end + + -- check light + local light = minetest.get_node_light(pos) + if not light or light < def.minlight or light > def.maxlight then + tick_again(pos) + return + end + + -- grow + minetest.swap_node(pos, {name = def.next_plant}) + + -- new timer needed? + if minetest.registered_nodes[def.next_plant].next_plant then + tick(pos) + end + return +end + -- Register plants farming.register_plant = function(name, def) local mname = name:split(":")[1] @@ -200,6 +264,7 @@ farming.register_plant = function(name, def) end -- Register seed + local lbm_nodes = {mname .. ":seed_" .. pname} local g = {seed = 1, snappy = 3, attached_node = 1} for k, v in pairs(def.fertility) do g[v] = 1 @@ -228,6 +293,10 @@ farming.register_plant = function(name, def) on_place = function(itemstack, placer, pointed_thing) return farming.place_seed(itemstack, placer, pointed_thing, mname .. ":seed_" .. pname) end, + next_plant = mname .. ":" .. pname .. "_1", + on_timer = farming.grow_plant, + minlight = def.minlight, + maxlight = def.maxlight, }) -- Register harvest @@ -237,7 +306,7 @@ farming.register_plant = function(name, def) }) -- Register growing steps - for i=1,def.steps do + for i = 1, def.steps do local drop = { items = { {items = {mname .. ":" .. pname}, rarity = 9 - i}, @@ -248,6 +317,16 @@ farming.register_plant = function(name, def) } local nodegroups = {snappy = 3, flammable = 2, plant = 1, not_in_creative_inventory = 1, attached_node = 1} nodegroups[pname] = i + + local next_plant = nil + local on_timer = nil + + if i < def.steps then + next_plant = mname .. ":" .. pname .. "_" .. (i + 1) + on_timer = farming.grow_plant + lbm_nodes[#lbm_nodes + 1] = mname .. ":" .. pname .. "_" .. i + end + minetest.register_node(mname .. ":" .. pname .. "_" .. i, { drawtype = "plantlike", waving = 1, @@ -262,61 +341,20 @@ farming.register_plant = function(name, def) }, groups = nodegroups, sounds = default.node_sound_leaves_defaults(), + next_plant = next_plant, + on_timer = farming.grow_plant, + minlight = def.minlight, + maxlight = def.maxlight, }) end - -- Growing ABM - minetest.register_abm({ - nodenames = {"group:" .. pname, "group:seed"}, - neighbors = {"group:soil"}, - interval = 9, - chance = 20, + -- replacement LBM for pre-nodetimer plants + minetest.register_lbm({ + name = "farming:start_nodetimer_" .. mname .. "_" .. pname, + nodenames = lbm_nodes, action = function(pos, node) - local plant_height = minetest.get_item_group(node.name, pname) - - -- return if already full grown - if plant_height == def.steps then - return - end - - local node_def = minetest.registered_items[node.name] or nil - - -- grow seed - if minetest.get_item_group(node.name, "seed") and node_def.fertility then - local can_grow = false - local soil_node = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z}) - if not soil_node then - return - end - for _, v in pairs(node_def.fertility) do - if minetest.get_item_group(soil_node.name, v) ~= 0 then - can_grow = true - end - end - if can_grow then - minetest.set_node(pos, {name = node.name:gsub("seed_", "") .. "_1"}) - end - return - end - - -- check if on wet soil - pos.y = pos.y - 1 - local n = minetest.get_node(pos) - if minetest.get_item_group(n.name, "soil") < 3 then - return - end - pos.y = pos.y + 1 - - -- check light - local ll = minetest.get_node_light(pos) - - if not ll or ll < def.minlight or ll > def.maxlight then - return - end - - -- grow - minetest.set_node(pos, {name = mname .. ":" .. pname .. "_" .. plant_height + 1}) - end + tick_again(pos) + end, }) -- Return From e0cb3fce02d172e477ed8bee3735fc7a13ed58c4 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Sun, 6 Mar 2016 21:39:07 -0800 Subject: [PATCH 016/121] Default: Convert saplings to use node timers Each sapling is given a single node timer that is between 2 and 4 days of game play time (40-80 minutes). If you walk out of the zone, and come back later, the tree will always grow to full if the timer has elapsed. Because trees.lua is all functions, it needs to be parsed before nodes.lua, since that references some of its functions. Hence, change the order of parsing here. Otherwise saplings would not grow to full. --- mods/default/init.lua | 2 +- mods/default/nodes.lua | 20 +++++++++ mods/default/trees.lua | 99 ++++++++++++++++++++++-------------------- 3 files changed, 73 insertions(+), 48 deletions(-) diff --git a/mods/default/init.lua b/mods/default/init.lua index 6f1b148b..b362fc75 100644 --- a/mods/default/init.lua +++ b/mods/default/init.lua @@ -36,6 +36,7 @@ default.gui_survival_form = "size[8,8.5]".. -- Load files dofile(minetest.get_modpath("default").."/functions.lua") +dofile(minetest.get_modpath("default").."/trees.lua") dofile(minetest.get_modpath("default").."/nodes.lua") dofile(minetest.get_modpath("default").."/furnace.lua") dofile(minetest.get_modpath("default").."/tools.lua") @@ -43,6 +44,5 @@ dofile(minetest.get_modpath("default").."/craftitems.lua") dofile(minetest.get_modpath("default").."/crafting.lua") dofile(minetest.get_modpath("default").."/mapgen.lua") dofile(minetest.get_modpath("default").."/player.lua") -dofile(minetest.get_modpath("default").."/trees.lua") dofile(minetest.get_modpath("default").."/aliases.lua") dofile(minetest.get_modpath("default").."/legacy.lua") diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua index a97a30fa..9c1dc447 100644 --- a/mods/default/nodes.lua +++ b/mods/default/nodes.lua @@ -455,6 +455,10 @@ minetest.register_node("default:sapling", { paramtype = "light", sunlight_propagates = true, walkable = false, + on_timer = default.grow_sapling, + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(2400,4800)) + end, selection_box = { type = "fixed", fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} @@ -573,6 +577,10 @@ minetest.register_node("default:junglesapling", { paramtype = "light", sunlight_propagates = true, walkable = false, + on_timer = default.grow_sapling, + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(2400,4800)) + end, selection_box = { type = "fixed", fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} @@ -634,6 +642,10 @@ minetest.register_node("default:pine_sapling", { paramtype = "light", sunlight_propagates = true, walkable = false, + on_timer = default.grow_sapling, + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(2400,4800)) + end, selection_box = { type = "fixed", fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} @@ -695,6 +707,10 @@ minetest.register_node("default:acacia_sapling", { paramtype = "light", sunlight_propagates = true, walkable = false, + on_timer = default.grow_sapling, + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(2400,4800)) + end, selection_box = { type = "fixed", fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} @@ -755,6 +771,10 @@ minetest.register_node("default:aspen_sapling", { paramtype = "light", sunlight_propagates = true, walkable = false, + on_timer = default.grow_sapling, + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(2400,4800)) + end, selection_box = { type = "fixed", fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} diff --git a/mods/default/trees.lua b/mods/default/trees.lua index de2452e4..1b062660 100644 --- a/mods/default/trees.lua +++ b/mods/default/trees.lua @@ -59,58 +59,63 @@ end -- Sapling ABM -minetest.register_abm({ - nodenames = {"default:sapling", "default:junglesapling", - "default:pine_sapling", "default:acacia_sapling", - "default:aspen_sapling"}, - interval = 10, - chance = 50, - action = function(pos, node) - if not default.can_grow(pos) then - return - end +function default.grow_sapling(pos) + if not default.can_grow(pos) then + -- try a bit later again + minetest.get_node_timer(pos):start(math.random(240, 600)) + return + end - local mapgen = minetest.get_mapgen_params().mgname - if node.name == "default:sapling" then - minetest.log("action", "A sapling grows into a tree at ".. - minetest.pos_to_string(pos)) - if mapgen == "v6" then - default.grow_tree(pos, random(1, 4) == 1) - else - default.grow_new_apple_tree(pos) - end - elseif node.name == "default:junglesapling" then - minetest.log("action", "A jungle sapling grows into a tree at ".. - minetest.pos_to_string(pos)) - if mapgen == "v6" then - default.grow_jungle_tree(pos) - else - default.grow_new_jungle_tree(pos) - end - elseif node.name == "default:pine_sapling" then - minetest.log("action", "A pine sapling grows into a tree at ".. - minetest.pos_to_string(pos)) - local snow = is_snow_nearby(pos) - if mapgen == "v6" then - default.grow_pine_tree(pos, snow) - elseif snow then - default.grow_new_snowy_pine_tree(pos) - else - default.grow_new_pine_tree(pos) - end - elseif node.name == "default:acacia_sapling" then - minetest.log("action", "An acacia sapling grows into a tree at ".. - minetest.pos_to_string(pos)) - default.grow_new_acacia_tree(pos) - elseif node.name == "default:aspen_sapling" then - minetest.log("action", "An aspen sapling grows into a tree at ".. - minetest.pos_to_string(pos)) - default.grow_new_aspen_tree(pos) + local mapgen = minetest.get_mapgen_params().mgname + local node = minetest.get_node(pos) + if node.name == "default:sapling" then + minetest.log("action", "A sapling grows into a tree at ".. + minetest.pos_to_string(pos)) + if mapgen == "v6" then + default.grow_tree(pos, random(1, 4) == 1) + else + default.grow_new_apple_tree(pos) end + elseif node.name == "default:junglesapling" then + minetest.log("action", "A jungle sapling grows into a tree at ".. + minetest.pos_to_string(pos)) + if mapgen == "v6" then + default.grow_jungle_tree(pos) + else + default.grow_new_jungle_tree(pos) + end + elseif node.name == "default:pine_sapling" then + minetest.log("action", "A pine sapling grows into a tree at ".. + minetest.pos_to_string(pos)) + local snow = is_snow_nearby(pos) + if mapgen == "v6" then + default.grow_pine_tree(pos, snow) + elseif snow then + default.grow_new_snowy_pine_tree(pos) + else + default.grow_new_pine_tree(pos) + end + elseif node.name == "default:acacia_sapling" then + minetest.log("action", "An acacia sapling grows into a tree at ".. + minetest.pos_to_string(pos)) + default.grow_new_acacia_tree(pos) + elseif node.name == "default:aspen_sapling" then + minetest.log("action", "An aspen sapling grows into a tree at ".. + minetest.pos_to_string(pos)) + default.grow_new_aspen_tree(pos) + end +end + +minetest.register_lbm({ + name = "default:convert_saplings_to_node_timer", + nodenames = {"default:sapling", "default:junglesapling", + "default:pine_sapling", "default:acacia_sapling", + "default:aspen_sapling"}, + action = function(pos) + minetest.get_node_timer(pos):start(math.random(1200, 2400)) end }) - -- -- Tree generation -- From d61803b65f22b5cd32f7938c64578b04dd437154 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Sat, 12 Mar 2016 20:19:37 -0800 Subject: [PATCH 017/121] Fire: move fire node removal out of ABM. Because the fire nodes are not removed 100% when there are no more burnable nodes nearby, they can potentially stay around for very, very long times, leading to ABM trains every 5 seconds for no good reason (only 1 in 16 will be removed every interval). A much better method to remove fire nodes is to remove them by timer, and give removal a 100% chance if no flammable nodes are adjacent. This makes fire cleanup a lot faster and more natural, and will reduce the amount of ABM hits making fire overall more responsive. We also remove the 1 in 4 chance and fold the removal of flammable nodes into the ABM chance. There's some low hanging fruit cleanups in here as well. --- mods/fire/init.lua | 56 +++++++++++++++------------------------------- 1 file changed, 18 insertions(+), 38 deletions(-) diff --git a/mods/fire/init.lua b/mods/fire/init.lua index 457f6b5e..832b7014 100644 --- a/mods/fire/init.lua +++ b/mods/fire/init.lua @@ -28,14 +28,24 @@ minetest.register_node("fire:basic_flame", { sunlight_propagates = true, damage_per_second = 4, groups = {igniter = 2, dig_immediate = 3, not_in_creative_inventory = 1}, + on_timer = function(pos) + local f = minetest.find_node_near(pos, 1, {"group:flammable"}) + if not f then + minetest.remove_node(pos) + return + end + -- restart timer + return true + end, drop = "", on_construct = function(pos) - minetest.after(0, fire.on_flame_add_at, pos) + minetest.get_node_timer(pos):start(math.random(30, 60)) + minetest.after(0, fire.update_sounds_around, pos) end, on_destruct = function(pos) - minetest.after(0, fire.on_flame_remove_at, pos) + minetest.after(0, fire.update_sounds_around, pos) end, on_blast = function() @@ -169,32 +179,6 @@ function fire.update_sounds_around(pos) end --- Update fire sounds on flame node construct or destruct - -function fire.on_flame_add_at(pos) - fire.update_sounds_around(pos) -end - - -function fire.on_flame_remove_at(pos) - fire.update_sounds_around(pos) -end - - --- Return positions for flames around a burning node - -function fire.find_pos_for_flame_around(pos) - return minetest.find_node_near(pos, 1, {"air"}) -end - - --- Detect nearby extinguishing nodes - -function fire.flame_should_extinguish(pos) - return minetest.find_node_near(pos, 1, {"group:puts_out_fire"}) -end - - -- Extinguish all flames quickly with water, snow, ice minetest.register_abm({ @@ -239,31 +223,27 @@ else catch_up = false, action = function(p0, node, _, _) -- If there is water or stuff like that around node, don't ignite - if fire.flame_should_extinguish(p0) then + if minetest.find_node_near(p0, 1, {"group:puts_out_fire"}) then return end - local p = fire.find_pos_for_flame_around(p0) + local p = minetest.find_node_near(p0, 1, {"air"}) if p then minetest.set_node(p, {name = "fire:basic_flame"}) end end, }) - -- Remove basic flames and flammable nodes + -- Remove flammable nodes minetest.register_abm({ nodenames = {"fire:basic_flame"}, + neighbors = "group:flammable", interval = 5, - chance = 6, + chance = 18, catch_up = false, action = function(p0, node, _, _) - -- If there are no flammable nodes around flame, remove flame local p = minetest.find_node_near(p0, 1, {"group:flammable"}) - if not p then - minetest.remove_node(p0) - return - end - if math.random(1, 3) == 1 then + if p then -- remove flammable nodes around flame local node = minetest.get_node(p) local def = minetest.registered_nodes[node.name] From 37347d40f4668ab2ed2e231e3008fd0bbb947df5 Mon Sep 17 00:00:00 2001 From: paramat Date: Tue, 24 May 2016 05:29:30 +0100 Subject: [PATCH 018/121] Default: Bookshelf has 2 openings instead of 4 Make rotatable with 'paramtype2 = facedir' --- mods/default/nodes.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua index 9c1dc447..3b6e0b1d 100644 --- a/mods/default/nodes.lua +++ b/mods/default/nodes.lua @@ -1586,7 +1586,9 @@ local bookshelf_formspec = minetest.register_node("default:bookshelf", { description = "Bookshelf", - tiles = {"default_wood.png", "default_wood.png", "default_bookshelf.png"}, + tiles = {"default_wood.png", "default_wood.png", "default_wood.png", + "default_wood.png", "default_bookshelf.png", "default_bookshelf.png"}, + paramtype2 = "facedir", is_ground_content = false, groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, sounds = default.node_sound_wood_defaults(), From 541b2d79c7813663feaa50c64151c175aef0f95f Mon Sep 17 00:00:00 2001 From: paramat Date: Sun, 22 May 2016 00:54:57 +0100 Subject: [PATCH 019/121] Default: New mese texture. Add missing texture credits Mese texture is a classic-mese-yellow version of celeron55's texture used in MTv0.4.0 Add missing texture credits for mese crystal and mese crystal fragment --- mods/default/README.txt | 3 +++ mods/default/textures/default_mese_block.png | Bin 224 -> 188 bytes 2 files changed, 3 insertions(+) diff --git a/mods/default/README.txt b/mods/default/README.txt index 8e72ca5e..051af060 100644 --- a/mods/default/README.txt +++ b/mods/default/README.txt @@ -58,6 +58,8 @@ VanessaE (WTFPL): default_desert_sand.png default_desert_stone.png default_sand.png + default_mese_crystal.png + default_mese_crystal_fragment.png Calinou (CC BY-SA): default_brick.png @@ -121,6 +123,7 @@ paramat (CC BY-SA 3.0): default_grass.png default_grass_side.png default_snow_side.png + default_mese_block.png brunob.santos (CC BY-SA 4.0): default_desert_cobble.png diff --git a/mods/default/textures/default_mese_block.png b/mods/default/textures/default_mese_block.png index 2e6895d370621397b51f5e960bb04ece03971345..e30994e21c3104b547ef397a1fa7e01dc956b8c5 100644 GIT binary patch delta 172 zcmaFBxQB6qL_HHT0|P_ST=7ppiYLG)#C6#+hBIdvo;_pu|DT~r^}8KVoU_0qvY3H^ z?+6GpPSxg<1`4v5c>21sKVX$$v69y)wJHJ%IeWS|hHzX@zVZM6fBUxb*Wdo9RP4>Z z>eUv$UaY`q&kLrFTN>7cuWnf5-YsPzdG9~77Ncr$yum>gxq^d{J`SqE&d!G!{!Z7Z U7Qd-|0cakBr>mdKI;Vst0H0?)dH?_b delta 208 zcmV;>05AW%0pJ0U7=Hu<0002(-QrRJ0016POjJd}!~p;Q1?A`f$jSiWf1?cMl z`TPa(^aR@70PQl@MgRZ+eMv+?R0!8&P;mhRPX-SKafKiT24MzQ1tx|jwlrY|M}-L! zgculufg+I#LTrh`4DJdN3POy6%|IzZg(e1uVg|=R(Lm9PQc0j Date: Sun, 29 May 2016 16:46:34 -0700 Subject: [PATCH 020/121] Doors: Pass pointed_thing to on_rightclick() callback This is an omission technicality. The callee should be able to trust this isn't `nil` --- mods/doors/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index 302eb08f..b1bf123c 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -254,7 +254,7 @@ function doors.register(name, def) local pdef = minetest.registered_nodes[node.name] if pdef and pdef.on_rightclick then return pdef.on_rightclick(pointed_thing.under, - node, placer, itemstack) + node, placer, itemstack, pointed_thing) end if pdef and pdef.buildable_to then From 6386684f3efd07443cc4ae25b0b3da22cfabaa33 Mon Sep 17 00:00:00 2001 From: paramat Date: Thu, 5 May 2016 00:55:56 +0100 Subject: [PATCH 021/121] Fire: Ignite tnt, gunpowder, permanent flame above coalblock Enable ignition of tnt, gunpowder and permanent flame above coalblock using flint and steel Override coalblock to remove flame above when dug Add depends.txt for default mod --- mods/fire/depends.txt | 1 + mods/fire/init.lua | 61 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 51 insertions(+), 11 deletions(-) create mode 100644 mods/fire/depends.txt diff --git a/mods/fire/depends.txt b/mods/fire/depends.txt new file mode 100644 index 00000000..4ad96d51 --- /dev/null +++ b/mods/fire/depends.txt @@ -0,0 +1 @@ +default diff --git a/mods/fire/init.lua b/mods/fire/init.lua index 832b7014..08b53a89 100644 --- a/mods/fire/init.lua +++ b/mods/fire/init.lua @@ -80,26 +80,51 @@ minetest.register_node("fire:permanent_flame", { end, }) + +-- Flint and steel + minetest.register_tool("fire:flint_and_steel", { description = "Flint and Steel", inventory_image = "fire_flint_steel.png", on_use = function(itemstack, user, pointed_thing) - local player_name = user:get_player_name() + itemstack:add_wear(1000) local pt = pointed_thing - - if pt.type == "node" and minetest.get_node(pt.above).name == "air" then - itemstack:add_wear(1000) + if pt.type == "node" then local node_under = minetest.get_node(pt.under).name - - if minetest.get_item_group(node_under, "flammable") >= 1 then - if not minetest.is_protected(pt.above, player_name) then - minetest.set_node(pt.above, {name = "fire:basic_flame"}) - else - minetest.chat_send_player(player_name, "This area is protected") + local is_coalblock = node_under == "default:coalblock" + local is_tnt = node_under == "tnt:tnt" + local is_gunpowder = node_under == "tnt:gunpowder" + if minetest.get_item_group(node_under, "flammable") >= 1 or + is_coalblock or is_tnt or is_gunpowder then + local flame_pos = pt.above + if is_coalblock then + flame_pos = {x = pt.under.x, y = pt.under.y + 1, z = pt.under.z} + elseif is_tnt or is_gunpowder then + flame_pos = pt.under + end + if minetest.get_node(flame_pos).name == "air" or + is_tnt or is_gunpowder then + local player_name = user:get_player_name() + if not minetest.is_protected(flame_pos, player_name) then + if is_coalblock then + minetest.set_node(flame_pos, + {name = "fire:permanent_flame"}) + elseif is_tnt then + minetest.set_node(flame_pos, + {name = "tnt:tnt_burning"}) + elseif is_gunpowder then + minetest.set_node(flame_pos, + {name = "tnt:gunpowder_burning"}) + else + minetest.set_node(flame_pos, + {name = "fire:basic_flame"}) + end + else + minetest.chat_send_player(player_name, "This area is protected") + end end end end - if not minetest.setting_getbool("creative_mode") then return itemstack end @@ -113,6 +138,20 @@ minetest.register_craft({ } }) + +-- Override coalblock to enable permanent flame above +-- Coalblock is non-flammable to avoid unwanted basic_flame nodes + +minetest.override_item("default:coalblock", { + after_destruct = function(pos, oldnode) + pos.y = pos.y + 1 + if minetest.get_node(pos).name == "fire:permanent_flame" then + minetest.remove_node(pos) + end + end, +}) + + -- Get sound area of position fire.D = 6 -- size of sound areas From dcf2465441c69550b4a41f8446abdc3981bd5a85 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Sat, 28 May 2016 23:21:54 -0700 Subject: [PATCH 022/121] Farming: allow LBM's for other mods as well. Fixes #1114 --- mods/farming/api.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/farming/api.lua b/mods/farming/api.lua index e25d5b91..966910f6 100644 --- a/mods/farming/api.lua +++ b/mods/farming/api.lua @@ -350,7 +350,7 @@ farming.register_plant = function(name, def) -- replacement LBM for pre-nodetimer plants minetest.register_lbm({ - name = "farming:start_nodetimer_" .. mname .. "_" .. pname, + name = ":" .. mname .. ":start_nodetimer_" .. pname, nodenames = lbm_nodes, action = function(pos, node) tick_again(pos) From b5ea7d17b26f84d5a37b03c27d95b4583e6767c0 Mon Sep 17 00:00:00 2001 From: paramat Date: Sun, 5 Jun 2016 17:21:15 +0100 Subject: [PATCH 023/121] Mapgen: Add biome fields for riverbed node and depth --- mods/default/mapgen.lua | 52 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/mods/default/mapgen.lua b/mods/default/mapgen.lua index 016d58de..c84aa7b4 100644 --- a/mods/default/mapgen.lua +++ b/mods/default/mapgen.lua @@ -334,6 +334,8 @@ function default.register_biomes() depth_water_top = 10, --node_water = "", node_river_water = "default:ice", + node_riverbed = "default:gravel", + depth_riverbed = 2, y_min = -8, y_max = 31000, heat_point = 0, @@ -372,6 +374,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:gravel", + depth_riverbed = 2, y_min = 2, y_max = 31000, heat_point = 15, @@ -390,6 +394,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:gravel", + depth_riverbed = 2, y_min = -3, y_max = 1, heat_point = 15, @@ -408,6 +414,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:gravel", + depth_riverbed = 2, y_min = -112, y_max = -4, heat_point = 15, @@ -427,6 +435,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = 2, y_max = 31000, heat_point = 15, @@ -445,6 +455,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = -112, y_max = 1, heat_point = 15, @@ -465,6 +477,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = 6, y_max = 31000, heat_point = 40, @@ -483,6 +497,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = 5, y_max = 5, heat_point = 40, @@ -501,6 +517,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = -112, y_max = 4, heat_point = 40, @@ -520,6 +538,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = 6, y_max = 31000, heat_point = 40, @@ -538,6 +558,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = 5, y_max = 5, heat_point = 40, @@ -556,6 +578,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = -112, y_max = 4, heat_point = 40, @@ -575,6 +599,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = 6, y_max = 31000, heat_point = 60, @@ -593,6 +619,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = 5, y_max = 5, heat_point = 60, @@ -611,6 +639,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = -112, y_max = 4, heat_point = 60, @@ -630,6 +660,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = 1, y_max = 31000, heat_point = 60, @@ -648,6 +680,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = -3, y_max = 0, heat_point = 60, @@ -666,6 +700,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = -112, y_max = -4, heat_point = 60, @@ -686,6 +722,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = 5, y_max = 31000, heat_point = 85, @@ -704,6 +742,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = -112, y_max = 4, heat_point = 85, @@ -723,6 +763,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = 1, y_max = 31000, heat_point = 85, @@ -741,6 +783,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = -3, y_max = 0, heat_point = 85, @@ -759,6 +803,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = -112, y_max = -4, heat_point = 85, @@ -778,6 +824,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = 1, y_max = 31000, heat_point = 85, @@ -796,6 +844,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = -3, y_max = 0, heat_point = 85, @@ -814,6 +864,8 @@ function default.register_biomes() --depth_water_top = , --node_water = "", --node_river_water = "", + node_riverbed = "default:sand", + depth_riverbed = 2, y_min = -112, y_max = -4, heat_point = 85, From 2199be51087d0d9661d1b3f80c0bb2a55410458b Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Mon, 30 May 2016 12:03:55 -0700 Subject: [PATCH 024/121] Stairs: Add mossy cobble slab and stair Allow water to turn cobble slab and stairs to turn into mossy versions. There is no crafting recipe for mossy stairs and mossy slabs, the stair/slab API has been modified to allow for a recipeitem that is `nil`, which will omit adding a crafting recipe for these two items. The API documentation is updated. The slabs and stairs will turn mossy when water is adjacent, just like cobblestone. You can either farm mossy versions by placing them in water for a while, then collecting them, or run water over your craft. --- game_api.txt | 2 +- mods/default/functions.lua | 10 +++++-- mods/stairs/init.lua | 57 +++++++++++++++++++++++--------------- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/game_api.txt b/game_api.txt index 634b7f29..93cf0527 100644 --- a/game_api.txt +++ b/game_api.txt @@ -343,7 +343,7 @@ delivered with Minetest Game, to keep them compatible with other mods. * Registers a stair. * `subname`: Basically the material name (e.g. cobble) used for the stair name. Nodename pattern: "stairs:stair_subname" - * `recipeitem`: Item used in the craft recipe, e.g. "default:cobble" + * `recipeitem`: Item used in the craft recipe, e.g. "default:cobble", may be `nil` * `groups`: see [Known damage and digging time defining groups] * `images`: see [Tile definition] * `description`: used for the description field in the stair's definition diff --git a/mods/default/functions.lua b/mods/default/functions.lua index 7e594b31..f3bb97cd 100644 --- a/mods/default/functions.lua +++ b/mods/default/functions.lua @@ -466,12 +466,18 @@ minetest.register_abm({ -- minetest.register_abm({ - nodenames = {"default:cobble"}, + nodenames = {"default:cobble", "stairs:slab_cobble", "stairs:stair_cobble"}, neighbors = {"group:water"}, interval = 16, chance = 200, catch_up = false, action = function(pos, node) - minetest.set_node(pos, {name = "default:mossycobble"}) + if node.name == "default:cobble" then + minetest.set_node(pos, {name = "default:mossycobble"}) + elseif node.name == "stairs:slab_cobble" then + minetest.set_node(pos, {name = "stairs:slab_mossycobble", param2 = node.param2}) + elseif node.name == "stairs:stair_cobble" then + minetest.set_node(pos, {name = "stairs:stair_mossycobble", param2 = node.param2}) + end end }) diff --git a/mods/stairs/init.lua b/mods/stairs/init.lua index 7c28fa4f..2195e4d4 100644 --- a/mods/stairs/init.lua +++ b/mods/stairs/init.lua @@ -87,24 +87,26 @@ function stairs.register_stair(subname, recipeitem, groups, images, description, }) end - minetest.register_craft({ - output = 'stairs:stair_' .. subname .. ' 6', - recipe = { - {recipeitem, "", ""}, - {recipeitem, recipeitem, ""}, - {recipeitem, recipeitem, recipeitem}, - }, - }) + if recipeitem then + minetest.register_craft({ + output = 'stairs:stair_' .. subname .. ' 6', + recipe = { + {recipeitem, "", ""}, + {recipeitem, recipeitem, ""}, + {recipeitem, recipeitem, recipeitem}, + }, + }) - -- Flipped recipe for the silly minecrafters - minetest.register_craft({ - output = 'stairs:stair_' .. subname .. ' 6', - recipe = { - {"", "", recipeitem}, - {"", recipeitem, recipeitem}, - {recipeitem, recipeitem, recipeitem}, - }, - }) + -- Flipped recipe for the silly minecrafters + minetest.register_craft({ + output = 'stairs:stair_' .. subname .. ' 6', + recipe = { + {"", "", recipeitem}, + {"", recipeitem, recipeitem}, + {recipeitem, recipeitem, recipeitem}, + }, + }) + end end @@ -218,12 +220,14 @@ function stairs.register_slab(subname, recipeitem, groups, images, description, }) end - minetest.register_craft({ - output = 'stairs:slab_' .. subname .. ' 6', - recipe = { - {recipeitem, recipeitem, recipeitem}, - }, - }) + if recipeitem then + minetest.register_craft({ + output = 'stairs:slab_' .. subname .. ' 6', + recipe = { + {recipeitem, recipeitem, recipeitem}, + }, + }) + end end @@ -310,6 +314,13 @@ stairs.register_stair_and_slab("cobble", "default:cobble", "Cobblestone Slab", default.node_sound_stone_defaults()) +stairs.register_stair_and_slab("mossycobble", nil, + {cracky = 3}, + {"default_mossycobble.png"}, + "Mossy Cobblestone Stair", + "Mossy Cobblestone Slab", + default.node_sound_stone_defaults()) + stairs.register_stair_and_slab("stonebrick", "default:stonebrick", {cracky = 3}, {"default_stone_brick.png"}, From da0fe31443df586198c1265d08deb5458017e664 Mon Sep 17 00:00:00 2001 From: paramat Date: Tue, 14 Jun 2016 21:16:22 +0100 Subject: [PATCH 025/121] Boats: Raise collisionbox top surface to fix boat behaviour Lowering the top surface to be level with the boat top somehow causes the boat to fall through world if underwater. Revert to previous position that is needed for correct behaviour --- mods/boats/init.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mods/boats/init.lua b/mods/boats/init.lua index f481b2a3..0097a57a 100644 --- a/mods/boats/init.lua +++ b/mods/boats/init.lua @@ -34,7 +34,9 @@ end local boat = { physical = true, - collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.15, 0.5}, + -- Warning: Do not change the position of the collisionbox top surface, + -- lowering it causes the boat to fall through the world if underwater + collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5}, visual = "mesh", mesh = "boats_boat.obj", textures = {"default_wood.png"}, From 50eb07981366ec4e7682c3bf292f74c321e8de99 Mon Sep 17 00:00:00 2001 From: paramat Date: Tue, 14 Jun 2016 21:44:49 +0100 Subject: [PATCH 026/121] Creative: Add missing 'formspec_escape' to fix bug Symbols used in search caused the game to hang with a grey screen, for example searching for 'diamond;ingot' --- mods/creative/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/creative/init.lua b/mods/creative/init.lua index 0f5bd364..7f952d32 100644 --- a/mods/creative/init.lua +++ b/mods/creative/init.lua @@ -124,7 +124,7 @@ creative.set_creative_formspec = function(player, start_i) tooltip[creative_clear;Reset] listring[current_player;main] ]] .. - "field[0.3,3.5;2.2,1;creative_filter;;" .. inv.filter .. "]" .. + "field[0.3,3.5;2.2,1;creative_filter;;" .. minetest.formspec_escape(inv.filter) .. "]" .. "listring[detached:creative_" .. player_name .. ";main]" .. "tabheader[0,0;creative_tabs;Crafting,All,Nodes,Tools,Items;" .. tostring(inv.tab_id) .. ";true;false]" .. "list[detached:creative_" .. player_name .. ";main;0,0;8,3;" .. tostring(start_i) .. "]" .. From ba1ae07b4a7b59fd27614b3d93ddc7faca28e3cf Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Sun, 29 May 2016 13:45:18 -0700 Subject: [PATCH 027/121] Default: Make brick and plank nodes rotatable Allow many crafted nodes to be rotated in any way possible. These blocks all have slab and stair versions, which can create awkward patterns if placed together. By allowing these to be rotated players can create new patterns and appearances that were not before possible. Since this wasn't possible before, there won't be any effect to existing builds, as param2 should always be '0'. The current screwdriver mod also refuses to rotate and alter param2, so this is safe to enable from now on. Personally, since these are all *crafted* nodes to begin with, it should be apparent that they can be rotated to begin with, but I can see people may disagree from a simplicity perspective. It also may affect param2 usage that other mods rely on, although I'm not aware of any mods that do this. --- mods/default/nodes.lua | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua index 3b6e0b1d..dcd92ecc 100644 --- a/mods/default/nodes.lua +++ b/mods/default/nodes.lua @@ -202,6 +202,8 @@ minetest.register_node("default:cobble", { minetest.register_node("default:stonebrick", { description = "Stone Brick", + paramtype2 = "facedir", + place_param2 = 0, tiles = {"default_stone_brick.png"}, is_ground_content = false, groups = {cracky = 2, stone = 1}, @@ -236,6 +238,8 @@ minetest.register_node("default:desert_cobble", { minetest.register_node("default:desert_stonebrick", { description = "Desert Stone Brick", + paramtype2 = "facedir", + place_param2 = 0, tiles = {"default_desert_stone_brick.png"}, is_ground_content = false, groups = {cracky = 2, stone = 1}, @@ -252,6 +256,8 @@ minetest.register_node("default:sandstone", { minetest.register_node("default:sandstonebrick", { description = "Sandstone Brick", + paramtype2 = "facedir", + place_param2 = 0, tiles = {"default_sandstone_brick.png"}, is_ground_content = false, groups = {cracky = 2}, @@ -268,6 +274,8 @@ minetest.register_node("default:obsidian", { minetest.register_node("default:obsidianbrick", { description = "Obsidian Brick", + paramtype2 = "facedir", + place_param2 = 0, tiles = {"default_obsidian_brick.png"}, is_ground_content = false, sounds = default.node_sound_stone_defaults(), @@ -439,6 +447,8 @@ minetest.register_node("default:tree", { minetest.register_node("default:wood", { description = "Wooden Planks", + paramtype2 = "facedir", + place_param2 = 0, tiles = {"default_wood.png"}, is_ground_content = false, groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, @@ -539,6 +549,8 @@ minetest.register_node("default:jungletree", { minetest.register_node("default:junglewood", { description = "Junglewood Planks", + paramtype2 = "facedir", + place_param2 = 0, tiles = {"default_junglewood.png"}, is_ground_content = false, groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, @@ -605,6 +617,8 @@ minetest.register_node("default:pine_tree", { minetest.register_node("default:pine_wood", { description = "Pine Wood Planks", + paramtype2 = "facedir", + place_param2 = 0, tiles = {"default_pine_wood.png"}, is_ground_content = false, groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, @@ -670,6 +684,8 @@ minetest.register_node("default:acacia_tree", { minetest.register_node("default:acacia_wood", { description = "Acacia Wood Planks", + paramtype2 = "facedir", + place_param2 = 0, tiles = {"default_acacia_wood.png"}, is_ground_content = false, groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, @@ -734,6 +750,8 @@ minetest.register_node("default:aspen_tree", { minetest.register_node("default:aspen_wood", { description = "Aspen Wood Planks", + paramtype2 = "facedir", + place_param2 = 0, tiles = {"default_aspen_wood.png"}, is_ground_content = false, groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, @@ -1815,6 +1833,8 @@ minetest.register_node("default:rail", { minetest.register_node("default:brick", { description = "Brick Block", + paramtype2 = "facedir", + place_param2 = 0, tiles = {"default_brick.png"}, is_ground_content = false, groups = {cracky = 3}, From 5775c9147c71c3a110d8106afc281a1a5935219f Mon Sep 17 00:00:00 2001 From: cd2 Date: Sat, 11 Jun 2016 18:50:22 +0200 Subject: [PATCH 028/121] Farming: Add negative fall_damage_add_percent to straw This doubles the fall height without damage to 11 nodes. --- mods/farming/nodes.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/farming/nodes.lua b/mods/farming/nodes.lua index b55a1aaa..c011df1e 100644 --- a/mods/farming/nodes.lua +++ b/mods/farming/nodes.lua @@ -89,7 +89,7 @@ minetest.register_node("farming:straw", { description = "Straw", tiles = {"farming_straw.png"}, is_ground_content = false, - groups = {snappy=3, flammable=4}, + groups = {snappy=3, flammable=4, fall_damage_add_percent=-30}, sounds = default.node_sound_leaves_defaults(), }) From 3e9afe097c74b0dd32d3983a3de37c66946a42d3 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Sat, 12 Mar 2016 16:12:37 -0800 Subject: [PATCH 029/121] Doors: Clean up nodedef usage Allows for more properties to be passed through. Somewhat simplifies the code as well. --- mods/doors/init.lua | 91 ++++++++++++--------------------------------- 1 file changed, 23 insertions(+), 68 deletions(-) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index b1bf123c..a3ecd384 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -321,6 +321,15 @@ function doors.register(name, def) return itemstack end }) + def.inventory_image = nil + + if def.recipe then + minetest.register_craft({ + output = name, + recipe = def.recipe, + }) + end + def.recipe = nil local can_dig = function(pos, digger) if not def.protected then @@ -386,76 +395,22 @@ function doors.register(name, def) minetest.remove_node({x = pos.x, y = pos.y + 1, z = pos.z}) end - minetest.register_node(":" .. name .. "_a", { - description = def.description, - visual = "mesh", - mesh = "door_a.obj", - tiles = def.tiles, - drawtype = "mesh", - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = true, - walkable = true, - is_ground_content = false, - buildable_to = false, - drop = def.drop, - groups = def.groups, - sounds = def.sounds, - door = def.door, - on_rightclick = def.on_rightclick, - after_dig_node = def.after_dig_node, - can_dig = def.can_dig, - on_rotate = def.on_rotate, - on_blast = def.on_blast, - on_destruct = def.on_destruct, - selection_box = { - type = "fixed", - fixed = { -1/2,-1/2,-1/2,1/2,3/2,-6/16} - }, - collision_box = { - type = "fixed", - fixed = { -1/2,-1/2,-1/2,1/2,3/2,-6/16} - }, - }) + def.drawtype = "mesh" + def.paramtype = "light" + def.paramtype2 = "facedir" + def.sunlight_propagates = true + def.use_texture_alpha = 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} } - minetest.register_node(":" .. name .. "_b", { - description = def.description, - visual = "mesh", - mesh = "door_b.obj", - tiles = def.tiles, - drawtype = "mesh", - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = true, - walkable = true, - is_ground_content = false, - buildable_to = false, - drop = def.drop, - groups = def.groups, - sounds = def.sounds, - door = def.door, - on_rightclick = def.on_rightclick, - after_dig_node = def.after_dig_node, - can_dig = def.can_dig, - on_rotate = def.on_rotate, - on_blast = def.on_blast, - on_destruct = def.on_destruct, - selection_box = { - type = "fixed", - fixed = { -1/2,-1/2,-1/2,1/2,3/2,-6/16} - }, - collision_box = { - type = "fixed", - fixed = { -1/2,-1/2,-1/2,1/2,3/2,-6/16} - }, - }) + def.mesh = "door_a.obj" + minetest.register_node(":" .. name .. "_a", def) - if def.recipe then - minetest.register_craft({ - output = name, - recipe = def.recipe, - }) - end + def.mesh = "door_b.obj" + minetest.register_node(":" .. name .. "_b", def) _doors.registered_doors[name .. "_a"] = true _doors.registered_doors[name .. "_b"] = true From e0bec501f224dbe93387c709c8257b90ae25dda7 Mon Sep 17 00:00:00 2001 From: Yutao Yuan Date: Fri, 17 Jun 2016 22:47:43 +0800 Subject: [PATCH 030/121] Flowers: Fix misaligned waterlily texture Previously waterlily has misaligned top and bottom textures and looks different when viewed from below. This also hides the flower in bottom texture. --- mods/flowers/init.lua | 2 +- .../flowers/textures/flowers_waterlily_bottom.png | Bin 0 -> 327 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 mods/flowers/textures/flowers_waterlily_bottom.png diff --git a/mods/flowers/init.lua b/mods/flowers/init.lua index 2d8c93e4..2f3cfe1b 100644 --- a/mods/flowers/init.lua +++ b/mods/flowers/init.lua @@ -217,7 +217,7 @@ minetest.register_node("flowers:waterlily", { drawtype = "nodebox", paramtype = "light", paramtype2 = "facedir", - tiles = {"flowers_waterlily.png"}, + tiles = {"flowers_waterlily.png", "flowers_waterlily_bottom.png"}, inventory_image = "flowers_waterlily.png", wield_image = "flowers_waterlily.png", liquids_pointable = true, diff --git a/mods/flowers/textures/flowers_waterlily_bottom.png b/mods/flowers/textures/flowers_waterlily_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..3dbeaf400e77f91f7181a0b149453f1488646bf9 GIT binary patch literal 327 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}RDe&2>;M1%GZ)zaQN|*huqj6A z3$45M`lc@5OyvjX&{EyY0W(=!06stX-3~FgbjfdGr~JgX+wb}uP>u35D#YwD?z9}`y^ zD_vqfwCvqI<5IW%VjSPfeh7wNJzrcO!jTZ)bE0IGr~^a9?RPOe-3cp~@cx;!f1bo6 W?$`EJrLTalWbkzLb6Mw<&;$Sw9)Sn| literal 0 HcmV?d00001 From 1fafed33873ab499d9c0c44068fb2addee25b3e3 Mon Sep 17 00:00:00 2001 From: paramat Date: Sun, 19 Jun 2016 05:27:06 +0100 Subject: [PATCH 031/121] Default: Remove mortar from stone brick, desert stone brick --- .../textures/default_desert_stone_brick.png | Bin 611 -> 552 bytes mods/default/textures/default_stone_brick.png | Bin 583 -> 545 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/mods/default/textures/default_desert_stone_brick.png b/mods/default/textures/default_desert_stone_brick.png index 42d9f2773dd0c41bf16a81105810dce86084a3ac..941523ecc070604a7a2604851414280aa37ed474 100644 GIT binary patch delta 499 zcmVF|OLEjO5Pj{)`uHm=BadxaQaoaz!6azWrS5)uuRo&euU|~>0CYZNgmhG% zv~nDHp|yl2)bcd|)Nduhw(j+7wFZ zgxlx_z`bb!D4x$0FF0eJ4_j?c@&BeLx0dIL5r{x6Je_t&TSEO`gKwQ@rN{xC;#qo8NC1kn zLh!i~r-;t^MBh7~0qk-$O9Z;J%R)s&0QFzib*XBR%be}IAtBk#_8}rh0Kg9z0PWyg p7v3%Etv0vX5GczCz-DIv`~mAK`ywamaBctq002ovPDHLkV1m+d=_LRF delta 559 zcmV+~0?_@a1mgsdKY!l{5EK;)^qnj;00064Nkl2Mxd!2&hjwtIKjLdQ7J?IK-x~t0+Wz^_m4Y)*R7g?DBXvO7^+N&>Q9>Y4V{Bac z05?sn6f7ZhgY^LbW*L8Xb-wF000IFxdy!EJ&eN3ToS)!d81$md0nBq*NU_|vQB{=* zguqsf`nB9dMt=Z>U;v&rjj|5F;6?zFGXU$h|M>cX{a)`bii{ZYGqDf-C%i|w#MBp&dxG%%At~?l7dCLZm`{8dpD=aaG5OvaS?7_Dr%Q_%M1e xSrT)2RVd}7_kXtgO7hWrmLwTZVNRc9SwcSID z9*XuKTJ$>$6zFgH5fr&JmTUuxP4OWF5qnri$Q~A$ea!C8vOm9nb!`VAk0ai!QVKvR zWsXqxd^(G+?Y6r;fDmJC4BnZw_IkYnV2oL70sMV@6abua0DnHL*8p}84^&+nzuRJ+PWqdYIDw|ltiV} zYPs~@TWg6708KcwEr9d+3_wb0v{q7ylrtrU5RBII#UVz5M(Z+702t?tGcmmu@4ePK z41pHNIlsKTlz-`_>D~Pu03{XUtnYhaO!f1}cdZQo#!#sWKzBTS`}*bI(-VLY0x7Gt z1|T-u-7pM9HjX0zRaK|cX|Z6N%@#n+dET=&MgUl?R@cjgalT%!ZCwMHUMKVRM7o4A zM)39r#yN>Y`h*w;?_JYeFP9MG`}d2!@9(9YG4Z98@?|(44hN(4JYfhSrzGZTO3*8m zR7y&U%oB1-0K{s!Bz$>(c1?3@u5Smprcp{srM&l4DR%ok08+i}jsWtQV@#hvermg8 i+a39WQ*+yOrIi1r`0=pcmt^z+0000v1jhuBKY!l{5EC#Yvhddr0005zNklfjN6r5z8*omF&mRt8+ zp>nANsN#l@_yr(-9})-t4(buwihgL@Zq+v1#ED}kip}9cgirIH=lP9iqVM0nZZn9Ds2c>$-WUo<4qfzq!4m9D?^!6~=T@O7`>DDYa%>w)gj|)#~x7y1Ke1o&Ouf zh}s$BoFj{^wIr`BOCptJNy%!hS!c|8y(U{ICZ2LPIDaYS-F8b&vXRQgyW?Z$+%OEB za{!$4s@k!Hz1Z6WB7~5pDUGFRnj{IMb#2#Cc1lXqn`OGR&e4-E4-O~|08P`dv-9&j z%K@0)gb=jW#`H?5-t=wT0{C%q()Ya(;_s)GQe^N9ilXq|UvD-_DFEL4`6@}0Ki(lL VXQqJ Date: Mon, 20 Jun 2016 18:05:07 +0300 Subject: [PATCH 032/121] Default: Fix character model uv-mapping Arm and leg textures are now edge-consistent --- mods/default/models/character.b3d | Bin 86830 -> 86830 bytes mods/default/models/character.blend | Bin 697616 -> 700448 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/mods/default/models/character.b3d b/mods/default/models/character.b3d index 2699d65b46a8b9a01c060e440efc981617e64882..7558e6f849369c419c8d307f022811ed546bc9f2 100644 GIT binary patch literal 86830 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 XOIzrRcy5N_d+3Xs7_U|y)V=wCU({5p literal 86830 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 diff --git a/mods/default/models/character.blend b/mods/default/models/character.blend index b5c7fc3aff1410f5db3c1a610a086906631068b0..7324325a1197155471dcd0a5aba574d001115c1f 100644 GIT binary patch delta 71213 zcmeFad3Y7&**|_}&P*~9BE$p_X+FW0Ve**kJ3;(Yq zvC(LQ`M<3_6pvZFWcl9zgTJK>)x9)x&>NP2D4ol55{ZPpX4Q)ImTH!^RKElLB|?Dw zXXs!%|NoXg#`-_|n1cRRzol(wZCG>D(|Jcbr8z5qbw{(6>bmOi<~a?Cgx3bgJ2qQ` z`qy84{(=jJ9Xj{i^Uqpv)`Wd13W5{X$BkU#j~!8vBP zV_j}Wd6t(7udgMe`#hS3J>7myRmEnjYaKW0#GMbK`(PR$J(0theoxow4uKa%O%;Y z$hAs}UK&9uUxOA3FyU_qcC8AM;#==Hw@~qx2 zsm%O5tI#FB*?ylM zQsKp19eVWUvg|EDOY_HDgL|mTf||z44$p_A^!zT?HCBqgg9l9u<_R6mn1X!k+k7wJ z-sCsK(d_JNUDQKW-+?u>=r6*g?Q^XG=8JAtj@i1u)sZ44m{w45BikXeDLcR_H(z(N z-cPAsap6tkkBkCtkoi}u{haA2uu4*zs9J;PO!WiPB<3VQfQ}$z~ zw8$En(nJLZw@Q>~n89}yS$|2XUUA_P#t|QJ{ml9vkZaW|&by6q#Akb-90>MQuQ-1x zQ%ksycLWiej0Gto<*k^|JRHmu32%B^_JN-2%EC#6&Ktu0V1D$ ze!jq3WA+?^bt8!irc#5VAS0ah{eNjaX-bD!BV8_1sOLhLc$nVD+&aYi+~skmq6L}& z)~+dg#rln@I@H=y)XLuR@>_5ycEm%b{!AZ)&lax8~Fzcuu zO4hSWNFy_x{NVg?nAJ5!G6bRN&3fiTr{;yjtllYADWpyyY|1(uAgWSG`B({+yd8-U zRVif8F$^K9nU4@vDI^pKQO!z(s7fJ$I3lXqi4avOq*Wk9HNB1ih^iFQArPXP8ic4y zA;sf3T%wvq2vLSj)W$LU~?QOhiZG&2}LM& zX#N5JY5U>!QZO1O6oOF39+A~jxmFo9ADmFc8Rf@vb*L|GI^@gHq(uLX5R-sVvKr`BVSS<#56US^BAK=Wc5`nZIsKZ32QLM zXct+1QI2s;ruJBK^bZ-H&pB6Lnsa7s&jW@aH0PBft1pd8eC+o_Mx8L!mon-pswSKa z$9y!4tiH%LezSIYg7t}vuj8>7=7uklWm_hv`#^?}Ped)+uNy88I zj~Js^&Wh?w%ZeG)KLnvU_eEA;+6U{{2lkH`qh4h7)gd*=4Co&{26OSNixwfMD+&fO z&IIZnF&BDrS6A9dxH_!405K8(tsquP-LCdXeZZ-kBXX34Q1mYK+he!4ChhN@p29@yaEH{RiUUfLQY!r zuvMDgKHfUha#^wYCI}Oure*>z1|Q;CU6=$1vKSPV&LsWc&~!7`>TP!X$gaZw0`u%~ zID^I%h)R(`3(I6QU2r_DWkjc#a3y2dDqvFP(A6*{FPaDjHBrId!we?FhQL=%w7y8G zUUB{-j3d68y~cXS%$bYLatS>II1%! ze&U;&Cn49!APKG3EKk1sIoc>n4RR)i8lhW>^v+80T9MOv$ zskNGdT5Dv<%QBglV{jE)@EfUlVXqO5wn<7!uc(Ec3YSsTYY>&LKGnLya?q67e46#Q z(Hf6-YyUB}uDwTlOQ&%L;-ubVcF%xbe0JeOk9Hja<37UMi^pJdg199A$>R0 zVGxxrn~D9JjF}a)tiQQl)!wDlX^t@4W?Mx=Nrn&(mX7Yj5QKl;#*>y}5#rLR5w@I3 zHU(!`MGd^wmM8?21^;N<6p%$Rxd){JQ}B??_`h+EA~~R~I}|zn&Esj@h~&>^Qe~># z5WF&>GXU3b5P$-_bu9M)MRtHu`t33N$FYE};Ph_F7g_iXiSmv^J2?!$J(dE>j}i7K z8A?D5?5`yf$u?-R(~~jTiODX=kkgF8oERWCCVMeCFDCC7le@&^t}!`3VPQ#Y0C}2Y zsl)wZau<~)$FK$mgV1IKkJmCf%P3{1V+m!;$wWhE1r|{@0E;MFmJ*5_N(n`>lu#r~ z2}QD$P$YM00P|1+kwS_nlA(yQ(p|}+wh<1`N@QftVMfL_ke$vM%%nH4iHw4Cn2|Y$ z8JTmKkvWGMnRA$txea7w&R`@rBshnvfDBT^-nP#DHrN&GR(Hj^-50U+TRNu)pT^Sb zIDI@0Nz1{hj;>hVROG*7f{wyE@zv>9Ak#rQE0~>U<7j&eQ}h^ICnj!&BTu44ql2w~ z1E#Flk}ON#c8+z1l_CZ72?cnI!~_!41?R%}n^K)(!W$XG##V2(?l%*EVYR1Jueboi z!2XUlP4#)WS((e{hoAt@lC%@9s^}c+K~fra7z<&`6~BW8P4o5>I+}@g7h!fHdd2x& z7)N~Gw}XvE*a{ZC;)1S>BYw1}m^MQ$#3_m-Dmct%Fd0EGocu4s*@@^C=XGNo@zb!m zh#QciQ;gqT0z_`Ku?PW*UU5`TScJ%r_7uNxx%_571v5)zM7xRW%&tpdw~?>tUF%4UaW3ADiG)rx!p~%{Nb+STB z2#i#AU8wn*ng(d5;Q^9aIeJrB_D{mlc~T%MZ8~8MCar9D%F=ctwo_7oc?AR~vJJA8 zUbqn3sp=F%_JPC3s0@ZTT8?SE#(KkL=QJ5YQ|Z;$;#7k|H5J!eA2?T!go4}oXJ=#) zegiY7X-B1f(AhUw7me1!(88h3QY-{1BrOzO5NThgLNWyb%;-LpYl3q0PT_n7r(ywc z*@#NB71m8vti8qR?(!b+_AX9Qf616m0d-L7yt=h+#af@qq3F?{A));Yj+nC{ zMWWG+d6<%Jx)o=F^xe>=IHI@(k6L1NH9MND4Mp2{QWZ60l+&wkqn&Z|o7IdrFSEv3 zC9(@1?TYI~bG>R?Xht?$(}$eEGw=FId~A_pbB)Z%SIda@1of(YT)EvbJU6dMtmu|! zCCYr^mcBy$Xi}X(J%Yf6TiErEv71F^D|qELr7E=&3WTV58MmY)W@L}Z#58$#fe}@y zk@AV0M>1xr5uz%E)Cz>C=2C>HN+E$jh-y|NL{$oD6$nwy#|TlCLOKLOR8w|0WJolM zD3+QbrkQ>>7*Ul%e1VWL(}WOJDMag;sOANLxTNB%;)FKVJ+K?C4MDeF+Ql}`9`IAy zsRn4DQ4q@TCU$ty zB_CWjw9go0gd(f2@=mo$`;0Nh9+A}-#Sc+&<PtIb zJ@yJi{UgTkWQbK?+7g*T{X-C%^GcD`SGlxA@qzs##;6lneNm1f=aLWHhmSFI;8$N- zRuUCnvO)%Lm`3KMc(`HEhN+x4be`Zn&gT&xJYa?*j7mAy$&nhRfxA=+&1WmD(p33N zylbk*U^blVFau}eIgfTtMWg3bPT9T1DNQf>HSS5Wg62I4HM4)6?3pfoz?x&ZWR>?% zH9nd0gd+Qr56V9H)grHzqNhqTy&i&j&8xCgrN^^4((r6_%JUjgX{eNxUilDh1QCoj zf)HiqcO(nbGg_>3Ee8#nnwOogM#X{**2u|O^cq|s!BJsC&=jos`nNDg@%nL8dJO7V z_J58}sXRraK~hQ@_IPnWjZjpSh%$p7#qHf9HW8MgitqIil}_sY9+(7I%d@w4@A)0> zOJWLysL0?zmdPmYOTJ^CU4=^%(JL@ES0xi3;`) zVlWv=!xk^BV^pV@ptl5whIxB;&J!4*=oJ^1Fpl`q_AUe{dc}Et7)N~EwSC8|O=E1L zSDfFMam0^ycRx?5UU5Mw~1v9lNh8VDwwJadlMQ@!|rYuSP)P(^3E>8d1rUp zdfeH?#*X+mu$WSvVki!!HzFbXt@iPPNgm z6tSM)bjZ}+O+{*Uzl243xnxIKfospxxFArcD%Ku#J~ zk(hC^L>VXMx>rG)r+(iz3s=|!as7mAs=D-!?Un-^S~K8{i32o`dLGq0Y4hOoQQ7M- zjCLQ#>p3|FS4vhEMp+R}l$8bybM@<#75tu^6=Y#nkdvNBA1LBREN*u1~7ayP{k?F7oOTezO>gcgKim#FB%EcHRBC9X54Yfw?ke6~XM)ApBWBQ2F2-mVS$%1JP>0~9T#VtJ z!Z}x8T2}3p4_e9zLUUdzvij1_#tho(h%xF!R$qaPd>j>Qb;NI$X%>RIDwgp;g2Fqh zVlG0F)s+TC9n;WGM~tyYWc5Y1p~{7UcT~j~<+aj1M6cPPPR!jy5L#5VBC9XW2Qz4= zBgP0sR$mkiM8yp19x+C%$m&a@s>4pq-6O{65Ltccz`zW;qbkNImPvs6DwhguCLh#2 z1feRQ^ml% zC}1-?-zq!|BQAuPZ83;)_Q$(Dphv2_zwx6~bi`Hd*nIz#DRkZ{pAJV<4K~Af+n!4y z^0g<-r%7FtEH2*h28Y;IJMK47WUcUrpEFGLSgU8=LyRzBSmr z5=+<2J~r9Q{Bf+cUk^;gGS-j36e2|TC+3G32^5a+M-jE1?RY)30&v<$)q@qm>+kjB z;4y;kO_p19Jr}GNv=?CP?sdsBJF7HLzV3f2%>i6`c>S9{DC>9B1b0xZ1@_WOWFKNx zf8iqb?@JtPVBXk7<0sGXcl;ma?@9hMNV_EA8+sXXHeY_fJ6w+O+W$DXBV{O>}WlM(PHz=_g|={+iCn);K-_u zou`p1_yCSr{{8Yhrk+IQPe;7o(btsLTW*PDO|u%@#98Gc9#mw%?}k~fUKdw*M7tN5 z(o?~Rkkp93n2k`mnaw@yUiP|iX4j(R5c_%8^tlo0DRh6FfWM}Ser9-S(xIkb0hv9+ z?7q<|>JO=j1mB^8*++DC?)_y_SGPOp%HTH7!4d=&SK_^~iMC^(O`c2g0jJhHhVM)&kiueu4$@^ z?WHb_EXKMdS$LSXb!|slP7+YU`^Pbz29R)q+)&jo)sdbiNqgyoV^9&?B1052yO({S zcmABSE-XFv-1AKJ3TKkpu{fFYZ#`^k;9=7q>3{XIT_@eWk3G)m#U5~!<(ItgOSi3Aot4tx0d3Jf{U?!@1* z9mzP|(#qqs*JC{8Uyl1Hyj!J>Ex`sr<8SIZB@8sLL~Z*V@0Vi-pKp`A0|2|l z=^rJK&{X^++0*(Xk3Hcwd;e~`6Yp3%;18CFM5U7$SPbdF6~F zK5s_Sjkv9Y0IZ1$_6ISTj4&8(#NB9i90FiXRB&(zgUJZrjXUpf81B0cv4^BIQNiJ0 z29puqvmHJZ!xg>ayrB{<8s`Y;mfYGyFCGNp+M_KsjM8Da3Y!@;QP73Wtnj`&$d ztx7Pei3$#mlt|GygG-OZNJX!>@F$ETz8IZu?`O8u+at`C)9rlz_UI}01k?2>d*lEm zr~z*j8&JdHABtfjHTqh+*j#y(o$i$b!}>p<_r4kRU>gHRq3JbLuAe z2F)!VWxw7Htwh65BF9`X+AbTQc;yF2Ghglc-x2?MyQkSY+FsuSjhq~fCLGF7DU_5_ z)l@h}iUvb6HIL->FrOT4|0AV(#d+0?BR&^l_Z#6hnbIn|Bc+K7_K#sO84>Ud+cQgt~&<6nyBD#9D~V77I?{60BfRxy<;V2^uXX%x4`qqPmQxbPidlp z{Rs>vBUzSrjK`QIQNe-FU^0>ghA?tXw+Z&gDMctFJdPP;i5YEI*?FeI$Ic>&3ieK5 zFc~56vNNH%o_d@Ocl=43V*QB{H`>TDyzqGJFp{X?U=oALNL1Th%%dmRpQbcX!Qo^E zlMx2LI1!tM=oRO+@m4+Y8TVh40H=Dz`I{L>e8wF#1#qfYT=2AP{i9vR9Wxbhs#je2 z4C9E;xS!Wxe4U24iRa3=G46ttm}ZaQGU7$w2!mJ60?Y6pge-{)_WvLu zqmeAj%V%TElBnR|O$L(@0z)UQf{7@z1B=l_{;#An>wKgak)uee|bjS5BmzUAqE}q_5#xxT3G|Km z7^tKv*6WZ!(FWVxbs+{Sdd2x4GmiL??|d_00R}3G3JyMDFd1QR)x}t%qE}q_DdUKr z33S0PF;GcUtoJ!%$p+h8atQ`1dd2x)NTA49n>4+GI3-Q7!Iz9B8{9yk0e3fpr`SVH zpUdngQ;JYVxQiKNi5Yp9V-pp<;=KQ29Pv3?8q}(;z{!dvD%k%UgUJYkXWfj$>XkUG zN}_^;uOwzP!eHphRR;cpZZC-n4*$+zG9qCtgbcPe;MgjO3ikfVU@{VctIf&=yPGLp zXt$&kp$vZyGssdDOP;Z=w!a*pi3$$BX0RFw-ohzkk8AALX}0)eY~nhRC$7p;E8#bi zBXRA&E%RWWxT+BcCa!(2gNdu+mG6BgnUrXP4`t%o+caKhw^AsGC(9gKsA|gp zUUIJ?{Z&kHD4(bioI~G$b7;XUKlqmvh}iW$7JiA@euJH+P}BzGhrUjgQW2_}3inE> zhzsvuXzIN{rt=vqxn|QMyDX)6<$D(Izfee0^*3VY620Pln{mV!98Ifl!qbx^DmX~W zrVbimFf?lz1w^m7&|w_$BcpkyX)&IgBvHX$4ui=EgJDJuk&0e%elFvP&p0~a?YtHH zlq4!R@EA-+2)wKb0~NKx!aNBS=?crk6TnFG{Suo_1tZP9*T5R?v)k;EDa9+_>%x4p z%P~z|im{7caei0E5kKQ+;q4f@q$xJYXDr!Zo6GOO*hR0naDT=TKVx(IGAv_BQ>@or z;zS#4bC7koa|AOX^OVQv%*qq|@Rrlgxi88p-^tz8&CZ4(O zKKq#gs!~X_za`Y5c?@i@&Ha`A@X+7`*lPo8xGfoiH-#!y`yiP#kfu zaB1VyzzuEhn_0iM_v_8*Vj*?3a%6jlCKAhW1n6m|4oSKVvMYnb0>{0_P(XAWaVSyGCbT!RiE4#F-->))rGU-RgZ9YKkEuy;g>D z_Q$_gwko&QQk8mm^uj{5ug8l-^}}s z-MvBUPwO+3`qbTb-EG(F&U#f;ci+{!ZeRZcs&F=3$Veu4C(g^-b+22)_30ldeT|Q> z>%NTZGc;HtW$=v65UIwx8)KX9g4F6{#-tXg&cwg9weCY)v-v_OZl&YJI&N@3+*%K> zmdZWnM6O&sa^(i6OTnHN6)ao`&2uPz+FF-5xoFnHMS$JU@b_8OiNyIJZv(mQ=^dcN zt#!OoR3m}>8MoF8T~e9(GvSuu+TYsyySo!VwRV_!%X1HGs_GW)t7BPD(ER+=k`4^k z(C$w)Yb1M`pIvfc7mu8umWiC7^5diY%z79u>{3nPWBBiv)n7e>E;Q&dC_VEw9Cs2I zomG0`nHQfo&lH?w4QnVqb1D@U_P_3ssxW<8e>&*!&%0~_U7SGN5@_ElmqEywjvsu^ zm~IFJH~;3d`wbBR4Pf1RSr6}{MjwO5bdvvtz8HVAjL@DC<+qJaA@Ye3l<>zk>jTfHOC207}58t~<+Ez}e~iFni^}96b*^}sm`+r+=?>> zxD{t)Zp9f{au~hx;y-yK1&mbtOPyy7N)97~^1g+vevP&6{WmZ9_-|h7@q>4Ic=R>` z9FgIJ27mB6g8$Rk9mwkpaL8T`K6ILZEfyPXux>iv{;Kl{y?ajYuA;loAV5!U3lr%nBU=7Hr;$h_g#JWUAruBt?Er^w6s2z2vSu9ZJDT*R}6;`{m1 zeKZ*qg3ccNyK%lT=&&Tr9uCzTsBE4Lw%P|J;14H*Y17mQlR?y!Ku&csh;sJF3uL}9 zN9GH7ZVC%&}cFS;RU$(KpTy$DKnwz0lQ_BioNE0uLO(DKCd znm4i;TrU~=S|$wt;A7BJ=5I&xu|ux9x75JZcg%3VRB#+;*qgw|)-6}VHFa1DEQVPG z-6yo{0JsB73`L8uVp>UMzY%$@nURKTjYBT5Qze)RHWck0#4?40uS1|$Bmd4^+X{rw zPP2;4yua9aC4y3x-`2v=_D0%G?yCkKF3JyvbOs>$yTjq@??PBWy+73x+vckg@ z!^sT7>7B{XnUPn4ZB10L*H^+v9}I?fCO>BSZvY1evIE5^$1i0L*+LGzKY6QpvCb(n z+lE7K1)zkWj0t3joxqEfpEIL2Kt!6T;P7Aulb7gi$}gD(X$)Ty73}qAFd0GcmuB2n zs3cJ<%pV{TBOTwE{JNR?vhD2mv+wurT@0=4Bg_2hM*EPI;*=NshDa9*47%aI$r^?@ImiMuWu|JeZvckh53@0-j z+te4~YVzYz$^`Ng5w@CpS}`+{s9=8>gUJhn>tC|BnrZU@tceN^ zhBKIqFnIY^0PmXYIp(uLR&h!Z$_OhYcyz;z@MU1YLq$bq#~^5{0#JfCf(c}Z3ASuvj zU5@o5R5cYG#-_*xwz`4#C1;r__vapBraogAMM6o+s-g;akHvOuto8Qr65*v=oH-zchkAS!G%6HWCbYej^1J)Xxh44B~@xx-S{$^Yuv%o zp|p~Nxaf28apO-JF>dD6X)|Y^f9~Ab=NW4qTFx_VX?wq%&bpjxfK)34eyahxeBnLP zH&&>{M6OwFLG|Fk<)C-CpV2DH*X(|95coG6pR;=>!J0XGnmvSa8c7a%LH#K1d?!gU zE;Vxp+5^j{f*(CKeGlJpLgC{n3eF+=$ynI-s-4$gQWZ@nG(fABu@{~-djZ}Ed6WUT zSE}iXSF7s9Y(K~vV}`-bKuXW-dZrKW<1;-^L1tGbdnRvcDl?aCgDXJYk4SoERb_G- z-os0$?7PA8h4AKNxZ|#m8FVDvSmWOy=jQL^+$_i7C(>B(i09%F`E|$gIXD;xM^p_q zJKls6Cq%(h$=ON)OSr^V;aKVL%a~I6LV9r?y)BGCjGS9LdryJHA zF6sF*u&JUKPGa&VNlr9pfy~A<#|%Fk?wq|Xb9+w$|mdOKlTzWD7 zlVvWk>gjLWuNEGIEGV`9Q32+dy-(W*_ZNzq@W)CHHHsG_ z@2NrHefW3iefm4#U7<=1#z}rPidT{P=sWhS?p@y^YvH^0u#}>d6^@teqGNuE*6w%h zHExP1E8oLx3PdU11g5B|;7xS&{d?f(YGQ5w6R;GeEZ=9ATJzhHb?;y7K4#1%)@t|X zME&~D5Tins8XU(|GRf6`#t!>Q_X47n?Zj*eL@D9%Od(U4tv=?ao%ZJgRIfO1qU1&R zVI_84i0W0d>U_(|!8$w7GUpG38I@v{>rav#p)W4Fo$uRg@_+XY*Y(N3EiyZAvU1-j5uh+C8pvddrjWsSOVbY zZ1ed?_F$Jr3Vv(^#}Im!JbyW)zXiQJ)3XOuTF=|1pwF>429!wV*FP7jb;qz*@>i&mA0BhG2yt=XNS7XAbU-*3d)2qJwRomU4Jy~^5+jGZk zUoiHVKRXS}t1uV*hw&y7|7nSw3nlW!O{3cGsop^)@*icW5OQ=m=IF@DZ41`?sTzz_ zo9fW|TT_*L?#VfiR#8Y<|NVQqQi|mI@0&*dtf|X}(S6?Cc^l;2!_ z)SU5K$Mowsxa~5t`%`;F*DVznkGU{)$I%@N%+XC1#rTMVTWrB3LiQnE049hDuL`b$ z?hsE#n??qOmIBb@#!9bzE}fprVJ_sRj`~Le^7B%m{wZ&d6gdd&o&I?wiDS z)1i)gJuw$voP<{r)AL#II7?A~iI6B@ir{eM?QSUSd05!c*^e^C{gMR^is_;Kk^}P^ za03dxV;N#G>PrT6qe}OkbRSBuXX*7x%qxD@!RUh5+!n%j+>gr1$xmkQM|J#Ou1ju{ z5p@i`O}8Q8uj1?mPw=s0Dvw5b41dl0QNfDN`%=o&BK00;K1HMdHI5m_U*%DfsaVbxxtPb|EP+JBC1i7RS%Gn?97MUo`9YDqD z;So!GY<^I~8LB%`hF5+7Fr@)&2EsL*0m>MU>sX-p$K!hS6V5<0yds(J+>B#)bw%>_ z65*%~Ekv@-HZT+TC+CJ^lLO6nIhJRp4zL{8Urc8Kc+$=#DmAfzVwCgOc#P!pm`|gK2$Y+Xo?9dn<4qy5VFoi`N`+)gBeHvqnsrs!kaLP z-QDbIU8hOq&y31y)`d=9ku)0Zf!?*zlZmi0b`EeFp|{CSD_=@VKlYXVNqN!A!S9al zQ~pahvGC`g!%nC+_q_%WGvYItJ^VBmxfY+d4rG3sahGguHss>7q1-eYa}P?uA3h)2 zkPBBMA@3j4WyC^E!Ty6i2tOdh@1NdFUPh7CtPUPNDHSc=nS#$O?s$g3QT6P{u)aLM^tidR&w-_7)e7e% zdZMt$K7YQ_e7QK;KmAs}r0W=XgmAy)yz|dVSKO97!tr3CPaji0Bw22Db%m|u;rvE( zt-`PZWK%X2xAsq!_J2;&TsRb}t_}t~_`@ge_Ji`64@J2I!dux?QCNs+n0M{eAZxwB zhE-=D!3dT;^ldgDnk=#5Y0y6(nyi5NJ3Q9h+YA{7&*b(^mcnDP_{=A{8{{Mszs0iU zI)OBZ!G^0={6TDXGxt*JMziK0#%?8x@Sfj%%mV(gT^L+natXz!e+<*?u1F3$xDR;2 zRx?4ehpkCvJoZVNpY(LflfF#>56nLVg3TDl=f?{nO=G2q5gP@(s?2pqK+DmFgNu7= zNPLP+&}awEfr<={nim=apl3J1v*b7)!b^Dj4!Y~Rkz>dO{D{U>q_*$dP z>kKTo@McG^GYIu{2G{ZM5L9!H{jq#hd*H^r0PH z-DWJU==B6$ieL=EmZ%?jJ3)bct7&}Da(ZatMXw^jLgdu~y^4TFukl=vS~TIYAgAF~ z1lVlxdv>$+S@w{Ve(-u~wxUzMe>`K@&gg)et>_fvO=L`fTzs7VE%V5Y$p>80bJIme zdhSispebs6-h6;&hyuX&DTbnx!L^-E2Hmnw2AGnD$IAQWnW?8cc_s1|v9F=*s57sT z8~x~Kfbr>Tvvparc4)o47Np~}VRU*bp25fVnSAt~lE=h1Vo$*P$8z{5JhFdXH?K&n zd?Vgk=+zp5+c^e_BQb;HeqMCv`0ir5}>=6i2&2b1(l|ss;bct#fB1BaRsTBxO z%{qjrN+E$jh-!8tL{$oD6$nwypt}H~Dur|igs5gVKwMJcJFJQvOf+|ba;Ub1Z>3Is zX&KrXwPLvn=zU6pP)5DTYDpQDSYZ4UbumVZ$m&a52A4j(PbvN$qIMyuD>4nOjS2K- z+?WgRbZK0oS4J}jHRcB{Dutk~2na5?F6nJbg3x@|iL9r#%LB z%{LR^WlC{EAcV+MClB;4B|&J>wu-E-w2N?KrdN%{7#$+3uR8I;40@MRj8QB@pZcQk zp)$Bn!Ml{=+39BaJ5eUBTN(gP~|8Y|M4V(=aEol83r^C?c1GuY{l~Ah*a@b ze$BET!%1>>oPuY^*|qS~1)|aOXMibbc+E1r7MQ;Co))6g@P=iW1d=V&G|rk94=`BI zCoDa2QS*i@X_wO4q{eCHKL7!G+c+RS`ZXe-2uJ>H1<`1L9;MK4)0I7#g!e$Rg5LXy zP_yEpB)q)1MmDj221lF?!4H*-O1J<0pJEd2Z)Sd*u4rX)c#2XWZbb$s%6btkq-U>8 z!ux|&r!n5F_SDb$e@+mWI_Wif45x9U^lPzwQLhn=Hp<{+NJ;NbOZb!kG?HiIaMoEq| zhaS!k!GU%^9no~u(P5XmpE-A9a%9P(3f=?N>1ixHZmVWVds$9ZS zHiA;{o^o>qQNes~}G8<{y2O<;%*)lKe1F=UCWXo8ae(0rq1!s_KnIjP)8qGwl z$Yjf`cn4QqF-RaX88dGqL{(~~RUkw)1@GdjD`urbWTKkm5TYuzQY_U%RJcb2AgWS` zFA$=dbqGwgR1#wu^0SxA>u|fnLoOKuak>D8sv- zi&rfvgNvKqOe+XwREn&=$Ts-k;-|G#j8P}D`XbvAgVs_pMzhH3%j?ukXe||Egd#`2 zgu!)1YpEDxkI3q)Sr}Y(u$C$s5@VDWgfH4`$GMD#mCLS$%1{s;3S@>!}z+M@#iZZ5Dhm1N(=A3|UaA zdFe6?TD>z_G)e|rosIZyJos{_gBhAsfp(@kk-3Xle}R*0t4s~`82p0UmOq!;68>(n zX!P95DX^e=&rGhf9&%Zx*&QO&6(8Wdf$W*pA10@b(x7D3=WUiVgaogBDv(i4TLJY0 zQ~eRl?$*k=NRJnAjNv?tktYD6(jX}*z5OGYGPw++b3dZe@QXDtu|r#C_s7YvMoBzc zh@r?@m>QS19BmKW+sZzLLJY5xfaDll$g+1O21rvn(P(`B0*qw!r!=L*?@;-g=KYdo zvXZX(oThZ5Q%raXW5|x#y*K$wGxN*jb@}1ztfwO_6J7e6o^Lt*V3S&CY9_dp;pEb+ z+>Hy(KZxZw;V27DQR#ZdrzBcv&TyQs%+ylLbx4Od20Mu68N(G{CE*c%@u5Eb%h>_N zl5YAtW>0mBp@M@VA#QrmKe0t|VbZb~Eu`V+FhEO1pRWEU`G^&-$N;AxU_=`nbztpe zaMVsm6>0{3hZT9V#3sj}k!9~DIC4dbMkDpF##q*UM-_?R!LX)z*Ro7j($oJ%6)8H! zgx4{K>|jO0FR{KQG(2)0l1l4P7-}K7f#KxMthSwR^TT#l(NS6fs?rq>wgP3S1%Hvi z(QtKzDPBByhkT>F{^Kt>>a;Z>_AR6nuNBZ}kb2d~97GSz;Kj#t4p_w54M5XjB z?MXU3(SQcFd4$dD>Oe)@B_YW%xP@i!PIN>)N;DdvzXUzr*%kJAQuIB$B5q?gSxFzc zKW5Mqo$|w_j3KVs-VKV;`y;F9$i+xswIYO}7J@qjj+RZ+0bs#@M~vbTEi7>Go7RI6 z)PQdoO`)V~dQd%xPBByfSP#fee|#X-0~HF@1ERSemK9SyVELu3gPjGyE80kH}=ptWG&_WhDkF{|)DmjG2!SqAJZstw4xs%K89ARSF3N zLR2#yA*xbHt3Zfqnh>HYg>(pnsOANPs7fKlQZYm|R$qXqN+G^Lh-!{Rh^iE#)l5_~ zA0RHNWR8yp%u3J>)pnpWt9G%ila0zwRX}rmK`6sp$>pn-l)>dqb9_N4qf%t`Mb!(f zpNpU7_%TME$m)x1M+}02Lv#EXBNSPEHA~L9I%$p{W9$)GeR;y* z+NC*uj8XnuX^W!Qd@utpm=p~WgqBsU$m)yYhkS7JpgDew5s0k5DE^2+bNm>iRb=%= z(Ey`^%8KUrF-C{T>WiX@7&OO^F^V7NoJYQ-CvXF$Ildq?=f245OLNW)x@Hn%)QhaX zw9ct>@YTc^qeW!(rFG5>n&Zb9?IK6Mq&J8UnBxzLF+3Sz)tAL=*ht=O{UC=rr4V zmQN!(d}wAXvxgA~jH<>g8~~F7?`6LDqsQPLZYlnK=$|G9qS3P@r@&fejd}J*&Ni22 zTB{&3y?P*>KhZA#x~2xDSExkRbDs7PYFQ8*)g>IMHJHtVAjsfT4oZ*Sya_ZZ4Clj9 z7AvCCC^-qQ0GUZO&QjwHhEQ2as}_Wt-GgC15xgro{sePOSAkTelk@OBOp09vnscZF z*F!J`f>osVXO_uAdi9|WUJntSV*DM9VXK*|Kx>DCK}}R}u#>@Lgs+G6sc_(Wi0Bm; z{)KVG=c_=@2n?`fOmU#XZs45CkAu+#m?Dws3e3~7D=;FL zK|%aqdIe_Wzj*})>vK8OD^-l)Um=w`(^IXU8|fqsbwfSge15VsvZPJkXeY<;dajiq zz*?azyQ0xrp_DXS_k=ddDC%Q~N~fkfurr3H(s0Rhy9o0{tM9dXvyf{jeq9I!>prvC|MUI<&R=}!2A79qOXu&O{&Et zkd=bnfj>EL12lJyQaCD3d4cfQv~{=zOEOU@q*Y|1nj;aSDur|igs5gdKu%JXLW(8h zO2we?vn1zJ`h_5@>r#*vr#vk@l)fl5r zWc8(tVvNPmTs6jM7Fm61L*c@twOou5imbkr!8xb3T#T_tWc5YSK+f3*t>t2ja_t79 zryK)=^FeDlL1>7+{~+YSUt5NjXnA%E ziE43Yl{LVeygb>hL?+&~a`bQHQO3I&M;SQv4Ji_hjxv;ze)LQnWf(=nKBDM%?G5~{ z{q1J`SZkY0M)CHm6Gunk$@H7X3kXNE(W!E@0O82Ra{4(i9wxY126790xR@jLo5(ZX zA0`@&G`JN~(x0D$`-b!#>}eXY&_8m_;&X9N@C$a}{SC{XX5gxdCVF3D63xJ8o#*74 zIgWFL$$XplrajJ-zV0~7&ci7xg29E7gI!`D{qPVARMNM? zlBi$`7Mzd~2Cq8b+2e91npQbQ4l=UL?7YDF(&a*<)e;xdJUBfRNeSzNaa7XC?2WIC z$;qwa$Knh;gxWK`{z9i@P!De@SArI6csmvO-B{%GJ*&urWsD_Gdhxw96+|81wnxkX zzap*P>R!}eLQ+3!Bf8W5mgr9RgH|}*92C<-S2zRnTs|Y=LmB<0YfxK)fV5jvZ^E*p zfvxGcxDH(*G0M?zX4(H0#!1~lG@4`YE=uWQ^+}I;*f|Thh0f)w9gu21R|?1vJI_-8MMzD zW3-B_z6c2nE_vE#jWIezR$tWOfWZ|(`>ZiW@mgtlqSvUnUTB|H5SnveWc5Y1!3S3p z?X$)h^&+b;LIQ)UknW|3F57^!u5@XbftiH59$QRFDV~l2z)mObl#q~jR*BB!dS$%2FxpZmn z8e`~4r@pk#sb1(;;vHo0yi(1pSq9OK{4!ALv@%p#`kk89&eXY!(2e{pGL_V0_-j7L z1P|c3fEKQz(Q^o;=#Bh@qJ=A>(oN6f8HH@|jrpnu_bK_g(LLd6;@c5Bdr=e(>P*MJ`WEc!NmV3-xqBYZ>U6LG8u7y#v}w2e*?z zj$xWJ<88ngshx;Ma}lh=7|-2FMSXk7HI2*c?$Dz~dk)Mgz3rNd`Vj=sU?Z0L3d`8^7Ac;B|4_ zn5a5AdTqNJP=XrprT3^|3;t$ap)&#LyHw%z#@Mo zi(%X%DNI>DSfreQg>_(pVyx|)AOC5zI6vP#)8(&Zu_JDg6lQ)mcd$z(U3;YUl+KirBtPmdV#Q&`3C?*RSM}42vN<) z2vLFqAGgD<_bhX5k^!L5oE>3>kdj8?4;Hp3HPt4SrEBm-zay{Z&X3W#cL2$1C&{PF)EI!-u@)X^bbJkeqRx;SEz{iNTmAQE( z7!(we28o98LvPgL9UJdp*Eg%~%AH5XWBtM7_zcb=27~cL1E+|d=H0{H(a!TY z&}9VQtUfF8o%Zz*v0vY>Z#DoJKU{thDCY0Vld?CCCpRm2+R|uKtNgZq7Kx7KRR+f z@K=ESB0m_;sdVI2{z|!;dMM-y&3DdKnG?@cIV$#@Db0jt3fnz?D6`!5OGiQDE3b%h zHKYP^wH0$Uw*qrTDV=i_q7EF=QCgS6evx1IV@{Q>CsS&lM>; z<*MM6DTzcWG(DYv|C-lz+o~Z4-U!SA%v=l8mB+ZtVMR!a&Vjd}4s6nqL*uUi`$fJ# zl2e1j&{V-gxrNKd!>{3~T4#nG2s5ei?lmd;3idRKm>?4cCZ1=S(qr9Xmkq)kvB)9r zNyoaE=jl%<)tIIlx7=70+*w^ek##m6X=rf0&*f{8Suw%&9ZLCpf;%MtQ(0?O!gHhz z=9SBG$D3dH?jW=3zTEwD8aH7rn-8IJdSxT7h{ZQO_+qc%;Z<@CY)VhZ4p)9^zl}Q}4ioREaN(SoS8!R=j%P=Jj>IGRE@9a1 z!>0}ZGwV-)*d^8|_QSB;rR?CSpRCyZiEh=A5PKV>RcShWh3^!5LSjD}gMwg=&I)AI z;b!whx1Ywm9%81qJR%HDWkX{zgL#O#WRg2^Xdppq(B2Uov=%%f@skyF3-AtOE!N_x zn={`NiJ=>wT7&X;dmE^bRi-9l22FPRl`uT>e>T+YXo0owRg>N0hiW7mSwPJg&MFeI z8pw*wo5GPba)YGE@H<5LzeToaira5E!m>Zvk*OI@m)`R(I2@{hX`pIBGZ4v{Hd{B< z^+%xolDx|(IM^9)%iRyZH;!3a^Ucabp%~#f2s85VZx1;fWjLDmr@DiNA^^z<0Ojuy zgffEA0PEnbkI=I&F-O+8Q{3_nm|B^|HSV=tZ;-dKEy9Ty_UNuR^6bZ398Jv{ugZ1I zjGwys{RREKj01tl=ng*~a%CJU#;>2B?DoX5F42N(GUEs_{CmaKfN5`ND-oSasY zjqwY>hH#=7L=N_0qZMtuJPl%~BmU>pe#rN3lo&LYtQgv&7_c0g$wvMuU_&@j3?c{n zuo0q-_fCQsLgG(4?T38tCW%2~$%_{ZvkGSy+Mhd98fq)qpoS`(C@_(Oec0H8Hm;ln71Tj|YN#>3cZQPxJos+APUO$N|8T$hKxe( zWP@6*aH1GQ4m6f58|7jH8sJk=tBvu!`4WTL$>I->V!&2gNj9j}3MYy|CmYmig%brPa@&H3C6)d&d7~fkU{xyy)|Fb%k zK{MH)Mk<^r29bk(*rnSYpsvvSOHr{HT%cAsf_4g%iafa%jq$x-N(>rHRt$|%3^cTo4QiyqiDD2r&{!fH1H1ri{7;SafvAzjjCz+yU}`)v z>Uv8suuLN*8`MaJ69p!6un!x}XoDLm@u`u<_+GulpmwriSdM&dq{OF2D)`91$iY7N zEs}@cZa@V~jWovhE*1Z3C(Hk;PG!(aHmH#bCyGJjU>`PGqcZ3qJ~h%9-@8m=P&-*M zv>`ugq{SPskx?TRP85U4!9Hw+VgpVw#HaIrjPG48F{qua7`8<*U?Z(38`MaJ6U88M zAU3?4!KTb1+R;WdkMSOi+GNazcZI~E@nqT9fi_@H*|QMOY(CnMcHi-rf0&skx(D?a zb`+7w!9J{Yh&5;(6iw<}x8HyuX282r!qKp@!r7(a&=fT!BM+hxB}Gw)5jCD&E_=|( z%Q#1Ep>m}*DtP64S4j{WOjZzyb8<>P#YCa6obebOLjRFiw!uT5TDv;jPEr{3>r&T45d*F*hZVl2DMS) zL@|gQXe?Pa$|D=9F0VaC!dUbh(?qYMIuJjc#vhJ z5{=O6DIf!L&xhHz;Fa%PEkUTAEPj>ndG!>MjlZJ};i!#3LSMXu9p}zmS`uz^%{{Moz08euq>%AgcHRea?BH)=c`6F}bcodmoTI+-buU@Z3AszbAM!J zKJM=4v}cldV+4|hJ3BI3-s&K22WU;xSCHBBHe+Ua!(#QfP!?~TkyB*8yb28NLh8jK z`r^%qSo$7J|HG@8&YKOf^aM@@cAk`bO8Vxv&LHD`wF@`AabSI*()oiB3sbE?qX?t&c53#~&Tsmk$D zdr~jd^6HkfQ&9_rv(!#c?3WWbF0WiEtya>YskM3VyBfSGg`|Vc%wahPII}Y8Rm*Z* zht_(Ttc$r8^n)>Ew4aGyDg*TH3ezgK}#b~8rl-{ z0bVL>UIQht1CwyTF;!o}pj7uz4h%}P3^0`5fd*GRLS;d-ankNW?dtDyjGeyc_c_-> zyUC>O!8916pkjIYUA;Z0(n-M3DB5&wjyiKhxHpQ{WWG z(s_29NiWT$Q_G}jQYN_^lB3cnvC?}wa$2Ap(S&ZhlPle5IHG7IhJt}I<5?%A)3{WL zPM~0*2tL?@MZmL40(2|S>5{~BC?Y5Zo-0BMbVJng_|3h7VuPfE&F>0x4{)Yt(yQ)- zx4p%ZYct8q4g3%kO^|m`v%#*Mb;Q}$5uD8#+vzyvV6zbv_eGRqSvi7-C-DOR^OE68)x0w zzC{j{t@{(Q_Je#c&hi~&(_{;Mi(XfsIzO*66-%;w2>!+Z%69vqzA7k-oypB0CM;O~43 z%}LT;yghhp5P^|sU zIo&@VX&M*i_QBAyZflr!eeRrGOoZ!5X4Cb#6+>IDyk~0#Sl3|4I>;JK@QvKxgF$kU zRNjzV(^c=QAT`7~-u&ywR*u~LF9)Ph&MNL2iC`++R)tu#sTWZyI`Z98f?DsiVj4W8T57vV0xIA@G6 zCW82iL03MkCS+q~=#Tezkn21ji2ry!{bh>nLt16)XI2LL#?t8+QKr8;s_h<+zV|BtN|;w+8V?`>;4u6v+9ql&Pc75HOB*Z)Wj8Cjuna{!fj%X7Gb8oe}cl3_X;E zona^KN%<3TMz&n|osl%Y?5p!*Gc#UO)6x&4{q?feeh6>zLqf&=89yqQtD8E>Zj$r6 zFnx*2pEhINbAh!3>5P-brRoLR3~SF!UR=h~c97v;W~<2D@S@GMHk!pI7YmGN-hOn- zuYS@Vt$XNXTc%2`o}HPbJ>-eJE=;k@IFrY6VkgVlS+#Xf75&uo3N<)fI)C<^ z-_Y=Hm+&qm_ zE_$meQ}$I*N}0;j*z!wWJBP6q`L(Cj@nA5hpI@yu>YFB#*LST^_l1&7mrQii2cKz^ zo9!I@{t6zHGG&Kf`|!$-5bTF0MP*&&_-UHiP6W$(&*L1nuW z`c1yV$+Oe$rojrE21pNNR`0}y7gR8q)r=Pg&aAuZRC(J@(X#Xtm>MpTVbctr9q;1V z`)&BPnFQfchGU0wf}m(ud)%UM=|QohT$G)ZZ%7`X8&>^)1yA|z(1y5qfcLN!`eF@-U({h6Fh+46Q;*y~{O)L!rUcvn@$LJ{sx_py*FjPE( zcC#i9ZBqYDTV}7rZ<5e&%dgYR>ecu9R7@}-k`k9vRb-mS=$2b+lfWSlxwLzNp+Yy> z6Fkzia%uMjLxtAfX4R;CQ!TIzPP|DcLwq~-Aa{974G+>?2qY7D5%2P+A1s=&{2u+! zZ>y=nNqWoMY8QSgwr?o2p+9t*pR!1I&KB_xZrXbA9o0W;!Sy)v(Q?x}DilMNknxA} zEU#$8J_DuKe+?i$3p*}jVh>u(Qk4)o0eN0|4AEkW*C?ET` zZc1P1fa$axbfLipVW?||4lM`>88PZ50{P~`5$UqNLtMkx_Z^guUUuaLjT5n$YaArj zuV3HFWAPrPkbn#ig+zY0>=xs^W8nRe;s!n>68ZbDO5@nSHMXe*0gz}P4qfmVl$V#r z0V6UEn6AO38{DT)x~NyL^sxN=^uXS|xx65O7_pP^O9=w0;lug3w1dNBw(T8|#(_GF z!vF~M$mzfb2o%u)JxC0p1M&bO(a>PLM-(9AkO;(35yMjEUUG>`05T3C02#)FKz`n( zX&j;(+P5#afx!IfW74P}K781nf{#D`nCq56EZx}H*or_wmz)*^P!|G_VH^e#0f6JU zk_=r*dW0XwpIbV`oq{7rj->bR-=9W_12)aL*x`#3fI%;TfjMSgL1O>g^U}@D%?x&J zQ6UqPu)nnO_VmKLB0OCmee_W}l}fSky?gg^e?QP4!ieMmWE>I!F9AeA0C)X* zc6y*qLXbHA-lBAB+jlt{Akfs*)Peva5R*`dVJYR*LJ5Q3I%G-0Q+vM0=Qv1wzI!oG z1B|cJx2F%jGe7+)k*L1!1{?0fOyIRwUzJG3()l?#+$e^ngb_K%ug)!C0#Zkb`3H&j zH_dhznV|(H>yZn;Tt3w$u&AOmEs2M+fNX-~u>4p)gCG=QSW2%k$le3w000ulc2>Fs zcK_x+_cUz$!~Hx3Xg@@efDK8&zS-G^Kzj>9jr!&7s$eQ66o;^o(rX1-=bsPhC#AS) zmpr}WU3IxWxK(AH*8)&wfo$GUc~J}S2Y&qDEx1!fmJq3n`G9C)s=lNJLPu6M?^t+I z3$1+Es(Ow^sBwU@LX`{Cd05Ez}eAr>Np2sPFM*` zlqYsQcn-K*yj{@^=?FM3?Zk*FZ~58#i_=Zp7q&|K7oYsLo4U@OUY~@tcV>WyLt=zJ z2Yx$WLfHx(3zVENzp0zSXW*UUu@?+F7!q&*d&wZc(CvG3t_vu@E35w@efW0^xc!6r zIc#JsfG_|DWPphdvXGE=X=|eOoQ&ulTUCzQTR$g#=MsqUS8 z&QJQ64|8Ht{FHGG8^3eTF&DCPzA?b2HrG{ln|NJ_8~Vr?aAeue!}nU5=p|!Wu#PRg81wDn> zZ*1u(`_bA!`)rQ?vhOWd*=PI}<~aN88@pto`E=kdD$QpM$)mU{=cl_>LT?z`rZatD z?d&lhw+D3R57pJWez#hnv-he`o%k{H$-7>^TYX*UeW)tXnAM3=IDlOgIPz*rx;b^t znT`>3Tv3E~Ex5O-o{k(kZAmByu#ee`}De(TzO>Yi+PY%%bl2aZUh=SS-4Hlu@b*V1MnHcsgEdau`E z7k{{`X-@>Y#tE)&tkE@2AYJ0*0o680$mBsiyy&|3)>8EDMfXHmUH!(@OGyWTzE^R_9YBef5;D?u=|{px9TB`sx)vf)y>>V}W=}MWE6* zAnvQL^405n^*4O=q_4iGMV)dY)j~lxr1=OXef5;D?u_z9#8;2{>J{EP*$PcUHk6SnP11VR*_5*c3LP=je<*Pfs)2`T8kNWBrQtxQ& z1>#WXl19}n#7lrKXrd3UMjcvA6^sl0580qbdwl;6&A>f1=N&SR!RcDh%;? zt!uo^g&_y2ta*5GMvSsJIYmz&c;%>~ol0!4Bt`Zrq^U3z7t!{r#YscH)tM~S|IQn;|)l5D83ze$}exB8FWEC5S3HoC> zLs#60_{>G&F~!NlZ7+-V89Rms;*7^=U>(QHhRSuw9n~Z*Qw6>`)AZ$ zm!m!N9VO(&JO+}H>&FCi%^B54UvXC5n1$FU9yqJI(Kc6H@#>l^XO?3xu6ye81~W-v zJtX9eirI^Ao+*51Vf&3EXe0uE+8=`<^Y>NPV_!Akm&A+x%{{y@AqwqM1?!;GgC!Tdqw$qEdI%|wV7j$!`g`8jD zWTz)~4X5uFA?t#*PFWrhD6%f%>!$9&k}e0T_D%e)BKf@^^&hScVr3X z)j<|@Ltlcl5H4hA^AtWqmLYG*C&=V`mTaD)r+GOGjY3Z@BC>G-CbBFWvKGlj?q!i- z(U6@!fRN+6fZQ+uWLeg=8=M>Uj7q1IVcg{=rv+n+QHpI_5YoA`sM4K zZAO70P-N>ok%er+U_o5ap%xUz0NPV8AMJc6CFoR~Duup7SV@7z&%j zFM7fY*(9+=a*@wkWNtPML)gN(gu7aJ5I67-JxlQMMS!PF!x8}*Np=UbOqk#@ zB%c))!iCJUkT9i}ti|fE7zjkRI`P;`PG`Eu#V9slb@(?=U?H2pS`ZiX3JVHj0PU_{ zew`e49sM1@JkMGbRnCx6-G+{aTQHE>e--+wyPZ4csZN>^Nf}7!LkzB5KS+3v=!XDnG*G|9XD$}lDG6M!!r z#({B-WVZi8HT@cyUnBFMcI{u=%&%?c*EaLBXZ8Q$MEPrP`n5Ox+M9muO+OofUz)K0 zUms_#zu~U!*IYOMzyA9rhkjw&39EzoAB;Qr;0bj%+;Hpm|Mu^YLnhQOUbJAT^?!xQ ztokAOI;>j$@A!pmZ^D9X%dfuuuj?1<^Vhij=l$W=xc%ob!!ai_Zl$GrR3383VfFv* zAL{EE@^P^4hh!gX@zqb~jIk?^zjDe=jaE^YAI;psb%})Aw&K#kH?6Yzo7Wms1A~5+ zwJOz6nVWm;ghXN*?4`I*-FE3|rh z?%7t4t_1_`B-Pq0x6c|}XVy5@p`+%X(nxFz_~=SHjLE}2Zy{X9(M-y+dgQ1>ADb;l zIJ@MoJasxDT`Zz$$g&P~6NzDoM5nJD^M009?6?O2l^NFA>SHEOu-pmm?g!LUEad1v zcnvuo9shbYrJEMxT>S7z1fu!pUStf3eEaP zYyY0A{GE{dvw@7s>rc1cB1(hjn%~mKMo7<0zs2fPq#}i=A51kV$Liyd$jrPCO@qE! ze~Yz?nV)0XgVfpYwQ#f9X-LvX$(d~Z{i*zcf>4cu>o1_nQzkXf9!{#T@&^h+H8e1; zFliZCWBn*A-^S3H>0Off`J$_={~indl$Ly zK1Fq`M{gsiz0Ghm>mRoV=8MFFj)eP??wgo1^E9hCXy|O6WEGJB>O%qHTS9?~rhBgS zeQvm&dz)K-Ifxegm^!zoihck}qO}lBO=xA1%rk4dT5Uxx3V~WdUXs(K9IWqVb+(FB zrWilP7}7PXcDD93+gp;)nYQj$VUcDkIJ6l|Bna+r4%x|iw@BrRbF&yn`iwj5spKQ3 zINusxq?ro#vc*dzXYj50K&o=Z`7Yx~-#}^lnWa6U)GAk8n8P^I55P$%waOIZc4iFe zB3F?a+{?-~xdqloMVhH#uM2~TBm#d?q;kdix#A#_2Q!!0U|3~}3A-|ebPZqzm}~l2 zn~PMgII4Q6O42vYMb=;w6k3}cZW7k{Ru6|%0?5MhNh8um<-aYiQ0v>cD>N!^HZ&$+ zq$4#dhrd=Ww;wcJa_!EhTVLy}B2`r?YTBSjCd@5;fy%#>sr+lA_NgNEKb(VE+CDp( z!}?iY6p=8keY%$m5Atzfcm0F4+zc3rWpT9#*nU=G}C(1 zT($>rsa$cP&p6^Vz*S=IIL8XiLuCNgOa;4h8B8P$F6xiXMC6L|t`-N8oN=F@XDv4E zdqShvOa)WuAQVKxMeq72Yl$fyXbpEbu29MOHgX0t2SQ;T9%HuM15&JA)Aw)IUrgm- z>$&{m3u*ks6ORvPVi(gvuOZfLDTf9sW392yw9i})N;B73*Ov^tM5<;XLR1t%&Sw@<1cxP>os{y403-9V)+BzdvXQLN!8(l-i0ks8=^&Z3sd&{08p# zYD+cJyb^?JghRO;YKxFCHgZQJ8-h@c7Acq7QX8y6O+8lfa%q-oONT}7sW@+rH{5a= zztk4R2+v#814%;=>Q#;Oezir&s2tRC1)&TEe#cE8d&(m`*^hu3TjGDN<7Z3 z&w<(ygqmoSKCh;9kmT+}PQ^xr0*S5KQVn*hVc`x=>3LmEX=TVrg-a{!9K5s=a;;*H z=K2Rx`J-f3fNK?8u7sMFVOblVjhVSu|*8cz}KdUyvQcEN{ zQ>C0>W|cL^as+iXxQnQu`&jEj%ONha{*lyCaR>dIc^c!2qZvaRv|b&Dcr@*MAUGJ_ zF7rJ(dLOZa?#JjLtp!D*4sy;_55ih-{eiF+bXYKZ5O|4DGwC2){r#DF{o8OJ$*VsR z>Fm+H4yT1%JgWz+C-FOYsCnKzP7{r3J`9&Ohrr}p<%;tg7)Sc1do#?H^T*>{S>%cf zuV) z90(tqh+ayjf?1LX zB3B$$5{`$cFSsS(+2HsecRaRvA&eNHUB z=$g#@;d3+6b#7-rL*U|SEuHX~D=FPm4aOa~B!=%DOP|W=ZmKV7akwrK{`HnjgKOEL z+?YaFN<##MpsPkCN+&^*o}Y@P?O57@G?cW1Fe?Vgj-}mLIwzLy6iauGrMtw^xd{s+ ztq$a9iKPxZ#nPQMEhWaiZ)!7whlUkPV=lC*C?6w~o=zp|G6fi-bO44ZJuMN62qi*M zS|SvsB|=eJA{3=N*8x35AQDK3qBMjkE#J`+N*iJKz`-ajC5+P82GaATfKh&(lrR!V z38S=>FiJ}aqqLMTN=pf&w6uXJEd|tcT|!DI0w^GRJU6o&`F%6f?q#v`Zn1Q2X4)^z zOuI9995@h%r1@Y}M_7zEhCGxJS4U!+;$m-+d7e%(>C9lZoC+hZ{|1k^dJNZdI&8%e zmre;H(Gk~w1#$w|qn-mBmiQeEXrA|~XroTh{d5?5i&Ul<_jSgQu4!In-DAd|VYL>i zTyf+9aFf2NIumy#?_yPNAsl(KqoU{(J0G($wi1_{iJOx7rnm(6s4*Kz6&@}SMr4jQ z6=A+2a>cp#Fpl(byAEaoGjS#$a>aS~GLG~E*i*!*ipUh>-^UozjrJ2iDpI-P!uuIV z`q5V6VpDq_Y!Pavg54%@5XqzcMA&x}x#B2v5CGDTwi3T^IHXnE;gSt%7}!O8-E2J{ z_7}M&3~PeZKGs|SXU;RN{F2x%BBp~?vv3!Ynv$7*aoR589J6_DD#sjui4~02Myie0 zzeOg~(s*eh2OjELB6GbqsSX?M15#KydT&X33%X9z1d(WCa^FVRx71;yrSD)s^TKyn zn^=O`v$4^tOffz(gAVE9(qn0AfP7QT#6m02)bF0m86^SH0C~7s3OX7%4U8^}w0HA@s=E*K zyrs91x4s;`_t^XJLpXALM55($KS0M9_!J-fo*p06f;6!NRdca$%tVcXG&f!ib3s?k zO~uQsdzjDWCiCG&|A(BkLSAznTz-1&S}V_?QqlFaQf&b`G1Os7_q}+DYh8yE#Lw6l zJ^F3p+b3`|lh&mM=8Hs2=3!3Ia2?KI>ARs#aYO~f8n7vs#hNmvgXZgLLmbV;oANkg zttyla@MuF^ua?urTD+8PhBsQ12g+W9e=YBW*2*?<+hu$W*S$@u_D(ovUaK9IFS@$N z*^V1JJhIWHT1rE;Xnw7(uThUL)v8D#u54Q{6<(?>QjtPJIaQD_OQhuTAFC)}^j1Uzmq-_>M zNY(Vc4GJU@MYLbS2+}l@Zvzq)DWp*#L}nTgq9TQ86_cu24G@P!W@Zjtej~K8ZihW+ zZ3DVZ)Ba~R59e?CXuWa`(EhL>RHIzd%A^_`ZrWyxX|%u3m+{q>R#=)1L8y(U%ejTB zE!AKfw0kRvNaJI%Axv7G+)hYC5USDoA#12D)!+)Bgd2>4Pz`qud(|XN+8($S(d`0) zP>u2{SVL{8Mp~={p&A93O5YSF)ex`n1_ME;M)jv$4z;D_5U+4+P7tc$zsnkGOB*eF zMcdGVP>oiJw%W>U))cE)eYAhVHq@4Ca5JZNB?z?J^uqT4Jn6>6ov!G*)5*E+p7^Rxr~SSUq|wy;cE-hc-*)l#$Rm zzoupQpe6(X)j>he0o)kjzLXy3vjtXhQH$)D>M{HrPIaK?e~G6&n)r*v5=)%Z{9vj$ zxaw})kQ6A+dk|_SJ)GJlD8AP^*>Z@L_fFM6Ww~9Zdm`7$(U5EB;mYcDKg?!+kXYGvGlg8A$Lr%-$ zqxz;pfewb`tNHc;n3#l1*s19F4X6EoqEQN`NYqKn31EL0oD>vB5>clA!??Bkpin%C zBHr2+k~asM>HfB@Dl3_hvbI#cTvN@{_dORsHL#;OKm1-KE~>2jn<~8P0_`fA$Ch? zq8Z~1$TLTgkC)*b*}8%qkfYbm4td+rEcF+WXj62*!yH)B_YH1c4x6Y&Bmi~=gx?DV zDjHbV-(!}pgf+X$73crRIMNSbZ4XN+l_`eY0B+I^4t@rg6YLsI%#nc?SeHF#t(Wc8q?OJ%Asx9%=9TPBO9f-5-f-zB5;ac~=P+Tv+JGP&EZszimH z5EF^K-PY1~+%_wQZ%V9F_onw?rqr>rs-rX*)O=qIs~(ZjKihC~ldcdH!%=anS0gh^ zUlc3B)d>@{cO+4 zR8*iU7GUH6uY{`Ch_^JuM;%q1>NU>cs#QKlL(6r+9@viBz$13o9z2Dkc&e=xgMt;8d?nZk$%bs@Ldd>M2h3+)t|N zD5Ppw6}#A(iU1^>DwaKe7xxk|+@Y6Qg^E+XPt`8RuobK(rR{sawu?n zP6xCMgxXVe3g0NVT`68W1hsFzp(1u;Rw!v@(w0sQ&CoI-rqM2GwWXbvnwX(wLQJFV zQeJqgEp3d{drWt{dq@ykj%rD(Ep3JD72Sgo)9@v&wzU1RSG3TJX|zaMZK(~?tmz)+zg3ywCl2%(<4z|&NHewpJl2%*V5vX4H zzNwf-lcd#__5h9*Z6L%nS|zQvRD*08T7Jef+{?J+YD?P{YtXVy5L)tbNvkcjLG@zR z<0eH+qejwdOG{2&-Oyq(rqL*AwWT&#gYMLcX@rtiTUrk4#oRw)8tsx+TiUKzgZf8I z!(YuKirUhlN^Ic0a)QuUwO`3+X0@eW(RjgqP!Ot7`vTigTRJkZ2HjmJ2-Rp2n`%qX zkvu%neQYtWbiSarw12P$wssq56uj_OdL0(okp{R+vreWPI zoZ|3^C-NmQy1oW~+1ZIsMM#=(6Wh1LEMj2=4dm{oJ88D%zs;8na@}q+{mR3M7Va@u zl)uWDwhes5vr#=zDO6{5A*$ecHT_e0oyne;I>fBLCRLhBbn0#XJ})((le+eb(=e>Z z@J_v99%Utxst0NGR6qW!A>Y^Sw9o@iE*^3AJ~p>(?!NR4RQTX27m;XyS$U3~W0UiA z;Q)(ca<5GlIbl^IvDpl{Hg!3f-$0Q8^Cg{9iAuGFM@XlC!VO>^%^jKRKK%}ru<84X z3&k88SJolb}BTK@6U4pe$ z6YMsJ=B52|TiP3G8AwO=d|qiPr%+6)3*j#80z2P7Klz^HZHx@9U_&k*aX;Y?W@{JA zDHI*$@Ov=_700aVne1iWzA?2t!~2k;V2w=OXd{}heIbuI{^r!{8Bp&vs-uGB4HL8_ zzb4hd0fN@5EnNbq9zZjok2{oCm5TS87eF1uHQs(jO^>`mH|ao^q7Qa}eCS-HVy5>> z?i^g$n99k)3u|s&)McSYu~OXyvbdJ6tuug(vl~`~Oyt#pTVQ&tb8#2EwC&R@o=0*Q zZffE#92W9@ICAWo@cKw>i!fH$g(rFg7g850KZoaY+JzOW)#9Q`ybC9SvFy{jDmvCL z9&6^^lN^{l)iQTBC5L98X7x_MU&F9|N2}9c;=N27S}hSA5qbcGMO!xT$8%$=PkZ=TOdkWr zPZI~ez*}SB6Y?R^U5=+}zFEJ*?qg=ur@D4K&H56m088e5dl$HHacQzot`->ezA&qD ztsVy=Mj}RRtRuv5@LrKJejD(3_D?x3~JsfV`7(fjHy zYMJg!QA~>WPUe&flkOII%QD-x`}@@}`kOV6ST85%TITnABnKBMMs@t z-n_CT-0LWr3JzB=m`M1}&6fUvQ@P^YRg5EjCZ(Od&3gh^GZpMT&0r!CFy6j7V;>lD zy9`VYEK-DO_|LEgF`>qrX6PVvSLBKdpA~n}0yEQnoYjNTXUSBs`#gh*ByFRwehB(3 znF{t^U@(#J&74g`0jF}s`61&-pFN<>zIDUUUCC5%xSGL4B4E6uvwbggS27jsz9{Y@ z3Ge?E4@XZ$t~hTk<4B)3MCykp+ly4LIR7Qak$!~BG0h{AUlwVmg2TTtm`E7BZXY03 zx#HYKJkF4Q8mUzdq?)N8_RSzs>SKN!;q7PtKGNdJoDE@tiM4D~_Um8tLpqut!Lyg1zS$Oe9ftb~Xh_aawZ_yXfd zpK)JJ0G!Gd=dNZP=`*hP;eb=Q;=DEDB=R!ufQf)px#Ij68Atkz`~4*JPvnXV*D{Xu z8F&2==%2_H=l+dxq|dk|N1}fsSDg2E#*seb-aQKa6S?C2b>biDGp^Gy=%2_H7p`X< z=`(JxW6?j6E6#m|aiq^R4FhkEnO==GEtv}THZYh-1Uwo0j>r|~zsfk$kD5=OX*n(l zkE2Vbg2UIuQzT*Vx+&NuMXorvm2spWk-9e@k9|k-6zgqdEO9Wl_ylxRxap zaGHrH0;y&yIDC`AM8e=1)6h|oE6&{{jv{#)>HO*FsbnhHdz-;T!r+y^Lr+DnIR72S zk$yy)W44`y-CQyi9ByVXk(ild+M8y$>e}KVH zGZpN8&R`;mz~HFJ73Y7!IMVNMbi+(^RPq!XekqP32Xk&c2OSl;;@oYFBmKyBt|>ha z9hFQ4dtWh_NElrCM~tY*73Y7=IMVNM^t?ZzqmrlC@EgVw2XoFl9~~9B;@p3Vqo}W( zG+P2cB~P*5zZgp#+(4iK=a~VACkL5bFGwyaQiN*w?W{petdVmeHc^o)F8r2pq|e^Y zxF}g^;GdQv%~Y`aJ%fpa!PBn6LG)rAL?u(f-Vfq4T43xp1{3O#Tz5lw*Yk4B7EU>UOyIl?w zQN^o%m|}h94d0WAXdhF5d9sBjqKHlZ942#OQB^9}k>ZO>{s%(Eu6)u#Vg7I>&WQ!D z`d*eqL|ytw^b5`UE0Y1aq8zfcPfTQ2R8^_`Y>A4P@P0t5O}Y$kQCN>JT_ z$y2P?Q(Q+5=A3^M`Yv+C`8zX?^gB4$-;6PqJjI5)FqSx&bE`o=MXorv7vo63gR}1~ z=%?f<*6Yn!;$Y6oThULED~>jdaMKL+l~dNe5aaZ9@4(xW@G=+LV4|CZkcpY+-JWdk zsryYoLF>nrW!WOwcjEj-cfeptX|SaEuIx*Zp1J(aMB*W{U{`p*%jR*GQzx6TSUN0VC~4ia)eE|MIZZE;>87o^ghvA#wD@@i z{o|Af!UHsrsyQ!Ti7 zHHt^iE*sNz-tg)j!qfE@>Dx zAP1#r{uQ|3QVO!ffoZN_I{o9KXK41wTz@KiQu6}rk+LWC_k$-GPQ0t~Ju~Ak$-FwP zMy*!=Zr*d(y?5Pf*XxmbxlFG~t99MY?F3ubE%290on}2s)yjMBHTOuh?#eyW6q^^*xX(n?W`vf4~{*%@_}dGs-N_X?yO_| z-^k#^(c+M{4@^_OY0iV4_38(bUEu=4O|X+SC;b8f*1(5pg5Fx`)~ zhSW8_*Ks8@53DOppYEOvGW>HZ@dcASz|DigXu2=N0Q2#K&!y_K+yBdFz3UQKlc zI1q{gKBbE-t|N^BPEX6j-w|FO{*Kc4+;2KQ^SR%wL^eJeoes!+@HZ=w`QUF>BJ;uD ztVHI6zgdaQ2Y<6-&;9aa$Q|~aL=wxNF32pAlgKQQlgKQQlgKQQ10~Aj%Pf!+D-hf} zmsuhwRw5@>A}3ZN)Fy-SEcbu>^g5QGT7C2|IMy+=i6|`(cSmV?xI0R7P&@G4YC6*Y z{^|8PTSF2NN<^Zx)Nz#l_fN0m8w}EW0l&eZqmg%|Q6fs$CAuc0gwZPwq=ZpgN*JZ3 zgi%^b7^S7oqx8Rfg8__aUA4|51u0>amZ#Sx&EBY;)Z`$wA4^Hq9rUE_Uxk7gJT2>Yt-de*sgs5h(W{5IU*E zbo$3%EvMffnFZW2~Y=$y2OX!dT*nUVrba6be8U+(E2B*6=;JuXn2XVf*&^&;aXG=8_xB7eaPfL3o%;Th{X|vYWPD~gA7J5(p_jqJqH?}g()gdPNASwD;z52K{nKS-JJY9 zD0I0Pt3fgq?C!;2GDX#Ja|nAa??0cs7y3^p@2BnCAA@qux6BDICHE{+xT<@5vpUhL z`dR}|SL7S)45gB^lj=^*G1;6X5R?9PKh@WW`~_3o*8 zX5UuWb>I4Xct=FZZdS3GR+{YU%ulo?t}`<)P4%a7()kixdERs{foC!|w-kh4$2$)0GBV3HCa*Tr zE=W3^&zyeVDT(5$GtW$%VyfRr4(~A>n&CV!{}`SH>9a?}uwHam*Papp4Tzro^z6X! z+Odhv^UT;eshhF}rV<%cD9>d z?}2%Rs%kh+%Bya?gsNw~2jyM(J!)0GpBz%8DAjU*E9FJQ{PLOR_mhh|odqhj;Abz( zEDw`=mMTv5yn|Rz`N9ooZP^E4t%0mHdO>qnte41RGyZt+k;W40_Z??=$ z?op~xRSmJXKnqt&e-#Gg;m;t9_{dsbTLnt%-DJ#E=np%rEXv~FX+vmx}Ijb;m zVCEw8@E6Ge4s~opw`yaT$Fb#}toe{XAcdW|cj-0BHTHN&>j%?36=#Y6JoIw2ty}V_ zE=@eaEc*cO&c-`;OWaBxM{#aU?;)2o?l$9~v-kW|rI~s~YE)gfo_Q;7DEMkj>ve-x zAn_x&9=YOQuiv};g(;tn!Sw6pi${F*?WBrTGk2=M^hGmPRh)R;eU)SO>ADIg2o)~q z-w!&8`YT6Zz7JfVgZ^irgXvd+cMWhoEBaXyZc1eKa5Bhh{&!lSFJo|+36IK|ENGc zphVAq^4rP{KOVU<>*iCdfTRk4Ii~&eE8o3^0?1DBzyFi0X5B?l2@_XhaZcH9!a?S<=W?xXZC9v_e4c=-rg%OHqBor_wI7@gA2wKp1EwyqVM}w zGz=>+o3Bc_J#|gC8WgeFxb@gn={!*RO|mL_k3GGCYH6=}z<5Ks<>?8`-3!verhg>y z-B9?w4wryT7w*kz(!rPLKWNI@lk199t~h@L<4B)+ifQ>a+3Jv-Z;wZ&;NkC*7g?jx zM=JE;F5S>R z?8j-+F|$uk6_}&@(OwGbcSg|sf|b%m}gcD*>D*L*M_ z_{oLw2CrY}$~~F9T2}6GfdKN|`{km*Jbpi=AKryA>6-9IaWKNZkU>|`2DLTwqPDGweoN@H`wH+Yl`UyW`VpMN7f}Jif$W3|{McmRjQE0(!ju)Oh@cP#qFbg!5?Xb}MAKy%tXs_(+Yz z)j_8mWHW;J3ECXoQ*Z8!O+;xWc;6ei(ib z3g7TnU?t5X7pMBEq_AIGgPI!|Ld zm~chvw$xw>1vnTDzMF+uyPK4d4Vp3EB**^Tfb0%tHT5qX0%;tOFS82qYg!2WVPXMQ zqVafrp@@~i+nZs;#ASiuc%zMCe*YUP$Y?B1>u4-v1lKc|R_~Pa7e?b={qsk#QFS8R zhisIlpcwcyy%^=3c2VVL#^Mo{jR>v}qJg3KB5M>6Ux^(?VvW0a;0t{;5|7Iqi75#q z@fp2_B!(o;J>{Hpha~=R&dJkHsu_|v<=ivQ`@@VO!OQ`vdt8SGX4CMgonI$Iwm$o< zPikg7e+flQ|KKxHt>6T{?f@Ti|p9jv8;v}$SWU`X_qeF)5=r9(h;{U*mIH z)2A83qK)M+^!_0%89wm%VAfX@6tn!=)Lsrh#0bORb^NfR1|)h|5d*{HO~=EE_j7Qx zxLy;a19(^w&inK|t*yBaFxE$%;HCx|HAJTR;e(7}oP^5$xl;Q}FJ>7^F?o%+&WDfT&1W3h)<@AV#EW zCL=^e3h@L&s-^)UDpE+3KuFc}Ut<>*ibN5uk|s@K-3uftQiyvcyFz4UBtlfAkaB^L zs+oxp6)B`fAf##*B1AjL8w=)l2%))!SzS4Mu=(D$j@o1Ekc3~u19qwh zjZo5Ri@3ptXy8xd#5CF^t+uouN;&Y?lVTcWS942MTdKh}=(Qe#&~j8uT5VB1fLG<% z&J4ZQBc|a?T5V~^WesX2F^v{Ut1T_L*ua;K#54-7;c}=gYVF`vBY8!2E(k4$Cuy~% zehR?=#Vya5|zi(k?a(`b^k+R|3iPF~SVI$|2Fl2%(<4%VQS7}IcNKvrAY zcFV9=;BVvP4~)IvREKc2MJ0xEum-kW8#UzJilR&oL?C*%qMQM6gvUWX)U=ES>WFsn z%#Pdl!PMSG)$%O69=-i!rZ)=bbM*2xk?48V#hd_MtB5ZvBos{+5EZ~16=7~pT>LUc zbx0ia@8eUJp1P=wLy@F#S<*(3{T==`kG5X}0b|7LEptG_#qnl4xVXVcmu1Gjyy>FSPEXm zE^@`WH!+U%`Ell>o=6QXQn}*1n;A#?%(wgr;8VHce8V`>XWS+DB=fy3K&qJv4jaWu zBoDT=q~KkFDpQPmD`QBP3F!gmZo93RIWJxcE*uDKf63` z89FF(#f5h;j`Z31Bg-&~B3B$$5=5W$8Fw~5wtVA?)KG_O5bi;SUkydQV9N?9s6!1# zeu+k!o%R#&ewjH*^VA_%2M2AA)I80kr=b}(Nk7q}S0#}c2S@HFBGG2(jwN57roAov z4*qLih+2>)7Bl-J*DX@#zIPvG0cHnJ*E;EYaLWZcm%tq zNB0m;yOYpW*y2jgfy{2d);80N54aPY?=J42HdoD+-k<#ygxbOh&&1 zaps0pYmv$oM{Z#3ku#Y7D%KRcMk6J%@EZU2*I~cHi|tonI+)c8`xOqAuj7r8`1_`J znD6GM?ssI)k1to0aBADtF`rH)-~@%!2EIZ!r6&$e{vxuF4vZ&2Fif{JjpDc1XZM~PuuRE64I=D943}-1<(tY6s z!MCpAsS9rI`v2)Civ}@082BH4vxx30HLKoB4IKZ!{IQ}V4@)GrVv%Gy7cK9OkmVgN z`}hHf@$cjEPTsNKK8?5D%BJ(N`eZ)(P11uOgyRm&J5kp4Lp7$;mUpr27DDAUwUQ<_vl>@`DpHmvfe@Q%_z)l}Qiv;2 zBUQ5+AV;f6A>{&5RjhjcoJR+2gT?SoajI7%dcx5|kgA!95EUsT6bPxB zg$PlRLfQpFs%8s791`)OkI<%98!Y;?Y3RhcTAB(K1OA~pgTBrcLkj>wsD>|TWl{~U z1X=*ZG+HFBwul>SaGlUHF{aTbX|+Y%kp?XjV;Tj&cwK)s||w z7)nD+hL}dJq}3L2gIDFGu^!(97}IEywAv!>NQ0IPF^yJ9t1Z>2Ase)0h-tVdamm$| z#)>s)$shlf3gk+j;P5=R=eK#plNN?L7^H<1P{kYgI5q}7&c zgj^rEK#pm&OImG_|6qeP=)Hb1jWQV!)t1JpoovtoSr8g49YWQX#)>ttf7qzO%d3bU z>A(>N;T!Zu$q1}76>lMr$lC4H5$#NwU1Zy5aLR3$X`>$9YB>c@#BKNOh+hEc+Nls33 z^rx_Y-tp)kO$kJz{!vb_Y8(2;D4Go*Du8#@!+Z~^%$9Fb-;5G>G=8C^HIA;hqm8Cf z(&VP;{!fUXcZT>QNB2Zd`=_IS6hD!uf8jLrWWhgi+D+e~+?wbAj)Em%2RHy;pSci1YLFZ2T5X?_&3ZO>EIp7WY&}lSOmO54hmGPek_% z!MQzEq{|$ivglIX_-^($W@54B*d(JTERldG5NB>rwHK)kwHcnq2FRDkXWMusO+*Tz zut7jbHRzQDjKiU%NAVCHz#FkaN`ViCIrc+Vyc&I+kRXXvC-q!NQ^$d$_BN_c(<|GC zYMdpm$3LKi zB2x^NA47@8f^WN1eNarOJ`inY_OlNPT6@@VzXOFa=-v}5#im)|s-5lp5~&95MLH^J zbx`$~Z+FIOxKdn_qkAEz{mao1^(K+1gW*Mx6I`_m)dPM{uZK%GO)NqGUQ`bvQ+=V53q=iTo3eB>p?V>!M&8>J~ErxMZn-cC?Y&E1BtXEL_-C#T5W|)V05{s|WdV zdTKwF&oE`D@v-0xK6(#vhYIJygU0chzAEdav4zfDG)Bh5K=YW`vXKp z3UMW7q-qXEh>8?aE)Y^Rvk{^qh13XyRLzqJQISF#1wyK38$wj1kWe6`YWnX95EUt; zT_B`trUS$wkxc0^*W3cqLD~kQDT}lTom*(Nauv{&UJ$C`OIn#!gX2w8`j|$Gq^sqq zO@+fxQ~H=jo21niaYJL13d6~BOrxMi8kfik2^w5~G^H1Wmcx^@+A5Gn(TYc&(#JGv zC9SrosblA*@Y0k%rqLv6wWZ}?4Vu!&G+HICw#a|5QBF2!N*~j3Pv?@WE%HCopeel| zwB+TIR$Jr^Xw+~y@KxP0jT%X-E%GMPpecP!qfye4Er~8SP@2-mG(t(MEiJid;FLb5 z(JpDVrF9;1tnivwOrz}g94ob@bXB{<49g?LIR~%&n9)=18_YK&>~#(cX_10(vt=Kg3_iqM{t^`NZ&is%C*$rTkQK}cnVj3a%%`g7v}=%C0I=RL_d(r4p89e`03x#FmjAo`@wIJ)}t{y2N6!!=0j zBUB599SG%gsO{iSRFzoqmgqks%NJ>p8GRP4Xs_oUx!@pdi7h;_)1$jcCVBx*^l08J z5^afLGv?6sh9f*1uQ#9o*cIR}77A1h)*p*$M%NpgUA)0LuHe%9tFZL+6I~+F(o;?V zmtLUsg2D^fhzj7U3sy05@&%WsZsi#lTsTb^T(K_f%zFdNk3zAzBz7O=(cp{8llhdfXrI-z>VtTrYys;n_L))5EUt;Mj)hWW&-4B6)B`qAgZbk&dd5Vh22*jRGjLCqDOpY z+3#V^MI!#~Cq*mUQF2#4vXz0bU9@$gS#}o3Uhx`63Jd?rk|0#0TGGm-8s*5$w`0XL zd`YV<4LO&9rlv8C7D=lu;)cp)4Vs$9G}`iQo~XXSXSA{ z$y02lR}j$~y17a^Uo`YfI)_O4Rx5Q6x(fCd8Z*E>9YZqeM&k!Z zj>?2{U`))ribfmvZtelz8g?{%2@TVjC=zwlT?;wErgLCSETZqgr+K6WX<{)KpNBht z%lRbeJwqq1A5*XcE~03vw*s?h5Sw_uonwybX76h{z72glInLz0ZQEw+pKyYTXt1H$ z;Yu-ptUS(wF1$HW+7aCn}Jw^V0j68i$i@f^^V@W5txQXTpDC6lMY4&^oq@%T_T8VC~ToP(@nx;d7Wpt#M@lFYZ0_NxQ9xgg~tz(uXuD2k^2FSbi`k-;zcgARb_@ z>0`ZRijRYzFcNRnefJIaj*GEsDfX3+y`!V-lA|c7T22=mL_--UG~fi4Gnl;s>zu@H9%zW~xw>kR~>rV57v2tvj&6sU3 z*!ecjbGYFbhA^LT|G*Z~kp}I#3PQ_KE@`zz+@Mj0vE!ddjA_(JT5Y+~B)B4I&o!peC~38&UU9w9o@-1a zl(gC+Zt#k$sR8#~V;b#}R$GJw4X#4EjUuK|cCIv3k&`!(2JN{DLSt1eX|+W$0*wN! z1)kW(G<->`twxCzYtY0trqLp4wWTE&8~B_-OruTGYD?>bZ1K;B#xx3K_)%M0=Ug8& zu@!`t+>^B0(vr7PE1`*POhbn_wWW2=HHiJgMh%{HD!tN5HRHanjF39%bjR|DsohR# z%hN|Ls1hoYp*#B9WWK3K?;Sq5xLa_rrfHl=^yEP~dPhH@XlaY6VD`&+Dj_c3*HwpP zni)#k6UVhSGU^c=EqGxV{v7*52Din`neW=uMr$xMICLHcY7LqOMO&FKClqe>Iq%_C=o)rj zkKX6(o&OaaIXWUy|J^S!XG@*c*Zg#jeZ3j~zP+x9gy~`0$}~i0X3w^Yf@40gPk?Ah zhO&_zj0UmNQ{U%(WW$Rq$Ua@HM~&e0HktyVw`SNC*8BEL@D4 z88sdJo*t8bahh0o_O`M!yq|0S7xsptP%@Q>OkiAyu;EK;C1jRjg6N?CHf$y0+t0R= z+rPG_+j#4>vA(e{tZUkqc~!}kojEt{9lmHkyuk@*LK%rvac?qMpAaJrgnE1ceDxZ@N%UOjjjH0NgF;@`K^7 zGZY@mz^Iw#wb{Fw`kRw^&<985dS7uQ{jV`^OODg0r;7N!$Iz@Ot9vJBN^YB=y=Fwu z>I7&NDcakBSqnQkbKnP@m|L@&KH@Z~n1eez7Z#~VA?|&3^h$eX+0xm$s8A$|XnT%H zNYl*f0wgL@2ziH14pmL}T<0R2{B6i}dN>3&3v-#M*>=88j5YtG?n@zg+Z{7xl5l;in#c zk+06BH^X)isDct`^HyRc(6@BdCq9hcOsftkUiBNr0p&&KacPY_^@+-3qE}cefhs6L zCUx~4%Hs&J<%=F&Q0EZ%A2EDN>O_Y6QY8(~AJ2B88OQ#4Mz0HX=kt z3JDEENYzZ*6(A~7NK+$2NY$)Hh>8@_b~8gr)l}^U5EUt;9miUTI;ol`5u&09ay>&x z)eI{}h=>&8OPW;8!eVD?VGKcII@lpi)3+})FA|yAeVu$8!R8ha=IE(pAzw<&-`!c% zQ%@xiNCojJW#jJ7Jq~}J-OuTfqo{LC#Ut6H%^UrkZXVK>RK%(@?v-{EgY^ACvUD837qX2w9LoZ)5x{D!kxInc=|q?dDbIEK{t zp}j}m(`g^*cn04Y6af89+dMbSIoxh5ffIAVUQWGJ6SqHqxZ|=^%nWyO>|=1|@zQX| zw(@)PxV$G=!S+t?+on+5ypJ={XtJk)7Osm>D)3DK;wB9 z+)bKcd&4iYj<13cL8a--!nH8&Zd^DQ3u*4yA4ZF^7Bo%;y67M%kb?zUc91j9vMDFC zJZ0^2?QZT?Dya#wIJ9XXf3QlTnGLZOg8 ztx)YFVg44ztBC|ZUn(tymI_-qeyFtE%JU9_##ggEDpuhrC{_*@>-bSvEXv6&R`@hK zPDgaS&_)T)`Jk#+aV8z5s!)WveazM|P%31Pm#XIWH5sRzq0%!!mV2W0I7Cpj19=r3zbGP9>TWoFwX zXIht4viim&Pqf_^;GcfmQ!LGrhS$=u;fo95)PXB__``*1bOr-F-M5;UaQ<1%8LW$M9&rIm#&;y0r85+t5BDKx?u3gDBQO9}|i0*B$fM zVQbwHX8h64gn?)n!l#b-&vDup2T=h(Ziic~M>~~OT@E{_62vRvPd=3^6N$H0K5yxZ;^(dMy8J)8?f=oZMr%fAqyGnhS1UeAX3jFI`$Yd;h~es#}pTlaF!wlq2-R zO`As{9C;AFxm)LERKYZ=0KB3%s9_pDE6MkVjsf4rSM{B$4a!2ngrk1ad@n!NsT>Ku zuY|lx&4;h>J;V1g;QJ_WW=xvzqn4WHW1W8L^HT763{oI0=JTkS&z0nJmuhGHAazom z_CpD{6h@s&bGi}qMgRl68WmgEajVYFn@iu%T>JSRgO)wD7>M4%5_g%-`x%m8?3m~HSXc_*zl9RI_BZ3IY}<@K-pMTy^p7%5 z_!}6D=JDgAF6orI^}IE~8SqMJ_|m?rt^$V_{Iuf|4j!L(N=k%8NnJDyHR_77bW(pu z(&ru?HX0XlNL=El$B{!1q~{YqU?Py&Aq z2P*O|Dyri)3c)Tpuy9QHL~`_rK%z!UVbp4g6ziB$?*OES$Kopd~e~}%C97!udC=TqB1M`GL zla`{SM0AwHl~$+D_z_2`yAC*@0qO^v?zw-htDx-y_})sS&~za*v9{|!B(YTw(^y+~ zWUc(`u+i9Lu*Te43^=r1Xg0zU`FantsOsB)Z~^`v#X^3@{!t=bBpDT_knfTSZw(g+%nfSR&CZ=fYRcuL&!d?rr~~dZ64#$0XhMRhE!PkUv}GuTC@G0AY4xU~avXP& zkiZG6qZBcH_gM*}I+Iq4mdFVjmC{NgN|6(ij+}WDNM&4J2_&(`oIa8EsD`OA$4FhB zr>Tb#=@2*Ek#xz!!FyvAQovB`JHv>bRSMl_%cq zX{|&QBDW;1#BLfv8xlNx0?Yu=ld_AV_8#MKSBn$sOd7{l;eZ(c>2rG*g~$m>`#(d_ zjs$n$#M>tV8ne^c4U1Y8oRCyMLEjQJyG%Ffl^?sDXRL!RK{Riky(N|1%_&LIM*5BB04hOy6B6PAE^B z6CUbA`zo}x4A2M!ulC*b64{^8pNRU@z+2M_APP$0OInH3qgX8ta07QQiDp?rTzr9XMcX2smQB{F|kRMr(q0B3)L8 zy*m0E?9ed+SLf~OURu%SApuO9U<@XLmykde)B_hc%D{Og zPWPZOBQ`#fa1D!+lF)7&kSKXN$$TM!ftU!OhD%Cf`f!?|PvlHmDVicD@J!oA9MIQx z%W+}6qg^@E{H$}VDPEYhA!wQ7Y;_#oi<|w3v#WXWDrZ+4ciGJJzc|MRMD!$Qo+n){sbfUx=i* z*<)sJhr&)>i-qOgodsE0yP9Xu%E~wITm^)_OZc5@1hajK#75HdnCC0VUZIn;9HkJO8yh_P~mbTKhpsCQh7_xRZhwqoQlkH{XJ9aF4Vn((t%i<38YRq4CJvzjz zUCMg&SYV!pSu+=86=vJC0_w=A=}>BlWzB%Be;=;5rct=4gbU7snA9TM>{BUH9nyM~ zesC5=szd6dlq2=l`4lOdM-$IH$%9A@ErCwO>o&;hXSUAC>S;H|@_AX-kv~6{&&#fk z{3gujQ1N1F%Pm>M?L{3@ULldRr9&Fhl$xX~K}thU0Bs5S054pcmqQRj%)$Z34E+v9 zrRwG^7?o%ZVkmzd5;g=B4k|K9TT!~e%{Iy4npIhsLBpXb7v*inJQ$*&W_eaW?5(VF zyRAdY({z$96-KYRjG!R2vAY?pKrFNB-f1fPG>tpQmG_Px;jy`NbaqJvZrA-bONZC%AVjHWe=O2y{q|t z60p~FWYfuor%4_8Gdl7oUY@;!dM##mKLP{Ba~secW!Iy0=46!eARRCQf0xz8JztnNOooLft~F^N zJ8dQvT{4pkCY5H(b=l(^Dm$CJE3$Kj#g zj%(v=3ANM*Su*N`z0&l(Elpd{YMUlr7<=_WXX!FW8*3&_aSk%Yhb4D1y9U|W`KR)I zL^pvB)*0Ps%GXt!uF9^?_W4FY(|oRdmE*NH!ps$Kx5#Z;4A*GU%e8p3%=DJ*IcDG? z$^3@Ooz0S_>;m}h@!*oHvzJ?z6^#CK_SaTVAxhvab!dn$^1|J8(|4<{pxas@!~YF? zbF{P|w?E#l1y_0dnYQb)C*|XP6<}09oDKJQk1^Z#vT{x1yzD|3cc1X8tI1oDJ+y3U zPF=;YInB|J9K-izC{v0jpYK_b=)G=~S=pK@DA*&G3&<5HGvgYvPtLyk`JOAjHpiMT zZ^+(j;2RJMa78^QS0JsP`vc_uEG!Ynv+VlpNnPYl5h^I&OL(C9X)pMF#dX(bm*nA9 zJiO+HSIF>smZ{&%%C9@{>AH#wmJJ*I{g#mddOd5|uw^LQefO^@z29Rc`+m3WAN%4B z37Eh8SDl``ZFA2RP^zUU1MG^sK_~IlMuB3ZhuC3Z_*&{F3 zRV+Gc=TTU?yPWf%TH0E$bny>d$Mpjb8NKtN&n!=Tcm+jcUc5~bl#!W5UgEG^e%$}L4H~dGr0SNL$w-W9b!cVF~1eMwriT&mJ-GgUo{ zF&@3gqMMFJjsM^C7dBUQ#h~)Qih7J*0EbzwSTk#s9Ck zYk`iUO4Hq;o2r)ZNYd$~^L}9x9(fbOBT2{b2ns}GMj3T{jIXGGq7LGyG>8nrQ82tN z$QyjHs7ORp6SQ%$Yu?sQ>p*>vBZ~(sG~!-~U>*b=T5%!dX;*aR2<*=Xat1 z*~72yA-NGcw6QKeamSloRrQx+u~bPAJ=$k%di;?SC&pL5xn@B3m4A3QB)(W_RMwn{ zCBspIvCgKK>+>E57^d@~P73qRrUiWK`E)!k=nqGx548Hx-igStB@{}=8x3ix% zUdqxCHl%*=MqMKSQY1WML_BPP0ET+ayc@!5!syp2x=w_h8%FFX+s~)%GZkvz{*t2@e|D2H)uv}U}X0ha$<#0_LUv9LD2MZGD zTk7+MCtGPLOLVU`?nTpufaqN>#`J7UWp#<_E<98mKo?78bt%y_@K8~?i@I1Ut4q7? z!b8PYbg@)cmovHx4;4u-P!~&Obs?|$!$ZYF>Y@px$=xjG?Kb>go&wRa+nDJ&(?v1S zUB!NTJ}(h;YaKm_pc2W>g84eJkR3>@%*d0ShTHAQLYot7`X1x@KB9Y>(WVge2pd5^ z0mctZjyMPj~LBo@?qy<*ne#+yDqLZ*uOxe{;mK==J+;#Y@_E8MN3^RV%*n7iK{ z5MSIw&wbp9xcC<8Pd1Ts;2ndim&LR17)747NN~FDE*7C9hBu5R;o^g888m2+OioUg zNl8g^;J|^hU%!4bF)@+%7hG_Gtj|o4~- zI5y(`OnFg9fh@h*FB=}om17^tk+tDWIdQ{aSw1Hqhs{itwevIOhzBxQJ{}S5z{lO& zWzQR1*r8Kh+gL~Ya4+L<#Gl3Zz_<}_YRe{ zOEP#retn@Fxj0i!-B}`Q!WnYZl1$n9e5q{RRVqi4{LxFRWzXxIB|Gr?Ci&6JYgj(M zSI|DZ{X7TK3w|N9O0Hp}a3EN8g=*72tzfzwNzs9Up|_>-egZjAMv*fEcLikieL*>4 zU6Guywn$domBut%4xD^#gZyyMN_OC*msiV=!$eCw{gBfOe#r*mNNR4YOfS5g+mO@p zFOw6WERqwq70HIxxy-+hanEz96Y?UAFT_ca}Sz$X6 zMuIpUK$Ku0kawx{=S(ICltYly@~6vD4`nk8RliMV23j@_mcwSJ%2A85WZB(mvhv<^ z*}N)WHg)7vP7niR@D$B`57B?@#TC3^I*5TVC&d5d02uIRUlPZ_RCeH^_4#tbwnEvk zGKU$MxRIzP1{xmEmDQ93bu{neHx|lq>kDMv(oC5%d4L?dB$pC4PZnR7B8#p{mQ9Zr z$RRg}{p4lAc?_iHPL;vIzml27zh(x~bWT7I2FmY9V+P7*1qe7tHZISTrMIRKGg)#t zF;PVffQ^w0vt;Ex>9VxVFYBpV#;q>ov86YqkOO&gX!ur@L{0|$Ia4UvR3gG?Dzz~s zU<3}-JRFqcHy3aYG;bi9XQ#`GxdE<(%HO5SI?932>O9%FDo@ruk}0bmq$wdbroA{s zHmu5(RST%Sp+JV~iNYz*7oW#KV)8JW|7mvO!J*6xui^?oUXwnm+R9QJUjU&d2SbblHtf0O_ZzpzU2IO$c8|2RL3+Uj8-(^4{y52W} z*9MDb$PCInthXsCDd%|wt60)d$Tbua=qtaIECKcQzSp?BI z2UX7tvVr6K*2%Gd$dP4~9gUCX$=dsAa)>Ku|E9Hha`Lmq@)VY`uB|E(tcQpO=gFUn zq+(7wEx;?W)X2KURGh^3(6&@rMiEw1iaL!nug;f^w2H(T2{w<+PvT{YPo_9=(t3tP z6(>;WtPQ7@kp)SzB72~$${DEkxr1c$&@{361EcgR5@cgZK#mzqC(q(k-j5(~oRzJ! zGeF;Z>i2YpUdIcibqpucTIvhnv4d0On4%O}Nrsw+q{%|R4|EK^3XQQB`ejR5hMZKM zA?q)s9L*WTt1nhuY&Zv5GNOQt(*wY3$lJPtWEw~76>S*XNRAFpWdr%w()&o+a~Qd} zB9pgq!>EGEt9M>l#XtbW2m9LE&zLI6Ctg|4MykmOHbj99QNU5lNEk+-7)vxE3TzF< z0q%%1DLlnMcnx4|q^3O5c5dJv5hYBbE04mBLG5Vm>U=xO^Gm?9AP7*hjWl|4E-yz2govN zV~mw_*wsOVr-+x05TRbqN^Y<&lt6DehYaQZ z+F{7!C`tqc2f!+fHxUb91bGyq{Uz)rMGLC1!7v?~MojxC2!K3E@Bt*#TT?;EL^ zcf0!717XdwPN|K;tjq-p!ay+s>FCZS^26Pa$-nG+RMPr%J_^zinE{t*78MGZw}J*S zN1t6HkN(rcg!b@Hqcjo<7#L5Hj~^anlvdD$c>xj5HZPE}z6U z-{s*TK`Rn!QaN3fYtUQ^6u8y@cg^+ zg;^3&e;5*5PZ?uH;%WN(0Uh-8hXvd&ge@K8TlU5}hR|_UG5S={)=k?`+G3wX`Yyj9 zL~Ys<#ha&%+M>8v`L93tmQSAJ$DDVlqjI(E$uE zunrl&5QJz;Z)#ou3P2e?b(%)2-QsA^bF_E#g!yevm_~d`@Jv17S?wL0dbh*vPxMx_ zI|j6z>z;zL$rtw%#7QqHVdoC_Uq#yu~rT6<^u1)q`B^URe^O8{S_L*s zuBanv+8hSvIT+dJXwP$0%|6HYsH45ZZY%q)qqYM6QiSUqIpC;*9gcR?5uxdr^D~YB zORStpRQ6mY02EDUjTA300iyCN`ZFX~zY@9dmB=+OI=-TJZU9EO|Jx|^mcW7%xyB(D zc~DzQ;=^a5V@o`SYgufCGHx`B*MCXxZtMQqpj$gpf1>G2a))bI(4j&vS1m-{i>p?2 zq8AseNP>H)EOGWrTlybMqUiKdj+1LrOtY082;KyzqVp?QLqb9<@}T&XlIu=P`uH+lRqKi z(;(h)n}NtqxA~;I?*cl~-5}~b<`C}HZS`yr&w0!Oab;gKQH)M7gMHNj@j)N+Ch;~v zLsnP93^j;xea+$lYyeFb#5#}pwNcRs6E5+J*Bm9v`kH3{JknU7yvWC1b78_@bxCj? z_l?Qcr2>9uC0Q&r&D+H)(@ai&Kxr5TG6k{4G;>6)&usO8jmT1;nL_u9;|f!39ca$9 zu4{u9Yd%pw$gB(N%U-4qKLF{=-)4fw#He@wvmO5DZ`}_6tpWd^c;UZ$gg@_4`0r2g z&pJT%|Dg=P{y)+IwQ&6`MdTo=BSdw{UlJo*Q_Lj%QoqM~IUtZ}m_^0R#7GaZO0^><(Pl@Tu=LWnJcw69r)_>W5SUZoJ%SCOyL zIA2*7?5jqyef?A;!)N8|>>5HglY!h*17BGdon2$YF@$$TD+$rh>6y zztXTU2iQg4DE^agME}oyMb~)qkWz?_3Efj9!Rh z&do%H2C{+mt5i)G1aPW2eKSp4Gy}ktyp#~XolObB3gvQ(1q_lInO)XMHu8nqWmr_m zKi-Mt%>weAIZQI-c#;`ek<7q6dm6|FuF$|RDBSl`O0?tvlTsqn5LpKk`iU1FB63)( z@**1NGRuOIHIj`yS|h_EkOQK8F<4$e?a0=}%razvUhVmp7{3rj#|g>^gfPYiq(SyhE*2|y)MK#8;v1rBpdlVjSP#5)c<@Jq%H&U_3tsMkX6RM6(bd*Dgq5* zLweMUi%pnPkbO@QWOO+oRT^A6#obSA{)9qctIZ?_ya#Oy^!P9F!NB1WQdAn4P*lk)4(tY;DETr^bwtF08D3!Y(tzI z=$oq)dfByr!7n58va6A7@&q8&B6hgYcStETzj4k+W5^oGM!r}h!=gfd;X*<-H)tBLCO}qe!rL)sA*wY& zL)eh|J>n)ziOvcitqB`}W?zVvieJ|G=!6EXz8bTD!E6j!BiYE;XlG$jW$y9OKFZw9 zfS)#onS~se4DF1p_+?;TaWs$(+@^tHPywGCN5Cyx0Zjb5eH58iPIG3X~ zvIj__XR6QdfenQ Date: Wed, 22 Jun 2016 01:41:26 +0100 Subject: [PATCH 033/121] Stairs: Stair recipe returns 8 stairs not 6 Make it consistent with the slab recipe which conserves volume --- mods/stairs/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/stairs/init.lua b/mods/stairs/init.lua index 2195e4d4..8a4ebdad 100644 --- a/mods/stairs/init.lua +++ b/mods/stairs/init.lua @@ -89,7 +89,7 @@ function stairs.register_stair(subname, recipeitem, groups, images, description, if recipeitem then minetest.register_craft({ - output = 'stairs:stair_' .. subname .. ' 6', + output = 'stairs:stair_' .. subname .. ' 8', recipe = { {recipeitem, "", ""}, {recipeitem, recipeitem, ""}, @@ -99,7 +99,7 @@ function stairs.register_stair(subname, recipeitem, groups, images, description, -- Flipped recipe for the silly minecrafters minetest.register_craft({ - output = 'stairs:stair_' .. subname .. ' 6', + output = 'stairs:stair_' .. subname .. ' 8', recipe = { {"", "", recipeitem}, {"", recipeitem, recipeitem}, From 9d6df824d6062fdf8bfd7c6c204753f13b3b1ac7 Mon Sep 17 00:00:00 2001 From: paramat Date: Thu, 23 Jun 2016 04:37:19 +0100 Subject: [PATCH 034/121] Default: Add stone / desert stone / sandstone / obsidian blocks --- mods/default/README.txt | 4 ++ mods/default/crafting.lua | 36 ++++++++++++++++++ mods/default/nodes.lua | 36 ++++++++++++++++++ .../textures/default_desert_stone_block.png | Bin 0 -> 527 bytes .../textures/default_obsidian_block.png | Bin 0 -> 336 bytes .../textures/default_sandstone_block.png | Bin 0 -> 637 bytes mods/default/textures/default_stone_block.png | Bin 0 -> 498 bytes 7 files changed, 76 insertions(+) create mode 100644 mods/default/textures/default_desert_stone_block.png create mode 100644 mods/default/textures/default_obsidian_block.png create mode 100644 mods/default/textures/default_sandstone_block.png create mode 100644 mods/default/textures/default_stone_block.png diff --git a/mods/default/README.txt b/mods/default/README.txt index 051af060..41dd1eb0 100644 --- a/mods/default/README.txt +++ b/mods/default/README.txt @@ -114,6 +114,10 @@ paramat (CC BY-SA 3.0): default_obsidian_brick.png default_stone_brick.png default_desert_stone_brick.png + default_sandstone_block.png + default_obsidian_block.png + default_stone_block.png + default_desert_stone_block.png default_river_water.png default_river_water_source_animated.png default_river_water_flowing_animated.png diff --git a/mods/default/crafting.lua b/mods/default/crafting.lua index 998d86ba..0f10e7f9 100644 --- a/mods/default/crafting.lua +++ b/mods/default/crafting.lua @@ -499,6 +499,15 @@ minetest.register_craft({ } }) +minetest.register_craft({ + output = 'default:sandstone_block 9', + recipe = { + {'default:sandstone', 'default:sandstone', 'default:sandstone'}, + {'default:sandstone', 'default:sandstone', 'default:sandstone'}, + {'default:sandstone', 'default:sandstone', 'default:sandstone'}, + } +}) + minetest.register_craft({ output = 'default:clay', recipe = { @@ -627,6 +636,15 @@ minetest.register_craft({ } }) +minetest.register_craft({ + output = 'default:obsidian_block 9', + recipe = { + {'default:obsidian', 'default:obsidian', 'default:obsidian'}, + {'default:obsidian', 'default:obsidian', 'default:obsidian'}, + {'default:obsidian', 'default:obsidian', 'default:obsidian'}, + } +}) + minetest.register_craft({ output = 'default:stonebrick 4', recipe = { @@ -635,6 +653,15 @@ minetest.register_craft({ } }) +minetest.register_craft({ + output = 'default:stone_block 9', + recipe = { + {'default:stone', 'default:stone', 'default:stone'}, + {'default:stone', 'default:stone', 'default:stone'}, + {'default:stone', 'default:stone', 'default:stone'}, + } +}) + minetest.register_craft({ output = 'default:desert_stonebrick 4', recipe = { @@ -643,6 +670,15 @@ minetest.register_craft({ } }) +minetest.register_craft({ + output = 'default:desert_stone_block 9', + recipe = { + {'default:desert_stone', 'default:desert_stone', 'default:desert_stone'}, + {'default:desert_stone', 'default:desert_stone', 'default:desert_stone'}, + {'default:desert_stone', 'default:desert_stone', 'default:desert_stone'}, + } +}) + minetest.register_craft({ output = 'default:snowblock', recipe = { diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua index dcd92ecc..494a4cb1 100644 --- a/mods/default/nodes.lua +++ b/mods/default/nodes.lua @@ -19,17 +19,21 @@ Stone default:stone default:cobble default:stonebrick +default:stone_block default:mossycobble default:desert_stone default:desert_cobble default:desert_stonebrick +default:desert_stone_block default:sandstone default:sandstonebrick +default:sandstone_block default:obsidian default:obsidianbrick +default:obsidian_block Soft / Non-Stone ---------------- @@ -210,6 +214,14 @@ minetest.register_node("default:stonebrick", { sounds = default.node_sound_stone_defaults(), }) +minetest.register_node("default:stone_block", { + description = "Stone Block", + tiles = {"default_stone_block.png"}, + is_ground_content = false, + groups = {cracky = 2, stone = 1}, + sounds = default.node_sound_stone_defaults(), +}) + minetest.register_node("default:mossycobble", { description = "Mossy Cobblestone", tiles = {"default_mossycobble.png"}, @@ -246,6 +258,14 @@ minetest.register_node("default:desert_stonebrick", { sounds = default.node_sound_stone_defaults(), }) +minetest.register_node("default:desert_stone_block", { + description = "Desert Stone Block", + tiles = {"default_desert_stone_block.png"}, + is_ground_content = false, + groups = {cracky = 2, stone = 1}, + sounds = default.node_sound_stone_defaults(), +}) + minetest.register_node("default:sandstone", { description = "Sandstone", @@ -264,6 +284,14 @@ minetest.register_node("default:sandstonebrick", { sounds = default.node_sound_stone_defaults(), }) +minetest.register_node("default:sandstone_block", { + description = "Sandstone Block", + tiles = {"default_sandstone_block.png"}, + is_ground_content = false, + groups = {cracky = 2}, + sounds = default.node_sound_stone_defaults(), +}) + minetest.register_node("default:obsidian", { description = "Obsidian", @@ -282,6 +310,14 @@ minetest.register_node("default:obsidianbrick", { groups = {cracky = 1, level = 2}, }) +minetest.register_node("default:obsidian_block", { + description = "Obsidian Block", + tiles = {"default_obsidian_block.png"}, + is_ground_content = false, + sounds = default.node_sound_stone_defaults(), + groups = {cracky = 1, level = 2}, +}) + -- -- Soft / Non-Stone -- diff --git a/mods/default/textures/default_desert_stone_block.png b/mods/default/textures/default_desert_stone_block.png new file mode 100644 index 0000000000000000000000000000000000000000..ef7ba5bc64680852d603ccd62bf813759bdcac58 GIT binary patch literal 527 zcmV+q0`UEbP)3CL*bduZdF-WANM3-n@imbw%hclGxTbp2=<;7aiN1gPdhT3C05ByaN@)U* zTZn6|@H!~Nxpu31NH@R*8(j@&Gnk z9^UV2-vb~JfbE+acPlN7l#BeU!<_h?$yd4h-CViV-O401vphSp0~g>Veuw~!k^s6s z5=d-J{;AkjF0cc`0dTnA0Z1ve{lHp{548)T^+V-CLhAYm;7@x4(2p-Rms*OgRtbso z0N5BMmh@YrI5&VU#HA~Px`uJankcb+A4dSITrFglc!kxK3;VUHTo68tdutdA*FD_t z8Xo{0%WgK;3c#ss-4KP%)v0V3y~66o2WIej{~rc`b*_w*f;rxX$Z(f8SysM${J@9+ z{Jb>c8pgtEPWd+Ra`VS?voIi#czCWJ&ouxe=Wlnsv^?p@ars47NdU*P{RgY`0Eq@> RNOAxG002ovPDHLkV1o4;<52(r literal 0 HcmV?d00001 diff --git a/mods/default/textures/default_obsidian_block.png b/mods/default/textures/default_obsidian_block.png new file mode 100644 index 0000000000000000000000000000000000000000..262cd37e0d58269035ccc4351f3f6f39b21c7d94 GIT binary patch literal 336 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#0h>6JA*YJ8!yTZ|drud~5RLP_6MeG|8wj+z+lz2*wWK+PGKv0J478q8Ba6CUNQ8JV+V&ii_&Jd?veepg(6 zeMN;cOZsn3pq&33>!0lJ%C0{=6P1xvcBuG8>iG<#XIVhp+$u0Qj)jZs3N|pT_MoK=HBt`1y(ez&SZL)mHAi z#7P@_#|kH7cP>mR2SO?(VDM*XJPZfhKhD!TG`?dfNgHdVP0<@^=lRH$$MFja)F24{ z2bJdJNzk}?$TSDTb$y`~QK?ni>Zk(b=BmjuTD>J5Wz5kT8 z=EMG*TQ8_|-)&P4sm8*(02ly)*y)W@=2qCd6LXOOFwbuQz%hD3oRjSzy*ue{@7%fX zAH2VTAZ;v(L5Nu*s$uiQjY*Jm=h{k&@UO8uZXENx-@b5T?{6hLtgZU6kf6i~0EW%e zFdUpalORbd`r9~ub?%&^CvBzbv6e(iFY5;(3DnM=Qx1LqAQ0VpsjYZ-8n@3eT{(F~ zl+ZYZD+(z|fdK$}H*;6q5=%32_FaCP4zRa85bY!lW(d zq)C$?(zZ2LW*j#Uwi{x&$=Boc{cXx6)>=z;t+DBLDK6IT5h=u#NHU+a`V4;l^?UjY X^zU=7P3joD00000NkvXXu0mjfs@EKb literal 0 HcmV?d00001 diff --git a/mods/default/textures/default_stone_block.png b/mods/default/textures/default_stone_block.png new file mode 100644 index 0000000000000000000000000000000000000000..3b771e725e32c342a26dcee06ec7b7cb5800d974 GIT binary patch literal 498 zcmV#g1^`uEr&2!*^?ncFa=FU(+8&Qbo#$a30Tf!NBJLp~ zk!7uO0Qy@m0q8t0joG#hz_zYqj41c;A#M-C{ly9R_0ol z#sEkTDX}d}02G4vep}b7u3gv3zw&7Y@BJ8K3(V65Kq-~7$)YHlrzav}hpMW$^Z9V# z4TZp0L^Q@IV~p&`0)5|eU6y4#rFa0&1E9zY$=y7h$g;95+5PXVah~Hm|6twLmF1UZ zVZ@0{idR(?zibFW&dXBo_l$*u9-4+i0Kkt0fHAhtP17XvJpVeKg%H+SCQTtQ1BQ`; zmBtW}G{y)a!Z Date: Sun, 20 Sep 2015 16:31:29 +0200 Subject: [PATCH 035/121] Gitignore: Update to ignore additional ide/editors --- .gitignore | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 717f5fe0..ef02689c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,22 @@ -## Generic ignorable patterns and files -*~ -.*.swp -*bak* -tags -*.vim - ## Files related to minetest development cycle -*.patch +/*.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/* From 22dc7b2d9e14e0cca72ff7518c60584f9ea5800d Mon Sep 17 00:00:00 2001 From: paramat Date: Sun, 26 Jun 2016 03:11:42 +0100 Subject: [PATCH 036/121] Stairs: Register stone / desert stone / sandstone / obsidian blocks --- mods/stairs/init.lua | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/mods/stairs/init.lua b/mods/stairs/init.lua index 8a4ebdad..4a15b5a6 100644 --- a/mods/stairs/init.lua +++ b/mods/stairs/init.lua @@ -328,6 +328,13 @@ stairs.register_stair_and_slab("stonebrick", "default:stonebrick", "Stone Brick Slab", default.node_sound_stone_defaults()) +stairs.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()) + stairs.register_stair_and_slab("desert_stone", "default:desert_stone", {cracky = 3}, {"default_desert_stone.png"}, @@ -349,13 +356,20 @@ stairs.register_stair_and_slab("desert_stonebrick", "default:desert_stonebrick", "Desert Stone Brick Slab", default.node_sound_stone_defaults()) +stairs.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()) + stairs.register_stair_and_slab("sandstone", "default:sandstone", {crumbly = 1, cracky = 3}, {"default_sandstone.png"}, "Sandstone Stair", "Sandstone Slab", default.node_sound_stone_defaults()) - + stairs.register_stair_and_slab("sandstonebrick", "default:sandstonebrick", {cracky = 2}, {"default_sandstone_brick.png"}, @@ -363,6 +377,13 @@ stairs.register_stair_and_slab("sandstonebrick", "default:sandstonebrick", "Sandstone Brick Slab", default.node_sound_stone_defaults()) +stairs.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()) + stairs.register_stair_and_slab("obsidian", "default:obsidian", {cracky = 1, level = 2}, {"default_obsidian.png"}, @@ -377,6 +398,13 @@ stairs.register_stair_and_slab("obsidianbrick", "default:obsidianbrick", "Obsidian Brick Slab", default.node_sound_stone_defaults()) +stairs.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()) + stairs.register_stair_and_slab("brick", "default:brick", {cracky = 3}, {"default_brick.png"}, From 983af7b1c0a01436fe38111d5aed664e4765d7ea Mon Sep 17 00:00:00 2001 From: paramat Date: Sun, 26 Jun 2016 03:57:30 +0100 Subject: [PATCH 037/121] Stairs: Code cleanup, fix various errors Improve registration format Fix groups not matching corresponding full node Improve some descriptions --- mods/stairs/init.lua | 394 ++++++++++++++++++++++++++----------------- 1 file changed, 236 insertions(+), 158 deletions(-) diff --git a/mods/stairs/init.lua b/mods/stairs/init.lua index 4a15b5a6..faaa92b3 100644 --- a/mods/stairs/init.lua +++ b/mods/stairs/init.lua @@ -256,8 +256,8 @@ 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) +function stairs.register_stair_and_slab(subname, recipeitem, + groups, images, desc_stair, desc_slab, sounds) stairs.register_stair(subname, recipeitem, groups, images, desc_stair, sounds) stairs.register_slab(subname, recipeitem, groups, images, desc_slab, sounds) end @@ -265,184 +265,262 @@ end -- Register default stairs and slabs -stairs.register_stair_and_slab("wood", "default:wood", - {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, - {"default_wood.png"}, - "Wooden Stair", - "Wooden Slab", - default.node_sound_wood_defaults()) +stairs.register_stair_and_slab( + "wood", + "default:wood", + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + {"default_wood.png"}, + "Wooden Stair", + "Wooden Slab", + default.node_sound_wood_defaults() +) -stairs.register_stair_and_slab("junglewood", "default:junglewood", - {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, - {"default_junglewood.png"}, - "Junglewood Stair", - "Junglewood Slab", - default.node_sound_wood_defaults()) +stairs.register_stair_and_slab( + "junglewood", + "default:junglewood", + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + {"default_junglewood.png"}, + "Jungle Wood Stair", + "Jungle Wood Slab", + default.node_sound_wood_defaults() +) -stairs.register_stair_and_slab("pine_wood", "default:pine_wood", - {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, - {"default_pine_wood.png"}, - "Pine Wood Stair", - "Pine Wood Slab", - default.node_sound_wood_defaults()) +stairs.register_stair_and_slab( + "pine_wood", + "default:pine_wood", + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + {"default_pine_wood.png"}, + "Pine Wood Stair", + "Pine Wood Slab", + default.node_sound_wood_defaults() +) -stairs.register_stair_and_slab("acacia_wood", "default:acacia_wood", - {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, - {"default_acacia_wood.png"}, - "Acacia Wood Stair", - "Acacia Wood Slab", - default.node_sound_wood_defaults()) +stairs.register_stair_and_slab( + "acacia_wood", + "default:acacia_wood", + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + {"default_acacia_wood.png"}, + "Acacia Wood Stair", + "Acacia Wood Slab", + default.node_sound_wood_defaults() +) -stairs.register_stair_and_slab("aspen_wood", "default:aspen_wood", - {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, - {"default_aspen_wood.png"}, - "Aspen Wood Stair", - "Aspen Wood Slab", - default.node_sound_wood_defaults()) +stairs.register_stair_and_slab( + "aspen_wood", + "default:aspen_wood", + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + {"default_aspen_wood.png"}, + "Aspen Wood Stair", + "Aspen Wood Slab", + default.node_sound_wood_defaults() +) -stairs.register_stair_and_slab("stone", "default:stone", - {cracky = 3}, - {"default_stone.png"}, - "Stone Stair", - "Stone Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "stone", + "default:stone", + {cracky = 3}, + {"default_stone.png"}, + "Stone Stair", + "Stone Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("cobble", "default:cobble", - {cracky = 3}, - {"default_cobble.png"}, - "Cobblestone Stair", - "Cobblestone Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "cobble", + "default:cobble", + {cracky = 3}, + {"default_cobble.png"}, + "Cobblestone Stair", + "Cobblestone Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("mossycobble", nil, - {cracky = 3}, - {"default_mossycobble.png"}, - "Mossy Cobblestone Stair", - "Mossy Cobblestone Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "mossycobble", + nil, + {cracky = 3}, + {"default_mossycobble.png"}, + "Mossy Cobblestone Stair", + "Mossy Cobblestone Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("stonebrick", "default:stonebrick", - {cracky = 3}, - {"default_stone_brick.png"}, - "Stone Brick Stair", - "Stone Brick Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "stonebrick", + "default:stonebrick", + {cracky = 2}, + {"default_stone_brick.png"}, + "Stone Brick Stair", + "Stone Brick Slab", + default.node_sound_stone_defaults() +) -stairs.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()) +stairs.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() +) -stairs.register_stair_and_slab("desert_stone", "default:desert_stone", - {cracky = 3}, - {"default_desert_stone.png"}, - "Desertstone Stair", - "Desertstone Slab", - default.node_sound_stone_defaults()) +stairs.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() +) -stairs.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()) +stairs.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() +) -stairs.register_stair_and_slab("desert_stonebrick", "default:desert_stonebrick", - {cracky = 3}, - {"default_desert_stone_brick.png"}, - "Desert Stone Brick Stair", - "Desert Stone Brick Slab", - default.node_sound_stone_defaults()) +stairs.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() +) -stairs.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()) +stairs.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() +) -stairs.register_stair_and_slab("sandstone", "default:sandstone", - {crumbly = 1, cracky = 3}, - {"default_sandstone.png"}, - "Sandstone Stair", - "Sandstone Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "sandstone", + "default:sandstone", + {crumbly = 1, cracky = 3}, + {"default_sandstone.png"}, + "Sandstone Stair", + "Sandstone Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("sandstonebrick", "default:sandstonebrick", - {cracky = 2}, - {"default_sandstone_brick.png"}, - "Sandstone Brick Stair", - "Sandstone Brick Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "sandstonebrick", + "default:sandstonebrick", + {cracky = 2}, + {"default_sandstone_brick.png"}, + "Sandstone Brick Stair", + "Sandstone Brick Slab", + default.node_sound_stone_defaults() +) -stairs.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()) +stairs.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() +) -stairs.register_stair_and_slab("obsidian", "default:obsidian", - {cracky = 1, level = 2}, - {"default_obsidian.png"}, - "Obsidian Stair", - "Obsidian Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "obsidian", + "default:obsidian", + {cracky = 1, level = 2}, + {"default_obsidian.png"}, + "Obsidian Stair", + "Obsidian Slab", + default.node_sound_stone_defaults() +) -stairs.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()) +stairs.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() +) -stairs.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()) +stairs.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() +) -stairs.register_stair_and_slab("brick", "default:brick", - {cracky = 3}, - {"default_brick.png"}, - "Brick Stair", - "Brick Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "brick", + "default:brick", + {cracky = 3}, + {"default_brick.png"}, + "Brick Stair", + "Brick Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("straw", "farming:straw", - {snappy = 3, flammable = 4}, - {"farming_straw.png"}, - "Straw Stair", - "Straw Slab", - default.node_sound_leaves_defaults()) +stairs.register_stair_and_slab( + "straw", + "farming:straw", + {snappy = 3, flammable = 4}, + {"farming_straw.png"}, + "Straw Stair", + "Straw Slab", + default.node_sound_leaves_defaults() +) -stairs.register_stair_and_slab("steelblock", "default:steelblock", - {cracky = 1, level = 2}, - {"default_steel_block.png"}, - "Steel Block Stair", - "Steel Block Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "steelblock", + "default:steelblock", + {cracky = 1, level = 2}, + {"default_steel_block.png"}, + "Steel Block Stair", + "Steel Block Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("copperblock", "default:copperblock", - {cracky = 1, level = 2}, - {"default_copper_block.png"}, - "Copper Block Stair", - "Copper Block Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "copperblock", + "default:copperblock", + {cracky = 1, level = 2}, + {"default_copper_block.png"}, + "Copper Block Stair", + "Copper Block Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("bronzeblock", "default:bronzeblock", - {cracky = 1, level = 2}, - {"default_bronze_block.png"}, - "Bronze Block Stair", - "Bronze Block Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "bronzeblock", + "default:bronzeblock", + {cracky = 1, level = 2}, + {"default_bronze_block.png"}, + "Bronze Block Stair", + "Bronze Block Slab", + default.node_sound_stone_defaults() +) -stairs.register_stair_and_slab("goldblock", "default:goldblock", - {cracky = 1}, - {"default_gold_block.png"}, - "Gold Block Stair", - "Gold Block Slab", - default.node_sound_stone_defaults()) +stairs.register_stair_and_slab( + "goldblock", + "default:goldblock", + {cracky = 1}, + {"default_gold_block.png"}, + "Gold Block Stair", + "Gold Block Slab", + default.node_sound_stone_defaults() +) From 6bf552eb10ff4ecdf27324d2a4d6a19a83b92a75 Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Wed, 18 May 2016 08:18:59 +0100 Subject: [PATCH 038/121] Creative: Document creative.formspec_add in game_api.txt --- game_api.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/game_api.txt b/game_api.txt index 93cf0527..ca090c4b 100644 --- a/game_api.txt +++ b/game_api.txt @@ -61,6 +61,11 @@ Beds API } } +Creative API +------------ + +A global string called `creative.formspec_add` was added which allows mods to add additional formspec elements onto the default creative inventory formspec to be drawn after each update. + Doors API --------- From be918d2d98b5af15f0d99b271e1e29e5c53fac2c Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Sun, 22 May 2016 10:31:21 +0100 Subject: [PATCH 039/121] Default: Craft locked chest from chest plus steel ingot --- mods/default/crafting.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mods/default/crafting.lua b/mods/default/crafting.lua index 0f10e7f9..11cdab76 100644 --- a/mods/default/crafting.lua +++ b/mods/default/crafting.lua @@ -365,6 +365,12 @@ minetest.register_craft({ } }) +minetest.register_craft( { + type = "shapeless", + output = "default:chest_locked", + recipe = {"default:chest", "default:steel_ingot"}, +}) + minetest.register_craft({ output = 'default:furnace', recipe = { From f15f35c6042e61f27c32eaad5d24a1b9c143110e Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Mon, 23 May 2016 08:02:48 +0100 Subject: [PATCH 040/121] Default: Enable crafting of mese crystal fragments into mese crystal --- mods/default/crafting.lua | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mods/default/crafting.lua b/mods/default/crafting.lua index 11cdab76..3bfce07c 100644 --- a/mods/default/crafting.lua +++ b/mods/default/crafting.lua @@ -610,6 +610,15 @@ minetest.register_craft({ } }) +minetest.register_craft({ + output = "default:mese_crystal", + recipe = { + {"default:mese_crystal_fragment", "default:mese_crystal_fragment", "default:mese_crystal_fragment"}, + {"default:mese_crystal_fragment", "default:mese_crystal_fragment", "default:mese_crystal_fragment"}, + {"default:mese_crystal_fragment", "default:mese_crystal_fragment", "default:mese_crystal_fragment"}, + } +}) + minetest.register_craft({ output = 'default:meselamp 1', recipe = { From 84e4ae1881504153f7c3c9011fc612bb1d0469a6 Mon Sep 17 00:00:00 2001 From: paramat Date: Tue, 21 Jun 2016 22:53:09 +0100 Subject: [PATCH 041/121] Default: New aspen tree schematics --- mods/default/schematics/aspen_tree.mts | Bin 179 -> 176 bytes .../schematics/aspen_tree_from_sapling.mts | Bin 171 -> 175 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/mods/default/schematics/aspen_tree.mts b/mods/default/schematics/aspen_tree.mts index 3bccd4b5722fa3ed955676592e74f64de4e1cd2f..724aae08d67834daea27dcfdcc9c2def13b435bd 100644 GIT binary patch delta 132 zcmdnYxPei^Hze4XfrWvUfscW;zTV!x9tiA#aH5E5a&p1~u7nonOGj6*COlKR?YK%p zD?w@YQI3>@XHuJPH^%eKj$R??cZFX(YiH-Tmq+dP+ufH_@0MT);W_d(LCBh$>)&JL kSO2dYUt#X7;t8v@ox!ql;k;-Lrc;MgMFLnD)QhZn0I*au5dZ)H delta 135 zcmV;20C@kf0kZ)VO;l4&00aO9015yFe}7+pe}8{pkr*{<fFKN8z1WV{qt8td zd6*c`_+yuq21?0-$P|!QY#LQb;_ZD4cUi-8(vxZ-eW0R89e2*4p3zHq@=$$6scs$2%umU58GKicbJSPAE diff --git a/mods/default/schematics/aspen_tree_from_sapling.mts b/mods/default/schematics/aspen_tree_from_sapling.mts index 6bf0f186595934f7e7118c0e5dfa6bb141543e4b..b7ca161903056454f78f4672000947d2ebf60035 100644 GIT binary patch delta 131 zcmZ3@xSmnMHze4XfrWvUfscW;zTV!x9tiA#aH5E5QgXrqu7nonOGj6*COlKR?YK%p zD?w@YQI3>@XHuJPH^%eKj$R??cZFX(YiH-Tmq+dP+ufH_@0MT);W_d(LCBh$>y_h? jdJFEU3|ef79Gz2HLw#ho3$RRSKdrHVgMs1rSu-909&|7c delta 127 zcmV-_0D%9m0jmKNO;l4&00aO9015yFe}7+pe}8{pkr*{%B{Du zvXQ9Mc(H`iECoU)G6d9$tl>fm-=B9jxsBcDF?9;2;1r5Nqx#A5jxX-GinsoQDM?Wy hRSGrs>CsFNYpz}M=F4x9Ips>DJD%L}8!X?2F9%7jI=BD; From f796194c6959ca4e560bfcb03f173e06a94755de Mon Sep 17 00:00:00 2001 From: paramat Date: Thu, 23 Jun 2016 03:06:57 +0100 Subject: [PATCH 042/121] Doors: Add dedicated sounds for glass doors Changed node sounds for steel door/trapdoor to stone defaults instead of wood defaults --- mods/doors/README.txt | 4 +++- mods/doors/init.lua | 6 ++++++ mods/doors/sounds/doors_glass_door_close.ogg | Bin 0 -> 7289 bytes mods/doors/sounds/doors_glass_door_open.ogg | Bin 0 -> 7288 bytes 4 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 mods/doors/sounds/doors_glass_door_close.ogg create mode 100644 mods/doors/sounds/doors_glass_door_open.ogg diff --git a/mods/doors/README.txt b/mods/doors/README.txt index b1c1363e..6c036782 100644 --- a/mods/doors/README.txt +++ b/mods/doors/README.txt @@ -75,7 +75,9 @@ fencegate_open.ogg: 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 +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 index a3ecd384..8d3e8472 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -434,6 +434,7 @@ doors.register("door_steel", { inventory_image = "doors_item_steel.png", protected = true, groups = { snappy = 1, bendy = 2, cracky = 1, melty = 2, level = 2 }, + sounds = default.node_sound_stone_defaults(), sound_open = "doors_steel_door_open", sound_close = "doors_steel_door_close", recipe = { @@ -449,6 +450,8 @@ doors.register("door_glass", { inventory_image = "doors_item_glass.png", groups = { snappy=1, cracky=1, oddly_breakable_by_hand=3 }, sounds = default.node_sound_glass_defaults(), + sound_open = "doors_glass_door_open", + sound_close = "doors_glass_door_close", recipe = { {"default:glass", "default:glass"}, {"default:glass", "default:glass"}, @@ -462,6 +465,8 @@ doors.register("door_obsidian_glass", { inventory_image = "doors_item_obsidian_glass.png", groups = { snappy=1, cracky=1, oddly_breakable_by_hand=3 }, sounds = default.node_sound_glass_defaults(), + sound_open = "doors_glass_door_open", + sound_close = "doors_glass_door_close", recipe = { {"default:obsidian_glass", "default:obsidian_glass"}, {"default:obsidian_glass", "default:obsidian_glass"}, @@ -626,6 +631,7 @@ doors.register_trapdoor("doors:trapdoor_steel", { tile_front = "doors_trapdoor_steel.png", tile_side = "doors_trapdoor_steel_side.png", protected = true, + sounds = default.node_sound_stone_defaults(), sound_open = "doors_steel_door_open", sound_close = "doors_steel_door_close", groups = {snappy=1, bendy=2, cracky=1, melty=2, level=2, door=1}, 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 0000000000000000000000000000000000000000..b3c135598e8a7c7a56d54e05c3ed7ceb006004ca GIT binary patch literal 7289 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 N#BKh$-tEoM{{YSn#=8Ij literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..66e6812d1877340c2f12ddeae02eae1f7c0e1cb1 GIT binary patch literal 7288 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 JtvWFX`X7uryYB!1 literal 0 HcmV?d00001 From 15b82f5b03228f0ded4760ed17934a726ca0003b Mon Sep 17 00:00:00 2001 From: HybridDog Date: Mon, 27 Jun 2016 14:02:44 +0200 Subject: [PATCH 043/121] Wool: Clean up code --- mods/wool/init.lua | 47 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/mods/wool/init.lua b/mods/wool/init.lua index f485e4fb..a36e4dd8 100644 --- a/mods/wool/init.lua +++ b/mods/wool/init.lua @@ -1,14 +1,8 @@ --- minetest/wool/init.lua - --- Backwards compatibility with jordach's 16-color wool mod -minetest.register_alias("wool:dark_blue", "wool:blue") -minetest.register_alias("wool:gold", "wool:yellow") - -local wool = {} -- This uses a trick: you can first define the recipes using all of the base -- colors, and then some recipes using more specific colors for a few non-base -- colors available. When crafting, the last recipes will be checked first. -wool.dyes = { + +local dyes = { {"white", "White", "basecolor_white"}, {"grey", "Grey", "basecolor_grey"}, {"black", "Black", "basecolor_black"}, @@ -26,25 +20,28 @@ wool.dyes = { {"dark_green", "Dark Green", "unicolor_dark_green"}, } -for _, row in ipairs(wool.dyes) do - local name = row[1] - local desc = row[2] - local craft_color_group = row[3] - -- Node Definition - minetest.register_node("wool:"..name, { - description = desc.." Wool", - tiles = {"wool_"..name..".png"}, +for i = 1, #dyes do + local name, desc, craft_color_group = unpack(dyes[i]) + + minetest.register_node("wool:" .. name, { + description = desc .. " Wool", + tiles = {"wool_" .. name .. ".png"}, is_ground_content = false, - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=3,flammable=3,wool=1}, + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 3, + flammable = 3, wool = 1}, sounds = default.node_sound_defaults(), }) - if craft_color_group then - -- Crafting from dye and white wool - minetest.register_craft({ - type = "shapeless", - output = 'wool:'..name, - recipe = {'group:dye,'..craft_color_group, 'group:wool'}, - }) - end + + minetest.register_craft{ + type = "shapeless", + output = "wool:" .. name, + recipe = {"group:dye," .. craft_color_group, "group:wool"}, + } end + +-- legacy + +-- Backwards compatibility with jordach's 16-color wool mod +minetest.register_alias("wool:dark_blue", "wool:blue") +minetest.register_alias("wool:gold", "wool:yellow") From 1231f726280decf506d36a25d5494302ebb31818 Mon Sep 17 00:00:00 2001 From: HybridDog Date: Mon, 27 Jun 2016 14:04:35 +0200 Subject: [PATCH 044/121] Wool: Use adv- and optipng to optimise texture files --- mods/wool/textures/wool_black.png | Bin 213 -> 209 bytes mods/wool/textures/wool_blue.png | Bin 269 -> 264 bytes mods/wool/textures/wool_cyan.png | Bin 305 -> 302 bytes mods/wool/textures/wool_dark_green.png | Bin 259 -> 254 bytes mods/wool/textures/wool_dark_grey.png | Bin 265 -> 260 bytes mods/wool/textures/wool_green.png | Bin 308 -> 304 bytes mods/wool/textures/wool_grey.png | Bin 315 -> 248 bytes mods/wool/textures/wool_magenta.png | Bin 301 -> 296 bytes mods/wool/textures/wool_orange.png | Bin 288 -> 284 bytes mods/wool/textures/wool_pink.png | Bin 221 -> 218 bytes mods/wool/textures/wool_red.png | Bin 292 -> 288 bytes mods/wool/textures/wool_violet.png | Bin 251 -> 244 bytes mods/wool/textures/wool_white.png | Bin 306 -> 243 bytes mods/wool/textures/wool_yellow.png | Bin 263 -> 255 bytes 14 files changed, 0 insertions(+), 0 deletions(-) diff --git a/mods/wool/textures/wool_black.png b/mods/wool/textures/wool_black.png index a9e566bbdaf336094fa1ad82e3622037da18b129..700d439dca261455e623c41db9b409d1f6afc46c 100644 GIT binary patch delta 145 zcmV;C0B--)0nq`FNPl!mL_t&t9Rp1_V1Qh;wKpUq3015yANkvXXu0mjfm^VRD delta 149 zcmV;G0BZly0o4JJNPl=qL_t&t*By*83dArB1ea4jpvHC3*}cJrw89BoFVF+7acxME z@5c$tHp4K;UaiOxQTxWknZY{0@PNQos#Sd3A=HpSljGgeDeMfS)#223Ks2p(8Ym!8 zxEOCO&W``uNGcbaL9$T9r%TrW#-IA*6~tmg)VCX@1Qh<3C=Pao00000NkvXXu0mjf D>lQ{F diff --git a/mods/wool/textures/wool_blue.png b/mods/wool/textures/wool_blue.png index 035a8da4dadaa094755c729ea9fb5ce083bf80c6..a07498673388d51341283862496692fd99158fe1 100644 GIT binary patch delta 192 zcmV;x06+hY0*C^T7zqdi0000eEe}(XAv}MUNkl)r(3_0VDlymB5OvQ);u1Z5=w$&Nz@r$ zV{99z_&;ao?(5#aG!624?zm~)Q#Rt6tdHuLGp|s!zKn{ z28IQb7Z@|BGYB!X8ub;0XkHa(2rRAiP%KsUV=!D`&Y;X?%)r2Ap0+8ckU^OtBD&YO zL$P!cgR;kL-=Ge`D-4Qk#%vqe1lbr83>OG9L~;o;yeph4+5WDX|%`2{A+}whD!8zAFd-5o#y!ZyA+^00000NkvXXu0mjf8NN-e diff --git a/mods/wool/textures/wool_cyan.png b/mods/wool/textures/wool_cyan.png index 4e1e4a3cda41aa425869a22608daac5cdca1f7cd..395b6ac77404f2c244ee34a9dfe5d89f452acddf 100644 GIT binary patch delta 196 zcmV;#06YJ&0YOa$D)vIgf_#7qmIweeiQa{6M*%4CTjl&z z&(RY85R^Hq*w6LMEZ4w-E{ZM%JrfNLIu?pH_=A;#_l_+ykil#&>gjbH^Nw-gbzmb2d&Ibua+5}<%0000T1WMdT8&t#93kAgB9ODH@g)Od;6EEV=(CdR#<9zaW?`;np1d377JDutwL z0qbgNYdND4&52csS`$GPLd^s#)VC!vedYUl`T?uX2MG*WY0v-w002ovPDHLkV1n4b BR>S}R diff --git a/mods/wool/textures/wool_dark_green.png b/mods/wool/textures/wool_dark_green.png index 92c563188dceea896acf7b676a04dcfb71435e16..0e73999eae3a20fae94b07c477625f09178da6ea 100644 GIT binary patch delta 188 zcmV;t07L(S0{#Jz7zqdi0000eEe}(XAvS-KNklj5+SC4csKNN#3iGhJ~D-q53Mbn;p^Ge%>hh qzRLBO@ooHn<^d9MHK>dCV*UUta0Da%-yO{W0000TO9R@Q+|MfNaaV#^T2$)pV` zG34RO9k8~x7gjbnQbv+e24_0i6(q3@27H87kaf_g{{DvGgbUp+4t^uT!a+gdHX vI$T^@$x4(sP33%M5GLp)8~DPtVLrxx--je2OOtx~00000NkvXXu0mjfzQ9*H diff --git a/mods/wool/textures/wool_dark_grey.png b/mods/wool/textures/wool_dark_grey.png index 0624525478e3ac6aaa8b154890e90614575bd19d..7253696edc72e9024268b46c95b2e445f0400cf2 100644 GIT binary patch delta 191 zcmV;w06_nV0)zsP7zqdi0000eEe}(XAvu4QNkl8HP$#y*ab8o2Efn2d@uF} zbBEqHsw?^e-488doUO1fntf^mH3&W+Q{U{&cUDNR<>v$L4XqLf4wmpZW^w}An!PL2 tYVUw=@*M0W^B>StL@lc8V_D#~z8_#81d>RdQ_lbZ002ovPDHLkV1nV`P__U7 delta 196 zcmV;#06YJL0*L~U7zqRe0002(-QrS_Avu4VNkl<~SySR84}pt(xPg)v3J zg<;!-EetNAE{Y81j6H$HlI^MtMd6XgLg4~73`|>CT?D)t+!)+gS21P+l=d)m z2!&5%5HOxU>c*FB15H6`^Dmb6S@GfZYN+~t0P1J00008bmVS_#o}O8P>IKX;9U)G=g2 zE)6jNmVp^)f~o9kdcLLplzLneRg$OrY?b7i0Om(g(d~BMP9$uVK002ovPDHLkV1g?-Tk-$^ delta 199 zcmV;&0671!0<;2H~l4NKHu7I_?bwF)wqsy??;Pz?|vlz^T zEJ2=HOl$1{g&9E29LuR$A~Hp2iuCHmYPWnJT|b=H2OfWt`a}Q#002ovPDHLkV1n-G BVLAW+ diff --git a/mods/wool/textures/wool_grey.png b/mods/wool/textures/wool_grey.png index ff38bf7c41b013146c55f74b703cfcc76112e732..2f4c338078ddaf11ab3cef8682fc247d803ffe32 100644 GIT binary patch delta 231 zcmVeX3;7z*f}WH^ zltV`^1sn>iml#jjjDW>4i&w&JJdeTmU<6Dw>&$7boWY?t1YlN5pDigq<;&Cr47U}} z!}i@%E}xIFZZ^EJ7y!CQ&;xmT&A%$n7#R#12G5#P#Z|dKAEk(|4mCjEF`378Gl6I$af{I%~dnF#vnx$ zN$4Ud=jBCIr65Zo(9F^A8~|$@Ga{B(YlsUyZYTrHuz>=ekfix}qH<*Z->`18Z};B+ z=mMavty#C>+g|PpFp$eLc_w}&A)Owz^dxpkc@_7ac^Of^m$!q&Ji4hK2eek_v0}?e x)yBvw4^Rq50whx8Ob$r|Y=PZgSe?E%KR z$w-3QM}6&tjUjRxC~!6S6S(}~a9EiTb3|f_;`>rE#M-Dfx;hAMU!mGNwKXffLi_d> vd#A$5IkBB|H-j7DLPTX*A&mCyobvkvc`gQ@Sdap+00000NkvXXu0mjfS`1XN delta 198 zcmV;%06G7t0<8j&Z-1#tL_t&-(+!MC4g?_#1D%~68s`6Rog@cKma9-`9r|8l@^Nbm zl)86eK*+!fV4~`T2tXgegyBl-1$n1>oC99Mzd8nSxJrMJl0c4CFcZu(3A0r0j{y?+ z^1F`eTAEN$c74>_j_VlAr-3*jh22d4!SXe=tOgHE7Q7e9vOl&_b#!KYeYr^QB&})b z71Fmg-#Y|GG$(e3nWk1LwFIwJmNR*~dQSQM0eLP4pD&kNS^xk507*qoM6N<$g2qEu A+yDRo diff --git a/mods/wool/textures/wool_orange.png b/mods/wool/textures/wool_orange.png index 64f34c003fe5fa79046572672cfbfbebcf3e5182..a059f3646f4043897ef1315584cf8e3e9cdb540f 100644 GIT binary patch delta 187 zcmV;s07UunOsZNGxiTO0E)CTA3v3Ex*%Vd}4GTr=$ZA~f?}sCVHui7wC$hz7hcMBkbdzd!ys1;jKKR)hcm002ovPDHLkV1oI)Q0V{w delta 191 zcmV;w06_no0-yqrX@8ELeiNS<9t2FTD^ zPat?~HK~5_AMZhxH*+}CWn5hxPj3I^sSlmIB8(w4g51#UF~==y{Lvg!wMrO~mM&xC z4$-2<-gn#N!bc~r=>E-IVQ8A^ZJQ< tOX1{NxK6s8!HsYsqA5F)afW@LQuLJBlqWeZ{u%+xFm&Tu{Bt&RxB&vy?O}V>#cj!T|9;EsGl6mMaCf6TX_Uz x9NT_Q7Z}l;I0Z9Rm=cT$9>mKV`A+>lZa-ka26}phLe2mH002ovPDHLkV1mdDQs)2w diff --git a/mods/wool/textures/wool_violet.png b/mods/wool/textures/wool_violet.png index a41a9f4714c472e19ab185a434f4346238cfcddf..d7d67831e227ae0a7ea47e76175c4898945d9233 100644 GIT binary patch delta 181 zcmV;m080P+0rUZo7zqdi0000eEe}(XAv1rANkly!tO4!)E|0&T9E0nj&jDyN#6Gp zwLfY9r38EK_Kn&bZd0t0JQD{v>t)edk&k>|+NFA@b_4km>c$ft=1j*-x>IFoPB9_x jdi0VI0o#q})V=Tn;}-*}!+E9>B6bNNBzPADRXvmlTqLr0QGi}$`M zo+Vb!joyU|m?{eYg{~q$S_;_JcQbj{B8>HUJK+VdjA8|i%p~%L1ir14qrCx#WCkcP qaF1o|qg5T@>SL!_18XGN*cm^6%O2@&awhNq0000b>*?OS@Azh%aw;=u%%J$B9? zQ*t8?1DjTPCgi%>tTtWWilTGMr>}LW4yYou3d%~gwHlc2=g3MQneIC=m@&lah}Wi@ ccHDRT{_7{)9#3m&y8r+H07*qoM6N<$f`eIVn*aa+ delta 290 zcmV+-0p0%d0kQ&+8Gi!+001a04^sdD076hqR7Kp}-1GDE;o;%l-rmp8&+qT=&CSiy z($e7I;N#=t$jHdl)YSF$_1W3k@$vEN>+8eA!`9Z;zrVk;v$MOqyXEEOGriAW00021 zNkl;+nqg>w{Xie%I6x3sr?8hI=TS>JynS!ZjG$MC%~uGM?8+lEe+ZUx*0`>w8gXF4X* o^RR}r@}?Cms^pVKHN3Cy4+_Tv?*Z*r(f|Me07*qoM6N<$f-59c3;+NC delta 194 zcmV;z06qWz0fz#R7zqRe0002(-QrS_Avu4TNklw=l`}~*3o0;pI?Q31 zshpC;pwQtEAlmWw?+@o wLv|;KE3INER4P{j+G@n$qCCaOmEnvv0Q<)vmRNr24gdfE07*qoM6N<$f=JFzi2wiq From 55fd28608339cd4fddfc3a378dec10dbc8ab7bda Mon Sep 17 00:00:00 2001 From: Thomas--S Date: Thu, 30 Jun 2016 19:08:55 +0200 Subject: [PATCH 045/121] Doors: Remove use_texture_alpha from door definition --- mods/doors/init.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index 8d3e8472..343a7772 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -399,7 +399,6 @@ function doors.register(name, def) def.paramtype = "light" def.paramtype2 = "facedir" def.sunlight_propagates = true - def.use_texture_alpha = true def.walkable = true def.is_ground_content = false def.buildable_to = false From f4f9e58ef2b537a65654c76ad99486cf4e7e497a Mon Sep 17 00:00:00 2001 From: paramat Date: Thu, 30 Jun 2016 22:16:46 +0100 Subject: [PATCH 046/121] Flowers: Make waterlily floodable When waterlilies are placed near river water source make flowing river water remove waterlilies instead of flowing around them in an ugly way --- mods/flowers/init.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/flowers/init.lua b/mods/flowers/init.lua index 2f3cfe1b..2de575fe 100644 --- a/mods/flowers/init.lua +++ b/mods/flowers/init.lua @@ -224,6 +224,7 @@ minetest.register_node("flowers:waterlily", { walkable = false, buildable_to = true, sunlight_propagates = true, + floodable = true, groups = {snappy = 3, flower = 1}, sounds = default.node_sound_leaves_defaults(), node_placement_prediction = "", From 80d49095f5decc3407275016612abc275da601a9 Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Sun, 3 Jul 2016 17:40:43 +0100 Subject: [PATCH 047/121] Tidy sethome code, add global functions, round coords to 1 decimal - Global functions sethome.set(name, pos) , sethome.get(name) and sethome.go(name) - Tidy: trim coords to one decimal place and write to table and output table in one go. - Add error checking - Add t4im's homepos loader --- mods/sethome/init.lua | 115 ++++++++++++++++++++++++------------------ 1 file changed, 65 insertions(+), 50 deletions(-) diff --git a/mods/sethome/init.lua b/mods/sethome/init.lua index 590086b4..4246f7a5 100644 --- a/mods/sethome/init.lua +++ b/mods/sethome/init.lua @@ -1,65 +1,80 @@ + +sethome = {} + local homes_file = minetest.get_worldpath() .. "/homes" local homepos = {} local function loadhomes() - local input = io.open(homes_file, "r") - if input 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") - homepos[name:sub(2)] = {x = x, y = y, z = z} - until input:read(0) == nil - io.close(input) - else - homepos = {} - end + local input, err = io.open(homes_file, "r") + if not input then + return minetest.log("info", "Could not load player homes file: " .. err) + 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 data = {} + local output, err = io.open(homes_file, "w") + if output then + homepos[name] = pos + 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 + minetest.log("action", "Unable to write to player homes file: " .. err) + return false +end + +sethome.get = function(name) + return homepos[name] +end + +sethome.go = function(name) + local player = minetest.get_player_by_name(name) + if player and homepos[name] then + player:setpos(homepos[name]) + return true + end + return false +end + minetest.register_privilege("home", "Can use /sethome and /home") -local changed = false - minetest.register_chatcommand("home", { - description = "Teleport you to your home point", - privs = {home=true}, - func = function(name) - local player = minetest.get_player_by_name(name) - if player == nil then - -- just a check to prevent the server crashing - return false - end - if homepos[player:get_player_name()] then - player:setpos(homepos[player:get_player_name()]) - minetest.chat_send_player(name, "Teleported to home!") - else - minetest.chat_send_player(name, "Set a home using /sethome") - end - end, + description = "Teleport you to your home point", + privs = {home = true}, + func = function(name) + if sethome.go(name) then + return true, "Teleported to home!" + end + return false, "Set a home using /sethome" + end, }) minetest.register_chatcommand("sethome", { - description = "Set your home point", - privs = {home=true}, - func = function(name) - local player = minetest.get_player_by_name(name) - local pos = player:getpos() - homepos[player:get_player_name()] = pos - minetest.chat_send_player(name, "Home set!") - changed = true - if changed then - local output = io.open(homes_file, "w") - for i, v in pairs(homepos) do - output:write(v.x.." "..v.y.." "..v.z.." "..i.."\n") - end - io.close(output) - changed = false - end - end, + description = "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:getpos()) then + return true, "Home set!" + end + return false, "Player not found!" + end, }) From 21b457c9e1df74f6e0a38bf44eaf6f3a05bdf232 Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Fri, 1 Jul 2016 17:45:24 +0200 Subject: [PATCH 048/121] Bucket: Correct liquid placing in protected areas - Placing liquid inside a protected area no longer returns an empty bucket - Remove on_place function, tidy up code, return proper itemstack - Shorten code (changes from HybridDog/patch-35) --- mods/bucket/init.lua | 51 +++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/mods/bucket/init.lua b/mods/bucket/init.lua index 89730de7..2d2690fe 100644 --- a/mods/bucket/init.lua +++ b/mods/bucket/init.lua @@ -52,54 +52,57 @@ function bucket.register_liquid(source, flowing, itemname, inventory_image, name 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 - if node then - ndef = minetest.registered_nodes[node.name] + if not node then + return end + local ndef = minetest.registered_nodes[node.name] + if not ndef then + return + end + -- Call on_rightclick if the pointed node defines it - if ndef and ndef.on_rightclick and + if ndef.on_rightclick and user and not user:get_player_control().sneak then return ndef.on_rightclick( pointed_thing.under, node, user, - itemstack) or itemstack + itemstack) end - local place_liquid = function(pos, node, source, flowing) - if check_protection(pos, - user and user:get_player_name() or "", - "place "..source) then - return - end - minetest.add_node(pos, {name=source}) - end + local lpos -- Check if pointing to a buildable node - if ndef and ndef.buildable_to then + if ndef.buildable_to then -- buildable; replace the node - place_liquid(pointed_thing.under, node, - source, flowing) + lpos = pointed_thing.under else -- not buildable to; place the liquid above -- check if the node above can be replaced - local node = minetest.get_node_or_nil(pointed_thing.above) - if node and minetest.registered_nodes[node.name].buildable_to then - place_liquid(pointed_thing.above, - node, source, - flowing) - else + lpos = pointed_thing.above + local node = minetest.get_node_or_nil(lpos) + if not node + or not minetest.registered_nodes[node.name].buildable_to then -- do not remove the bucket with the liquid return end end - return {name="bucket:bucket_empty"} + + 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 From 1886d293d750425e250d65270385b30515d20f26 Mon Sep 17 00:00:00 2001 From: paramat Date: Sat, 2 Jul 2016 04:10:29 +0100 Subject: [PATCH 049/121] Default/mapgen: Clean up ore registrations Re-order registrations Add and improve comments Change sand blob ymax to 0 as sand does not always rise above 0 Remove dirt blobs from sandstone as it is unsuitable for many sandstone biomes and ugly in stony sandstone desert Change ymax of first iron region to 0 --- mods/default/mapgen.lua | 92 +++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 44 deletions(-) diff --git a/mods/default/mapgen.lua b/mods/default/mapgen.lua index c84aa7b4..7e803205 100644 --- a/mods/default/mapgen.lua +++ b/mods/default/mapgen.lua @@ -42,12 +42,12 @@ minetest.register_alias("mapgen_stair_sandstonebrick", "stairs:stair_sandstonebr -- Register ores -- --- All mapgens except singlenode --- Blob ore first to avoid other ores inside blobs - function default.register_ores() + -- Blob ores + -- These first to avoid other ores in blobs -- Clay + -- This first to avoid clay in sand blobs minetest.register_ore({ ore_type = "blob", @@ -78,7 +78,7 @@ function default.register_ores() clust_scarcity = 16 * 16 * 16, clust_size = 5, y_min = -31, - y_max = 4, + y_max = 0, noise_threshold = 0.0, noise_params = { offset = 0.5, @@ -95,7 +95,7 @@ function default.register_ores() minetest.register_ore({ ore_type = "blob", ore = "default:dirt", - wherein = {"default:stone", "default:sandstone"}, + wherein = {"default:stone"}, clust_scarcity = 16 * 16 * 16, clust_size = 5, y_min = -31, @@ -132,6 +132,8 @@ function default.register_ores() }, }) + -- Scatter ores + -- Coal minetest.register_ore({ @@ -166,7 +168,7 @@ function default.register_ores() clust_num_ores = 3, clust_size = 2, y_min = -15, - y_max = 2, + y_max = 0, }) minetest.register_ore({ @@ -202,39 +204,28 @@ function default.register_ores() y_max = -64, }) - --Mese + -- Copper minetest.register_ore({ ore_type = "scatter", - ore = "default:stone_with_mese", + ore = "default:stone_with_copper", wherein = "default:stone", - clust_scarcity = 18 * 18 * 18, - clust_num_ores = 3, - clust_size = 2, - y_min = -255, - y_max = -64, + clust_scarcity = 12 * 12 * 12, + clust_num_ores = 4, + clust_size = 3, + y_min = -63, + y_max = -16, }) minetest.register_ore({ ore_type = "scatter", - ore = "default:stone_with_mese", + ore = "default:stone_with_copper", wherein = "default:stone", - clust_scarcity = 14 * 14 * 14, + clust_scarcity = 9 * 9 * 9, clust_num_ores = 5, clust_size = 3, y_min = -31000, - y_max = -256, - }) - - minetest.register_ore({ - ore_type = "scatter", - ore = "default:mese", - wherein = "default:stone", - clust_scarcity = 36 * 36 * 36, - clust_num_ores = 3, - clust_size = 2, - y_min = -31000, - y_max = -1024, + y_max = -64, }) -- Gold @@ -261,6 +252,30 @@ function default.register_ores() y_max = -256, }) + -- Mese crystal + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_mese", + wherein = "default:stone", + clust_scarcity = 18 * 18 * 18, + clust_num_ores = 3, + clust_size = 2, + y_min = -255, + y_max = -64, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_mese", + wherein = "default:stone", + clust_scarcity = 14 * 14 * 14, + clust_num_ores = 5, + clust_size = 3, + y_min = -31000, + y_max = -256, + }) + -- Diamond minetest.register_ore({ @@ -285,28 +300,17 @@ function default.register_ores() y_max = -256, }) - -- Copper + -- Mese block minetest.register_ore({ ore_type = "scatter", - ore = "default:stone_with_copper", + ore = "default:mese", wherein = "default:stone", - clust_scarcity = 12 * 12 * 12, - clust_num_ores = 4, - clust_size = 3, - y_min = -63, - y_max = -16, - }) - - minetest.register_ore({ - ore_type = "scatter", - ore = "default:stone_with_copper", - wherein = "default:stone", - clust_scarcity = 9 * 9 * 9, - clust_num_ores = 5, - clust_size = 3, + clust_scarcity = 36 * 36 * 36, + clust_num_ores = 3, + clust_size = 2, y_min = -31000, - y_max = -64, + y_max = -1024, }) end From d476d017a497fad925ef4cab75694be045b78dbe Mon Sep 17 00:00:00 2001 From: paramat Date: Sun, 3 Jul 2016 07:33:48 +0100 Subject: [PATCH 050/121] Default/mapgen: Add ores above y = 1024 Each ore's rarity is equal to that occuring below y= -1024 --- mods/default/mapgen.lua | 77 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/mods/default/mapgen.lua b/mods/default/mapgen.lua index 7e803205..dc359a0b 100644 --- a/mods/default/mapgen.lua +++ b/mods/default/mapgen.lua @@ -136,6 +136,17 @@ function default.register_ores() -- Coal + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_coal", + wherein = "default:stone", + clust_scarcity = 8 * 8 * 8, + clust_num_ores = 9, + clust_size = 3, + y_min = 1025, + y_max = 31000, + }) + minetest.register_ore({ ore_type = "scatter", ore = "default:stone_with_coal", @@ -160,6 +171,17 @@ function default.register_ores() -- Iron + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_iron", + wherein = "default:stone", + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 12, + clust_size = 3, + y_min = 1025, + y_max = 31000, + }) + minetest.register_ore({ ore_type = "scatter", ore = "default:stone_with_iron", @@ -206,6 +228,17 @@ function default.register_ores() -- Copper + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_copper", + wherein = "default:stone", + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 5, + clust_size = 3, + y_min = 1025, + y_max = 31000, + }) + minetest.register_ore({ ore_type = "scatter", ore = "default:stone_with_copper", @@ -230,6 +263,17 @@ function default.register_ores() -- Gold + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_gold", + wherein = "default:stone", + clust_scarcity = 13 * 13 * 13, + clust_num_ores = 5, + clust_size = 3, + y_min = 1025, + y_max = 31000, + }) + minetest.register_ore({ ore_type = "scatter", ore = "default:stone_with_gold", @@ -254,6 +298,17 @@ function default.register_ores() -- Mese crystal + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_mese", + wherein = "default:stone", + clust_scarcity = 14 * 14 * 14, + clust_num_ores = 5, + clust_size = 3, + y_min = 1025, + y_max = 31000, + }) + minetest.register_ore({ ore_type = "scatter", ore = "default:stone_with_mese", @@ -278,6 +333,17 @@ function default.register_ores() -- Diamond + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_diamond", + wherein = "default:stone", + clust_scarcity = 15 * 15 * 15, + clust_num_ores = 4, + clust_size = 3, + y_min = 1025, + y_max = 31000, + }) + minetest.register_ore({ ore_type = "scatter", ore = "default:stone_with_diamond", @@ -302,6 +368,17 @@ function default.register_ores() -- Mese block + minetest.register_ore({ + ore_type = "scatter", + ore = "default:mese", + wherein = "default:stone", + clust_scarcity = 36 * 36 * 36, + clust_num_ores = 3, + clust_size = 2, + y_min = 1025, + y_max = 31000, + }) + minetest.register_ore({ ore_type = "scatter", ore = "default:mese", From d42f77cc5fd0d45997adfded2f26882e5328ff77 Mon Sep 17 00:00:00 2001 From: paramat Date: Sun, 3 Jul 2016 08:52:53 +0100 Subject: [PATCH 051/121] Default/mapgen: Simplify iron ore registrations Preserve overlapping registrations of large and small clusters below y = -64 but now extend the small clusters up to y = 0 (the previous highest iron ore level) in a similar to way to coal --- mods/default/mapgen.lua | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/mods/default/mapgen.lua b/mods/default/mapgen.lua index dc359a0b..89ded047 100644 --- a/mods/default/mapgen.lua +++ b/mods/default/mapgen.lua @@ -182,28 +182,6 @@ function default.register_ores() y_max = 31000, }) - minetest.register_ore({ - ore_type = "scatter", - ore = "default:stone_with_iron", - wherein = "default:stone", - clust_scarcity = 12 * 12 * 12, - clust_num_ores = 3, - clust_size = 2, - y_min = -15, - y_max = 0, - }) - - minetest.register_ore({ - ore_type = "scatter", - ore = "default:stone_with_iron", - wherein = "default:stone", - clust_scarcity = 9 * 9 * 9, - clust_num_ores = 5, - clust_size = 3, - y_min = -63, - y_max = -16, - }) - minetest.register_ore({ ore_type = "scatter", ore = "default:stone_with_iron", @@ -212,7 +190,7 @@ function default.register_ores() clust_num_ores = 5, clust_size = 3, y_min = -31000, - y_max = -64, + y_max = 0, }) minetest.register_ore({ From c5b0fe72ea47c9c2ede2d0097e53e6c0a7c514f6 Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Mon, 4 Jul 2016 09:12:37 +0100 Subject: [PATCH 052/121] Game_api.txt: Add API information for sethome functions - Documentation for sethome.get, sethome.set and sethome.go --- game_api.txt | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/game_api.txt b/game_api.txt index ca090c4b..e80b2043 100644 --- a/game_api.txt +++ b/game_api.txt @@ -338,6 +338,30 @@ To use it, add the `on_screwdriver` function to the node definition. * use `on_rotate = screwdriver.disallow` to always disallow rotation * use `on_rotate = screwdriver.rotate_simple` to allow only face rotation + +Sethome API +----------- + +The sethome API adds three global functions to allow mods to read a players home position, +set a players home position and teleport a player to home position. + +`sethome.get(name)` + + * `name` Player who's home position you wish to get + * return value: false if no player home coords exist, position table if true + +`sethome.set(name, pos)` + + * `name` Player who's home position you wish to set + * `pos` Position table containing coords of home position + * return value: false if unable to set and save new home position, otherwise true + +`sethome.go(name)` + + * `name` Player you wish to teleport to their home position + * return value: false if player cannot be sent home, otherwise true + + Stairs API ---------- From 98551edd942f1dd7a2c597e4ac4ba6504ebcdd93 Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Mon, 4 Jul 2016 11:59:07 +0100 Subject: [PATCH 053/121] Game_api.txt: Add position table reference --- game_api.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/game_api.txt b/game_api.txt index e80b2043..e04a33b4 100644 --- a/game_api.txt +++ b/game_api.txt @@ -12,6 +12,7 @@ Please note: * [XYZ] refers to a section the Minetest API * [#ABC] refers to a section in this document + * [pos] refers to a position table `{x = -5, y = 0, z = 200}` Bucket API ---------- From 497e6f6257d3f126fb4c578e84fb79e3d31b5c46 Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Mon, 27 Jun 2016 16:45:40 +0200 Subject: [PATCH 054/121] TNT: When disabled leave some useful functionality enabled - Only remove the TNT craft recipe, tnt:tnt node and the ABM - Leave tnt:tnt_burning available for explosions in 3rd party mods --- mods/tnt/init.lua | 93 ++++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/mods/tnt/init.lua b/mods/tnt/init.lua index 9fd97f49..a481ae95 100644 --- a/mods/tnt/init.lua +++ b/mods/tnt/init.lua @@ -1,10 +1,8 @@ tnt = {} --- Default to enabled in singleplayer and disabled in multiplayer -local singleplayer = minetest.is_singleplayer() -local setting = minetest.setting_getbool("enable_tnt") -if (not singleplayer and setting ~= true) or - (singleplayer and setting == false) then - return +-- Default to enabled when in singleplayer +local enable_tnt = minetest.setting_getbool("enable_tnt") +if enable_tnt == nil + enable_tnt = minetest.is_singleplayer() end -- loss probabilities array (one in X will be lost) @@ -492,28 +490,30 @@ minetest.register_node("tnt:gunpowder_burning", { end, }) -minetest.register_abm({ - nodenames = {"group:tnt", "tnt:gunpowder"}, - neighbors = {"fire:basic_flame", "default:lava_source", "default:lava_flowing"}, - interval = 4, - chance = 1, - action = tnt.burn, -}) - minetest.register_craft({ output = "tnt:gunpowder", type = "shapeless", recipe = {"default:coal_lump", "default:gravel"} }) -minetest.register_craft({ - output = "tnt:tnt", - recipe = { - {"", "group:wood", ""}, - {"group:wood", "tnt:gunpowder", "group:wood"}, - {"", "group:wood", ""} - } -}) +if enable_tnt then + minetest.register_craft({ + output = "tnt:tnt", + recipe = { + {"", "group:wood", ""}, + {"group:wood", "tnt:gunpowder", "group:wood"}, + {"", "group:wood", ""} + } + }) + + minetest.register_abm({ + nodenames = {"group:tnt", "tnt:gunpowder"}, + neighbors = {"fire:basic_flame", "default:lava_source", "default:lava_flowing"}, + interval = 4, + chance = 1, + action = tnt.burn, + }) +end function tnt.register_tnt(def) local name = "" @@ -530,30 +530,32 @@ function tnt.register_tnt(def) local tnt_burning = def.tiles.burning or def.name .. "_top_burning_animated.png" if not def.damage_radius then def.damage_radius = def.radius * 2 end - minetest.register_node(":" .. name, { - description = def.description, - tiles = {tnt_top, tnt_bottom, tnt_side}, - is_ground_content = false, - groups = {dig_immediate = 2, mesecon = 2, tnt = 1}, - sounds = default.node_sound_wood_defaults(), - on_punch = function(pos, node, puncher) - if puncher:get_wielded_item():get_name() == "default:torch" then - minetest.set_node(pos, {name = name .. "_burning"}) - end - end, - on_blast = function(pos, intensity) - minetest.after(0.1, function() - tnt.boom(pos, def) - end) - end, - mesecons = {effector = - {action_on = - function(pos) - tnt.boom(pos, def) + if enable_tnt then + minetest.register_node(":" .. name, { + description = def.description, + tiles = {tnt_top, tnt_bottom, tnt_side}, + is_ground_content = false, + groups = {dig_immediate = 2, mesecon = 2, tnt = 1}, + sounds = default.node_sound_wood_defaults(), + on_punch = function(pos, node, puncher) + if puncher:get_wielded_item():get_name() == "default:torch" then + minetest.set_node(pos, {name = name .. "_burning"}) end - } - }, - }) + end, + on_blast = function(pos, intensity) + minetest.after(0.1, function() + tnt.boom(pos, def) + end) + end, + mesecons = {effector = + {action_on = + function(pos) + tnt.boom(pos, def) + end + } + }, + }) + end minetest.register_node(":" .. name .. "_burning", { tiles = { @@ -590,4 +592,3 @@ tnt.register_tnt({ description = "TNT", radius = radius, }) - From f17d7911737ea553fa63aeaafa9ef5b7a60d608d Mon Sep 17 00:00:00 2001 From: paramat Date: Wed, 6 Jul 2016 17:14:39 +0100 Subject: [PATCH 055/121] Default, flowers: Use 'get_mapgen_setting()' --- mods/default/mapgen.lua | 6 +++--- mods/flowers/mapgen.lua | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mods/default/mapgen.lua b/mods/default/mapgen.lua index 89ded047..7d0b0fd4 100644 --- a/mods/default/mapgen.lua +++ b/mods/default/mapgen.lua @@ -1523,12 +1523,12 @@ end -- Mods using singlenode mapgen can call these functions to enable -- the use of minetest.generate_ores or minetest.generate_decorations -local mg_params = minetest.get_mapgen_params() -if mg_params.mgname == "v6" then +local mg_name = minetest.get_mapgen_setting("mg_name") +if mg_name == "v6" then default.register_ores() default.register_mgv6_decorations() minetest.register_on_generated(default.generate_nyancats) -elseif mg_params.mgname ~= "singlenode" then +elseif mg_name ~= "singlenode" then default.register_biomes() default.register_ores() default.register_decorations() diff --git a/mods/flowers/mapgen.lua b/mods/flowers/mapgen.lua index 59ce97a3..162b11db 100644 --- a/mods/flowers/mapgen.lua +++ b/mods/flowers/mapgen.lua @@ -165,9 +165,9 @@ end -- Mods using singlenode mapgen can call these functions to enable -- the use of minetest.generate_ores or minetest.generate_decorations -local mg_params = minetest.get_mapgen_params() -if mg_params.mgname == "v6" then +local mg_name = minetest.get_mapgen_setting("mg_name") +if mg_name == "v6" then flowers.register_mgv6_decorations() -elseif mg_params.mgname ~= "singlenode" then +elseif mg_name ~= "singlenode" then flowers.register_decorations() end From 60f6564c753494dcb8597ba8d67a4202cc8601c4 Mon Sep 17 00:00:00 2001 From: paramat Date: Thu, 7 Jul 2016 17:25:42 +0100 Subject: [PATCH 056/121] Doors / default: Remove 'hot', 'bendy' and 'melty' groups from nodes --- mods/default/nodes.lua | 6 +++--- mods/doors/init.lua | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua index 494a4cb1..bfc0898e 100644 --- a/mods/default/nodes.lua +++ b/mods/default/nodes.lua @@ -1360,7 +1360,7 @@ minetest.register_node("default:lava_source", { liquid_renewable = false, damage_per_second = 4 * 2, post_effect_color = {a = 191, r = 255, g = 64, b = 0}, - groups = {lava = 3, liquid = 2, hot = 3, igniter = 1}, + groups = {lava = 3, liquid = 2, igniter = 1}, }) minetest.register_node("default:lava_flowing", { @@ -1406,7 +1406,7 @@ minetest.register_node("default:lava_flowing", { liquid_renewable = false, damage_per_second = 4 * 2, post_effect_color = {a = 191, r = 255, g = 64, b = 0}, - groups = {lava = 3, liquid = 2, hot = 3, igniter = 1, + groups = {lava = 3, liquid = 2, igniter = 1, not_in_creative_inventory = 1}, }) @@ -1862,7 +1862,7 @@ minetest.register_node("default:rail", { -- but how to specify the dimensions for curved and sideways rails? fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2}, }, - groups = {bendy = 2, dig_immediate = 2, attached_node = 1, + groups = {dig_immediate = 2, attached_node = 1, connect_to_raillike = minetest.raillike_group("rail")}, }) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index 343a7772..913f7cf2 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -432,7 +432,7 @@ doors.register("door_steel", { description = "Steel Door", inventory_image = "doors_item_steel.png", protected = true, - groups = { snappy = 1, bendy = 2, cracky = 1, melty = 2, level = 2 }, + groups = { snappy = 1, cracky = 1, level = 2 }, sounds = default.node_sound_stone_defaults(), sound_open = "doors_steel_door_open", sound_close = "doors_steel_door_close", @@ -633,7 +633,7 @@ doors.register_trapdoor("doors:trapdoor_steel", { sounds = default.node_sound_stone_defaults(), sound_open = "doors_steel_door_open", sound_close = "doors_steel_door_close", - groups = {snappy=1, bendy=2, cracky=1, melty=2, level=2, door=1}, + groups = {snappy=1, cracky=1, level=2, door=1}, }) minetest.register_craft({ From 3d44804074035efcc88d6dfde6b06ec276ffe5ca Mon Sep 17 00:00:00 2001 From: paramat Date: Thu, 7 Jul 2016 17:48:02 +0100 Subject: [PATCH 057/121] Doors: Code cleanup Remove spaces inside curly brackets Split lines over 90 columns --- mods/doors/init.lua | 120 ++++++++++++++++++++++++-------------------- 1 file changed, 66 insertions(+), 54 deletions(-) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index 913f7cf2..f21381fe 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -1,4 +1,3 @@ - --[[ Copyright (C) 2012 PilzAdam @@ -105,28 +104,28 @@ minetest.register_node("doors:hidden", { -- 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 = "_a", param2 = 3}, + {v = "_a", param2 = 0}, + {v = "_a", param2 = 1}, + {v = "_a", param2 = 2}, }, { - { v = "_b", param2 = 1 }, - { v = "_b", param2 = 2 }, - { v = "_b", param2 = 3 }, - { v = "_b", param2 = 0 }, + {v = "_b", param2 = 1}, + {v = "_b", param2 = 2}, + {v = "_b", param2 = 3}, + {v = "_b", param2 = 0}, }, { - { v = "_b", param2 = 1 }, - { v = "_b", param2 = 2 }, - { v = "_b", param2 = 3 }, - { v = "_b", param2 = 0 }, + {v = "_b", param2 = 1}, + {v = "_b", param2 = 2}, + {v = "_b", param2 = 3}, + {v = "_b", param2 = 0}, }, { - { v = "_a", param2 = 3 }, - { v = "_a", param2 = 0 }, - { v = "_a", param2 = 1 }, - { v = "_a", param2 = 2 }, + {v = "_a", param2 = 3}, + {v = "_a", param2 = 0}, + {v = "_a", param2 = 1}, + {v = "_a", param2 = 2}, }, } @@ -166,9 +165,11 @@ function _doors.door_toggle(pos, clicker) local dir = minetest.get_node(pos).param2 if state % 2 == 0 then - minetest.sound_play(def.door.sounds[1], {pos = pos, gain = 0.3, max_hear_distance = 10}) + minetest.sound_play(def.door.sounds[1], + {pos = pos, gain = 0.3, max_hear_distance = 10}) else - minetest.sound_play(def.door.sounds[2], {pos = pos, gain = 0.3, max_hear_distance = 10}) + minetest.sound_play(def.door.sounds[2], + {pos = pos, gain = 0.3, max_hear_distance = 10}) end minetest.swap_node(pos, { @@ -181,21 +182,25 @@ function _doors.door_toggle(pos, clicker) end -local function on_place_node(place_to, newnode, placer, oldnode, itemstack, pointed_thing) +local function on_place_node(place_to, newnode, + placer, oldnode, itemstack, pointed_thing) -- Run script hook local _, callback for _, callback in ipairs(core.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 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) + callback(place_to_copy, newnode_copy, placer, + oldnode_copy, itemstack, pointed_thing_copy) end end @@ -214,8 +219,8 @@ function doors.register(name, def) 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 } } + {{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 @@ -268,8 +273,9 @@ function doors.register(name, def) end end - local above = { x = pos.x, y = pos.y + 1, z = pos.z } - if not minetest.registered_nodes[minetest.get_node(above).name].buildable_to then + local above = {x = pos.x, y = pos.y + 1, z = pos.z} + if not minetest.registered_nodes[ + minetest.get_node(above).name].buildable_to then return itemstack end @@ -281,10 +287,10 @@ function doors.register(name, def) local dir = minetest.dir_to_facedir(placer:get_look_dir()) 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 }, + {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 = { @@ -316,7 +322,8 @@ function doors.register(name, def) itemstack:take_item() end - on_place_node(pos, minetest.get_node(pos), placer, node, itemstack, pointed_thing) + on_place_node(pos, minetest.get_node(pos), + placer, node, itemstack, pointed_thing) return itemstack end @@ -402,8 +409,8 @@ function doors.register(name, def) 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.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.mesh = "door_a.obj" minetest.register_node(":" .. name .. "_a", def) @@ -419,7 +426,7 @@ doors.register("door_wood", { tiles = {{ name = "doors_door_wood.png", backface_culling = true }}, description = "Wooden Door", inventory_image = "doors_item_wood.png", - groups = { snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, + groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, recipe = { {"group:wood", "group:wood"}, {"group:wood", "group:wood"}, @@ -428,11 +435,11 @@ doors.register("door_wood", { }) doors.register("door_steel", { - tiles = {{ name = "doors_door_steel.png", backface_culling = true }}, + tiles = {{name = "doors_door_steel.png", backface_culling = true}}, description = "Steel Door", inventory_image = "doors_item_steel.png", protected = true, - groups = { snappy = 1, cracky = 1, level = 2 }, + groups = {snappy = 1, cracky = 1, level = 2}, sounds = default.node_sound_stone_defaults(), sound_open = "doors_steel_door_open", sound_close = "doors_steel_door_close", @@ -444,10 +451,10 @@ doors.register("door_steel", { }) doors.register("door_glass", { - tiles = { "doors_door_glass.png"}, + tiles = {"doors_door_glass.png"}, description = "Glass Door", inventory_image = "doors_item_glass.png", - groups = { snappy=1, cracky=1, oddly_breakable_by_hand=3 }, + groups = {snappy=1, cracky=1, oddly_breakable_by_hand=3}, sounds = default.node_sound_glass_defaults(), sound_open = "doors_glass_door_open", sound_close = "doors_glass_door_close", @@ -459,10 +466,10 @@ doors.register("door_glass", { }) doors.register("door_obsidian_glass", { - tiles = { "doors_door_obsidian_glass.png" }, + tiles = {"doors_door_obsidian_glass.png"}, description = "Obsidian Glass Door", inventory_image = "doors_item_obsidian_glass.png", - groups = { snappy=1, cracky=1, oddly_breakable_by_hand=3 }, + groups = {snappy=1, cracky=1, oddly_breakable_by_hand=3}, sounds = default.node_sound_glass_defaults(), sound_open = "doors_glass_door_open", sound_close = "doors_glass_door_close", @@ -514,11 +521,15 @@ function _doors.trapdoor_toggle(pos, clicker) local def = minetest.registered_nodes[node.name] if string.sub(node.name, -5) == "_open" then - minetest.sound_play(def.sound_close, {pos = pos, gain = 0.3, max_hear_distance = 10}) - minetest.swap_node(pos, {name = string.sub(node.name, 1, string.len(node.name) - 5), param1 = node.param1, param2 = node.param2}) + minetest.sound_play(def.sound_close, + {pos = pos, gain = 0.3, max_hear_distance = 10}) + 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 = 0.3, max_hear_distance = 10}) - minetest.swap_node(pos, {name = node.name .. "_open", param1 = node.param1, param2 = node.param2}) + minetest.sound_play(def.sound_open, + {pos = pos, gain = 0.3, max_hear_distance = 10}) + minetest.swap_node(pos, {name = node.name .. "_open", + param1 = node.param1, param2 = node.param2}) end end @@ -527,7 +538,8 @@ function doors.register_trapdoor(name, def) local name_opened = name.."_open" local function check_player_priv(pos, player) - if not def.protected or minetest.check_player_privs(player, "protection_bypass") then + if not def.protected or + minetest.check_player_privs(player, "protection_bypass") then return true end local meta = minetest.get_meta(pos) @@ -560,8 +572,8 @@ function doors.register_trapdoor(name, def) else def.on_blast = function(pos, intensity) minetest.remove_node(pos) - minetest.remove_node({ x = pos.x, y = pos.y + 1, z = pos.z}) - return { name } + minetest.remove_node({x = pos.x, y = pos.y + 1, z = pos.z}) + return {name} end end @@ -588,8 +600,8 @@ function doors.register_trapdoor(name, def) type = "fixed", fixed = {-0.5, -0.5, -0.5, 0.5, -6/16, 0.5} } - def_closed.tiles = { def.tile_front, def.tile_front, def.tile_side, def.tile_side, - def.tile_side, def.tile_side } + def_closed.tiles = {def.tile_front, def.tile_front, def.tile_side, def.tile_side, + def.tile_side, def.tile_side} def_opened.node_box = { type = "fixed", @@ -599,10 +611,10 @@ function doors.register_trapdoor(name, def) type = "fixed", fixed = {-0.5, -0.5, 6/16, 0.5, 0.5, 0.5} } - def_opened.tiles = { def.tile_side, def.tile_side, + def_opened.tiles = {def.tile_side, def.tile_side, def.tile_side .. '^[transform3', def.tile_side .. '^[transform1', - def.tile_front, def.tile_front } + def.tile_front, def.tile_front} def_opened.drop = name_closed def_opened.groups.not_in_creative_inventory = 1 @@ -660,13 +672,13 @@ function doors.register_fencegate(name, def) local fence = { description = def.description, drawtype = "mesh", - tiles = { def.texture }, + tiles = {def.texture}, paramtype = "light", paramtype2 = "facedir", sunlight_propagates = true, is_ground_content = false, drop = name .. "_closed", - connect_sides = { "left", "right" }, + connect_sides = {"left", "right"}, groups = def.groups, sounds = def.sounds, on_rightclick = function(pos, clicker) From fe450b4144cfe93136849ea2c9713cce3dd21aa6 Mon Sep 17 00:00:00 2001 From: Tim Date: Tue, 5 Jul 2016 19:30:33 +0200 Subject: [PATCH 058/121] Bucket: Prevent crashing when placing liquid against a buildable node into an unknown node --- mods/bucket/init.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mods/bucket/init.lua b/mods/bucket/init.lua index 2d2690fe..521a4463 100644 --- a/mods/bucket/init.lua +++ b/mods/bucket/init.lua @@ -88,10 +88,11 @@ function bucket.register_liquid(source, flowing, itemname, inventory_image, name -- check if the node above can be replaced lpos = pointed_thing.above local node = minetest.get_node_or_nil(lpos) - if not node - or not minetest.registered_nodes[node.name].buildable_to then + 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 + return itemstack end end From 5644ab4bd37b7bbbb7d911c95b41f6d55c428301 Mon Sep 17 00:00:00 2001 From: Tim Date: Tue, 5 Jul 2016 19:36:36 +0200 Subject: [PATCH 059/121] Bucket: Allow liquid placed against unknown nodes instead of aborting abnormally --- mods/bucket/init.lua | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/mods/bucket/init.lua b/mods/bucket/init.lua index 521a4463..ad5e309c 100644 --- a/mods/bucket/init.lua +++ b/mods/bucket/init.lua @@ -60,16 +60,10 @@ function bucket.register_liquid(source, flowing, itemname, inventory_image, name end local node = minetest.get_node_or_nil(pointed_thing.under) - if not node then - return - end - local ndef = minetest.registered_nodes[node.name] - if not ndef then - return - end + local ndef = node and minetest.registered_nodes[node.name] -- Call on_rightclick if the pointed node defines it - if ndef.on_rightclick and + if ndef and ndef.on_rightclick and user and not user:get_player_control().sneak then return ndef.on_rightclick( pointed_thing.under, @@ -80,7 +74,7 @@ function bucket.register_liquid(source, flowing, itemname, inventory_image, name local lpos -- Check if pointing to a buildable node - if ndef.buildable_to then + if ndef and ndef.buildable_to then -- buildable; replace the node lpos = pointed_thing.under else From e38099225c9265c1c9cb88ff49613432a3848372 Mon Sep 17 00:00:00 2001 From: paramat Date: Thu, 7 Jul 2016 18:56:43 +0100 Subject: [PATCH 060/121] TNT: Add missing 'then' --- mods/tnt/init.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mods/tnt/init.lua b/mods/tnt/init.lua index a481ae95..e343d055 100644 --- a/mods/tnt/init.lua +++ b/mods/tnt/init.lua @@ -1,7 +1,8 @@ tnt = {} + -- Default to enabled when in singleplayer local enable_tnt = minetest.setting_getbool("enable_tnt") -if enable_tnt == nil +if enable_tnt == nil then enable_tnt = minetest.is_singleplayer() end @@ -82,7 +83,6 @@ local function add_drop(drops, item) end end - local function destroy(drops, npos, cid, c_air, c_fire, on_blast_queue, ignore_protection, ignore_on_blast) if not ignore_protection and minetest.is_protected(npos, "") then return cid @@ -106,7 +106,6 @@ local function destroy(drops, npos, cid, c_air, c_fire, on_blast_queue, ignore_p 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 From 71c7e21669cfb0b9499a3e376ef2f763b94c960b Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 1 Jul 2016 22:43:02 +0200 Subject: [PATCH 061/121] Always return the leftover ItemStack for on_place and on_rightclick --- mods/beds/api.lua | 3 ++- mods/boats/init.lua | 4 ++-- mods/default/nodes.lua | 3 ++- mods/doors/init.lua | 9 ++++++--- mods/farming/api.lua | 14 +++++++------- mods/flowers/init.lua | 2 +- 6 files changed, 20 insertions(+), 15 deletions(-) diff --git a/mods/beds/api.lua b/mods/beds/api.lua index 53d4e488..d640a311 100644 --- a/mods/beds/api.lua +++ b/mods/beds/api.lua @@ -91,8 +91,9 @@ function beds.register_bed(name, def) destruct_bed(pos, 1) end, - on_rightclick = function(pos, node, clicker) + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) beds.on_rightclick(pos, clicker) + return itemstack end, on_rotate = function(pos, node, user, mode, new_param2) diff --git a/mods/boats/init.lua b/mods/boats/init.lua index 0097a57a..db8258bc 100644 --- a/mods/boats/init.lua +++ b/mods/boats/init.lua @@ -224,10 +224,10 @@ minetest.register_craftitem("boats:boat", { on_place = function(itemstack, placer, pointed_thing) if pointed_thing.type ~= "node" then - return + return itemstack end if not is_water(pointed_thing.under) then - return + return itemstack end pointed_thing.under.y = pointed_thing.under.y + 0.5 minetest.add_entity(pointed_thing.under, "boats:boat") diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua index bfc0898e..86d5565c 100644 --- a/mods/default/nodes.lua +++ b/mods/default/nodes.lua @@ -1612,7 +1612,7 @@ minetest.register_node("default:chest_locked", { " takes " .. stack:get_name() .. " from locked chest at " .. minetest.pos_to_string(pos)) end, - on_rightclick = function(pos, node, clicker) + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) local meta = minetest.get_meta(pos) if has_locked_chest_privilege(meta, clicker) then minetest.show_formspec( @@ -1621,6 +1621,7 @@ minetest.register_node("default:chest_locked", { get_locked_chest_formspec(pos) ) end + return itemstack end, on_blast = function() end, }) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index f21381fe..1c20e0b4 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -373,8 +373,9 @@ function doors.register(name, def) sounds = { def.sound_close, def.sound_open }, } - def.on_rightclick = function(pos, node, clicker) + def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) _doors.door_toggle(pos, clicker) + return itemstack end def.after_dig_node = function(pos, node, meta, digger) minetest.remove_node({x = pos.x, y = pos.y + 1, z = pos.z}) @@ -547,8 +548,9 @@ function doors.register_trapdoor(name, def) return meta:get_string("doors_owner") == pn end - def.on_rightclick = function(pos, node, clicker) + def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) _doors.trapdoor_toggle(pos, clicker) + return itemstack end -- Common trapdoor configuration @@ -681,12 +683,13 @@ function doors.register_fencegate(name, def) connect_sides = {"left", "right"}, groups = def.groups, sounds = def.sounds, - on_rightclick = function(pos, clicker) + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) local node = minetest.get_node(pos) local node_def = minetest.registered_nodes[node.name] minetest.swap_node(pos, {name = node_def.gate, param2 = node.param2}) minetest.sound_play(node_def.sound, {pos = pos, gain = 0.3, max_hear_distance = 8}) + return itemstack end, selection_box = { type = "fixed", diff --git a/mods/farming/api.lua b/mods/farming/api.lua index 966910f6..69c6769b 100644 --- a/mods/farming/api.lua +++ b/mods/farming/api.lua @@ -133,10 +133,10 @@ farming.place_seed = function(itemstack, placer, pointed_thing, plantname) local pt = pointed_thing -- check if pointing at a node if not pt then - return + return itemstack end if pt.type ~= "node" then - return + return itemstack end local under = minetest.get_node(pt.under) @@ -153,25 +153,25 @@ farming.place_seed = function(itemstack, placer, pointed_thing, plantname) -- return if any of the nodes is not registered if not minetest.registered_nodes[under.name] then - return + return itemstack end if not minetest.registered_nodes[above.name] then - return + return itemstack end -- check if pointing at the top of the node if pt.above.y ~= pt.under.y+1 then - return + return itemstack end -- check if you can replace the node above the pointed node if not minetest.registered_nodes[above.name].buildable_to then - return + return itemstack end -- check if pointing at soil if minetest.get_item_group(under.name, "soil") < 2 then - return + return itemstack end -- add the node and remove 1 item from the itemstack diff --git a/mods/flowers/init.lua b/mods/flowers/init.lua index 2de575fe..2ec661e1 100644 --- a/mods/flowers/init.lua +++ b/mods/flowers/init.lua @@ -251,8 +251,8 @@ minetest.register_node("flowers:waterlily", { end if not minetest.setting_getbool("creative_mode") then itemstack:take_item() - return itemstack end end + return itemstack end }) From 594365310db712595446b4a0fcb1be31160c2f25 Mon Sep 17 00:00:00 2001 From: Tim Date: Sat, 2 Jul 2016 02:30:45 +0200 Subject: [PATCH 062/121] Doors: Remove unnecessary node lookups --- mods/doors/init.lua | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index 1c20e0b4..ae41f2dd 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -16,7 +16,8 @@ _doors.registered_trapdoors = {} -- returns an object to a door object or nil function doors.get(pos) - if _doors.registered_doors[minetest.get_node(pos).name] then + local node_name = minetest.get_node(pos).name + if _doors.registered_doors[node_name] then -- A normal upright door return { pos = pos, @@ -40,7 +41,7 @@ function doors.get(pos) return state %2 == 1 end } - elseif _doors.registered_trapdoors[minetest.get_node(pos).name] then + elseif _doors.registered_trapdoors[node_name] then -- A trapdoor return { pos = pos, @@ -60,8 +61,7 @@ function doors.get(pos) return _doors.trapdoor_toggle(self.pos, player) end, state = function(self) - local name = minetest.get_node(pos).name - return name:sub(-5) == "_open" + return node_name:sub(-5) == "_open" end } else @@ -129,15 +129,15 @@ local transform = { }, } -function _doors.door_toggle(pos, clicker) +function _doors.door_toggle(pos, node, clicker) local meta = minetest.get_meta(pos) - local def = minetest.registered_nodes[minetest.get_node(pos).name] + 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 minetest.get_node(pos).name:sub(-2) == "_b" then + if node.name:sub(-2) == "_b" then state = 2 else state = 0 @@ -163,7 +163,7 @@ function _doors.door_toggle(pos, clicker) state = state + 1 end - local dir = minetest.get_node(pos).param2 + local dir = node.param2 if state % 2 == 0 then minetest.sound_play(def.door.sounds[1], {pos = pos, gain = 0.3, max_hear_distance = 10}) @@ -374,7 +374,7 @@ function doors.register(name, def) } def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) - _doors.door_toggle(pos, clicker) + _doors.door_toggle(pos, node, clicker) return itemstack end def.after_dig_node = function(pos, node, meta, digger) @@ -507,7 +507,7 @@ end ----trapdoor---- -function _doors.trapdoor_toggle(pos, clicker) +function _doors.trapdoor_toggle(pos, node, clicker) if clicker and not minetest.check_player_privs(clicker, "protection_bypass") then local meta = minetest.get_meta(pos) local owner = meta:get_string("doors_owner") @@ -518,7 +518,6 @@ function _doors.trapdoor_toggle(pos, clicker) end end - local node = minetest.get_node(pos) local def = minetest.registered_nodes[node.name] if string.sub(node.name, -5) == "_open" then @@ -549,7 +548,7 @@ function doors.register_trapdoor(name, def) end def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) - _doors.trapdoor_toggle(pos, clicker) + _doors.trapdoor_toggle(pos, node, clicker) return itemstack end @@ -684,7 +683,6 @@ function doors.register_fencegate(name, def) groups = def.groups, sounds = def.sounds, on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) - local node = minetest.get_node(pos) local node_def = minetest.registered_nodes[node.name] minetest.swap_node(pos, {name = node_def.gate, param2 = node.param2}) minetest.sound_play(node_def.sound, {pos = pos, gain = 0.3, From f1f96dbe6b2af33f669283252861e1cb74eef496 Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Fri, 8 Jul 2016 15:41:37 +0100 Subject: [PATCH 063/121] Default/trees: Faster way to detect snow around pine saplings Instead of using voxelmanip use 'find nodes in area' instead --- mods/default/trees.lua | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/mods/default/trees.lua b/mods/default/trees.lua index 1b062660..1e0df1bc 100644 --- a/mods/default/trees.lua +++ b/mods/default/trees.lua @@ -27,33 +27,10 @@ end -- 'is snow nearby' function local function is_snow_nearby(pos) - local x, y, z = pos.x, pos.y, pos.z - local c_snow = minetest.get_content_id("default:snow") - local c_snowblock = minetest.get_content_id("default:snowblock") - local c_dirtsnow = minetest.get_content_id("default:dirt_with_snow") - - local vm = minetest.get_voxel_manip() - local minp, maxp = vm:read_from_map( - {x = x - 1, y = y - 1, z = z - 1}, - {x = x + 1, y = y + 1, z = z + 1} - ) - local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) - local data = vm:get_data() - - for yy = y - 1, y + 1 do - for zz = z - 1, z + 1 do - local vi = a:index(x - 1, yy, zz) - for xx = x - 1, x + 1 do - local nodid = data[vi] - if nodid == c_snow or nodid == c_snowblock or nodid == c_dirtsnow then - return true - end - vi = vi + 1 - end - end - end - - return false + return #minetest.find_nodes_in_area( + {x = pos.x - 1, y = pos.y - 1, z = pos.z - 1}, + {x = pos.x + 1, y = pos.y + 1, z = pos.z + 1}, + {"default:snow", "default:snowblock", "default:dirt_with_snow"}) > 0 end From fcceec0e8ce94babaaabb4ec8fe4676213ad82ab Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 8 Jul 2016 00:51:54 +0200 Subject: [PATCH 064/121] Doors: Fix trapdoor crash on can_dig with nil-player (e.g. minetest.dig_node) --- mods/doors/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index ae41f2dd..0f72a321 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -543,8 +543,8 @@ function doors.register_trapdoor(name, def) return true end local meta = minetest.get_meta(pos) - local pn = player:get_player_name() - return meta:get_string("doors_owner") == pn + local player_name = player and player:get_player_name() + return meta:get_string("doors_owner") == player_name end def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) From 07141b4a2ea4892c55b1ea7d10e85e05bd73113b Mon Sep 17 00:00:00 2001 From: paramat Date: Sat, 9 Jul 2016 19:23:54 +0100 Subject: [PATCH 065/121] Bones: New textures --- mods/bones/README.txt | 2 +- mods/bones/textures/bones_bottom.png | Bin 181 -> 740 bytes mods/bones/textures/bones_front.png | Bin 183 -> 655 bytes mods/bones/textures/bones_rear.png | Bin 187 -> 637 bytes mods/bones/textures/bones_side.png | Bin 188 -> 700 bytes mods/bones/textures/bones_top.png | Bin 182 -> 644 bytes 6 files changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/bones/README.txt b/mods/bones/README.txt index b40a384d..cf99bc8b 100644 --- a/mods/bones/README.txt +++ b/mods/bones/README.txt @@ -14,4 +14,4 @@ http://creativecommons.org/licenses/by-sa/3.0/ Authors of media files ---------------------- -Bad_Command_ +All textures: paramat diff --git a/mods/bones/textures/bones_bottom.png b/mods/bones/textures/bones_bottom.png index ada72ceaee53f83beb0963a5e5788ed423c7155b..859c6bbe243f4f1f7397a95007df53e52432a00b 100644 GIT binary patch delta 727 zcmV;|0x12p0ptac8Gix*005AYXf^-<010qNS#tmY3ljhU3ljkVnw%H_000McNliru z;0Fm32Or2&&XfQE0)t6JK~yNuC6P@}t56t(-*Vu1THs27B9us)YD^OwLl=!Jw_W+0 zUAS{q<40@^nnJ3E2rYzfdceErdS;$XW;(aGw{aYMp2u~k#yQP#~U0sD?cra8|rK;*?vq8OH zk6{=^QL3tPT{j4VG);@5I6FHtP4oHrxoMj3@9(y4i=rrsqGK2a03=DGC`w(|JkJwC z%CaPc^!xp~u74jM9t1%EfHX}30O`8E-EMVV*EDUlS`CN8lamvcW%v7i6h(i3f5YJr zV=M^5(a{kAAW;;1z20~{K0iMP0L!xSJa3w2v)M?Jlq3nqagC+k z?{+(k@!Q)QrL-)|BuQ-Bj-n`vq9jS;I7SE!1_O@cP=B}EbzRrC?bT{kRh1wJFE1~h zPN!*_10DeKJkPSM+wHb(izbsv+qMkDNRosQ;(2~Hn`K${`}>PAPSf;|q?EEOD~ci$ zhM{FyudlDi$H%_!13*y}gb>3pT-OBvK@g_XDF9?y1^^w~ws*T-zu$j+e4I|FEXz_# zlOz#E5q|&FEgoCX>klF9?F7 zD1?yFXyp68VHkIJcMQ+->-C!F`8bYE)11%e08rpK&h_>6<>jU4d50M+%c|=d0MKHw zsOwsiB$j2rzP{ey-zlZ4s&X9Xd0r3%nx+*+;W!SZ^xwaK{{aJoU*GftL`MJs002ov JPDHLkV1lspOD6yT delta 164 zcmV;V09*g$1+@W?8Gi!+001a04^sdD01r@1R7C&)03972Jv}|Ar>ET9+)_}sWB>pF zVM#nfl=5YcA+76Bs&EMswF={|-Ps+$ zR&HNZ19lIFC32^cp!ZNH*zRKFw|g|ur2n4*-4BSN4bOdI%OcR+p{xYHo77ZArRFQTet^`347rucn z;S=~aeT^=X3Y}@vIU(>W`G

T!D_Y2<#N$z^l&)L=kw$7`2GFOIj`62 zyWLI*f*{CdvtM6dSFu=3k|aV%5CoQGZMR#`^B800a=B0_e0+TT{{AkP%k%ln7-Nh@ zG))5l*L4XYVSgB6j1fY2(4DDcDpSn5($hkrS$sx`jUFRUK2tL!*Co&a$R>a zndrJcolY-3aLy^Er_*V_-%G;%X0s9L2ZO!!Vsr%d)&!EM~JA=RBLuDvDy;_IA6?<#LQM(=<8f b$z<{m*nc9f1|MgS00000NkvXXu0mjfRY)cr delta 166 zcmV;X09pT!1-Ai^8Gi!+001a04^sdD01r@1R7C&)03972Jv}|Ar>ET9+)_}sWB>pF zV@X6oRCob3ivg;|01U#C`0jt^zp_8ENW>y68>>k~o&`oBEefSBm;Cm7)G7=f*fj&# z>MLr%^5A3)yMosV+P=jR6udn0uBkAb4K%-x3`jlpNDTj%E+5Al?y^xaWagBlKM>CW U_tR6pjsO4v07*qoM6N<$f>%mGP5=M^ diff --git a/mods/bones/textures/bones_rear.png b/mods/bones/textures/bones_rear.png index 8e1ac10b4f0ee0956c6e19a6ca4d75c2d8f2c783..4cfe236d5d6017af2f7879cbc0ba8b1d8434b6e4 100644 GIT binary patch delta 623 zcmV-#0+9W?0sRD!8Gix*005AYXf^-<010qNS#tmY3ljhU3ljkVnw%H_000McNliru z;0Fm303nW}Z(-)WIoocxN`I*=%WT_ze0&73+wJb} z?{~Xhk|aWio12>~%lf`|UHAO_{45B9!{Ok09)OpZ7XZ)C&y2Bg9DU#a{QP8$<#`Su zilU+@tYH`kAr}`H<2V8UP?lw$=bUrSxl*cWnyRX_)=82mrHB#5aXg#N%zLp|^nEX- z9ERcj{T;yF-G3c`q9_0m$8pNC6hcfNIOlEKc3o!_0E7?#x~|h&Tc^`$Hk$=Ouv{(; z9)NYmFv0&Z-2Mj>+9=j0RVm9_kG{CEdZ;o zYv1?dIKH~NGWd8rQc7Ld{rdVcoz-e(mIh!k#)nF;58OG=U_`c5=BZL4T zZQI(mJ)h5~;0PhMZR5ZC`S}q-P)gV9wPh@;s)}=NaND+&QYqzrzn_*4g21FnjM-h+ z)ph;w@Myp}kD}=N`x^jbY|1`OQ`dFh-rg+7andw(97ieTdER=x29PAlX0y4yy`60E zecuF1mdoYu?=NG_^SnII&Dn)vcsw4`9LJf@=YQRUCKpFI_qPB5002ov JPDHLkV1jt?Er|dC delta 170 zcmV;b09F6}1iJx{8Gi!+001a04^sdD01r@1R7C&)03972Jv}|Ar>ET9+)_}sWB>pF zXGugsRCoau%K-`iF%ZJQB=-MrzFTZr84zLFSWUWkPhb?%;)>MWCCAh{2-Y_10c_=# z@ZQ@=&MrSNED_Zo1Z}*c$K#}Kj4|?lJ772)Xb0EHfS#8ykRvNLP?uxf_->p&QVU-K~z%|zNHjY)%{L=i!exG1g!LFmfg z?804FEm}|{N*byXNScJncPHwiKj7YHdkzl=&ffj~eU@cG5PyiGcyn_D0Q33$>gsAf zpL?EX7{=-8X%GZ;U7Mzf5aOGr`TqXabsZs86vg}dds&v7&4w{{d3hPf@vhJ`jizbq z^_uVXdK|~8s@gQoYPE`@D9`h%s*aD3Ez5d-e(t*N>+9?1=clTws;c%((*yuYsj8}N z+e(szF|O+xV}Cpt4BEDx&1QrU0Lb$k0C>YNHk*xM7`m>%zP^q|qr<~PK@hgvZJMUP zzrUl=2q8oW+27v>0A7~mUa#jk&dJFM0NA!&mSxv<>-D;eSvRMS)W4`~G6FfPZm!cb6oI zU>FAcA9Z$y0^Etv)RmX970GKh5)c!E>%?}gvheITrM%j0I=t}ZjvN} z!C+AFL^B@QS zpsFg{w%fJ^0Dd~1wr$(*_XR=t{QP`-dt;1gnkXiUVh{vT6zRHNRh8#?jIo1*gFg_# VJXL%dq$B_U002ovPDHLkV1g1+N%#N& delta 171 zcmV;c0960H1-t=}8Gi!+001a04^sdD01r@1R7C&)03972Jv}|Ar>ET9+)_}sWB>pF zXh}ptRCoa$ivbEiQ3!+7b^kMe-XB4v4Pn_>O(OD*+>Jt76nDMg61;cs2f@0VHGr+2 z7W&bz%`S{#cZl9af;Lt>fkMHCapcIR!nm{Xw+Z`6a4%-qAtd(D|LJn9$0fYsR8Gix*005AYXf^-<010qNS#tmY3ljhU3ljkVnw%H_000McNliru z;0Fm32q5{b|7HLH0wYO8K~yNub&|hI>_8aBPxcN=Ff$}U!ff0kQ3hFXg-sz=TDXmc zMS3g22k?=61WOx1Yy~Te6{c7RLb64OFf$T#!CMS$aq*sRn17GoIo}^o2m!!a%Q*+I zSS&c_LWs6)*X#9awE{36kGHqC+qNx=;?L*j=kD(A-rnADIMiDI{QQi^<1h?gUS4Li zSy2?$+N!F8Ab5Lw^E{6L7!HR@sXWi`?(XoL&d<-SwRxUfYX@g%XLVh3&X>z2{-Z3* zf*=6U_dVg9D}SZl-`^>vWm#&i8DqD%w*aoMuNh;EvDIpo=Xu+<0Lb(6vtys0o&r!x zZNTgGT5H{P-RtWsA>{k}JC0-GKKi~_N@=Z)F^&X)b8d{Os_Nq6;_>mZD2lqSz3FsX z*R?B>Qo7QQj}HJ*6uIZs)z#P6SJO13(P#jGQtJD@?|=IM=JWY{K98a(iXtIIS(X6m zx=xa$ZQG`4NF2v~-*e8L$-~3LriYE;WHMPUmj?$2*4jZBhEht#*l09z4vy-Q+}zv% zNRote-ZYKY+M|>*#@v|i@9%%z!{z0r%j2MMZBR<3l*h-%CnqOTN-5=ZIu$}lDYGo2 zl%{E#rf;d2Bncs;>$<-0H=+MgS(ZT%xD|Oqh%`+Xi-o&NW6b{kzEX-1VvO;9KaOLq zHGrzBwzjqgS(X6^!;o{nv$F%>>FJ3OQWOQH^yuhF2w{xrx^6O=93CG21$LPQQWkH8 QTL1t607*qoM6N<$f^qmUi2wiq delta 165 zcmV;W09yZq1-1c@8Gi!+001a04^sdD01r@1R7C&)03972Jv}|Ar>ET9+)_}sWB>pF zVo5|nRCobR&e4fQQ3%D*B-{RL9u5PKyFk#NAi}b-nnWb&0i%!>-6>VL1n;O-821CP zmD@Y20lN=|CGw(?p!cCr@ES4l&3!b`r2jnw`u-t?w%2nx)*f)XYE%rFIVI^28;=4a T4BWyh00000NkvXXu0mjfi(^4Z From b74954969cb9268c553f2dcdde672e268ba032c1 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 11 Jul 2016 17:50:19 +0200 Subject: [PATCH 066/121] Doors: Fix missing node parameter passing --- mods/doors/init.lua | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index 0f72a321..1e682e1d 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -25,16 +25,16 @@ function doors.get(pos) if self:state() then return false end - return _doors.door_toggle(self.pos, player) + 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, player) + return _doors.door_toggle(self.pos, nil, player) end, toggle = function(self, player) - return _doors.door_toggle(self.pos, player) + return _doors.door_toggle(self.pos, nil, player) end, state = function(self) local state = minetest.get_meta(self.pos):get_int("state") @@ -49,19 +49,19 @@ function doors.get(pos) if self:state() then return false end - return _doors.trapdoor_toggle(self.pos, player) + 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, player) + return _doors.trapdoor_toggle(self.pos, nil, player) end, toggle = function(self, player) - return _doors.trapdoor_toggle(self.pos, player) + return _doors.trapdoor_toggle(self.pos, nil, player) end, state = function(self) - return node_name:sub(-5) == "_open" + return minetest.get_node(self.pos).name:sub(-5) == "_open" end } else @@ -131,6 +131,7 @@ local transform = { 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 @@ -508,6 +509,7 @@ end ----trapdoor---- function _doors.trapdoor_toggle(pos, node, clicker) + node = node or minetest.get_node(pos) if clicker and not minetest.check_player_privs(clicker, "protection_bypass") then local meta = minetest.get_meta(pos) local owner = meta:get_string("doors_owner") From d7a74560072b0e2c2b0f35b49cbd46a0a1852a4a Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Fri, 20 May 2016 11:40:15 +0100 Subject: [PATCH 067/121] Beds: Save respawn position when entering bed, only read bed spawns once No longer require night to be skipped for resawn position to be saved Remove constant beds.read_spawns() calls when a player joins as this is only required once --- mods/beds/functions.lua | 6 +----- mods/beds/spawns.lua | 2 ++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/mods/beds/functions.lua b/mods/beds/functions.lua index afc8e15a..c383a3f2 100644 --- a/mods/beds/functions.lua +++ b/mods/beds/functions.lua @@ -130,7 +130,6 @@ end function beds.skip_night() minetest.set_timeofday(0.23) - beds.set_spawns() end function beds.on_rightclick(pos, player) @@ -149,6 +148,7 @@ function beds.on_rightclick(pos, player) -- 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 @@ -174,10 +174,6 @@ end -- Callbacks -minetest.register_on_joinplayer(function(player) - beds.read_spawns() -end) - -- respawn player at bed if enabled and valid position is found minetest.register_on_respawnplayer(function(player) if not enable_respawn then diff --git a/mods/beds/spawns.lua b/mods/beds/spawns.lua index 48b8a669..2e27f21a 100644 --- a/mods/beds/spawns.lua +++ b/mods/beds/spawns.lua @@ -37,6 +37,8 @@ function beds.read_spawns() end end +beds.read_spawns() + function beds.save_spawns() if not beds.spawn then return From 4473627de04ab3b0dddd740ea963281460cff8cf Mon Sep 17 00:00:00 2001 From: Tim Date: Sun, 26 Jun 2016 13:34:14 +0200 Subject: [PATCH 068/121] Remove unused and clean up missused variable-value assignments. * Unused variables * Unused values (assigned to variables, but overwritten before use) * Defining already defined variables instead of reassigning to them. --- mods/beds/functions.lua | 2 +- mods/beds/spawns.lua | 2 -- mods/boats/init.lua | 2 +- mods/bones/init.lua | 1 - mods/bucket/init.lua | 3 ++- mods/creative/init.lua | 1 - mods/default/craftitems.lua | 4 ++-- mods/default/furnace.lua | 3 +-- mods/default/trees.lua | 10 +++++----- mods/doors/init.lua | 7 ++----- mods/farming/api.lua | 2 -- mods/tnt/init.lua | 16 ++++++++-------- 12 files changed, 22 insertions(+), 31 deletions(-) diff --git a/mods/beds/functions.lua b/mods/beds/functions.lua index c383a3f2..96cebe81 100644 --- a/mods/beds/functions.lua +++ b/mods/beds/functions.lua @@ -100,7 +100,7 @@ end local function update_formspecs(finished) local ges = #minetest.get_connected_players() - local form_n = "" + local form_n local is_majority = (ges / 2) < player_in_bed if finished then diff --git a/mods/beds/spawns.lua b/mods/beds/spawns.lua index 2e27f21a..6b1f4041 100644 --- a/mods/beds/spawns.lua +++ b/mods/beds/spawns.lua @@ -32,8 +32,6 @@ function beds.read_spawns() beds.save_spawns() os.rename(file, file .. ".backup") file = org_file - else - spawns = {} end end diff --git a/mods/boats/init.lua b/mods/boats/init.lua index db8258bc..caaef578 100644 --- a/mods/boats/init.lua +++ b/mods/boats/init.lua @@ -167,7 +167,7 @@ function boat.on_step(self, dtime) local p = self.object:getpos() p.y = p.y - 0.5 - local new_velo = {x = 0, y = 0, z = 0} + local new_velo local new_acce = {x = 0, y = 0, z = 0} if not is_water(p) then local nodedef = minetest.registered_nodes[minetest.get_node(p).name] diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 661bbab8..08a422d0 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -174,7 +174,6 @@ minetest.register_on_dieplayer(function(player) pos.z = math.floor(pos.z+0.5) local param2 = minetest.dir_to_facedir(player:get_look_dir()) local player_name = player:get_player_name() - local player_inv = player:get_inventory() if (not may_replace(pos, player)) then if (may_replace({x=pos.x, y=pos.y+1, z=pos.z}, player)) then diff --git a/mods/bucket/init.lua b/mods/bucket/init.lua index ad5e309c..3770be6a 100644 --- a/mods/bucket/init.lua +++ b/mods/bucket/init.lua @@ -80,8 +80,9 @@ function bucket.register_liquid(source, flowing, itemname, inventory_image, name else -- not buildable to; place the liquid above -- check if the node above can be replaced + lpos = pointed_thing.above - local node = minetest.get_node_or_nil(lpos) + 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 diff --git a/mods/creative/init.lua b/mods/creative/init.lua index 7f952d32..abb11aa5 100644 --- a/mods/creative/init.lua +++ b/mods/creative/init.lua @@ -197,7 +197,6 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) creative.update_creative_inventory(player_name) creative.set_creative_formspec(player, 0) else - local formspec = player:get_inventory_formspec() local start_i = player_inventory[player_name].start_i or 0 if fields.creative_prev then diff --git a/mods/default/craftitems.lua b/mods/default/craftitems.lua index 2fe59784..d821af06 100644 --- a/mods/default/craftitems.lua +++ b/mods/default/craftitems.lua @@ -15,7 +15,7 @@ local lpp = 14 -- Lines per book's page local function book_on_use(itemstack, user) local player_name = user:get_player_name() local data = minetest.deserialize(itemstack:get_metadata()) - local formspec, title, text, owner = "", "", "", player_name + local title, text, owner = "", "", player_name local page, page_max, lines, string = 1, 1, {}, "" if data then @@ -38,6 +38,7 @@ local function book_on_use(itemstack, user) end end + local formspec if owner == player_name then formspec = "size[8,8]" .. default.gui_bg .. default.gui_bg_img .. @@ -152,7 +153,6 @@ minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv return end - local copy = ItemStack("default:book_written") local original local index for i = 1, player:get_inventory():get_size("craft") do diff --git a/mods/default/furnace.lua b/mods/default/furnace.lua index 3047dc41..b5bca889 100644 --- a/mods/default/furnace.lua +++ b/mods/default/furnace.lua @@ -111,7 +111,6 @@ local function furnace_node_timer(pos, elapsed) local inv = meta:get_inventory() local srclist = inv:get_list("src") local fuellist = inv:get_list("fuel") - local dstlist = inv:get_list("dst") -- -- Cooking @@ -172,7 +171,7 @@ local function furnace_node_timer(pos, elapsed) -- Update formspec, infotext and node -- local formspec = inactive_formspec - local item_state = "" + local item_state local item_percent = 0 if cookable then item_percent = math.floor(src_time / cooked.time * 100) diff --git a/mods/default/trees.lua b/mods/default/trees.lua index 1e0df1bc..07071c74 100644 --- a/mods/default/trees.lua +++ b/mods/default/trees.lua @@ -176,8 +176,8 @@ function default.grow_tree(pos, is_apple_tree, bad) local vm = minetest.get_voxel_manip() local minp, maxp = vm:read_from_map( - {x = pos.x - 2, y = pos.y, z = pos.z - 2}, - {x = pos.x + 2, y = pos.y + height + 1, z = pos.z + 2} + {x = x - 2, y = y, z = z - 2}, + {x = x + 2, y = y + height + 1, z = z + 2} ) local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) local data = vm:get_data() @@ -211,8 +211,8 @@ function default.grow_jungle_tree(pos, bad) local vm = minetest.get_voxel_manip() local minp, maxp = vm:read_from_map( - {x = pos.x - 3, y = pos.y - 1, z = pos.z - 3}, - {x = pos.x + 3, y = pos.y + height + 1, z = pos.z + 3} + {x = x - 3, y = y - 1, z = z - 3}, + {x = x + 3, y = y + height + 1, z = z + 3} ) local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) local data = vm:get_data() @@ -331,7 +331,7 @@ function default.grow_pine_tree(pos, snow) end end - local dev = 2 + dev = 2 for yy = my + 1, my + 2 do for zz = z - dev, z + dev do local vi = a:index(x - dev, yy, zz) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index 1e682e1d..f39cedff 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -156,7 +156,6 @@ function _doors.door_toggle(pos, node, clicker) end end - local old = state -- until Lua-5.2 we have no bitwise operators :( if state % 2 == 1 then state = state - 1 @@ -186,7 +185,6 @@ end local function on_place_node(place_to, newnode, placer, oldnode, itemstack, pointed_thing) -- Run script hook - local _, callback for _, callback in ipairs(core.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} @@ -250,7 +248,7 @@ function doors.register(name, def) inventory_image = def.inventory_image, on_place = function(itemstack, placer, pointed_thing) - local pos = nil + local pos if not pointed_thing.type == "node" then return itemstack @@ -314,7 +312,6 @@ function doors.register(name, def) meta:set_int("state", state) if def.protected then - local pn = placer:get_player_name() meta:set_string("doors_owner", pn) meta:set_string("infotext", "Owned by " .. pn) end @@ -347,7 +344,7 @@ function doors.register(name, def) return true end local meta = minetest.get_meta(pos) - local name = "" + local name if digger then name = digger:get_player_name() end diff --git a/mods/farming/api.lua b/mods/farming/api.lua index 69c6769b..901f7245 100644 --- a/mods/farming/api.lua +++ b/mods/farming/api.lua @@ -319,11 +319,9 @@ farming.register_plant = function(name, def) nodegroups[pname] = i local next_plant = nil - local on_timer = nil if i < def.steps then next_plant = mname .. ":" .. pname .. "_" .. (i + 1) - on_timer = farming.grow_plant lbm_nodes[#lbm_nodes + 1] = mname .. ":" .. pname .. "_" .. i end diff --git a/mods/tnt/init.lua b/mods/tnt/init.lua index e343d055..023a39b1 100644 --- a/mods/tnt/init.lua +++ b/mods/tnt/init.lua @@ -153,7 +153,7 @@ local function entity_physics(pos, radius, drops) local dir = vector.normalize(vector.subtract(obj_pos, pos)) local moveoff = vector.multiply(dir, dist + 1.0) local newpos = vector.add(pos, moveoff) - local newpos = vector.add(newpos, {x = 0, y = 0.2, z = 0}) + newpos = vector.add(newpos, {x = 0, y = 0.2, z = 0}) obj:setpos(newpos) obj:set_hp(obj:get_hp() - damage) @@ -261,7 +261,7 @@ function tnt.burn(pos) end local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast) - local pos = vector.round(pos) + pos = vector.round(pos) -- scan for adjacent TNT nodes first, and enlarge the explosion local vm1 = VoxelManip() local p1 = vector.subtract(pos, 2) @@ -298,11 +298,11 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast) -- perform the explosion local vm = VoxelManip() local pr = PseudoRandom(os.time()) - local p1 = vector.subtract(pos, radius) - local p2 = vector.add(pos, radius) - local minp, maxp = vm:read_from_map(p1, p2) - local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) - local data = vm:get_data() + 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 = {} @@ -515,7 +515,7 @@ if enable_tnt then end function tnt.register_tnt(def) - local name = "" + local name if not def.name:find(':') then name = "tnt:" .. def.name else From 30b0a155fb1f116a6fe51cdf482cc5d8e653f503 Mon Sep 17 00:00:00 2001 From: Tim Date: Sun, 26 Jun 2016 14:46:15 +0200 Subject: [PATCH 069/121] Stop shadowing upvalues and definitions. --- mods/beds/api.lua | 8 ++++---- mods/creative/init.lua | 19 ++++++++++--------- mods/doors/init.lua | 6 +++--- mods/fire/init.lua | 4 ++-- mods/tnt/init.lua | 10 +++++----- 5 files changed, 24 insertions(+), 23 deletions(-) diff --git a/mods/beds/api.lua b/mods/beds/api.lua index d640a311..3624ea45 100644 --- a/mods/beds/api.lua +++ b/mods/beds/api.lua @@ -59,8 +59,8 @@ function beds.register_bed(name, def) return itemstack end - local def = minetest.registered_nodes[minetest.get_node(pos).name] - if not def or not def.buildable_to then + 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 @@ -113,8 +113,8 @@ function beds.register_bed(name, def) end local newp = vector.add(pos, minetest.facedir_to_dir(new_param2)) local node3 = minetest.get_node_or_nil(newp) - local def = node3 and minetest.registered_nodes[node3.name] - if not def or not def.buildable_to then + 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 diff --git a/mods/creative/init.lua b/mods/creative/init.lua index abb11aa5..1e7b4087 100644 --- a/mods/creative/init.lua +++ b/mods/creative/init.lua @@ -5,15 +5,16 @@ local player_inventory = {} local creative_mode = minetest.setting_getbool("creative_mode") -- Create detached creative inventory after loading all mods -creative.init_creative_inventory = function(player) - local player_name = player:get_player_name() - player_inventory[player_name] = {} - player_inventory[player_name].size = 0 - player_inventory[player_name].filter = "" - player_inventory[player_name].start_i = 1 - player_inventory[player_name].tab_id = 2 +creative.init_creative_inventory = function(owner) + local owner_name = owner:get_player_name() + player_inventory[owner_name] = { + size = 0, + filter = "", + start_i = 1, + tab_id = 2, + } - minetest.create_detached_inventory("creative_" .. player_name, { + minetest.create_detached_inventory("creative_" .. owner_name, { allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) if creative_mode and not to_list == "main" then return count @@ -45,7 +46,7 @@ creative.init_creative_inventory = function(player) end, }) - creative.update_creative_inventory(player_name) + creative.update_creative_inventory(owner_name) --print("creative inventory size: " .. player_inventory[player_name].size) end diff --git a/mods/doors/init.lua b/mods/doors/init.lua index f39cedff..7e587dcf 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -344,11 +344,11 @@ function doors.register(name, def) return true end local meta = minetest.get_meta(pos) - local name + local owner_name if digger then - name = digger:get_player_name() + owner_name = digger:get_player_name() end - return meta:get_string("doors_owner") == name + return meta:get_string("doors_owner") == owner_name end if not def.sounds then diff --git a/mods/fire/init.lua b/mods/fire/init.lua index 08b53a89..90e2f0a8 100644 --- a/mods/fire/init.lua +++ b/mods/fire/init.lua @@ -284,8 +284,8 @@ else local p = minetest.find_node_near(p0, 1, {"group:flammable"}) if p then -- remove flammable nodes around flame - local node = minetest.get_node(p) - local def = minetest.registered_nodes[node.name] + 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 diff --git a/mods/tnt/init.lua b/mods/tnt/init.lua index 023a39b1..c5aa95c9 100644 --- a/mods/tnt/init.lua +++ b/mods/tnt/init.lua @@ -12,7 +12,7 @@ local loss_prob = {} loss_prob["default:cobble"] = 3 loss_prob["default:dirt"] = 4 -local radius = tonumber(minetest.setting_get("tnt_radius") or 3) +local tnt_radius = tonumber(minetest.setting_get("tnt_radius") or 3) -- Fill a list with data for content IDs, after all nodes are registered local cid_data = {} @@ -345,10 +345,10 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast) end end - for _, data in ipairs(on_blast_queue) do - local dist = math.max(1, vector.distance(data.pos, pos)) + for _, queued_data in ipairs(on_blast_queue) do + local dist = math.max(1, vector.distance(queued_data.pos, pos)) local intensity = (radius * radius) / (dist * dist) - local node_drops = data.on_blast(data.pos, intensity) + local node_drops = queued_data.on_blast(queued_data.pos, intensity) if node_drops then for _, item in ipairs(node_drops) do add_drop(drops, item) @@ -589,5 +589,5 @@ end tnt.register_tnt({ name = "tnt:tnt", description = "TNT", - radius = radius, + radius = tnt_radius, }) From 9524ff67a320dfebf9bb551e67711b922ee37963 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 11 Jul 2016 15:11:57 +0200 Subject: [PATCH 070/121] Clean up fire ABM parameters. --- mods/fire/init.lua | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/mods/fire/init.lua b/mods/fire/init.lua index 90e2f0a8..34613da5 100644 --- a/mods/fire/init.lua +++ b/mods/fire/init.lua @@ -226,10 +226,10 @@ minetest.register_abm({ interval = 3, chance = 1, catch_up = false, - action = function(p0, node, _, _) - minetest.remove_node(p0) + action = function(pos, node, active_object_count, active_object_count_wider) + minetest.remove_node(pos) minetest.sound_play("fire_extinguish_flame", - {pos = p0, max_hear_distance = 16, gain = 0.25}) + {pos = pos, max_hear_distance = 16, gain = 0.25}) end, }) @@ -245,9 +245,7 @@ if minetest.setting_getbool("disable_fire") then interval = 7, chance = 1, catch_up = false, - action = function(p0, node, _, _) - minetest.remove_node(p0) - end, + action = minetest.remove_node, }) else @@ -260,12 +258,12 @@ else interval = 7, chance = 12, catch_up = false, - action = function(p0, node, _, _) + action = function(pos, node, active_object_count, active_object_count_wider) -- If there is water or stuff like that around node, don't ignite - if minetest.find_node_near(p0, 1, {"group:puts_out_fire"}) then + if minetest.find_node_near(pos, 1, {"group:puts_out_fire"}) then return end - local p = minetest.find_node_near(p0, 1, {"air"}) + local p = minetest.find_node_near(pos, 1, {"air"}) if p then minetest.set_node(p, {name = "fire:basic_flame"}) end @@ -280,8 +278,8 @@ else interval = 5, chance = 18, catch_up = false, - action = function(p0, node, _, _) - local p = minetest.find_node_near(p0, 1, {"group:flammable"}) + action = function(pos, node, active_object_count, active_object_count_wider) + local p = minetest.find_node_near(pos, 1, {"group:flammable"}) if p then -- remove flammable nodes around flame local flammable_node = minetest.get_node(p) @@ -309,13 +307,13 @@ minetest.register_abm({ neighbors = {"air"}, interval = 5, chance = 10, - action = function(p0, node, _, _) + action = function(pos, node, active_object_count, active_object_count_wider) local reg = minetest.registered_nodes[node.name] if not reg or not reg.groups.igniter or reg.groups.igniter < 2 then return end local d = reg.groups.igniter - local p = minetest.find_node_near(p0, d, {"group:flammable"}) + local p = minetest.find_node_near(pos, d, {"group:flammable"}) if p then -- If there is water or stuff like that around flame, don't ignite if fire.flame_should_extinguish(p) then From d89bb69a22e7abe90c80e827e07ea20a2c633a35 Mon Sep 17 00:00:00 2001 From: adrido Date: Tue, 12 Jul 2016 11:02:01 +0200 Subject: [PATCH 071/121] Beds: Only register respawn callbacks if respawn is enabled --- mods/beds/functions.lua | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/mods/beds/functions.lua b/mods/beds/functions.lua index 96cebe81..5eed27d9 100644 --- a/mods/beds/functions.lua +++ b/mods/beds/functions.lua @@ -173,19 +173,18 @@ end -- Callbacks - --- respawn player at bed if enabled and valid position is found -minetest.register_on_respawnplayer(function(player) - if not enable_respawn then - return false - end - local name = player:get_player_name() - local pos = beds.spawn[name] or nil - if pos then - player:setpos(pos) - return true - end -end) +-- 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:setpos(pos) + return true + end + end) +end minetest.register_on_leaveplayer(function(player) local name = player:get_player_name() From 0bd13d11cf9ac03de3a53611105ed880b2285322 Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Wed, 13 Jul 2016 19:24:49 +0100 Subject: [PATCH 072/121] Doors: Make door groups consistent with corresponding materials --- mods/doors/init.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index 7e587dcf..0d3fd23f 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -425,7 +425,7 @@ doors.register("door_wood", { tiles = {{ name = "doors_door_wood.png", backface_culling = true }}, description = "Wooden Door", inventory_image = "doors_item_wood.png", - groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, recipe = { {"group:wood", "group:wood"}, {"group:wood", "group:wood"}, @@ -438,7 +438,7 @@ doors.register("door_steel", { description = "Steel Door", inventory_image = "doors_item_steel.png", protected = true, - groups = {snappy = 1, cracky = 1, level = 2}, + groups = {cracky = 1, level = 2}, sounds = default.node_sound_stone_defaults(), sound_open = "doors_steel_door_open", sound_close = "doors_steel_door_close", @@ -453,7 +453,7 @@ doors.register("door_glass", { tiles = {"doors_door_glass.png"}, description = "Glass Door", inventory_image = "doors_item_glass.png", - groups = {snappy=1, cracky=1, oddly_breakable_by_hand=3}, + groups = {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", @@ -468,7 +468,7 @@ doors.register("door_obsidian_glass", { tiles = {"doors_door_obsidian_glass.png"}, description = "Obsidian Glass Door", inventory_image = "doors_item_obsidian_glass.png", - groups = {snappy=1, cracky=1, oddly_breakable_by_hand=3}, + groups = {cracky=3}, sounds = default.node_sound_glass_defaults(), sound_open = "doors_glass_door_open", sound_close = "doors_glass_door_close", @@ -632,7 +632,7 @@ doors.register_trapdoor("doors:trapdoor", { wield_image = "doors_trapdoor.png", tile_front = "doors_trapdoor.png", tile_side = "doors_trapdoor_side.png", - groups = {snappy=1, choppy=2, oddly_breakable_by_hand=2, flammable=2, door=1}, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, door = 1}, }) doors.register_trapdoor("doors:trapdoor_steel", { @@ -645,7 +645,7 @@ doors.register_trapdoor("doors:trapdoor_steel", { sounds = default.node_sound_stone_defaults(), sound_open = "doors_steel_door_open", sound_close = "doors_steel_door_close", - groups = {snappy=1, cracky=1, level=2, door=1}, + groups = {cracky = 1, level = 2, door = 1}, }) minetest.register_craft({ From 3661cb61e37ee6b7a8818f7a28e9102fb0674e54 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Mon, 11 Jul 2016 17:55:17 +0100 Subject: [PATCH 073/121] Move nyancats into a separate mod Nyancats are independent in the default mod. Nothing else uses them or their code. Separating it into a separate mod makes it easier for subgames to remove them. It also makes it easier for a mod to depend on nyancats, as lots of subgames don't have them. Default/mapgen.lua: Register biomes, ores and decorations in singlenode mapgen. These were never disabled anyway because singlenode was removed from the world creation menu. --- game_api.txt | 12 +++ mods/default/README.txt | 4 - mods/default/aliases.lua | 3 - mods/default/crafting.lua | 13 --- mods/default/mapgen.lua | 63 +------------ mods/default/nodes.lua | 25 ------ mods/nyancat/README.txt | 29 ++++++ mods/nyancat/depends.txt | 1 + mods/nyancat/init.lua | 84 ++++++++++++++++++ .../textures/default_nc_back.png | Bin .../textures/default_nc_front.png | Bin .../textures/default_nc_rb.png | Bin .../textures/default_nc_side.png | Bin 13 files changed, 129 insertions(+), 105 deletions(-) create mode 100644 mods/nyancat/README.txt create mode 100644 mods/nyancat/depends.txt create mode 100644 mods/nyancat/init.lua rename mods/{default => nyancat}/textures/default_nc_back.png (100%) rename mods/{default => nyancat}/textures/default_nc_front.png (100%) rename mods/{default => nyancat}/textures/default_nc_rb.png (100%) rename mods/{default => nyancat}/textures/default_nc_side.png (100%) diff --git a/game_api.txt b/game_api.txt index e04a33b4..581d76cc 100644 --- a/game_api.txt +++ b/game_api.txt @@ -250,6 +250,18 @@ Give Initial Stuff API ^ str is a comma separated list of initial stuff ^ Adds items to the list of items to be given +Nyancat API +----------- + +`nyancat.place(pos, facedir, length)` + +^ Place a cat at `pos` facing `facedir` with tail length `length` + Only accepts facedir 0-3, if facedir > 3 then it will be interpreted as facedir = 0 + +`nyancat.generate(minp, maxp, seed)` + +^ Called by `minetest.register_on_generated`. To disable nyancat generation, + you can redefine nyancat.generate() to be an empty function TNT API ---------- diff --git a/mods/default/README.txt b/mods/default/README.txt index 41dd1eb0..85c5a4ef 100644 --- a/mods/default/README.txt +++ b/mods/default/README.txt @@ -51,10 +51,6 @@ RealBadAngel's animated water (WTFPL): default_water_flowing_animated.png VanessaE (WTFPL): - default_nc_back.png - default_nc_front.png - default_nc_rb.png - default_nc_side.png default_desert_sand.png default_desert_stone.png default_sand.png diff --git a/mods/default/aliases.lua b/mods/default/aliases.lua index 63fe59b2..1259ac0e 100644 --- a/mods/default/aliases.lua +++ b/mods/default/aliases.lua @@ -39,8 +39,6 @@ minetest.register_alias("locked_chest", "default:chest_locked") minetest.register_alias("cobble", "default:cobble") minetest.register_alias("mossycobble", "default:mossycobble") minetest.register_alias("steelblock", "default:steelblock") -minetest.register_alias("nyancat", "default:nyancat") -minetest.register_alias("nyancat_rainbow", "default:nyancat_rainbow") minetest.register_alias("sapling", "default:sapling") minetest.register_alias("apple", "default:apple") @@ -77,4 +75,3 @@ minetest.register_alias("default:pinewood", "default:pine_wood") minetest.register_alias("default:ladder", "default:ladder_wood") minetest.register_alias("default:sign_wall", "default:sign_wall_wood") - diff --git a/mods/default/crafting.lua b/mods/default/crafting.lua index 3bfce07c..1151f47b 100644 --- a/mods/default/crafting.lua +++ b/mods/default/crafting.lua @@ -888,18 +888,6 @@ minetest.register_craft({ burntime = 30, }) -minetest.register_craft({ - type = "fuel", - recipe = "default:nyancat", - burntime = 1, -}) - -minetest.register_craft({ - type = "fuel", - recipe = "default:nyancat_rainbow", - burntime = 1, -}) - minetest.register_craft({ type = "fuel", recipe = "group:sapling", @@ -935,4 +923,3 @@ minetest.register_craft({ recipe = "default:dry_grass_1", burntime = 2, }) - diff --git a/mods/default/mapgen.lua b/mods/default/mapgen.lua index 7d0b0fd4..52aa294c 100644 --- a/mods/default/mapgen.lua +++ b/mods/default/mapgen.lua @@ -49,7 +49,7 @@ function default.register_ores() -- Clay -- This first to avoid clay in sand blobs - minetest.register_ore({ + minetest.register_ore({ ore_type = "blob", ore = "default:clay", wherein = {"default:sand"}, @@ -70,7 +70,7 @@ function default.register_ores() -- Sand - minetest.register_ore({ + minetest.register_ore({ ore_type = "blob", ore = "default:sand", wherein = {"default:stone", "default:sandstone", @@ -1464,73 +1464,16 @@ function default.register_decorations() end --- --- Generate nyan cats --- - --- All mapgens except singlenode - -function default.make_nyancat(pos, facedir, length) - local tailvec = {x = 0, y = 0, z = 0} - if facedir == 0 then - tailvec.z = 1 - elseif facedir == 1 then - tailvec.x = 1 - elseif facedir == 2 then - tailvec.z = -1 - elseif facedir == 3 then - tailvec.x = -1 - else - facedir = 0 - tailvec.z = 1 - end - local p = {x = pos.x, y = pos.y, z = pos.z} - minetest.set_node(p, {name = "default:nyancat", param2 = facedir}) - for i = 1, length do - p.x = p.x + tailvec.x - p.z = p.z + tailvec.z - minetest.set_node(p, {name = "default:nyancat_rainbow", param2 = facedir}) - end -end - -function default.generate_nyancats(minp, maxp, seed) - local height_min = -31000 - local height_max = -32 - if maxp.y < height_min or minp.y > height_max then - return - end - local y_min = math.max(minp.y, height_min) - local y_max = math.min(maxp.y, height_max) - local volume = (maxp.x - minp.x + 1) * (y_max - y_min + 1) * (maxp.z - minp.z + 1) - local pr = PseudoRandom(seed + 9324342) - local max_num_nyancats = math.floor(volume / (16 * 16 * 16)) - for i = 1, max_num_nyancats do - if pr:next(0, 1000) == 0 then - local x0 = pr:next(minp.x, maxp.x) - local y0 = pr:next(minp.y, maxp.y) - local z0 = pr:next(minp.z, maxp.z) - local p0 = {x = x0, y = y0, z = z0} - default.make_nyancat(p0, pr:next(0, 3), pr:next(3, 15)) - end - end -end - - -- -- Detect mapgen to select functions -- --- Mods using singlenode mapgen can call these functions to enable --- the use of minetest.generate_ores or minetest.generate_decorations - local mg_name = minetest.get_mapgen_setting("mg_name") if mg_name == "v6" then default.register_ores() default.register_mgv6_decorations() - minetest.register_on_generated(default.generate_nyancats) -elseif mg_name ~= "singlenode" then +else default.register_biomes() default.register_ores() default.register_decorations() - minetest.register_on_generated(default.generate_nyancats) end diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua index 86d5565c..31e063d4 100644 --- a/mods/default/nodes.lua +++ b/mods/default/nodes.lua @@ -178,8 +178,6 @@ Misc ---- default:cloud -default:nyancat -default:nyancat_rainbow --]] @@ -1902,26 +1900,3 @@ minetest.register_node("default:cloud", { sounds = default.node_sound_defaults(), groups = {not_in_creative_inventory = 1}, }) - -minetest.register_node("default:nyancat", { - description = "Nyan Cat", - tiles = {"default_nc_side.png", "default_nc_side.png", "default_nc_side.png", - "default_nc_side.png", "default_nc_back.png", "default_nc_front.png"}, - paramtype2 = "facedir", - groups = {cracky = 2}, - is_ground_content = false, - legacy_facedir_simple = true, - sounds = default.node_sound_defaults(), -}) - -minetest.register_node("default:nyancat_rainbow", { - description = "Nyan Cat Rainbow", - tiles = { - "default_nc_rb.png^[transformR90", "default_nc_rb.png^[transformR90", - "default_nc_rb.png", "default_nc_rb.png" - }, - paramtype2 = "facedir", - groups = {cracky = 2}, - is_ground_content = false, - sounds = default.node_sound_defaults(), -}) diff --git a/mods/nyancat/README.txt b/mods/nyancat/README.txt new file mode 100644 index 00000000..95850c92 --- /dev/null +++ b/mods/nyancat/README.txt @@ -0,0 +1,29 @@ +Minetest Game mod: nyancat +========================== + +License of source code: +----------------------- +Copyright (C) 2011-2012 celeron55, Perttu Ahola + +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. + +http://www.gnu.org/licenses/lgpl-2.1.html + +License of media (textures and sounds) +-------------------------------------- +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +http://creativecommons.org/licenses/by-sa/3.0/ + +Authors of media files +----------------------- +Everything not listed in here: +Copyright (C) 2010-2012 celeron55, Perttu Ahola + +VanessaE (WTFPL): + default_nc_back.png + default_nc_front.png + default_nc_rb.png + default_nc_side.png diff --git a/mods/nyancat/depends.txt b/mods/nyancat/depends.txt new file mode 100644 index 00000000..4ad96d51 --- /dev/null +++ b/mods/nyancat/depends.txt @@ -0,0 +1 @@ +default diff --git a/mods/nyancat/init.lua b/mods/nyancat/init.lua new file mode 100644 index 00000000..6c1d9036 --- /dev/null +++ b/mods/nyancat/init.lua @@ -0,0 +1,84 @@ +minetest.register_node("nyancat:nyancat", { + description = "Nyan Cat", + tiles = {"default_nc_side.png", "default_nc_side.png", "default_nc_side.png", + "default_nc_side.png", "default_nc_back.png", "default_nc_front.png"}, + paramtype2 = "facedir", + groups = {cracky = 2}, + is_ground_content = false, + legacy_facedir_simple = true, + sounds = default.node_sound_defaults(), +}) + +minetest.register_node("nyancat:nyancat_rainbow", { + description = "Nyan Cat Rainbow", + tiles = { + "default_nc_rb.png^[transformR90", "default_nc_rb.png^[transformR90", + "default_nc_rb.png", "default_nc_rb.png" + }, + paramtype2 = "facedir", + groups = {cracky = 2}, + is_ground_content = false, + sounds = default.node_sound_defaults(), +}) + +minetest.register_craft({ + type = "fuel", + recipe = "nyancat:nyancat", + burntime = 1, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "nyancat:nyancat_rainbow", + burntime = 1, +}) + +nyancat = {} + +function nyancat.place(pos, facedir, length) + if facedir > 3 then + facedir = 0 + end + local tailvec = minetest.facedir_to_dir(facedir) + local p = {x = pos.x, y = pos.y, z = pos.z} + minetest.set_node(p, {name = "nyancat:nyancat", param2 = facedir}) + for i = 1, length do + p.x = p.x + tailvec.x + p.z = p.z + tailvec.z + minetest.set_node(p, {name = "nyancat:nyancat_rainbow", param2 = facedir}) + end +end + +function nyancat.generate(minp, maxp, seed) + local height_min = -31000 + local height_max = -32 + if maxp.y < height_min or minp.y > height_max then + return + end + local y_min = math.max(minp.y, height_min) + local y_max = math.min(maxp.y, height_max) + local volume = (maxp.x - minp.x + 1) * (y_max - y_min + 1) * (maxp.z - minp.z + 1) + local pr = PseudoRandom(seed + 9324342) + local max_num_nyancats = math.floor(volume / (16 * 16 * 16)) + for i = 1, max_num_nyancats do + if pr:next(0, 1000) == 0 then + local x0 = pr:next(minp.x, maxp.x) + local y0 = pr:next(minp.y, maxp.y) + local z0 = pr:next(minp.z, maxp.z) + local p0 = {x = x0, y = y0, z = z0} + nyancat.place(p0, pr:next(0, 3), pr:next(3, 15)) + end + end +end + +minetest.register_on_generated(function(minp, maxp, seed) + nyancat.generate(minp, maxp, seed) +end) + +-- Legacy +minetest.register_alias("default:nyancat", "nyancat:nyancat") +minetest.register_alias("default:nyancat_rainbow", "nyancat:nyancat_rainbow") +minetest.register_alias("nyancat", "nyancat:nyancat") +minetest.register_alias("nyancat_rainbow", "nyancat:nyancat_rainbow") +default.make_nyancat = nyancat.place +default.generate_nyancats = nyancat.generate diff --git a/mods/default/textures/default_nc_back.png b/mods/nyancat/textures/default_nc_back.png similarity index 100% rename from mods/default/textures/default_nc_back.png rename to mods/nyancat/textures/default_nc_back.png diff --git a/mods/default/textures/default_nc_front.png b/mods/nyancat/textures/default_nc_front.png similarity index 100% rename from mods/default/textures/default_nc_front.png rename to mods/nyancat/textures/default_nc_front.png diff --git a/mods/default/textures/default_nc_rb.png b/mods/nyancat/textures/default_nc_rb.png similarity index 100% rename from mods/default/textures/default_nc_rb.png rename to mods/nyancat/textures/default_nc_rb.png diff --git a/mods/default/textures/default_nc_side.png b/mods/nyancat/textures/default_nc_side.png similarity index 100% rename from mods/default/textures/default_nc_side.png rename to mods/nyancat/textures/default_nc_side.png From 9862bbc8e5bdb7ce1fd1878c6f40c23c2a3fbb72 Mon Sep 17 00:00:00 2001 From: Thomas--S Date: Sun, 17 Jul 2016 18:52:42 +0200 Subject: [PATCH 074/121] Doors: Same naming for trapdoors as for doors This makes register_trapdoor act the same as the register_door. If `name` isn't prefixed, it will be prefixed with "doors:". --- mods/doors/init.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index 0d3fd23f..914e385f 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -533,6 +533,10 @@ function _doors.trapdoor_toggle(pos, node, clicker) 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" From f018e06d9b7c8e8b14034c4dc8ac2dcffe5e0eab Mon Sep 17 00:00:00 2001 From: Thomas--S Date: Sun, 17 Jul 2016 20:37:29 +0200 Subject: [PATCH 075/121] Doors: Fix trapdoor on_blast Removing the node above was an error and is unnecessary --- mods/doors/init.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index 914e385f..abd24bde 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -576,7 +576,6 @@ function doors.register_trapdoor(name, def) else def.on_blast = function(pos, intensity) minetest.remove_node(pos) - minetest.remove_node({x = pos.x, y = pos.y + 1, z = pos.z}) return {name} end end From 1a2eb89f17d1228d81b44516c62cabfe13d093c3 Mon Sep 17 00:00:00 2001 From: paramat Date: Mon, 18 Jul 2016 22:50:00 +0100 Subject: [PATCH 076/121] Default/trees: Update to 'get_mapgen_setting()' --- mods/default/trees.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mods/default/trees.lua b/mods/default/trees.lua index 07071c74..dbcdcfaf 100644 --- a/mods/default/trees.lua +++ b/mods/default/trees.lua @@ -43,12 +43,12 @@ function default.grow_sapling(pos) return end - local mapgen = minetest.get_mapgen_params().mgname + local mg_name = minetest.get_mapgen_setting("mg_name") local node = minetest.get_node(pos) if node.name == "default:sapling" then minetest.log("action", "A sapling grows into a tree at ".. minetest.pos_to_string(pos)) - if mapgen == "v6" then + if mg_name == "v6" then default.grow_tree(pos, random(1, 4) == 1) else default.grow_new_apple_tree(pos) @@ -56,7 +56,7 @@ function default.grow_sapling(pos) elseif node.name == "default:junglesapling" then minetest.log("action", "A jungle sapling grows into a tree at ".. minetest.pos_to_string(pos)) - if mapgen == "v6" then + if mg_name == "v6" then default.grow_jungle_tree(pos) else default.grow_new_jungle_tree(pos) @@ -65,7 +65,7 @@ function default.grow_sapling(pos) minetest.log("action", "A pine sapling grows into a tree at ".. minetest.pos_to_string(pos)) local snow = is_snow_nearby(pos) - if mapgen == "v6" then + if mg_name == "v6" then default.grow_pine_tree(pos, snow) elseif snow then default.grow_new_snowy_pine_tree(pos) From 79dbafc13b256a38c13d7abd2ea7af0f50e64394 Mon Sep 17 00:00:00 2001 From: paramat Date: Mon, 18 Jul 2016 23:07:11 +0100 Subject: [PATCH 077/121] Nyancat: Fix texture names --- mods/nyancat/README.txt | 8 ++++---- mods/nyancat/init.lua | 9 +++++---- .../{default_nc_back.png => nyancat_back.png} | Bin .../{default_nc_front.png => nyancat_front.png} | Bin .../{default_nc_rb.png => nyancat_rainbow.png} | Bin .../{default_nc_side.png => nyancat_side.png} | Bin 6 files changed, 9 insertions(+), 8 deletions(-) rename mods/nyancat/textures/{default_nc_back.png => nyancat_back.png} (100%) rename mods/nyancat/textures/{default_nc_front.png => nyancat_front.png} (100%) rename mods/nyancat/textures/{default_nc_rb.png => nyancat_rainbow.png} (100%) rename mods/nyancat/textures/{default_nc_side.png => nyancat_side.png} (100%) diff --git a/mods/nyancat/README.txt b/mods/nyancat/README.txt index 95850c92..2e7de71d 100644 --- a/mods/nyancat/README.txt +++ b/mods/nyancat/README.txt @@ -23,7 +23,7 @@ Everything not listed in here: Copyright (C) 2010-2012 celeron55, Perttu Ahola VanessaE (WTFPL): - default_nc_back.png - default_nc_front.png - default_nc_rb.png - default_nc_side.png + nyancat_front.png + nyancat_back.png + nyancat_side.png + nyancat_rainbow.png diff --git a/mods/nyancat/init.lua b/mods/nyancat/init.lua index 6c1d9036..677ed50a 100644 --- a/mods/nyancat/init.lua +++ b/mods/nyancat/init.lua @@ -1,7 +1,7 @@ minetest.register_node("nyancat:nyancat", { description = "Nyan Cat", - tiles = {"default_nc_side.png", "default_nc_side.png", "default_nc_side.png", - "default_nc_side.png", "default_nc_back.png", "default_nc_front.png"}, + tiles = {"nyancat_side.png", "nyancat_side.png", "nyancat_side.png", + "nyancat_side.png", "nyancat_back.png", "nyancat_front.png"}, paramtype2 = "facedir", groups = {cracky = 2}, is_ground_content = false, @@ -12,8 +12,9 @@ minetest.register_node("nyancat:nyancat", { minetest.register_node("nyancat:nyancat_rainbow", { description = "Nyan Cat Rainbow", tiles = { - "default_nc_rb.png^[transformR90", "default_nc_rb.png^[transformR90", - "default_nc_rb.png", "default_nc_rb.png" + "nyancat_rainbow.png^[transformR90", + "nyancat_rainbow.png^[transformR90", + "nyancat_rainbow.png" }, paramtype2 = "facedir", groups = {cracky = 2}, diff --git a/mods/nyancat/textures/default_nc_back.png b/mods/nyancat/textures/nyancat_back.png similarity index 100% rename from mods/nyancat/textures/default_nc_back.png rename to mods/nyancat/textures/nyancat_back.png diff --git a/mods/nyancat/textures/default_nc_front.png b/mods/nyancat/textures/nyancat_front.png similarity index 100% rename from mods/nyancat/textures/default_nc_front.png rename to mods/nyancat/textures/nyancat_front.png diff --git a/mods/nyancat/textures/default_nc_rb.png b/mods/nyancat/textures/nyancat_rainbow.png similarity index 100% rename from mods/nyancat/textures/default_nc_rb.png rename to mods/nyancat/textures/nyancat_rainbow.png diff --git a/mods/nyancat/textures/default_nc_side.png b/mods/nyancat/textures/nyancat_side.png similarity index 100% rename from mods/nyancat/textures/default_nc_side.png rename to mods/nyancat/textures/nyancat_side.png From 72f4c6be483a52a1ad56c7de5a75f56938ef7db1 Mon Sep 17 00:00:00 2001 From: Thomas--S Date: Mon, 18 Jul 2016 07:14:01 +0200 Subject: [PATCH 078/121] Doors: Fix orientations of trapdoor textures --- mods/doors/init.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index abd24bde..20dbb855 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -603,8 +603,10 @@ function doors.register_trapdoor(name, def) type = "fixed", fixed = {-0.5, -0.5, -0.5, 0.5, -6/16, 0.5} } - def_closed.tiles = {def.tile_front, def.tile_front, def.tile_side, def.tile_side, - def.tile_side, def.tile_side} + def_closed.tiles = {def.tile_front, + def.tile_front .. '^[transformFY', + def.tile_side, def.tile_side, + def.tile_side, def.tile_side} def_opened.node_box = { type = "fixed", @@ -617,7 +619,8 @@ function doors.register_trapdoor(name, def) def_opened.tiles = {def.tile_side, def.tile_side, def.tile_side .. '^[transform3', def.tile_side .. '^[transform1', - def.tile_front, def.tile_front} + def.tile_front .. '^[transform46', + def.tile_front .. '^[transform6'} def_opened.drop = name_closed def_opened.groups.not_in_creative_inventory = 1 From db129f4ca077f5b3dbdb524511bedd13bc9207f3 Mon Sep 17 00:00:00 2001 From: paramat Date: Tue, 19 Jul 2016 22:26:02 +0100 Subject: [PATCH 079/121] Flowers: Fix waterlily on-place itemstack code Add 'record_protection_violation()' --- mods/flowers/init.lua | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/mods/flowers/init.lua b/mods/flowers/init.lua index 2ec661e1..83a05fad 100644 --- a/mods/flowers/init.lua +++ b/mods/flowers/init.lua @@ -243,16 +243,20 @@ minetest.register_node("flowers:waterlily", { local def = minetest.registered_nodes[node] local player_name = placer:get_player_name() - if def and def.liquidtype == "source" and minetest.get_item_group(node, "water") > 0 then + if def and def.liquidtype == "source" and + minetest.get_item_group(node, "water") > 0 then if not minetest.is_protected(pos, player_name) then - minetest.set_node(pos, {name = "flowers:waterlily", param2 = math.random(0, 3)}) + minetest.set_node(pos, {name = "flowers:waterlily", + param2 = math.random(0, 3)}) + if not minetest.setting_getbool("creative_mode") then + itemstack:take_item() + end else - minetest.chat_send_player(player_name, "This area is protected") - end - if not minetest.setting_getbool("creative_mode") then - itemstack:take_item() + minetest.chat_send_player(player_name, "Node is protected") + minetest.record_protection_violation(pos, player_name) end end + return itemstack end }) From 2df7ce20dd8290b677cc32c4b4a1bde3654c137f Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Mon, 21 Mar 2016 21:22:26 +0000 Subject: [PATCH 080/121] Bones: Ability to change bones mode. Tidy up code Add 'bones_mode' setting to minetest.conf -> Modes: bones, drop, keep Remove table 'bones' Add minetest.conf.example description Remove protection check from may_replace --- minetest.conf.example | 6 ++ mods/bones/init.lua | 148 +++++++++++++++++++++++------------------- 2 files changed, 88 insertions(+), 66 deletions(-) diff --git a/minetest.conf.example b/minetest.conf.example index 813f1957..d6e00000 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -5,6 +5,12 @@ # Whether creative mode (fast digging of all blocks, unlimited resources) should be enabled #creative_mode = false +# Sets the behaviour of the inventory items when a player dies. +# "bones": Store all items inside a bone node but drop items if inside protected area +# "drop": Drop all items on the ground +# "keep": Player keeps all items +#bones_mode = "bones" + # The time in seconds after which the bones of a dead player can be looted by everyone # 0 to disable #share_bones_time = 1200 diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 08a422d0..a39b23d4 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -1,7 +1,5 @@ -- Minetest 0.4 mod: bones --- See README.txt for licensing and other information. - -bones = {} +-- See README.txt for licensing and other information. local function is_owner(pos, name) local owner = minetest.get_meta(pos):get_string("owner") @@ -11,7 +9,7 @@ local function is_owner(pos, name) return false end -bones.bones_formspec = +local bones_formspec = "size[8,9]" .. default.gui_bg .. default.gui_bg_img .. @@ -37,12 +35,12 @@ minetest.register_node("bones:bones", { "bones_front.png" }, paramtype2 = "facedir", - groups = {dig_immediate=2}, + groups = {dig_immediate = 2}, sounds = default.node_sound_dirt_defaults({ - footstep = {name="default_gravel_footstep", gain=0.5}, - dug = {name="default_gravel_footstep", gain=1.0}, + footstep = {name = "default_gravel_footstep", gain = 0.5}, + dug = {name = "default_gravel_footstep", gain = 1.0}, }), - + can_dig = function(pos, player) local inv = minetest.get_meta(pos):get_inventory() local name = "" @@ -51,46 +49,46 @@ minetest.register_node("bones:bones", { end return is_owner(pos, name) and inv:is_empty("main") end, - + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) if is_owner(pos, player:get_player_name()) then return count end return 0 end, - + allow_metadata_inventory_put = function(pos, listname, index, stack, player) return 0 end, - + allow_metadata_inventory_take = function(pos, listname, index, stack, player) if is_owner(pos, player:get_player_name()) then return stack:get_count() end return 0 end, - + on_metadata_inventory_take = function(pos, listname, index, stack, player) local meta = minetest.get_meta(pos) if meta:get_inventory():is_empty("main") then minetest.remove_node(pos) end end, - + on_punch = function(pos, node, player) - if(not is_owner(pos, player:get_player_name())) then + if not is_owner(pos, player:get_player_name()) then return end - - if(minetest.get_meta(pos):get_string("infotext") == "") then + + if minetest.get_meta(pos):get_string("infotext") == "" then return end - + local inv = minetest.get_meta(pos):get_inventory() local player_inv = player:get_inventory() local has_space = true - - for i=1,inv:get_size("main") do + + for i = 1, inv:get_size("main") do local stk = inv:get_stack("main", i) if player_inv:room_for_item("main", stk) then inv:set_stack("main", i, nil) @@ -100,7 +98,7 @@ minetest.register_node("bones:bones", { break end end - + -- remove bones if player emptied them if has_space then if player_inv:room_for_item("main", {name = "bones:bones"}) then @@ -111,12 +109,12 @@ minetest.register_node("bones:bones", { minetest.remove_node(pos) end end, - + on_timer = function(pos, elapsed) local meta = minetest.get_meta(pos) local time = meta:get_int("time") + elapsed if time >= share_bones_time then - meta:set_string("infotext", meta:get_string("owner").."'s old bones") + meta:set_string("infotext", meta:get_string("owner") .. "'s old bones") meta:set_string("owner", "") else meta:set_int("time", time) @@ -131,13 +129,9 @@ local function may_replace(pos, player) local node_name = minetest.get_node(pos).name local node_definition = minetest.registered_nodes[node_name] - -- if the node is unknown, we let the protection mod decide - -- this is consistent with when a player could dig or not dig it - -- unknown decoration would often be removed - -- while unknown building materials in use would usually be left + -- if the node is unknown, we return false if not node_definition then - -- only replace nodes that are not protected - return not minetest.is_protected(pos, player:get_player_name()) + return false end -- allow replacing air and liquids @@ -157,70 +151,92 @@ local function may_replace(pos, player) return node_definition.buildable_to and not minetest.is_protected(pos, player:get_player_name()) end +local drop = function(pos, itemstack) + local obj = core.add_item(pos, itemstack:take_item(itemstack:get_count())) + if obj then + obj:setvelocity({ + x = math.random(-10, 10) / 9, + y = 5, + z = math.random(-10, 10) / 9, + }) + end +end + minetest.register_on_dieplayer(function(player) - if minetest.setting_getbool("creative_mode") then + + local bones_mode = minetest.setting_get("bones_mode") or "bones" + if bones_mode ~= "bones" and bones_mode ~= "drop" and bones_mode ~= "keep" then + bones_mode = "bones" + end + + -- return if keep inventory set or in creative mode + if bones_mode == "keep" or minetest.setting_getbool("creative_mode") then return end - + local player_inv = player:get_inventory() if player_inv:is_empty("main") and player_inv:is_empty("craft") then return end - local pos = player:getpos() - pos.x = math.floor(pos.x+0.5) - pos.y = math.floor(pos.y+0.5) - pos.z = math.floor(pos.z+0.5) - local param2 = minetest.dir_to_facedir(player:get_look_dir()) + local pos = vector.round(player:getpos()) local player_name = player:get_player_name() - if (not may_replace(pos, player)) then - if (may_replace({x=pos.x, y=pos.y+1, z=pos.z}, player)) then - -- drop one node above if there's space - -- this should solve most cases of protection related deaths in which players dig straight down - -- yet keeps the bones reachable - pos.y = pos.y+1 - else - -- drop items instead of delete - for i=1,player_inv:get_size("main") do - minetest.add_item(pos, player_inv:get_stack("main", i)) - end - for i=1,player_inv:get_size("craft") do - minetest.add_item(pos, player_inv:get_stack("craft", i)) - end - -- empty lists main and craft - player_inv:set_list("main", {}) - player_inv:set_list("craft", {}) - return - end + -- check if it's possible to place bones, if not go 1 higher + if bones_mode == "bones" and not may_replace(pos, player) then + pos.y = pos.y + 1 end - - minetest.set_node(pos, {name="bones:bones", param2=param2}) - + + -- still cannot place bones? change mode to 'drop' + if bones_mode == "bones" and not may_replace(pos, player) then + bones_mode = "drop" + end + + if bones_mode == "drop" then + + -- drop inventory items + for i = 1, player_inv:get_size("main") do + drop(pos, player_inv:get_stack("main", i)) + end + player_inv:set_list("main", {}) + + -- drop crafting grid items + for i = 1, player_inv:get_size("craft") do + drop(pos, player_inv:get_stack("craft", i)) + end + player_inv:set_list("craft", {}) + + drop(pos, ItemStack("bones:bones")) + return + end + + local param2 = minetest.dir_to_facedir(player:get_look_dir()) + minetest.set_node(pos, {name = "bones:bones", param2 = param2}) + local meta = minetest.get_meta(pos) local inv = meta:get_inventory() - inv:set_size("main", 8*4) + inv:set_size("main", 8 * 4) inv:set_list("main", player_inv:get_list("main")) - - for i=1,player_inv:get_size("craft") do + + for i = 1, player_inv:get_size("craft") do local stack = player_inv:get_stack("craft", i) if inv:room_for_item("main", stack) then inv:add_item("main", stack) else --drop if no space left - minetest.add_item(pos, stack) + drop(pos, stack) end end - + player_inv:set_list("main", {}) player_inv:set_list("craft", {}) - - meta:set_string("formspec", bones.bones_formspec) + + meta:set_string("formspec", bones_formspec) meta:set_string("owner", player_name) - + if share_bones_time ~= 0 then - meta:set_string("infotext", player_name.."'s fresh bones") + meta:set_string("infotext", player_name .. "'s fresh bones") if share_bones_time_early == 0 or not minetest.is_protected(pos, player_name) then meta:set_int("time", 0) From 0ac096991c51d664007ebb53b8117baca0271459 Mon Sep 17 00:00:00 2001 From: paramat Date: Tue, 19 Jul 2016 01:01:59 +0100 Subject: [PATCH 081/121] Default: Prevent placing sapling if grown tree intersects protection Add a global 'intersects protection' function to functions.lua for checking if a specified volume intersects with a protected volume. A 3D lattice of points are checked with an adjustable interval. Add a global 'sapling on place' function to avoid duplicated code in nodes.lua. --- mods/default/functions.lua | 40 +++++++++++++++ mods/default/nodes.lua | 101 +++++++++++++++++++++++++++++++------ mods/default/trees.lua | 46 +++++++++++++++++ 3 files changed, 172 insertions(+), 15 deletions(-) diff --git a/mods/default/functions.lua b/mods/default/functions.lua index f3bb97cd..a98d091f 100644 --- a/mods/default/functions.lua +++ b/mods/default/functions.lua @@ -481,3 +481,43 @@ minetest.register_abm({ end end }) + + +-- +-- Checks if specified volume intersects a protected volume +-- + +function default.intersects_protection(minp, maxp, player_name, interval) + -- 'interval' is the largest allowed interval for the 3D lattice of checks + + -- Compute the optimal float step 'd' for each axis so that all corners and + -- borders are checked. 'd' will be smaller or equal to 'interval'. + -- Subtracting 1e-4 ensures that the max co-ordinate will be reached by the + -- for loop (which might otherwise not be the case due to rounding errors). + local d = {} + for _, c in pairs({"x", "y", "z"}) do + if maxp[c] > minp[c] then + d[c] = (maxp[c] - minp[c]) / math.ceil((maxp[c] - minp[c]) / interval) - 1e-4 + elseif maxp[c] == minp[c] then + d[c] = 1 -- Any value larger than 0 to avoid division by zero + else -- maxp[c] < minp[c], print error and treat as protection intersected + minetest.log("error", "maxp < minp in 'default.intersects_protection()'") + return true + end + end + + for zf = minp.z, maxp.z, d.z do + local z = math.floor(zf + 0.5) + for yf = minp.y, maxp.y, d.y do + local y = math.floor(yf + 0.5) + for xf = minp.x, maxp.x, d.x do + local x = math.floor(xf + 0.5) + if minetest.is_protected({x = x, y = y, z = z}, player_name) then + return true + end + end + end + end + + return false +end diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua index 31e063d4..05d9f32d 100644 --- a/mods/default/nodes.lua +++ b/mods/default/nodes.lua @@ -500,9 +500,6 @@ minetest.register_node("default:sapling", { sunlight_propagates = true, walkable = false, on_timer = default.grow_sapling, - on_construct = function(pos) - minetest.get_node_timer(pos):start(math.random(2400,4800)) - end, selection_box = { type = "fixed", fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} @@ -510,6 +507,23 @@ minetest.register_node("default:sapling", { groups = {snappy = 2, dig_immediate = 3, flammable = 2, attached_node = 1, sapling = 1}, sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(2400,4800)) + end, + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:sapling", + -- minp, maxp to be checked, relative to sapling pos + -- minp_relative.y = 1 because sapling pos has been checked + {x = -2, y = 1, z = -2}, + {x = 2, y = 6, z = 2}, + -- maximum interval of interior volume check + 4) + + return itemstack + end, }) minetest.register_node("default:leaves", { @@ -624,9 +638,6 @@ minetest.register_node("default:junglesapling", { sunlight_propagates = true, walkable = false, on_timer = default.grow_sapling, - on_construct = function(pos) - minetest.get_node_timer(pos):start(math.random(2400,4800)) - end, selection_box = { type = "fixed", fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} @@ -634,6 +645,23 @@ minetest.register_node("default:junglesapling", { groups = {snappy = 2, dig_immediate = 3, flammable = 2, attached_node = 1, sapling = 1}, sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(2400,4800)) + end, + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:junglesapling", + -- minp, maxp to be checked, relative to sapling pos + -- minp_relative.y = 1 because sapling pos has been checked + {x = -2, y = 1, z = -2}, + {x = 2, y = 15, z = 2}, + -- maximum interval of interior volume check + 4) + + return itemstack + end, }) @@ -691,9 +719,6 @@ minetest.register_node("default:pine_sapling", { sunlight_propagates = true, walkable = false, on_timer = default.grow_sapling, - on_construct = function(pos) - minetest.get_node_timer(pos):start(math.random(2400,4800)) - end, selection_box = { type = "fixed", fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} @@ -701,6 +726,23 @@ minetest.register_node("default:pine_sapling", { groups = {snappy = 2, dig_immediate = 3, flammable = 2, attached_node = 1, sapling = 1}, sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(2400,4800)) + end, + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:pine_sapling", + -- minp, maxp to be checked, relative to sapling pos + -- minp_relative.y = 1 because sapling pos has been checked + {x = -2, y = 1, z = -2}, + {x = 2, y = 12, z = 2}, + -- maximum interval of interior volume check + 4) + + return itemstack + end, }) @@ -758,9 +800,6 @@ minetest.register_node("default:acacia_sapling", { sunlight_propagates = true, walkable = false, on_timer = default.grow_sapling, - on_construct = function(pos) - minetest.get_node_timer(pos):start(math.random(2400,4800)) - end, selection_box = { type = "fixed", fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} @@ -768,6 +807,23 @@ minetest.register_node("default:acacia_sapling", { groups = {snappy = 2, dig_immediate = 3, flammable = 2, attached_node = 1, sapling = 1}, sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(2400,4800)) + end, + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:acacia_sapling", + -- minp, maxp to be checked, relative to sapling pos + -- minp_relative.y = 1 because sapling pos has been checked + {x = -4, y = 1, z = -4}, + {x = 4, y = 6, z = 4}, + -- maximum interval of interior volume check + 4) + + return itemstack + end, }) minetest.register_node("default:aspen_tree", { @@ -824,9 +880,6 @@ minetest.register_node("default:aspen_sapling", { sunlight_propagates = true, walkable = false, on_timer = default.grow_sapling, - on_construct = function(pos) - minetest.get_node_timer(pos):start(math.random(2400,4800)) - end, selection_box = { type = "fixed", fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} @@ -834,7 +887,25 @@ minetest.register_node("default:aspen_sapling", { groups = {snappy = 2, dig_immediate = 3, flammable = 2, attached_node = 1, sapling = 1}, sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(2400,4800)) + end, + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:aspen_sapling", + -- minp, maxp to be checked, relative to sapling pos + -- minp_relative.y = 1 because sapling pos has been checked + {x = -2, y = 1, z = -2}, + {x = 2, y = 12, z = 2}, + -- maximum interval of interior volume check + 4) + + return itemstack + end, }) + -- -- Ores -- diff --git a/mods/default/trees.lua b/mods/default/trees.lua index dbcdcfaf..7df35666 100644 --- a/mods/default/trees.lua +++ b/mods/default/trees.lua @@ -418,6 +418,7 @@ function default.grow_new_acacia_tree(pos) path, "random", nil, false) end + -- New aspen tree function default.grow_new_aspen_tree(pos) @@ -426,3 +427,48 @@ function default.grow_new_aspen_tree(pos) minetest.place_schematic({x = pos.x - 2, y = pos.y - 1, z = pos.z - 2}, path, "0", nil, false) end + + +-- +-- Sapling 'on place' function to check protection of node and resulting tree volume +-- + +function default.sapling_on_place(itemstack, placer, pointed_thing, + sapling_name, minp_relative, maxp_relative, interval) + -- Position of sapling + local pos = pointed_thing.under + local node = minetest.get_node(pos) + local pdef = minetest.registered_nodes[node.name] + if not pdef or not pdef.buildable_to then + 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 player_name = placer:get_player_name() + -- Check sapling position for protection + if minetest.is_protected(pos, player_name) then + minetest.record_protection_violation(pos, player_name) + return itemstack + end + -- Check tree volume for protection + if not default.intersects_protection( + vector.add(pos, minp_relative), + vector.add(pos, maxp_relative), + player_name, + interval) then + minetest.set_node(pos, {name = sapling_name}) + if not minetest.setting_getbool("creative_mode") then + itemstack:take_item() + end + else + minetest.record_protection_violation(pos, player_name) + -- Print extra information to explain + minetest.chat_send_player(player_name, "Tree will intersect protection") + end + + return itemstack +end From ea49eb3f3d4bc910da3101d3fd1038e4c2242fbe Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Mon, 25 Jul 2016 17:42:42 +0200 Subject: [PATCH 082/121] Beds, boats: Replace deprecated get_look_yaw/set_look_yaw --- mods/beds/functions.lua | 4 ++-- mods/boats/init.lua | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mods/beds/functions.lua b/mods/beds/functions.lua index 5eed27d9..b1c2c977 100644 --- a/mods/beds/functions.lua +++ b/mods/beds/functions.lua @@ -70,7 +70,7 @@ local function lay_down(player, pos, bed_pos, state, skip) -- physics, eye_offset, etc player:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0}) - player:set_look_yaw(math.random(1, 180) / 100) + player:set_look_horizontal(math.random(1, 180) / 100) default.player_attached[name] = false player:set_physics_override(1, 1, 1) hud_flags.wielditem = true @@ -85,7 +85,7 @@ local function lay_down(player, pos, bed_pos, state, skip) -- physics, eye_offset, etc player:set_eye_offset({x = 0, y = -13, z = 0}, {x = 0, y = 0, z = 0}) local yaw, param2 = get_look_yaw(bed_pos) - player:set_look_yaw(yaw) + player:set_look_horizontal(yaw) local dir = minetest.facedir_to_dir(param2) local p = {x = bed_pos.x + dir.x / 2, y = bed_pos.y, z = bed_pos.z + dir.z / 2} player:set_physics_override(0, 0, 0) diff --git a/mods/boats/init.lua b/mods/boats/init.lua index caaef578..37cb916b 100644 --- a/mods/boats/init.lua +++ b/mods/boats/init.lua @@ -79,7 +79,7 @@ function boat.on_rightclick(self, clicker) minetest.after(0.2, function() default.player_set_animation(clicker, "sit" , 30) end) - self.object:setyaw(clicker:get_look_yaw() - math.pi / 2) + self.object:setyaw(clicker:get_look_horizontal() - math.pi / 2) end end From 4fba897a96a0fdd113632bc82a99a530c42e5c73 Mon Sep 17 00:00:00 2001 From: paramat Date: Sat, 30 Jul 2016 01:49:49 +0100 Subject: [PATCH 083/121] Bones: Improve bones textures Add mouth, remove jaw shadow, shade eyesockets. Darker shading for spine and rotate texture using ^[transform2 instead of inverting texture. Use 'node sound gravel defaults' for sounds. --- mods/bones/init.lua | 7 ++----- mods/bones/textures/bones_front.png | Bin 655 -> 656 bytes mods/bones/textures/bones_top.png | Bin 644 -> 662 bytes 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index a39b23d4..8c355426 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -27,7 +27,7 @@ local share_bones_time_early = tonumber(minetest.setting_get("share_bones_time_e minetest.register_node("bones:bones", { description = "Bones", tiles = { - "bones_top.png", + "bones_top.png^[transform2", "bones_bottom.png", "bones_side.png", "bones_side.png", @@ -36,10 +36,7 @@ minetest.register_node("bones:bones", { }, paramtype2 = "facedir", groups = {dig_immediate = 2}, - sounds = default.node_sound_dirt_defaults({ - footstep = {name = "default_gravel_footstep", gain = 0.5}, - dug = {name = "default_gravel_footstep", gain = 1.0}, - }), + sounds = default.node_sound_gravel_defaults(), can_dig = function(pos, player) local inv = minetest.get_meta(pos):get_inventory() diff --git a/mods/bones/textures/bones_front.png b/mods/bones/textures/bones_front.png index bfec3a11637e8d96a6d53d775085cabf20cd1241..1e52437017beddaad8f4febf9427cb5e95b81ce0 100644 GIT binary patch delta 602 zcmV-g0;THHmp65kTWSV9+n}6Mk<9ITeluD&+HoIQ0 zUteE8KR=htrBbThZZ8&#R1n8;u~>Y6f8W~K+0itOa~{XB>$>y#JPboAWvx~#m&?!3 z&tG3(2%6Dw{6?^eJu!r!C+un*2~MwUkgepA;f00S*=#OVHf~rvss${=H>>#?d|RVJc^<; zbUvTg7K=r-S{)1qdwY8T2qA=!^zaXFwOVOt0GUpwvwvEx3WdVsDr<#L>JN~vX8LI~3|d%d2<7<+qrV~qK} zUoMxs-BT_A$8kvlI-vA>$?8&@i80@l~ToGkr3i} o-h4hUl}b`d$8nTWySuyp07^y~%YEn0RR91007*qoM6N<$g5TsR{{R30 delta 601 zcmV-f0;c_t1&;-gL4OGmFdteH(D?uW0xn5JK~yNuby3Y~>OdI%OcR+p{xYHo77ZAr zRFQTet^`347rucn;S=~aeT^=hzrfI6GTB%fQ+xC55)3j(bdVduJ!D_Y2<#N$z^l&)L z=kw$7`2GFOIj`62yWLI*f*{CdvtM6dSFu=3k|aV%5CoQGZMR#`^B800a=B0_e0+TT z{{AkP%k%ln7-Nh@G))5l*L4XYVHjeJ5kkK2BZM-UOc;hQFE82(4DDcDpSn5($hkrS$sx`jUFR zUK2tL!*Co&a$R>andrJcolY-3aLy^Er_*V_-%G;%X0s9L2ZOPWm$sMYBdoW03!GI_ka8SK9kA3y}iA@zNXXZzx@3C z{ESAU=jUet&~;t*JWo-So0}WXxj6ruVYytYs)`V5G#U}ZFc3l*W3djURIElR-E207 zVTexi`MhOWl}bfI2nm0dWxc<@1HkR=tt`s`5Rb!!Vsr%d)&!EM~JA=RBLuDvDy; n_IA6?<#LQM(=<8f$z<{m*nc9f1|MgS00000NkvXXu0mjf<~JVP diff --git a/mods/bones/textures/bones_top.png b/mods/bones/textures/bones_top.png index 29320ce99b2d04e6aea36fa90c8c9336858ceb69..198a8a2ddeb5de43a9579e6ba2ed5eff001b3876 100644 GIT binary patch delta 608 zcmV-m0-yba1(pSnL4O_r5iVA{33dPg0yRlQK~yNubyB}-`cM=;wm0@dZbi636DVnr z;9x_kgF}ZxKqw9l4t)XNzz6Ulx_0X1?$EWxH^^e3hy{C9Qb|*h>#ZiO`|9( zl}h=1UI_8=@$vin`}6Z7rM$krPLf0s(lj*;W3gDEEXxo=XJ=M(Hk&HP7)Md$`+m;zJYCm?5RT(KK0Y3G zxVgEZlxmu0S=I^XJPbp}ao*qGm8$Eyiq~v5m4lRWwOSnxhxK}mOw$B_IF2pL0suAc zd_D(&*Vk9ox!>;rV7uL(pP!>7No?B=g24Cv+uPeprGG*Q>G%6;o0L*Qi066Z@mL4} z0EiI67;|0s<>kfmyfjT!0RTMD0|48$0bn+pDG+V9TTRn0E-s{$wrz9HIp_bz<(xCd z5JIMDVvHM&MowK(*L6b3)6>(@EpX{JiWia&$6soEFy%K%jIM; uky09lp=lap?ECw>R4VOuJN0>mLg5coB@Z+lWlxy^0000_8aBPxcN=Ff$}U!ff0k zQ3hFXg-sz=TDXmcMS3g22k?=61WOx1Yy~Te6{c7RLb64OFf$T#!CMS$aq*sRn2+B% z-ycs10l-?zIR~&-B220x%wrx3{<3wk?X{&wuCV=kD(A-rnADIMiDI z{QQi^<1h?gUS4LiSy2?$+N!F8Ab5Lw^E{6L7!HR@sXWi`?(XoL&d<-SwRxUfYX@g% zXLVh3&X>z2{-Z3*f*=6U_dVg9E2ZAw-zlYKS!%5rW4E`r0IsjE8DosG)oPXJdE2%C z$n*2FW1pU$0)J3SZNTgGT5H{P-RtWsA>{k}JC0-GKKi~_N@=Z)F^&X)b8d{Os_Nq6 z;_>mZD2lqSz3FsX*R?B>Qo7QQj}HJ*6uIZs)z#P6SJO13(P#jGQtJD@@B0Ae^Z9%} zkD@4wA|XUsmH_IyPLiZ;+oowq9LIg%bIzT~!^6X-hkuRXWHMPUmj?$2*4jZBhEht# z*l09z4vy-Q+}zv%NRote-ZYKY+M|>*#@v|i@9%%z!{z0r%j2MMZBR<3l*h-%CnqOT zN-5=ZIu$}lDYGo2l%{E#rm2@C2_dBGy1wr>q5n}?mO&7>6?sC4G))(ag}X{)%>Mqq zQi>2_j7RZ(KaOLqHGrzBwzjqgS(X6^!;o{nv$F%>>FJ3OQWOQH^yuhF2w{xrx^6O= c93CG21$LPQQWkH8TL1t607*qoM6N<$f^M!VPyhe` From 00c2dde4ea0d08224235649af25d23a4c49b15b3 Mon Sep 17 00:00:00 2001 From: Tim Date: Sat, 30 Jul 2016 14:21:30 +0200 Subject: [PATCH 084/121] Doors: Fix potential crashes, code improvements Fix crash when doors are placed under unknown nodes. Share a can_dig among doors, that does not crash on nil-player. Only set can_dig if we actually protect the door. --- mods/doors/init.lua | 45 ++++++++++++++------------------------------- 1 file changed, 14 insertions(+), 31 deletions(-) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index 20dbb855..88849652 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -203,6 +203,14 @@ local function on_place_node(place_to, newnode, end end +local function can_dig_door(pos, digger) + local digger_name = digger and digger:get_player_name() + if digger_name and minetest.get_player_privs(digger_name).protection_bypass then + return true + end + return minetest.get_meta(pos):get_string("doors_owner") == digger_name +end + function doors.register(name, def) if not name:find(":") then name = "doors:" .. name @@ -273,8 +281,10 @@ function doors.register(name, def) end local above = {x = pos.x, y = pos.y + 1, z = pos.z} - if not minetest.registered_nodes[ - minetest.get_node(above).name].buildable_to then + 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 @@ -336,21 +346,6 @@ function doors.register(name, def) end def.recipe = nil - local can_dig = function(pos, digger) - if not def.protected then - return true - end - if minetest.check_player_privs(digger, "protection_bypass") then - return true - end - local meta = minetest.get_meta(pos) - local owner_name - if digger then - owner_name = digger:get_player_name() - end - return meta:get_string("doors_owner") == owner_name - end - if not def.sounds then def.sounds = default.node_sound_wood_defaults() end @@ -379,14 +374,12 @@ function doors.register(name, def) minetest.remove_node({x = pos.x, y = pos.y + 1, z = pos.z}) nodeupdate({x = pos.x, y = pos.y + 1, z = pos.z}) end - def.can_dig = function(pos, player) - return can_dig(pos, player) - 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 else def.on_blast = function(pos, intensity) @@ -540,16 +533,6 @@ function doors.register_trapdoor(name, def) local name_closed = name local name_opened = name.."_open" - local function check_player_priv(pos, player) - if not def.protected or - minetest.check_player_privs(player, "protection_bypass") then - return true - end - local meta = minetest.get_meta(pos) - local player_name = player and player:get_player_name() - return meta:get_string("doors_owner") == player_name - end - def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) _doors.trapdoor_toggle(pos, node, clicker) return itemstack @@ -560,9 +543,9 @@ function doors.register_trapdoor(name, def) def.paramtype = "light" def.paramtype2 = "facedir" def.is_ground_content = false - def.can_dig = check_player_priv 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) From 265c40b5584661bd51087dcf755195c8ef11a4a4 Mon Sep 17 00:00:00 2001 From: paramat Date: Wed, 3 Aug 2016 01:35:20 +0100 Subject: [PATCH 085/121] Doors: Trim open fence gate collision box Previously, the collision box extended into an empty node, causing falling node objects to land on the open gate but not transform back into normal nodes. Now fallng node objects will fall through and either side of the end of the open gate and transform back. --- mods/doors/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index 88849652..3e67ef44 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -706,7 +706,7 @@ function doors.register_fencegate(name, def) fence_open.collision_box = { type = "fixed", fixed = {{-1/2, -1/2, -1/4, -3/8, 1/2, 1/4}, - {-5/8, -3/8, -14/16, -3/8, 3/8, 0}}, + {-5/8, -3/8, -1/2, -3/8, 3/8, 0}}, } minetest.register_node(":" .. name .. "_closed", fence_closed) From 6c83ea0b482545517632907498eecec9c7e6012f Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Wed, 3 Aug 2016 09:10:09 +0100 Subject: [PATCH 086/121] TNT: Fix bug with huge stacks This fixes the TNT bug that can crash game when blowing up a container which holds huge stacks above the norm... e.g. give yourself 65535 snow, place in chest, blow up, stalled! --- mods/tnt/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/tnt/init.lua b/mods/tnt/init.lua index c5aa95c9..2e82c4ed 100644 --- a/mods/tnt/init.lua +++ b/mods/tnt/init.lua @@ -47,7 +47,7 @@ end local function eject_drops(drops, pos, radius) local drop_pos = vector.new(pos) for _, item in pairs(drops) do - local count = item:get_count() + local count = math.min(item:get_count(), 99) while count > 0 do local take = math.max(1,math.min(radius * radius, count, From 60cf3f85b6e661482ec2705cadbdc1b04e388d19 Mon Sep 17 00:00:00 2001 From: Tim Date: Tue, 2 Aug 2016 20:10:57 +0200 Subject: [PATCH 087/121] Doors: Allow the screwdriver to rotate doors around y-axis. Keep other axis' disabled to prevent the hidden placeholder node to become irremovable to players. --- mods/doors/init.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index 3e67ef44..b4cf90ff 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -374,9 +374,7 @@ function doors.register(name, def) minetest.remove_node({x = pos.x, y = pos.y + 1, z = pos.z}) nodeupdate({x = pos.x, y = pos.y + 1, z = pos.z}) end - def.on_rotate = function(pos, node, user, mode, new_param2) - return false - end + def.on_rotate = screwdriver and screwdriver.rotate_simple or false if def.protected then def.can_dig = can_dig_door From 20fa037313d681e5986708b60c1143081aaad318 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 5 Aug 2016 12:14:33 +0200 Subject: [PATCH 088/121] Screwdriver: disallow rotation with `on_rotate = false` Other screwdriver mods, or mods that cause rotation, might operate without the screwdriver mod loaded and have `screwdriver.disallow` unavailable. This allows nodes to default to full-disallow rather than full-rotation in such a situation. --- game_api.txt | 2 +- mods/screwdriver/init.lua | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/game_api.txt b/game_api.txt index 581d76cc..2f0715f8 100644 --- a/game_api.txt +++ b/game_api.txt @@ -348,7 +348,7 @@ To use it, add the `on_screwdriver` function to the node definition. * `new_param2` the new value of param2 that would have been set if on_rotate wasn't there * return value: false to disallow rotation, nil to keep default behaviour, true to allow it but to indicate that changed have already been made (so the screwdriver will wear out) - * use `on_rotate = screwdriver.disallow` to always disallow rotation + * use `on_rotate = false` to always disallow rotation * use `on_rotate = screwdriver.rotate_simple` to allow only face rotation diff --git a/mods/screwdriver/init.lua b/mods/screwdriver/init.lua index 5e6df62f..e73b618f 100644 --- a/mods/screwdriver/init.lua +++ b/mods/screwdriver/init.lua @@ -64,6 +64,7 @@ screwdriver.handler = function(itemstack, user, pointed_thing, mode, uses) end else if not ndef or not ndef.paramtype2 == "facedir" or + ndef.on_rotate == false or (ndef.drawtype == "nodebox" and not ndef.node_box.type == "fixed") or node.param2 == nil then From b408e9cce608fd8988d1112a61cb315e18dcff25 Mon Sep 17 00:00:00 2001 From: Tim Date: Sun, 26 Jun 2016 17:12:40 +0200 Subject: [PATCH 089/121] Let Travis-CI automatically run luacheck on the game --- .luacheckrc | 17 +++++++++++++++++ .travis.yml | 14 ++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 .luacheckrc create mode 100644 .travis.yml diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 00000000..f087d303 --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,17 @@ +unused_args = false +allow_defined_top = true + +read_globals = { + "DIR_DELIM", + "minetest", "core", + "dump", + "vector", "nodeupdate", + "VoxelManip", "VoxelArea", + "PseudoRandom", "ItemStack", +} + +-- Overwrites minetest.handle_node_drops +files["mods/creative/init.lua"].globals = { "minetest" } + +-- Don't report on legacy definitions of globals. +files["mods/default/legacy.lua"].global = false diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..805fe08c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +language: generic + +branches: + only: + - master + +sudo: required + +before_install: + - sudo apt-get update + - sudo apt-get install -y luarocks + - sudo luarocks install luacheck + +script: luacheck --no-color ./mods From 76211624acb92bad1a933fd040bedf05c87c06e5 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 5 Aug 2016 14:55:43 +0200 Subject: [PATCH 090/121] Use minetest instead of core namespace, discourage via luacheck --- mods/bones/init.lua | 2 +- mods/bucket/init.lua | 2 +- mods/doors/init.lua | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 8c355426..2a54ee06 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -149,7 +149,7 @@ local function may_replace(pos, player) end local drop = function(pos, itemstack) - local obj = core.add_item(pos, itemstack:take_item(itemstack:get_count())) + local obj = minetest.add_item(pos, itemstack:take_item(itemstack:get_count())) if obj then obj:setvelocity({ x = math.random(-10, 10) / 9, diff --git a/mods/bucket/init.lua b/mods/bucket/init.lua index 3770be6a..a7cb0f27 100644 --- a/mods/bucket/init.lua +++ b/mods/bucket/init.lua @@ -141,7 +141,7 @@ minetest.register_craftitem("bucket:bucket_empty", { else local pos = user:getpos() pos.y = math.floor(pos.y + 0.5) - core.add_item(pos, liquiddef.itemname) + minetest.add_item(pos, liquiddef.itemname) end -- set to return empty buckets minus 1 diff --git a/mods/doors/init.lua b/mods/doors/init.lua index b4cf90ff..86f5f7e7 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -185,7 +185,7 @@ end local function on_place_node(place_to, newnode, placer, oldnode, itemstack, pointed_thing) -- Run script hook - for _, callback in ipairs(core.registered_on_placenodes) do + 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 = From 14b99a72a90bcfe6712caa5c50255bce2e880b37 Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Thu, 4 Aug 2016 10:22:41 +0100 Subject: [PATCH 091/121] Tnt: Limit blown up dropped stacks to stack_max This replaces the hardcoded 99 item limit and instead uses the get_stack_max() limit for each item. --- mods/tnt/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/tnt/init.lua b/mods/tnt/init.lua index 2e82c4ed..3a397a78 100644 --- a/mods/tnt/init.lua +++ b/mods/tnt/init.lua @@ -47,7 +47,7 @@ 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(), 99) + 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, From 61a197ffd87aa0f813479012f93cc5965eb9017d Mon Sep 17 00:00:00 2001 From: DonBatman Date: Sun, 7 Aug 2016 17:23:44 -0700 Subject: [PATCH 092/121] Changed snow nodebox to 'walkable = false' Allows walking in, and prevents being trapped in, 2 node high spaces. Simulates player's feet sinking into snow. Easier jumping up onto nodes with snow. --- mods/default/nodes.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua index 05d9f32d..5bf5458c 100644 --- a/mods/default/nodes.lua +++ b/mods/default/nodes.lua @@ -422,6 +422,7 @@ minetest.register_node("default:snow", { paramtype = "light", buildable_to = true, floodable = true, + walkable = false, drawtype = "nodebox", node_box = { type = "fixed", From 619ac5269393534c3f8ad8229514b17aa47eb513 Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Mon, 8 Aug 2016 10:56:13 +0100 Subject: [PATCH 093/121] Add labels to ABMs Useful for searches and the mod profiler. --- mods/default/functions.lua | 7 +++++++ mods/farming/nodes.lua | 1 + mods/fire/init.lua | 4 ++++ mods/flowers/init.lua | 2 ++ mods/stairs/init.lua | 1 + mods/tnt/init.lua | 1 + 6 files changed, 16 insertions(+) diff --git a/mods/default/functions.lua b/mods/default/functions.lua index a98d091f..07f358cb 100644 --- a/mods/default/functions.lua +++ b/mods/default/functions.lua @@ -111,6 +111,7 @@ default.cool_lava = function(pos, node) end minetest.register_abm({ + label = "Lava cooling", nodenames = {"default:lava_source", "default:lava_flowing"}, neighbors = {"group:water"}, interval = 1, @@ -189,6 +190,7 @@ function default.grow_papyrus(pos, node) end minetest.register_abm({ + label = "Grow cactus", nodenames = {"default:cactus"}, neighbors = {"group:sand"}, interval = 12, @@ -199,6 +201,7 @@ minetest.register_abm({ }) minetest.register_abm({ + label = "Grow papyrus", nodenames = {"default:papyrus"}, neighbors = {"default:dirt", "default:dirt_with_grass"}, interval = 14, @@ -303,6 +306,7 @@ default.after_place_leaves = function(pos, placer, itemstack, pointed_thing) end minetest.register_abm({ + label = "Leaf decay", nodenames = {"group:leafdecay"}, neighbors = {"air", "group:liquid"}, -- A low interval and a high inverse chance spreads the load @@ -384,6 +388,7 @@ minetest.register_abm({ -- minetest.register_abm({ + label = "Grass spread", nodenames = {"default:dirt"}, neighbors = { "default:dirt_with_grass", @@ -440,6 +445,7 @@ minetest.register_abm({ -- minetest.register_abm({ + label = "Grass covered", nodenames = { "default:dirt_with_grass", "default:dirt_with_dry_grass", @@ -466,6 +472,7 @@ minetest.register_abm({ -- minetest.register_abm({ + label = "Moss growth", nodenames = {"default:cobble", "stairs:slab_cobble", "stairs:stair_cobble"}, neighbors = {"group:water"}, interval = 16, diff --git a/mods/farming/nodes.lua b/mods/farming/nodes.lua index c011df1e..9fa66c30 100644 --- a/mods/farming/nodes.lua +++ b/mods/farming/nodes.lua @@ -94,6 +94,7 @@ minetest.register_node("farming:straw", { }) minetest.register_abm({ + label = "Farming soil", nodenames = {"group:field"}, interval = 15, chance = 4, diff --git a/mods/fire/init.lua b/mods/fire/init.lua index 34613da5..3e04264e 100644 --- a/mods/fire/init.lua +++ b/mods/fire/init.lua @@ -221,6 +221,7 @@ end -- Extinguish all flames quickly with water, snow, ice minetest.register_abm({ + label = "Extinguish flame", nodenames = {"fire:basic_flame", "fire:permanent_flame"}, neighbors = {"group:puts_out_fire"}, interval = 3, @@ -241,6 +242,7 @@ if minetest.setting_getbool("disable_fire") then -- Remove basic flames only minetest.register_abm({ + label = "Remove disabled fire", nodenames = {"fire:basic_flame"}, interval = 7, chance = 1, @@ -253,6 +255,7 @@ else -- Ignite neighboring nodes, add basic flames minetest.register_abm({ + label = "Ignite flame", nodenames = {"group:flammable"}, neighbors = {"group:igniter"}, interval = 7, @@ -273,6 +276,7 @@ else -- Remove flammable nodes minetest.register_abm({ + label = "Remove flammable nodes", nodenames = {"fire:basic_flame"}, neighbors = "group:flammable", interval = 5, diff --git a/mods/flowers/init.lua b/mods/flowers/init.lua index 83a05fad..8cf7ade2 100644 --- a/mods/flowers/init.lua +++ b/mods/flowers/init.lua @@ -110,6 +110,7 @@ function flowers.flower_spread(pos, node) end minetest.register_abm({ + label = "Flower spread", nodenames = {"group:flora"}, neighbors = {"default:dirt_with_grass", "default:dirt_with_dry_grass", "default:desert_sand"}, @@ -167,6 +168,7 @@ minetest.register_node("flowers:mushroom_brown", { -- Mushroom spread and death minetest.register_abm({ + label = "Mushroom spread", nodenames = {"flowers:mushroom_brown", "flowers:mushroom_red"}, interval = 11, chance = 50, diff --git a/mods/stairs/init.lua b/mods/stairs/init.lua index faaa92b3..001640fa 100644 --- a/mods/stairs/init.lua +++ b/mods/stairs/init.lua @@ -236,6 +236,7 @@ end if replace then minetest.register_abm({ + label = "Slab replace", nodenames = {"group:slabs_replace"}, interval = 16, chance = 1, diff --git a/mods/tnt/init.lua b/mods/tnt/init.lua index 3a397a78..1e6e29d5 100644 --- a/mods/tnt/init.lua +++ b/mods/tnt/init.lua @@ -506,6 +506,7 @@ if enable_tnt then }) minetest.register_abm({ + label = "TNT ignition", nodenames = {"group:tnt", "tnt:gunpowder"}, neighbors = {"fire:basic_flame", "default:lava_source", "default:lava_flowing"}, interval = 4, From 2ecbc43a7a299894d1ce0f7b27b262a0b6fba71c Mon Sep 17 00:00:00 2001 From: paramat Date: Sun, 7 Aug 2016 03:54:08 +0100 Subject: [PATCH 094/121] Default: Optimise and simplify leafdecay ABM, remove cache With thanks to contributor tenplus1 Remove leaf cache and globalstep accumulator limiter Use 'pos' instead of 'p0' Remove non-essential 'group:liquid' from 'neighbors' Increase chance value to 10 to compensate for disabled cache Disable 'catch-up' to avoid the ABM often becoming 10 times more intensive Remove use of 'do preserve' bool, instead simply 'return' Remove unnecessary checks for 'd' and 'd == 0' Don't 'get' n0, use already present 'node' instead Swap order two conditionals so that the one most likely is first --- mods/default/functions.lua | 104 +++++++++++-------------------------- 1 file changed, 31 insertions(+), 73 deletions(-) diff --git a/mods/default/functions.lua b/mods/default/functions.lua index 07f358cb..3c8a871a 100644 --- a/mods/default/functions.lua +++ b/mods/default/functions.lua @@ -126,6 +126,7 @@ minetest.register_abm({ -- -- optimized helper to put all items in an inventory into a drops list -- + function default.get_inventory_drops(pos, inventory, drops) local inv = minetest.get_meta(pos):get_inventory() local n = #drops @@ -229,6 +230,7 @@ end -- -- Fence registration helper -- + function default.register_fence(name, def) minetest.register_craft({ output = name .. " 4", @@ -286,16 +288,7 @@ end -- Leafdecay -- -default.leafdecay_trunk_cache = {} -default.leafdecay_enable_cache = true --- Spread the load of finding trunks -default.leafdecay_trunk_find_allow_accumulator = 0 - -minetest.register_globalstep(function(dtime) - local finds_per_second = 5000 - default.leafdecay_trunk_find_allow_accumulator = - math.floor(dtime * finds_per_second) -end) +-- Prevent decay of placed leaves default.after_place_leaves = function(pos, placer, itemstack, pointed_thing) if placer and not placer:get_player_control().sneak then @@ -305,80 +298,44 @@ default.after_place_leaves = function(pos, placer, itemstack, pointed_thing) end end +-- Leafdecay ABM + minetest.register_abm({ label = "Leaf decay", nodenames = {"group:leafdecay"}, - neighbors = {"air", "group:liquid"}, - -- A low interval and a high inverse chance spreads the load + neighbors = {"air"}, interval = 2, - chance = 5, + chance = 10, + catch_up = false, - action = function(p0, node, _, _) - --print("leafdecay ABM at "..p0.x..", "..p0.y..", "..p0.z..")") - local do_preserve = false - local d = minetest.registered_nodes[node.name].groups.leafdecay - if not d or d == 0 then - --print("not groups.leafdecay") + action = function(pos, node, _, _) + -- Check if leaf is placed + if node.param2 ~= 0 then return end - local n0 = minetest.get_node(p0) - if n0.param2 ~= 0 then - --print("param2 ~= 0") + + local rad = minetest.registered_nodes[node.name].groups.leafdecay + -- Assume ignore is a trunk, to make this + -- work at the border of a loaded area + if minetest.find_node_near(pos, rad, {"ignore", "group:tree"}) then return end - local p0_hash = nil - if default.leafdecay_enable_cache then - p0_hash = minetest.hash_node_position(p0) - local trunkp = default.leafdecay_trunk_cache[p0_hash] - if trunkp then - local n = minetest.get_node(trunkp) - local reg = minetest.registered_nodes[n.name] - -- Assume ignore is a trunk, to make the thing - -- work at the border of the active area - if n.name == "ignore" or (reg and reg.groups.tree and - reg.groups.tree ~= 0) then - --print("cached trunk still exists") - return - end - --print("cached trunk is invalid") - -- Cache is invalid - table.remove(default.leafdecay_trunk_cache, p0_hash) + -- Drop stuff + local itemstacks = minetest.get_node_drops(node.name) + for _, itemname in ipairs(itemstacks) do + if itemname ~= node.name or + minetest.get_item_group(node.name, "leafdecay_drop") ~= 0 then + local p_drop = { + x = pos.x - 0.5 + math.random(), + y = pos.y - 0.5 + math.random(), + z = pos.z - 0.5 + math.random(), + } + minetest.add_item(p_drop, itemname) end end - if default.leafdecay_trunk_find_allow_accumulator <= 0 then - return - end - default.leafdecay_trunk_find_allow_accumulator = - default.leafdecay_trunk_find_allow_accumulator - 1 - -- Assume ignore is a trunk, to make the thing - -- work at the border of the active area - local p1 = minetest.find_node_near(p0, d, {"ignore", "group:tree"}) - if p1 then - do_preserve = true - if default.leafdecay_enable_cache then - --print("caching trunk") - -- Cache the trunk - default.leafdecay_trunk_cache[p0_hash] = p1 - end - end - if not do_preserve then - -- Drop stuff other than the node itself - local itemstacks = minetest.get_node_drops(n0.name) - for _, itemname in ipairs(itemstacks) do - if minetest.get_item_group(n0.name, "leafdecay_drop") ~= 0 or - itemname ~= n0.name then - local p_drop = { - x = p0.x - 0.5 + math.random(), - y = p0.y - 0.5 + math.random(), - z = p0.z - 0.5 + math.random(), - } - minetest.add_item(p_drop, itemname) - end - end - -- Remove node - minetest.remove_node(p0) - nodeupdate(p0) - end + -- Remove node + minetest.remove_node(pos) + nodeupdate(pos) end }) @@ -440,6 +397,7 @@ minetest.register_abm({ end }) + -- -- Grass and dry grass removed in darkness -- From 1b745d401df6a5fda7845dd080f0f0bdb948b4c8 Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Wed, 10 Aug 2016 14:03:18 +0100 Subject: [PATCH 095/121] Default/trees: Faster 'is snow nearby' function Use 'find node near' instead of 'find nodes in area' --- mods/default/trees.lua | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mods/default/trees.lua b/mods/default/trees.lua index 7df35666..5cd7e156 100644 --- a/mods/default/trees.lua +++ b/mods/default/trees.lua @@ -27,10 +27,8 @@ end -- 'is snow nearby' function local function is_snow_nearby(pos) - return #minetest.find_nodes_in_area( - {x = pos.x - 1, y = pos.y - 1, z = pos.z - 1}, - {x = pos.x + 1, y = pos.y + 1, z = pos.z + 1}, - {"default:snow", "default:snowblock", "default:dirt_with_snow"}) > 0 + return minetest.find_node_near(pos, 1, + {"default:snow", "default:snowblock", "default:dirt_with_snow"}) end From 088385493ad0d64555609c8cb570c6e35eb8157a Mon Sep 17 00:00:00 2001 From: pithydon Date: Sat, 30 Jul 2016 17:15:42 -0600 Subject: [PATCH 096/121] Default: Improve fences inventory/wield images --- mods/default/nodes.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua index 5bf5458c..fe7cbb12 100644 --- a/mods/default/nodes.lua +++ b/mods/default/nodes.lua @@ -1857,6 +1857,8 @@ minetest.register_node("default:ladder_steel", { default.register_fence("default:fence_wood", { description = "Wooden Fence", texture = "default_fence_wood.png", + inventory_image = "default_fence_overlay.png^default_wood.png^default_fence_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_overlay.png^default_wood.png^default_fence_overlay.png^[makealpha:255,126,126", material = "default:wood", groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, sounds = default.node_sound_wood_defaults() @@ -1865,6 +1867,8 @@ default.register_fence("default:fence_wood", { default.register_fence("default:fence_acacia_wood", { description = "Acacia Fence", texture = "default_fence_acacia_wood.png", + inventory_image = "default_fence_overlay.png^default_acacia_wood.png^default_fence_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_overlay.png^default_acacia_wood.png^default_fence_overlay.png^[makealpha:255,126,126", material = "default:acacia_wood", groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, sounds = default.node_sound_wood_defaults() @@ -1873,6 +1877,8 @@ default.register_fence("default:fence_acacia_wood", { default.register_fence("default:fence_junglewood", { description = "Junglewood Fence", texture = "default_fence_junglewood.png", + inventory_image = "default_fence_overlay.png^default_junglewood.png^default_fence_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_overlay.png^default_junglewood.png^default_fence_overlay.png^[makealpha:255,126,126", material = "default:junglewood", groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, sounds = default.node_sound_wood_defaults() @@ -1881,6 +1887,8 @@ default.register_fence("default:fence_junglewood", { default.register_fence("default:fence_pine_wood", { description = "Pine Fence", texture = "default_fence_pine_wood.png", + inventory_image = "default_fence_overlay.png^default_pine_wood.png^default_fence_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_overlay.png^default_pine_wood.png^default_fence_overlay.png^[makealpha:255,126,126", material = "default:pine_wood", groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, sounds = default.node_sound_wood_defaults() @@ -1889,6 +1897,8 @@ default.register_fence("default:fence_pine_wood", { default.register_fence("default:fence_aspen_wood", { description = "Aspen Fence", texture = "default_fence_aspen_wood.png", + inventory_image = "default_fence_overlay.png^default_aspen_wood.png^default_fence_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_overlay.png^default_aspen_wood.png^default_fence_overlay.png^[makealpha:255,126,126", material = "default:aspen_wood", groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, sounds = default.node_sound_wood_defaults() From cabf80b743e64869092127608c4d9ef5e09592c0 Mon Sep 17 00:00:00 2001 From: paramat Date: Mon, 15 Aug 2016 21:29:52 +0100 Subject: [PATCH 097/121] Fire: Use 'enable fire' setting instead of 'disable fire' --- minetest.conf.example | 6 +++--- mods/fire/init.lua | 13 ++++++++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/minetest.conf.example b/minetest.conf.example index d6e00000..f5e4e85d 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -20,9 +20,9 @@ # 0 to disable. By default it is "share_bones_time" divide by four. #share_bones_time_early = 300 -# Whether standard fire should be disabled ('basic flame' nodes will disappear) -# 'permanent flame' nodes will remain with either setting -#disable_fire = false +# Whether fire should be enabled. If disabled, 'basic flame' nodes will disappear. +# 'permanent flame' nodes will remain with either setting. +#enable_fire = true # Whether the stuff in initial_stuff should be given to new players #give_initial_stuff = false diff --git a/mods/fire/init.lua b/mods/fire/init.lua index 3e04264e..6543ceef 100644 --- a/mods/fire/init.lua +++ b/mods/fire/init.lua @@ -235,9 +235,16 @@ minetest.register_abm({ }) --- Enable the following ABMs according to 'disable fire' setting +-- Enable the following ABMs according to 'enable fire' setting -if minetest.setting_getbool("disable_fire") then +local fire_enabled = minetest.setting_getbool("enable_fire") +if fire_enabled == nil then + -- New setting not specified, check for old setting. + -- If old setting is also not specified, 'not nil' is true. + fire_enabled = not minetest.setting_getbool("disable_fire") +end + +if not fire_enabled then -- Remove basic flames only @@ -250,7 +257,7 @@ if minetest.setting_getbool("disable_fire") then action = minetest.remove_node, }) -else +else -- Fire enabled -- Ignite neighboring nodes, add basic flames From 3be2f12bebca154ca7e8ba155e1b05bc189179e1 Mon Sep 17 00:00:00 2001 From: Megaf Date: Sun, 21 Aug 2016 21:18:32 +0100 Subject: [PATCH 098/121] Flowers: Add missing aliases for mushrooms from the mushroom mod --- mods/flowers/init.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mods/flowers/init.lua b/mods/flowers/init.lua index 8cf7ade2..e572357c 100644 --- a/mods/flowers/init.lua +++ b/mods/flowers/init.lua @@ -208,6 +208,8 @@ minetest.register_alias("flowers:mushroom_spores_brown", "flowers:mushroom_brown minetest.register_alias("flowers:mushroom_spores_red", "flowers:mushroom_red") minetest.register_alias("flowers:mushroom_fertile_brown", "flowers:mushroom_brown") minetest.register_alias("flowers:mushroom_fertile_red", "flowers:mushroom_red") +minetest.register_alias("mushroom:brown_natural", "flowers:mushroom_brown") +minetest.register_alias("mushroom:red_natural", "flowers:mushroom_red") -- From b0bc1af42a263e0e0f0a44e20e1d9e1ea08c70f6 Mon Sep 17 00:00:00 2001 From: tchncs Date: Thu, 25 Aug 2016 15:16:46 +0200 Subject: [PATCH 099/121] update submodule illuna --- mods/illuna | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/illuna b/mods/illuna index b544316a..60fe9391 160000 --- a/mods/illuna +++ b/mods/illuna @@ -1 +1 @@ -Subproject commit b544316aea4b6914d13ba53ad83091fadd09936d +Subproject commit 60fe9391c2f7eb5970bc5640a62ddfd69e0283f3 From 471d1cf159f7cae6efacf911c04fed2fd697c6d9 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sat, 27 Aug 2016 18:07:57 +0100 Subject: [PATCH 100/121] Add search on enter press to creative inventory --- mods/creative/init.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mods/creative/init.lua b/mods/creative/init.lua index 1e7b4087..cc7f81c8 100644 --- a/mods/creative/init.lua +++ b/mods/creative/init.lua @@ -125,7 +125,7 @@ creative.set_creative_formspec = function(player, start_i) tooltip[creative_clear;Reset] listring[current_player;main] ]] .. - "field[0.3,3.5;2.2,1;creative_filter;;" .. minetest.formspec_escape(inv.filter) .. "]" .. + "field[0.3,3.5;2.2,1;creative_filter;;" .. minetest.formspec_escape(inv.filter) .. ";false]" .. "listring[detached:creative_" .. player_name .. ";main]" .. "tabheader[0,0;creative_tabs;Crafting,All,Nodes,Tools,Items;" .. tostring(inv.tab_id) .. ";true;false]" .. "list[detached:creative_" .. player_name .. ";main;0,0;8,3;" .. tostring(start_i) .. "]" .. @@ -192,7 +192,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) inv.filter = "" creative.update_creative_inventory(player_name) creative.set_creative_formspec(player, 0) - elseif fields.creative_search then + elseif fields.creative_search or + fields.key_enter_field == "creative_filter" then player_inventory[player_name].start_i = 1 inv.filter = fields.creative_filter:lower() creative.update_creative_inventory(player_name) From 995256744ad8c7ec396b3efd8f88a5a563b4886c Mon Sep 17 00:00:00 2001 From: paramat Date: Sat, 27 Aug 2016 02:41:31 +0100 Subject: [PATCH 101/121] Default, stairs, doors: Vary wood flammable and choppy group values Make the softer woods, pine and aspen, 'flammable = 3'. Correct inconsistent flammability of wood and stairs in relation to all other solid wood nodes in MTGame. Make the the softer woods, pine and aspen, 'choppy = 3'. --- mods/default/nodes.lua | 22 +++++++++++----------- mods/doors/init.lua | 4 ++-- mods/stairs/init.lua | 10 +++++----- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua index fe7cbb12..79aea5bb 100644 --- a/mods/default/nodes.lua +++ b/mods/default/nodes.lua @@ -486,7 +486,7 @@ minetest.register_node("default:wood", { place_param2 = 0, tiles = {"default_wood.png"}, is_ground_content = false, - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, wood = 1}, sounds = default.node_sound_wood_defaults(), }) @@ -602,7 +602,7 @@ minetest.register_node("default:junglewood", { place_param2 = 0, tiles = {"default_junglewood.png"}, is_ground_content = false, - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, wood = 1}, sounds = default.node_sound_wood_defaults(), }) @@ -672,7 +672,7 @@ minetest.register_node("default:pine_tree", { "default_pine_tree.png"}, paramtype2 = "facedir", is_ground_content = false, - groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + groups = {tree = 1, choppy = 3, oddly_breakable_by_hand = 1, flammable = 3}, sounds = default.node_sound_wood_defaults(), on_place = minetest.rotate_node @@ -684,7 +684,7 @@ minetest.register_node("default:pine_wood", { place_param2 = 0, tiles = {"default_pine_wood.png"}, is_ground_content = false, - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, sounds = default.node_sound_wood_defaults(), }) @@ -724,7 +724,7 @@ minetest.register_node("default:pine_sapling", { type = "fixed", fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} }, - groups = {snappy = 2, dig_immediate = 3, flammable = 2, + groups = {snappy = 2, dig_immediate = 3, flammable = 3, attached_node = 1, sapling = 1}, sounds = default.node_sound_leaves_defaults(), @@ -765,7 +765,7 @@ minetest.register_node("default:acacia_wood", { place_param2 = 0, tiles = {"default_acacia_wood.png"}, is_ground_content = false, - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, wood = 1}, sounds = default.node_sound_wood_defaults(), }) @@ -833,7 +833,7 @@ minetest.register_node("default:aspen_tree", { "default_aspen_tree.png"}, paramtype2 = "facedir", is_ground_content = false, - groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + groups = {tree = 1, choppy = 3, oddly_breakable_by_hand = 1, flammable = 3}, sounds = default.node_sound_wood_defaults(), on_place = minetest.rotate_node @@ -845,7 +845,7 @@ minetest.register_node("default:aspen_wood", { place_param2 = 0, tiles = {"default_aspen_wood.png"}, is_ground_content = false, - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, sounds = default.node_sound_wood_defaults(), }) @@ -885,7 +885,7 @@ minetest.register_node("default:aspen_sapling", { type = "fixed", fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} }, - groups = {snappy = 2, dig_immediate = 3, flammable = 2, + groups = {snappy = 2, dig_immediate = 3, flammable = 3, attached_node = 1, sapling = 1}, sounds = default.node_sound_leaves_defaults(), @@ -1890,7 +1890,7 @@ default.register_fence("default:fence_pine_wood", { inventory_image = "default_fence_overlay.png^default_pine_wood.png^default_fence_overlay.png^[makealpha:255,126,126", wield_image = "default_fence_overlay.png^default_pine_wood.png^default_fence_overlay.png^[makealpha:255,126,126", material = "default:pine_wood", - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, sounds = default.node_sound_wood_defaults() }) @@ -1900,7 +1900,7 @@ default.register_fence("default:fence_aspen_wood", { inventory_image = "default_fence_overlay.png^default_aspen_wood.png^default_fence_overlay.png^[makealpha:255,126,126", wield_image = "default_fence_overlay.png^default_aspen_wood.png^default_fence_overlay.png^[makealpha:255,126,126", material = "default:aspen_wood", - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, sounds = default.node_sound_wood_defaults() }) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index 86f5f7e7..0888077f 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -744,12 +744,12 @@ doors.register_fencegate("doors:gate_pine_wood", { description = "Pine Fence Gate", texture = "default_pine_wood.png", material = "default:pine_wood", - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2} + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3} }) doors.register_fencegate("doors:gate_aspen_wood", { description = "Aspen Fence Gate", texture = "default_aspen_wood.png", material = "default:aspen_wood", - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2} + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3} }) diff --git a/mods/stairs/init.lua b/mods/stairs/init.lua index 001640fa..78922e40 100644 --- a/mods/stairs/init.lua +++ b/mods/stairs/init.lua @@ -269,7 +269,7 @@ end stairs.register_stair_and_slab( "wood", "default:wood", - {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, {"default_wood.png"}, "Wooden Stair", "Wooden Slab", @@ -279,7 +279,7 @@ stairs.register_stair_and_slab( stairs.register_stair_and_slab( "junglewood", "default:junglewood", - {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, {"default_junglewood.png"}, "Jungle Wood Stair", "Jungle Wood Slab", @@ -289,7 +289,7 @@ stairs.register_stair_and_slab( stairs.register_stair_and_slab( "pine_wood", "default:pine_wood", - {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, {"default_pine_wood.png"}, "Pine Wood Stair", "Pine Wood Slab", @@ -299,7 +299,7 @@ stairs.register_stair_and_slab( stairs.register_stair_and_slab( "acacia_wood", "default:acacia_wood", - {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, {"default_acacia_wood.png"}, "Acacia Wood Stair", "Acacia Wood Slab", @@ -309,7 +309,7 @@ stairs.register_stair_and_slab( stairs.register_stair_and_slab( "aspen_wood", "default:aspen_wood", - {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, {"default_aspen_wood.png"}, "Aspen Wood Stair", "Aspen Wood Slab", From 5e9e3f7e84fafd6ece535b1c7aff3b9ea4e6405b Mon Sep 17 00:00:00 2001 From: Pinky Snow Date: Sat, 27 Aug 2016 18:28:02 -0400 Subject: [PATCH 102/121] Default: Eliminate redundant 'get modpath' calls --- mods/default/init.lua | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/mods/default/init.lua b/mods/default/init.lua index b362fc75..594ea36a 100644 --- a/mods/default/init.lua +++ b/mods/default/init.lua @@ -35,14 +35,16 @@ default.gui_survival_form = "size[8,8.5]".. default.get_hotbar_bg(0,4.25) -- Load files -dofile(minetest.get_modpath("default").."/functions.lua") -dofile(minetest.get_modpath("default").."/trees.lua") -dofile(minetest.get_modpath("default").."/nodes.lua") -dofile(minetest.get_modpath("default").."/furnace.lua") -dofile(minetest.get_modpath("default").."/tools.lua") -dofile(minetest.get_modpath("default").."/craftitems.lua") -dofile(minetest.get_modpath("default").."/crafting.lua") -dofile(minetest.get_modpath("default").."/mapgen.lua") -dofile(minetest.get_modpath("default").."/player.lua") -dofile(minetest.get_modpath("default").."/aliases.lua") -dofile(minetest.get_modpath("default").."/legacy.lua") +local default_path = minetest.get_modpath("default") + +dofile(default_path.."/functions.lua") +dofile(default_path.."/trees.lua") +dofile(default_path.."/nodes.lua") +dofile(default_path.."/furnace.lua") +dofile(default_path.."/tools.lua") +dofile(default_path.."/craftitems.lua") +dofile(default_path.."/crafting.lua") +dofile(default_path.."/mapgen.lua") +dofile(default_path.."/player.lua") +dofile(default_path.."/aliases.lua") +dofile(default_path.."/legacy.lua") From 55bdc674bae65c57ab2f21154ab88d5397de7643 Mon Sep 17 00:00:00 2001 From: Thomas--S Date: Sun, 17 Jul 2016 18:52:42 +0200 Subject: [PATCH 103/121] cherry-pick 3661cb61e37ee6b7a8818f7a28e9102fb0674e54..79dbafc13b256a38c13d7abd2ea7af0f50e64394 --- mods/doors/init.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mods/doors/init.lua b/mods/doors/init.lua index dfa9464d..60f81e07 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -533,6 +533,10 @@ function _doors.trapdoor_toggle(pos, node, clicker) 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" From 9fb3a1960b087b871ea40208f736737eb42be334 Mon Sep 17 00:00:00 2001 From: tchncs Date: Thu, 1 Sep 2016 14:08:58 +0200 Subject: [PATCH 104/121] re-add farming, bones --- .gitmodules | 6 ++++++ mods/boats | 1 + mods/farming | 1 + 3 files changed, 8 insertions(+) create mode 160000 mods/boats create mode 160000 mods/farming diff --git a/.gitmodules b/.gitmodules index 2b7a65dc..4f311509 100644 --- a/.gitmodules +++ b/.gitmodules @@ -62,3 +62,9 @@ [submodule "mods/columnia"] path = mods/columnia url = https://git.tchncs.de/Illuna-Minetest/columnia +[submodule "mods/farming"] + path = mods/farming + url = https://git.tchncs.de/Illuna-Minetest/farming +[submodule "mods/boats"] + path = mods/boats + url = https://git.tchncs.de/Illuna-Minetest/boats diff --git a/mods/boats b/mods/boats new file mode 160000 index 00000000..a7534e93 --- /dev/null +++ b/mods/boats @@ -0,0 +1 @@ +Subproject commit a7534e938834c1a0322e49df796f613ca1f55880 diff --git a/mods/farming b/mods/farming new file mode 160000 index 00000000..de0e7dcc --- /dev/null +++ b/mods/farming @@ -0,0 +1 @@ +Subproject commit de0e7dcc328df01e4934378efefb0cdd7a373e38 From 930d201f39be0ecd1e8613dee90e17a074640876 Mon Sep 17 00:00:00 2001 From: tchncs Date: Thu, 1 Sep 2016 14:22:49 +0200 Subject: [PATCH 105/121] bones: fix mergeconflict --- mods/bones/init.lua | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 13af52b5..20ae55e0 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -207,17 +207,11 @@ minetest.register_on_dieplayer(function(player) drop(pos, ItemStack("bones:bones")) return end -<<<<<<< HEAD - - minetest.set_node(pos, {name="bones:bones", param2=param2}) - - minetest.chat_send_player(player_name, "Your stuff is waiting for you at "..minetest.pos_to_string(pos).. ". Go and grab it! ;-)") - minetest.log("action", player_name.." left their bones at "..minetest.pos_to_string(pos)) -======= local param2 = minetest.dir_to_facedir(player:get_look_dir()) minetest.set_node(pos, {name = "bones:bones", param2 = param2}) ->>>>>>> 5e9e3f7e84fafd6ece535b1c7aff3b9ea4e6405b + minetest.chat_send_player(player_name, "Your stuff is waiting for you at "..minetest.pos_to_string(pos).. ". Go and grab it! ;-)") + minetest.log("action", player_name.." left their bones at "..minetest.pos_to_string(pos)) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() From f2553fc3ccfa2e9861c3c9194879708734de1c6b Mon Sep 17 00:00:00 2001 From: tchncs Date: Thu, 1 Sep 2016 14:45:02 +0200 Subject: [PATCH 106/121] fence: add missing textures --- .../textures/default_fence_acacia_wood.png | Bin 0 -> 232 bytes .../default/textures/default_fence_aspen_wood.png | Bin 0 -> 450 bytes .../default/textures/default_fence_junglewood.png | Bin 0 -> 231 bytes mods/default/textures/default_fence_overlay.png.1 | Bin 0 -> 219 bytes mods/default/textures/default_fence_pine_wood.png | Bin 0 -> 233 bytes mods/default/textures/default_fence_wood.png | Bin 0 -> 230 bytes 6 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 mods/default/textures/default_fence_acacia_wood.png create mode 100644 mods/default/textures/default_fence_aspen_wood.png create mode 100644 mods/default/textures/default_fence_junglewood.png create mode 100644 mods/default/textures/default_fence_overlay.png.1 create mode 100644 mods/default/textures/default_fence_pine_wood.png create mode 100644 mods/default/textures/default_fence_wood.png diff --git a/mods/default/textures/default_fence_acacia_wood.png b/mods/default/textures/default_fence_acacia_wood.png new file mode 100644 index 0000000000000000000000000000000000000000..3b973f34fbaf1d6d9351fe4e24b3da9e614ff666 GIT binary patch literal 232 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv4DbnYjZ>9K){rdHk(p>FJJmvd zx|8-yC+#^-TAMxe_xc*|@He{o`^IIU;wDcQ#}JO|qNfeH4mpUhT!>tgG&R(|qW`_v zNzNmeN+-x1a9*-?OZ=1Ny&SJK|K8@|`OLN_^lpu3i^TQZ7mT9Q^weFS?JW6{88U70 zOw-TzOdmfj-w--+#paBn^%fKO&7HDbbWn& z>~rq5xcz!#aWHH4;v<4UQs@N$I!jTrL&C{1)w*OCGJm{71S1e_Lg!BaB=ajz603xV zAGd8CU`^8zsM#R^E1jbbK7o*aQ;Z@Y1z>tK$2O(UyI8t~nw@$X<8a0hTEc!TZBr6X zj#>Zt?Kd`?4N?4|T?ZqY`k5$JgQQYtDXTp99zYI26f1}de^}1 z%cRaybe497Z!;l;?G@|nVc0}B2fY>v>-9S%^Q&P3H);QaF*QNZ4Ov;}Rzj>2%0mBh zV7Kp8sVP@ad^|b#`eT(K7kA$VZ`>u&*%E6Se*OIJeOl=pxv!>M+J*m(Wubc{pU=MZ s`tLp1)^AMhzic}X%EwjFef4ep1?f_*GKfbTk^lez07*qoM6N<$f|}jMmH+?% literal 0 HcmV?d00001 diff --git a/mods/default/textures/default_fence_junglewood.png b/mods/default/textures/default_fence_junglewood.png new file mode 100644 index 0000000000000000000000000000000000000000..c390941ce54ff75c8b4c2b4ffcbbe4fc040f8088 GIT binary patch literal 231 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv4DbnYl@?%-6Jk^qXE9Y~H&f-b z)Znwy;nv?13a2N9MFk!yUWuCMzbcVBms zaK>vZj+c8~ysTe$JowiAWd5bQX$dpTAL!nG=B(7AbNd4GGM(72wj;$aBbFbG=zDkX zO#XEr-TTe@Z633)CYk=5GsTA?B}}mKI7Xa3%Q_ZmbBZJtqYQFvls=l+>`)4-BUj5CiVJH_AX>9fI(u=7R`@MS$ z!tQvx>?+<>x_oZsB-f8G(q1W^C^v|j{JD6ugz~9ntXI0h gRn$^wUH(M--J3)mdKI;Vst02}LGZ2$lO literal 0 HcmV?d00001 diff --git a/mods/default/textures/default_fence_wood.png b/mods/default/textures/default_fence_wood.png new file mode 100644 index 0000000000000000000000000000000000000000..1e76430d2f54f3b259598fb396df4aaf8b30b39e GIT binary patch literal 230 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv4DbnYZOyb<*60=PtXh{~5M-~s zu+F0~*?4ZHYiG7?vbR=yw(ZwzhqeM0H+Z@@hHzXL?Kb2(w_*wCU=;m z*XQ-k{~ai%)VSJcr}BNjhrXKIR?Td@5te)P$>Od29Stwu86PUVs<^v& Date: Thu, 1 Sep 2016 16:12:43 +0200 Subject: [PATCH 107/121] update submodule bows --- mods/bows | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/bows b/mods/bows index 819daa52..5013537e 160000 --- a/mods/bows +++ b/mods/bows @@ -1 +1 @@ -Subproject commit 819daa52f1c8e1621489a5f8d73ad9a29e6efa4e +Subproject commit 5013537e24f526fbae97a6693a08d6eff7f8cd9b From 56534d5147afe3e6f58a64c65cca56566677ca73 Mon Sep 17 00:00:00 2001 From: tchncs Date: Fri, 2 Sep 2016 14:06:13 +0200 Subject: [PATCH 108/121] update submodule mobs_redo --- mods/mobs_redo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/mobs_redo b/mods/mobs_redo index a470ac7c..2aa6227f 160000 --- a/mods/mobs_redo +++ b/mods/mobs_redo @@ -1 +1 @@ -Subproject commit a470ac7cc1786c188866ca57d4a0d13e3e8f37d0 +Subproject commit 2aa6227f0a03d20a6c4733f74c46612bd33e0be1 From 35cfb2e4c5c2b8640d8286c9565a89fc3828540b Mon Sep 17 00:00:00 2001 From: tchncs Date: Sat, 3 Sep 2016 11:04:56 +0200 Subject: [PATCH 109/121] tnt: do not check for tnt enabled for serving recipe --- mods/tnt/init.lua | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/mods/tnt/init.lua b/mods/tnt/init.lua index 01758cd1..a9c86526 100644 --- a/mods/tnt/init.lua +++ b/mods/tnt/init.lua @@ -492,15 +492,14 @@ minetest.register_craft({ recipe = {"default:coal_lump", "default:gravel"} }) -if enable_tnt then - minetest.register_craft({ - output = "tnt:tnt", - recipe = { - {"", "group:wood", ""}, - {"group:wood", "tnt:gunpowder", "group:wood"}, - {"", "group:wood", ""} - } - }) +minetest.register_craft({ + output = "tnt:tnt", + recipe = { + {"", "group:wood", ""}, + {"group:wood", "tnt:gunpowder", "group:wood"}, + {"", "group:wood", ""} + } +}) minetest.register_abm({ label = "TNT ignition", @@ -510,7 +509,6 @@ if enable_tnt then chance = 1, action = tnt.burn, }) -end function tnt.register_tnt(def) local name From f9f75ade7689100a053507733f5d88bcc2c71500 Mon Sep 17 00:00:00 2001 From: tchncs Date: Sat, 3 Sep 2016 11:09:36 +0200 Subject: [PATCH 110/121] update submodule columnia --- mods/columnia | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/columnia b/mods/columnia index c3a57b9e..e5f5bd31 160000 --- a/mods/columnia +++ b/mods/columnia @@ -1 +1 @@ -Subproject commit c3a57b9e17bdca5679366fab1518d19d01fd433f +Subproject commit e5f5bd3168419ee5519e75dc8c9ed2e63c740df9 From ebe850969c4e702c2a1b6501ad351e0a6e910005 Mon Sep 17 00:00:00 2001 From: tchncs Date: Sat, 3 Sep 2016 11:15:35 +0200 Subject: [PATCH 111/121] fix submodule columnia --- .gitmodules | 6 +++--- mods/columnia | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitmodules b/.gitmodules index 4f311509..f7540d48 100644 --- a/.gitmodules +++ b/.gitmodules @@ -59,12 +59,12 @@ [submodule "mods/pkarcs"] path = mods/pkarcs url = https://git.tchncs.de/Illuna-Minetest/pkarcs -[submodule "mods/columnia"] - path = mods/columnia - url = https://git.tchncs.de/Illuna-Minetest/columnia [submodule "mods/farming"] path = mods/farming url = https://git.tchncs.de/Illuna-Minetest/farming [submodule "mods/boats"] path = mods/boats url = https://git.tchncs.de/Illuna-Minetest/boats +[submodule "mods/columnia"] + path = mods/columnia + url = https://git.tchncs.de/Illuna-Minetest/columnia diff --git a/mods/columnia b/mods/columnia index e5f5bd31..d19ac06a 160000 --- a/mods/columnia +++ b/mods/columnia @@ -1 +1 @@ -Subproject commit e5f5bd3168419ee5519e75dc8c9ed2e63c740df9 +Subproject commit d19ac06a5e1715e7bd157859405e09f83c1f7a13 From 1ff31ee41c673e4e245ad30ff40bc1e0a4bc2d12 Mon Sep 17 00:00:00 2001 From: tchncs Date: Sun, 4 Sep 2016 23:41:00 +0200 Subject: [PATCH 112/121] add submodule technic_chests --- .gitmodules | 3 +++ mods/technic_chests | 1 + 2 files changed, 4 insertions(+) create mode 160000 mods/technic_chests diff --git a/.gitmodules b/.gitmodules index 4f311509..53e4b54d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -68,3 +68,6 @@ [submodule "mods/boats"] path = mods/boats url = https://git.tchncs.de/Illuna-Minetest/boats +[submodule "mods/technic_chests"] + path = mods/technic_chests + url = https://git.tchncs.de/Illuna-Minetest/technic_chests diff --git a/mods/technic_chests b/mods/technic_chests new file mode 160000 index 00000000..5c6baef9 --- /dev/null +++ b/mods/technic_chests @@ -0,0 +1 @@ +Subproject commit 5c6baef96f7d9cb79ccc6c10b670bf0078d93d55 From 903f6cb2e3e88341bc7f0135426111726fa5dc64 Mon Sep 17 00:00:00 2001 From: tchncs Date: Tue, 6 Sep 2016 17:27:12 +0200 Subject: [PATCH 113/121] nyancat: add some more aliases --- mods/nyancat/init.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mods/nyancat/init.lua b/mods/nyancat/init.lua index 677ed50a..2e64bc12 100644 --- a/mods/nyancat/init.lua +++ b/mods/nyancat/init.lua @@ -81,5 +81,8 @@ minetest.register_alias("default:nyancat", "nyancat:nyancat") minetest.register_alias("default:nyancat_rainbow", "nyancat:nyancat_rainbow") minetest.register_alias("nyancat", "nyancat:nyancat") minetest.register_alias("nyancat_rainbow", "nyancat:nyancat_rainbow") +minetest.register_alias("default:nyancat_rainbow_doublepanel", "nyancat:nyancat_rainbow_doublepanel") +minetest.register_alias("default:nyancat_rainbow_outerstair", "nyancat:nyancat_rainbow_outerstair") + default.make_nyancat = nyancat.place default.generate_nyancats = nyancat.generate From 4973e2921bab989a5fbb6b147c04fd95ab4cb0ef Mon Sep 17 00:00:00 2001 From: tchncs Date: Tue, 6 Sep 2016 21:00:24 +0200 Subject: [PATCH 114/121] update submodule columnia --- mods/columnia | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/columnia b/mods/columnia index d19ac06a..50ea97ac 160000 --- a/mods/columnia +++ b/mods/columnia @@ -1 +1 @@ -Subproject commit d19ac06a5e1715e7bd157859405e09f83c1f7a13 +Subproject commit 50ea97ac54bca6c9313910bf9daa9f376c6d7311 From f678ef9fb8f4e1c06837ec4abe35998018bd8a8a Mon Sep 17 00:00:00 2001 From: tchncs Date: Tue, 6 Sep 2016 21:05:15 +0200 Subject: [PATCH 115/121] replace submodule columnia --- mods/columnia | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/columnia b/mods/columnia index 50ea97ac..7a538423 160000 --- a/mods/columnia +++ b/mods/columnia @@ -1 +1 @@ -Subproject commit 50ea97ac54bca6c9313910bf9daa9f376c6d7311 +Subproject commit 7a5384239d0e86b126cd873c5585061fb8926add From 6369809bfd1af9259c0b18e43881aa69d12d35ed Mon Sep 17 00:00:00 2001 From: tchncs Date: Wed, 14 Sep 2016 09:11:57 +0200 Subject: [PATCH 116/121] update submodule mobs_monster, xdecor --- mods/mobs_monster | 2 +- mods/xdecor | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/mobs_monster b/mods/mobs_monster index 97fad4d7..14d0ea47 160000 --- a/mods/mobs_monster +++ b/mods/mobs_monster @@ -1 +1 @@ -Subproject commit 97fad4d782e7d1bfac13ac28b8717fb46eb4ecea +Subproject commit 14d0ea47a98881b589684920ce658b299df46322 diff --git a/mods/xdecor b/mods/xdecor index e0f401ba..dbef5947 160000 --- a/mods/xdecor +++ b/mods/xdecor @@ -1 +1 @@ -Subproject commit e0f401bad71cc7ac8739251464902c921feba184 +Subproject commit dbef5947bf143986bd85083c3cf1b37ba076073e From 9e3cdbfa3f10b17dca1fe7534e638afd1ebe1192 Mon Sep 17 00:00:00 2001 From: tchncs Date: Wed, 14 Sep 2016 09:16:23 +0200 Subject: [PATCH 117/121] update submodule mobs_monster --- mods/mobs_monster | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/mobs_monster b/mods/mobs_monster index 14d0ea47..6b7c5ea9 160000 --- a/mods/mobs_monster +++ b/mods/mobs_monster @@ -1 +1 @@ -Subproject commit 14d0ea47a98881b589684920ce658b299df46322 +Subproject commit 6b7c5ea990999de385a9e9eda8cc08f1ce12c00e From b86541f77ed950ad281afac480d568a7fcbd612b Mon Sep 17 00:00:00 2001 From: tchncs Date: Wed, 14 Sep 2016 19:02:37 +0200 Subject: [PATCH 118/121] add submodule coloured_nametag --- .gitmodules | 3 +++ mods/coloured_nametag | 1 + 2 files changed, 4 insertions(+) create mode 160000 mods/coloured_nametag diff --git a/.gitmodules b/.gitmodules index 21c3b3e4..2b2a50bc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -71,3 +71,6 @@ [submodule "mods/columnia"] path = mods/columnia url = https://git.tchncs.de/Illuna-Minetest/columnia +[submodule "mods/coloured_nametag"] + path = mods/coloured_nametag + url = https://github.com/Amaz1/coloured_nametag diff --git a/mods/coloured_nametag b/mods/coloured_nametag new file mode 160000 index 00000000..c50a4ca8 --- /dev/null +++ b/mods/coloured_nametag @@ -0,0 +1 @@ +Subproject commit c50a4ca893e5383d75ff274533327a5faf20b1b7 From 2dda8597b7f56473b8e0b9fef1a15ae814aac208 Mon Sep 17 00:00:00 2001 From: tchncs Date: Wed, 14 Sep 2016 19:22:09 +0200 Subject: [PATCH 119/121] add mod random_messages --- mods/random_messages/depends.txt | 1 + mods/random_messages/init.lua | 141 +++++++++++++++++++++++++++++++ mods/random_messages/readme.md | 17 ++++ 3 files changed, 159 insertions(+) create mode 100644 mods/random_messages/depends.txt create mode 100644 mods/random_messages/init.lua create mode 100644 mods/random_messages/readme.md diff --git a/mods/random_messages/depends.txt b/mods/random_messages/depends.txt new file mode 100644 index 00000000..4ad96d51 --- /dev/null +++ b/mods/random_messages/depends.txt @@ -0,0 +1 @@ +default diff --git a/mods/random_messages/init.lua b/mods/random_messages/init.lua new file mode 100644 index 00000000..64d75065 --- /dev/null +++ b/mods/random_messages/init.lua @@ -0,0 +1,141 @@ +--[[ +RandomMessages mod by arsdragonfly. +arsdragonfly@gmail.com +6/19/2013 +--]] +--Time between two subsequent messages. +local MESSAGE_INTERVAL = 0 + +math.randomseed(os.time()) + +random_messages = {} +random_messages.messages = {} --This table contains all messages. + +function table.count( t ) + local i = 0 + for k in pairs( t ) do i = i + 1 end + return i +end + +function table.random( t ) + local rk = math.random( 1, table.count( t ) ) + local i = 1 + for k, v in pairs( t ) do + if ( i == rk ) then return v, k end + i = i + 1 + end +end + +function random_messages.initialize() --Set the interval in minetest.conf. + minetest.setting_set("random_messages_interval",300) + minetest.setting_save(); + return 300 +end + +function random_messages.set_interval() --Read the interval from minetest.conf(set it if it doesn'st exist) + MESSAGE_INTERVAL = tonumber(minetest.setting_get("random_messages_interval")) or random_messages.initialize() +end + +function random_messages.check_params(name,func,params) + local stat,msg = func(params) + if not stat then + minetest.chat_send_player(name,msg) + return false + end + return true +end + +function random_messages.read_messages() + random_messages.messages = { + "# Illuna-Notes: Soup is very useful to fight hunger, everyone should have some.", + "# Illuna-Notes: Meet your fellows on our Mumbleserver at tchncs.de", + "# Illuna-Notes: Enjoy Illuna? Invite your friends today!", + "# Illuna-Notes: Have something to share? Create and join discussion at the Illuna forum: https://forum.illuna-minetest.tk!", + "# Illuna-Notes: Sell and buy stuff on the Illuna marketplace. It is below the spawnhouse." + } +end + +function random_messages.display_message(message_number) + local msg = random_messages.messages[message_number] or message_number + if msg then + minetest.chat_send_all(msg) + end +end + +function random_messages.show_message() + random_messages.display_message(table.random(random_messages.messages)) +end + +function random_messages.list_messages() + local str = "" + for k,v in pairs(random_messages.messages) do + str = str .. k .. " | " .. v .. "\n" + end + return str +end + +function random_messages.remove_message(k) + table.remove(random_messages.messages,k) + random_messages.save_messages() +end + +function random_messages.add_message(t) + table.insert(random_messages.messages,table.concat(t," ",2)) + random_messages.save_messages() +end + +function random_messages.save_messages() + local output = io.open(minetest.get_worldpath().."/random_messages","w") + for k,v in pairs(random_messages.messages) do + output:write(v .. "\n") + end + io.close(output) +end + +--When server starts: +random_messages.set_interval() +random_messages.read_messages() + +local TIMER = 0 +minetest.register_globalstep(function(dtime) + TIMER = TIMER + dtime; + if TIMER > MESSAGE_INTERVAL then + random_messages.show_message() + TIMER = 0 + end +end) + +local register_chatcommand_table = { + params = "viewmessages | removemessage | addmessage ", + privs = {server = true}, + description = "View and/or alter the server's random messages", + func = function(name,param) + local t = string.split(param, " ") + if t[1] == "viewmessages" then + minetest.chat_send_player(name,random_messages.list_messages()) + elseif t[1] == "removemessage" then + if not random_messages.check_params( + name, + function (params) + if not tonumber(params[2]) or + random_messages.messages[tonumber(params[2])] == nil then + return false,"ERROR: No such message." + end + return true + end, + t) then return end + random_messages.remove_message(t[2]) + elseif t[1] == "addmessage" then + if not t[2] then + minetest.chat_send_player(name,"ERROR: No message.") + else + random_messages.add_message(t) + end + else + minetest.chat_send_player(name,"ERROR: Invalid command.") + end + end +} + +minetest.register_chatcommand("random_messages", register_chatcommand_table) +minetest.register_chatcommand("rmessages", register_chatcommand_table) diff --git a/mods/random_messages/readme.md b/mods/random_messages/readme.md new file mode 100644 index 00000000..ead798a7 --- /dev/null +++ b/mods/random_messages/readme.md @@ -0,0 +1,17 @@ +RandomMessages mod by arsdragonfly. +Put your messages in (world directory)/random_messages,1 message per line. +Messages can be all kinds of hints, mod usage, etc. +Add/Remove messages on the fly: +/rmessages viewmessages +to see all the messages. +/rmessages addmessage blah blah blah +to add the random message blah blah blah. +/rmessages removemessage 2 +to remove the 2nd random message in /rmessages viewmessages . +In minetest.conf, random_messages_interval decides how often a message is sent. +Released under CC0. +Special thanks to: +Michael Rasmussen (michael@jamhome.us) +Enjoy it! ^_^ +arsdragonfly@gmail.com +6/19/2013 \ No newline at end of file From 1a6e9cb3b2d02ed3e4a9e230bbb31c8c0e59d7d1 Mon Sep 17 00:00:00 2001 From: tchncs Date: Wed, 14 Sep 2016 20:21:00 +0200 Subject: [PATCH 120/121] random_messages: increase message interval --- mods/random_messages/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/random_messages/init.lua b/mods/random_messages/init.lua index 64d75065..056e9e00 100644 --- a/mods/random_messages/init.lua +++ b/mods/random_messages/init.lua @@ -27,9 +27,9 @@ function table.random( t ) end function random_messages.initialize() --Set the interval in minetest.conf. - minetest.setting_set("random_messages_interval",300) + minetest.setting_set("random_messages_interval",1800) minetest.setting_save(); - return 300 + return 1800 end function random_messages.set_interval() --Read the interval from minetest.conf(set it if it doesn'st exist) From 4cb83e53ef38c2ab181fcbf95b221558fbc8df4f Mon Sep 17 00:00:00 2001 From: tchncs Date: Thu, 15 Sep 2016 11:25:29 +0200 Subject: [PATCH 121/121] update submodule darkage --- mods/darkage | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/darkage b/mods/darkage index 272e10fc..3d7d76d4 160000 --- a/mods/darkage +++ b/mods/darkage @@ -1 +1 @@ -Subproject commit 272e10fc3d59e1f5dc05ebc2ec1bd2b46f8d725b +Subproject commit 3d7d76d4b4becaa00bb658769fa6dde4e2eafe96