add documentation to /doc folder. add old resources to /mods_disabled folder.

master
MeseCraft 2022-06-30 15:08:45 -05:00
parent e3eaf9c704
commit 45d1e23d3e
707 changed files with 24763 additions and 76 deletions

View File

@ -0,0 +1,27 @@
Glasslands
Coniferous Forest
Deciduous Forest
Rainforest
Savanna
Desert
Sandstone Desert
Cold Desert
Snowy Grassland
Taiga
Tundra
Ice Sheet
Grassland Dunes
Coniferous Forest Dunes
Deciduous Forest Shore
Rainforest Swamp
Savanna Shore
Taiga beach
Tundra Beach
Tundra Ocean
Other Oceans
Undergroud Biome
pyramids

View File

@ -0,0 +1,21 @@
DIMENSION ELEVATION RANGE SIZE
Otherworld Red Asteroids 22001-30912 8000
planet_mars 11000-22000 11000
Otherworld Asteroids 3500-10999 7500
planet_moon 3000-3300 300
earth orbital space 1000-2999 2000
Cloudlands 200-???
SURFACE
Geomoria (140)-(170) 30
Railcorridors (180)-(9500) 9500
DFCaverns Level1 (193)-(832) 639
DFCaverns Level2 (832)-(1472) 640
DFCaverns Level3 (1472)-(2122) 640
DFCaverns Sunless Sea (2112)-(2512) 400
DFCaverns Oil Sea (2700) 188
DFCaverns Lava Sea (2900) 200
DFCaverns Underworld (3200) 300
DFCaverns Primodial (3393)-(4032) 639
Nether (16500)-(30000) 14500
Bedrock (30000)-(30192) 1000

Binary file not shown.

View File

@ -0,0 +1,8 @@
README:
MeseCraft uses a standardized selection of 256-colors to reduce the complexity of game texturing. Please adhere to the palette colors when making textures. This palette was produced by a color and texturing wizard, so it should be very helpful. A GIMP palette file is included in this directory. There are additional palette files for other applications available at the URL below.
TITLE: Aurora Palette
AUTHOR: Dawnbringer
COLORS: 256
DESCRIPTION: Created by DawnBringer as part of the GrafX2 Toolbox.
URL: https://lospec.com/palette-list/aurora

View File

@ -0,0 +1,260 @@
GIMP Palette
#Palette Name: Aurora
#Description: Created by <a target="_blank" href="http://pixeljoint.com/p/23821.htm">DawnBringer</a> as part of the <a target="_blank" href="http://pixeljoint.com/forum/forum_posts.asp?TID=26080">GrafX2 Toolbox</a>.
#Colors: 256
0 0 0 000000
17 17 17 111111
34 34 34 222222
51 51 51 333333
68 68 68 444444
85 85 85 555555
102 102 102 666666
119 119 119 777777
136 136 136 888888
153 153 153 999999
170 170 170 aaaaaa
187 187 187 bbbbbb
204 204 204 cccccc
221 221 221 dddddd
238 238 238 eeeeee
255 255 255 ffffff
0 127 127 007f7f
63 191 191 3fbfbf
0 255 255 00ffff
191 255 255 bfffff
129 129 255 8181ff
0 0 255 0000ff
63 63 191 3f3fbf
0 0 127 00007f
15 15 80 0f0f50
127 0 127 7f007f
191 63 191 bf3fbf
245 0 245 f500f5
253 129 255 fd81ff
255 192 203 ffc0cb
255 129 129 ff8181
255 0 0 ff0000
191 63 63 bf3f3f
127 0 0 7f0000
85 20 20 551414
127 63 0 7f3f00
191 127 63 bf7f3f
255 127 0 ff7f00
255 191 129 ffbf81
255 255 191 ffffbf
255 255 0 ffff00
191 191 63 bfbf3f
127 127 0 7f7f00
0 127 0 007f00
63 191 63 3fbf3f
0 255 0 00ff00
175 255 175 afffaf
0 191 255 00bfff
0 127 255 007fff
75 125 200 4b7dc8
188 175 192 bcafc0
203 170 137 cbaa89
166 160 144 a6a090
126 148 148 7e9494
110 130 135 6e8287
126 110 96 7e6e60
160 105 95 a0695f
192 120 114 c07872
208 138 116 d08a74
225 155 125 e19b7d
235 170 140 ebaa8c
245 185 155 f5b99b
246 200 175 f6c8af
245 225 210 f5e1d2
127 0 255 7f00ff
87 59 59 573b3b
115 65 60 73413c
142 85 85 8e5555
171 115 115 ab7373
199 143 143 c78f8f
227 171 171 e3abab
248 210 218 f8d2da
227 199 171 e3c7ab
196 158 115 c49e73
143 115 87 8f7357
115 87 59 73573b
59 45 31 3b2d1f
65 65 35 414123
115 115 59 73733b
143 143 87 8f8f57
162 162 85 a2a255
181 181 114 b5b572
199 199 143 c7c78f
218 218 171 dadaab
237 237 199 ededc7
199 227 171 c7e3ab
171 199 143 abc78f
142 190 85 8ebe55
115 143 87 738f57
88 125 62 587d3e
70 80 50 465032
25 30 15 191e0f
35 80 55 235037
59 87 59 3b573b
80 100 80 506450
59 115 73 3b7349
87 143 87 578f57
115 171 115 73ab73
100 192 130 64c082
143 199 143 8fc78f
162 216 162 a2d8a2
225 248 250 e1f8fa
180 238 202 b4eeca
171 227 197 abe3c5
135 180 142 87b48e
80 125 95 507d5f
15 105 70 0f6946
30 45 35 1e2d23
35 65 70 234146
59 115 115 3b7373
100 171 171 64abab
143 199 199 8fc7c7
171 227 227 abe3e3
199 241 241 c7f1f1
190 210 240 bed2f0
171 199 227 abc7e3
168 185 220 a8b9dc
143 171 199 8fabc7
87 143 199 578fc7
87 115 143 57738f
59 87 115 3b5773
15 25 45 0f192d
31 31 59 1f1f3b
59 59 87 3b3b57
73 73 115 494973
87 87 143 57578f
115 110 170 736eaa
118 118 202 7676ca
143 143 199 8f8fc7
171 171 227 ababe3
208 218 248 d0daf8
227 227 255 e3e3ff
171 143 199 ab8fc7
143 87 199 8f57c7
115 87 143 73578f
87 59 115 573b73
60 35 60 3c233c
70 50 70 463246
114 64 114 724072
143 87 143 8f578f
171 87 171 ab57ab
171 115 171 ab73ab
235 172 225 ebace1
255 220 245 ffdcf5
227 199 227 e3c7e3
225 185 210 e1b9d2
215 160 190 d7a0be
199 143 185 c78fb9
200 125 160 c87da0
195 90 145 c35a91
75 40 55 4b2837
50 22 35 321623
40 10 30 280a1e
64 24 17 401811
98 24 0 621800
165 20 10 a5140a
218 32 16 da2010
213 82 74 d5524a
255 60 10 ff3c0a
245 90 50 f55a32
255 98 98 ff6262
246 189 49 f6bd31
255 165 60 ffa53c
215 155 15 d79b0f
218 110 10 da6e0a
180 90 0 b45a00
160 75 5 a04b05
95 50 20 5f3214
83 80 10 53500a
98 98 0 626200
140 128 90 8c805a
172 148 0 ac9400
177 177 10 b1b10a
230 213 90 e6d55a
255 213 16 ffd510
255 234 74 ffea4a
200 255 65 c8ff41
155 240 70 9bf046
150 220 25 96dc19
115 200 5 73c805
106 168 5 6aa805
60 110 20 3c6e14
40 52 5 283405
32 70 8 204608
12 92 12 0c5c0c
20 150 5 149605
10 215 10 0ad70a
20 230 10 14e60a
125 255 115 7dff73
75 240 90 4bf05a
0 197 20 00c514
5 180 80 05b450
28 140 78 1c8c4e
18 56 50 123832
18 152 128 129880
6 196 145 06c491
0 222 106 00de6a
45 235 168 2deba8
60 254 165 3cfea5
106 255 205 6affcd
145 235 255 91ebff
85 230 255 55e6ff
125 215 240 7dd7f0
8 222 213 08ded5
16 156 222 109cde
5 90 92 055a5c
22 44 82 162c52
15 55 125 0f377d
0 74 156 004a9c
50 100 150 326496
0 82 246 0052f6
24 106 189 186abd
35 120 220 2378dc
105 157 195 699dc3
74 164 255 4aa4ff
144 176 255 90b0ff
90 197 255 5ac5ff
190 185 250 beb9fa
120 110 240 786ef0
74 90 255 4a5aff
98 65 246 6241f6
60 60 245 3c3cf5
16 28 218 101cda
0 16 189 0010bd
35 16 148 231094
12 33 72 0c2148
80 16 176 5010b0
96 16 208 6010d0
135 50 210 8732d2
156 65 255 9c41ff
189 98 255 bd62ff
185 145 255 b991ff
215 165 255 d7a5ff
215 195 250 d7c3fa
248 198 252 f8c6fc
230 115 255 e673ff
255 82 255 ff52ff
218 32 224 da20e0
189 41 255 bd29ff
189 16 197 bd10c5
140 20 190 8c14be
90 24 123 5a187b
100 20 100 641464
65 0 98 410062
50 10 70 320a46
85 25 55 551937
160 25 130 a01982
200 0 120 c80078
255 80 191 ff50bf
255 106 197 ff6ac5
250 160 185 faa0b9
252 58 140 fc3a8c
230 30 120 e61e78
189 16 57 bd1039
152 52 77 98344d
145 20 55 911437

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

View File

@ -1,5 +1,10 @@
*** Reduce particles on Void chest and nether portal
*** Disable knockback mods.
// WEB
* Put MeseCraft on ContentDB
* Put MeseCraft on ContentDB (create submodules that target MTG)
* DDNS with HTTPS redirect to https://mesecraft.net --> mesecraft.com
// META
@ -22,6 +27,7 @@
* Refill canteens with water bucket, maybe use a water purifcation system, filter straws, unpurified water can make you sick?
// GAME
* add message about send screenshots in to contact@mesecraft.com
* Transparent leaves again
* Ethereal abms for torches, water, ice, etc.
* Radio item that grants a private chat channel?

View File

@ -0,0 +1,14 @@
Setting Global Git Username and Email
git config --global user.name "Your Name"
git config --global user.email "youremail@yourdomain.com"
Setting Single Repository Username and Email
git config user.name "Your Name"
git config user.email "youremail@yourdomain.com"
Verify that the changes were made correctly:
git config --list

View File

@ -1,4 +0,0 @@
Title: earth vibes palette
Author: Volatile_Shrub888
Colors: 67
Description: a mixture of Sweet canyon, Resurrect, and Apollo. Made to be a vibrant but natural palette.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

View File

@ -1,71 +0,0 @@
GIMP Palette
#Palette Name: Earth Vibes
#Description: a mixture of Sweet canyon, Resurrect, and Apollo. Made to be a vibrant but natural palette.
#Colors: 67
10 54 57 0a3639
12 79 63 0c4f3f
17 101 72 116548
29 126 69 1d7e45
34 148 67 229443
111 186 59 6fba3b
151 217 72 97d948
204 241 122 ccf17a
255 251 118 fffb76
240 192 76 f0c04c
249 194 43 f9c22b
247 150 23 f79617
251 107 29 fb6b1d
232 59 59 e83b3b
174 35 52 ae2334
245 125 74 f57d4a
234 79 54 ea4f36
179 56 49 b33831
117 36 56 752438
65 29 49 411d31
16 20 69 101445
31 41 102 1f2966
33 69 116 214574
42 86 132 2a5684
44 137 175 2c89af
47 182 195 2fb6c3
100 231 231 64e7e7
162 250 250 a2fafa
9 10 20 090a14
16 20 31 10141f
21 29 40 151d28
32 46 55 202e37
57 74 80 394a50
87 114 119 577277
129 151 150 819796
168 181 178 a8b5b2
199 207 204 c7cfcc
235 237 233 ebede9
30 29 57 1e1d39
64 39 81 402751
72 36 109 48246d
105 24 156 69189c
122 54 123 7a367b
198 81 151 c65197
229 39 210 e527d2
255 81 207 ff51cf
223 132 165 df84a5
77 43 50 4d2b32
122 72 65 7a4841
173 119 87 ad7757
192 148 115 c09473
215 181 148 d7b594
52 28 39 341c27
96 44 44 602c2c
136 75 43 884b2b
190 119 43 be772b
106 51 40 6a3328
120 58 41 783a29
134 72 47 86482f
154 100 58 9a643a
171 123 73 ab7b49
204 149 98 cc9562
225 161 126 e1a17e
76 62 36 4c3e24
103 102 51 676633
162 169 71 a2a947
213 224 75 d5e04b

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

View File

@ -0,0 +1,38 @@
Textures:
Original torch textures from minetest_game/default
Recoloured textures and edits by Shara RedCat
Torch model:
License: CC-BY 3.0
Attribution: BlockMen, from https://github.com/BlockMen/torches
Code:
License: MIT (https://opensource.org/licenses/MIT)
By Shara RedCat
---
The MIT License (MIT)
Copyright (c) 2017 Shara RedCat
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,39 @@
local recipe_list
local modname
-- recipes when caverealms is present
if minetest.get_modpath("caverealms") then
recipe_list = {
{"black", "spike",}, {"blue", "glow_crystal",},
{"cyan", "glow_gem",}, {"green", "glow_emerald",},
{"magenta", "salt_gem",}, {"orange", "fire_vine",},
{"purple", "glow_amethyst",}, {"red", "glow_ruby",},
{"yellow", "glow_mese",}, {"white", "glow_ore",},
}
modname = "caverealms"
-- recipes when caverealms not present
else
recipe_list = {
{"black", "black",}, {"blue", "blue",},
{"cyan", "cyan",}, {"green", "green",},
{"magenta", "magenta",}, {"orange", "orange",},
{"purple", "violet",}, {"red", "red",},
{"yellow", "yellow",}, {"white", "white",},
}
modname = "dye"
end
for i in ipairs(recipe_list) do
local colour = recipe_list[i][1]
local ingredient = recipe_list[i][2]
minetest.register_craft({
output = "abritorch:torch_"..colour.." 4",
recipe = {
{"default:torch", "", "default:torch" },
{"", modname..":"..ingredient, "" },
{"default:torch", "", "default:torch" },
}
})
end

View File

@ -0,0 +1 @@
default

View File

@ -0,0 +1,4 @@
local modpath = minetest.get_modpath("abritorch").. DIR_DELIM
dofile(modpath.."torches.lua")
dofile(modpath.."crafting.lua")

View File

@ -0,0 +1,48 @@
# Blender v2.73 (sub 0) OBJ File: 'mt_torch_full_vertices3.blend'
# www.blender.org
mtllib mt_torch_full_vertices3.mtl
o Cube_Cube.001
v 0.061653 -0.496733 0.061674
v 0.061653 -0.496733 -0.062460
v -0.059258 -0.496733 0.061674
v -0.059258 -0.496733 -0.062460
v -0.059994 -0.497234 0.497315
v -0.059994 -0.497234 -0.498102
v -0.059994 0.507706 -0.498102
v -0.059994 0.507706 0.497315
v -0.494900 0.507706 0.061709
v -0.494900 -0.497234 0.061709
v 0.497295 0.507706 0.061709
v 0.497295 -0.497234 0.061709
v 0.062686 0.507706 -0.498102
v 0.062686 -0.497234 -0.498102
v 0.062686 0.507706 0.497315
v 0.062686 -0.497234 0.497315
v -0.494900 0.507706 -0.063149
v -0.494900 -0.497234 -0.063149
v 0.497295 0.507706 -0.063149
v 0.497295 -0.497234 -0.063149
v -0.058217 0.134520 0.060216
v -0.058217 0.135872 -0.061813
v 0.061944 0.135872 -0.061813
v 0.061944 0.134520 0.060216
vt 0.000000 1.000000
vt 1.000000 1.000000
vt 1.000000 0.000000
vt 0.000000 0.000000
vt 0.437500 0.500000
vt 0.562500 0.500000
vt 0.562500 0.625000
vt 0.437541 0.625000
vt 0.437541 0.000000
vt 0.562500 0.000000
vt 0.562500 0.125000
vt 0.437500 0.125000
usemtl None
s off
f 11/1 9/2 10/3 12/4
f 22/5 21/6 24/7 23/8
f 17/2 19/1 20/4 18/3
f 13/2 15/1 16/4 14/3
f 3/9 4/10 2/11 1/12
f 8/1 7/2 6/3 5/4

View File

@ -0,0 +1,48 @@
# Blender v2.73 (sub 0) OBJ File: 'mt_torch_full_vertices3.blend'
# www.blender.org
mtllib torch_wall4.mtl
o Cube_Cube.001
v 0.061653 -0.554493 -0.328908
v 0.061653 -0.442208 -0.381835
v -0.059258 -0.554493 -0.328908
v -0.059258 -0.442208 -0.381835
v -0.059994 -0.948766 -0.143618
v -0.059994 -0.048361 -0.568031
v -0.059994 0.380112 0.340988
v -0.059994 -0.520293 0.765401
v -0.494900 -0.126265 0.579672
v -0.494900 -0.554738 -0.329346
v 0.497295 -0.126265 0.579672
v 0.497295 -0.554738 -0.329346
v 0.062686 0.380112 0.340988
v 0.062686 -0.048361 -0.568031
v 0.062686 -0.520293 0.765401
v 0.062686 -0.948766 -0.143618
v -0.494900 -0.013324 0.526437
v -0.494900 -0.441797 -0.382582
v 0.497295 -0.013324 0.526437
v 0.497295 -0.441797 -0.382582
v -0.058217 -0.284029 0.241470
v -0.058217 -0.173071 0.190665
v 0.061944 -0.173071 0.190665
v 0.061944 -0.284029 0.241470
vt 0.000000 1.000000
vt 1.000000 1.000000
vt 1.000000 0.000000
vt 0.000000 0.000000
vt 0.437500 0.500000
vt 0.562500 0.500000
vt 0.562500 0.625000
vt 0.437541 0.625000
vt 0.437541 0.000000
vt 0.562500 0.000000
vt 0.562500 0.125000
vt 0.437500 0.125000
usemtl None
s off
f 11/1 9/2 10/3 12/4
f 22/5 21/6 24/7 23/8
f 17/2 19/1 20/4 18/3
f 13/2 15/1 16/4 14/3
f 3/9 4/10 2/11 1/12
f 8/1 7/2 6/3 5/4

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -0,0 +1,121 @@
local colour_list = {
{"black", "Darkened",}, {"blue", "Blue",},
{"cyan", "Cyan",}, {"green", "Green",},
{"magenta", "Magenta",}, {"orange", "Orange",},
{"purple", "Purple",}, {"red", "Red",},
{"yellow", "Yellow",}, {"white", "Frosted",},
}
local enable_ceiling = true
for i in ipairs(colour_list) do
local colour = colour_list[i][1]
local desc = colour_list[i][2]
minetest.register_craftitem("abritorch:torch_"..colour, {
description = desc.." Torch",
inventory_image = "abritorch_torch_on_floor_"..colour..".png",
wield_image = "abritorch_torch_on_floor_"..colour..".png",
wield_scale = {x = 1, y = 1, z = 1 + 1/16},
liquids_pointable = false,
on_place = function(itemstack, placer, pointed_thing)
local above = pointed_thing.above
local under = pointed_thing.under
local wdir = minetest.dir_to_wallmounted({x = under.x - above.x, y = under.y - above.y, z = under.z - above.z})
if wdir < 1 and not enable_ceiling then
return itemstack
end
local fakestack = itemstack
local retval = false
if wdir <= 1 then
retval = fakestack:set_name("abritorch:floor_"..colour)
else
retval = fakestack:set_name("abritorch:wall_"..colour)
end
if not retval then
return itemstack
end
itemstack, retval = minetest.item_place(fakestack, placer, pointed_thing, param2)
itemstack:set_name("abritorch:torch_"..colour)
return itemstack
end
})
minetest.register_node("abritorch:floor_"..colour, {
description = desc.." Torch",
inventory_image = "abritorch_torch_on_floor_"..colour..".png",
wield_image = "abritorch_torch_on_floor_"..colour..".png",
wield_scale = {x = 1, y = 1, z = 1 + 1/16},
drawtype = "mesh",
mesh = "torch_floor.obj",
tiles = {
{
name = "abritorch_torch_on_floor_animated_"..colour..".png",
animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3}
}
},
paramtype = "light",
paramtype2 = "wallmounted",
sunlight_propagates = true,
walkable = false,
light_source = 13,
groups = {choppy=2, dig_immediate=3, flammable=1, not_in_creative_inventory=1, attached_node=1, torch=1},
drop = "abritorch:torch_"..colour,
selection_box = {
type = "wallmounted",
wall_top = {-1/16, -2/16, -1/16, 1/16, 0.5, 1/16},
wall_bottom = {-1/16, -0.5, -1/16, 1/16, 2/16, 1/16},
},
})
minetest.register_node("abritorch:wall_"..colour, {
inventory_image = "abritorch_torch_on_floor_"..colour..".png",
wield_image = "abritorch_torch_on_floor_"..colour..".png",
wield_scale = {x = 1, y = 1, z = 1 + 1/16},
drawtype = "mesh",
mesh = "torch_wall.obj",
tiles = {
{
name = "abritorch_torch_on_floor_animated_"..colour..".png",
animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3}
}
},
paramtype = "light",
paramtype2 = "wallmounted",
sunlight_propagates = true,
walkable = false,
light_source = 13,
groups = {choppy=2, dig_immediate=3, flammable=1, not_in_creative_inventory=1, attached_node=1, torch=1},
drop = "abritorch:torch_"..colour,
selection_box = {
type = "wallmounted",
wall_top = {-0.1, -0.1, -0.1, 0.1, 0.5, 0.1},
wall_bottom = {-0.1, -0.5, -0.1, 0.1, 0.1, 0.1},
wall_side = {-0.5, -0.3, -0.1, -0.2, 0.3, 0.1},
},
})
minetest.register_abm({
nodenames = {"abritorch:torch_"..colour},
interval = 1,
chance = 1,
action = function(pos)
local n = minetest.get_node(pos)
local def = minetest.registered_nodes[n.name]
if n and def then
local wdir = n.param2
local node_name = "abritorch:wall_"..colour
if wdir < 1 and not enable_ceiling then
minetest.remove_node(pos)
return
elseif wdir <= 1 then
node_name = "abritorch:floor_"..colour
end
minetest.set_node(pos, {name = node_name, param2 = wdir})
end
end
})
end

Binary file not shown.

674
mods_disabled/coins/LICENSE Normal file
View File

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{one line to give the program's name and a brief idea of what it does.}
Copyright (C) {year} {name of author}
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
{project} Copyright (C) {year} {fullname}
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

View File

@ -0,0 +1,17 @@
saras_simple_survival mod: coins
================================
Copyright (2020) freegamers.org
License of source code
------------------------------
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
https://www.gnu.org/licenses/gpl-3.0.html
License of textures
-------------------
commoditymarket_gold_coins.png - from https://commons.wikimedia.org/wiki/File:Farm-Fresh_coins.png, by FatCow under the CC-BY 3.0 license

View File

@ -0,0 +1,27 @@
-- Cook gold ingots into 100 gold coins.
minetest.register_craft({
type = "cooking",
cooktime = "60",
output = "coins:gold_coinss 8",
recipe = "default:gold_ingot",
})
-- Use a bucket of coins to smelt coins back into ingots.
minetest.register_craft({
type = "shapeless",
output = "coins:gold_scrap_bucket",
recipe = {
"coins:gold_coins", "coins:gold_coins","coins:gold_coins",
"coins:gold_coins", "bucket:bucket_empty","coins:gold_coins",
"coins:gold_coins", "coins:gold_coins","coins:gold_coins"
}
})
-- Cook a bucket of 8 gold coins to smelt gold ingot.
minetest.register_craft({
type = "cooking",
cooktime = "60",
output = "default:gold_ingot",
recipe = "coins:gold_scrap_bucket",
replacements = {{"coins:gold_scrap_bucket","bucket:bucket_empty"}}
})

View File

@ -0,0 +1,19 @@
-- TODO: coin press machine? (copper, silver) coins? melt coins back to ingots.
-- Get mod path and execute additional modules.
local path = minetest.get_modpath("coins")
dofile(path .. "/crafting.lua")
-- Register the gold coin craft item.
minetest.register_craftitem("coins:gold_coins", {
description = "Gold Coins",
inventory_image = "coins_gold_coins.png",
stack_max = "99",
})
-- Register the gold coin scrap bucket.
minetest.register_craftitem("coins:gold_scrap_bucket", {
description = "Bucket of Gold Scrap",
inventory_image = "coins_bucket_scrap_gold.png",
stack_max = 1,
})

View File

@ -0,0 +1,4 @@
name = coins
author = FreeGamers.org
description = Ore-based currencies.
depends = default

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

View File

@ -0,0 +1,64 @@
-- By FreeGamers.org
-- Facehuggers inspired by Alien,Aliens.
-- Texture, model, and foundation from "mobs_scifi" by D00Med.
mobs:register_mob("mobs_creatures:facehugger", {
type = "monster",
passive = false,
attacks_monsters = false,
damage = 5,
reach = 2,
attack_type = "dogfight",
hp_min = 5,
hp_max = 5,
armor = 100,
collisionbox = {-0.3, -0.1, -0.3, 0.3, 0.1, 0.3},
visual = "mesh",
mesh = "mobs_creatures_facehugger.b3d",
textures = {
{"mobs_creatures_facehugger.png"},
},
sounds = {
random ="mobs_creatures_facehugger_random",
jump = "mobs_creatures_facehugger_jump",
damage = "mobs_creatures_facehugger_damage",
death = "mobs_creatures_facehugger_death",
},
blood_texture = "mobs_blood.png",
visual_size = {x=1, y=1},
makes_footstep_sound = true,
walk_velocity = 1,
run_velocity = 3,
jump = true,
stepheight = 1.5,
water_damage = 0,
lava_damage = 2,
light_damage = 0,
view_range = 7,
animation = {
speed_normal = 12,
speed_run = 20,
walk_start = 10,
walk_end = 30,
run_start = 10,
run_end = 30,
punch_start = 30,
punch_end = 43,
},
-- do_custom = function(self)
-- local pos = self.object:getpos()
-- local objs = minetest.get_objects_inside_radius(pos, 2)
-- for _, obj in pairs(objs) do
-- if obj:is_player() and obj:get_attach() == nil then
-- obj:set_attach(self.object, "", {x=.2, y=15, z=3}, {x=-100, y=225, z=90})
-- self.object:set_animation({x=46, y=46}, 20, 0)
-- end
-- end
-- end,
-- on_die = function(
})
-- Register Spawn Egg
mobs:register_egg("mobs_creatures:facehugger", "Facehugger Spawn Egg", "default_obsidian.png", 1)
-- Register Spawn Parameters
--mobs:spawn_specific("mobs_creatures:facehugger", {"default:dirt_with_dry_grass"}, {"default:stone"}, 20, 0, 300, 15000, 2, 31000, 31001)

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

View File

@ -0,0 +1,14 @@
name: integration-test
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: integration-test
run: ./integration-test.sh

View File

@ -0,0 +1,17 @@
name: luacheck
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: apt
run: sudo apt-get install -y luarocks
- name: luacheck install
run: luarocks install --local luacheck
- name: luacheck run
run: $HOME/.luarocks/bin/luacheck ./

View File

@ -0,0 +1,39 @@
unused_args = false
allow_defined_top = true
ignore = {"512"}
globals = {
"jumpdrive",
-- write
"travelnet",
"pipeworks",
"beds"
}
read_globals = {
-- Stdlib
string = {fields = {"split"}},
table = {fields = {"copy", "getn"}},
"VoxelManip",
-- Minetest
"minetest",
"vector", "ItemStack",
"dump", "VoxelArea",
-- Deps
"unified_inventory", "default", "monitoring",
"digilines",
"mesecons",
"mesecon",
"technic",
"locator",
"display_api",
"areas",
"ropes",
"sethome",
"drawers",
"player_monoids"
}

View File

@ -0,0 +1,10 @@
minetest.register_node("jumpdrive:backbone", {
description = "Jumpdrive Backbone",
tiles = {"jumpdrive_backbone.png"},
groups = {cracky=3,oddly_breakable_by_hand=3},
sounds = default.node_sound_glass_defaults(),
light_source = 13
})

View File

@ -0,0 +1,6 @@
if minetest.get_modpath("technic") then
table.insert(jumpdrive.blacklist, "technic:forcefield_emitter_on")
end
-- TODO bedrock, advtrains tracks

View File

@ -0,0 +1,107 @@
jumpdrive.write_to_book = function(pos, sender)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if inv:contains_item("main", {name="default:book", count=1}) then
local stack = inv:remove_item("main", {name="default:book", count=1})
local new_stack = ItemStack("default:book_written")
local data = {}
data.owner = sender:get_player_name()
data.title = "Jumpdrive coordinates"
data.description = "Jumpdrive coordiates"
data.text = minetest.serialize(jumpdrive.get_meta_pos(pos))
data.page = 1
data.page_max = 1
new_stack:get_meta():from_table({ fields = data })
if inv:room_for_item("main", new_stack) then
-- put written book back
inv:add_item("main", new_stack)
else
-- put back old stack
inv:add_item("main", stack)
end
end
end
jumpdrive.read_from_book = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local player_name = meta:get_string("owner")
if inv:contains_item("main", {name="default:book_written", count=1}) then
local stack = inv:remove_item("main", {name="default:book_written", count=1})
local stackMeta = stack:get_meta()
local text = stackMeta:get_string("text")
local data = minetest.deserialize(text)
if data == nil then
-- put book back, it may contain other information
inv:add_item("main", stack)
-- alert player
if nil ~= player_name then
minetest.chat_send_player(player_name, "Invalid data")
end
return
end
local x = tonumber(data.x)
local y = tonumber(data.y)
local z = tonumber(data.z)
if x == nil or y == nil or z == nil then
-- put book back, it may contain other information
inv:add_item("main", stack)
-- alert player
if nil ~= player_name then
minetest.chat_send_player(player_name, "Invalid coordinates")
end
return
end
meta:set_int("x", jumpdrive.sanitize_coord(x))
meta:set_int("y", jumpdrive.sanitize_coord(y))
meta:set_int("z", jumpdrive.sanitize_coord(z))
-- put book back
inv:add_item("main", stack)
elseif inv:contains_item("main", {name="missions:wand_position", count=1}) then
local stack = inv:remove_item("main", {name="missions:wand_position", count=1})
local stackMeta = stack:get_meta()
local text = stackMeta:get_string("pos")
local target_pos = minetest.string_to_pos(text)
if nil == target_pos then
-- put wand back, I don't see a way to corrupt a wand atm
inv:add_item("main", stack)
return
end
local x = target_pos.x
local y = target_pos.y
local z = target_pos.z
if x == nil or y == nil or z == nil then
-- put wand back, I don't see a way to corrupt a wand atm
inv:add_item("main", stack)
return
end
meta:set_int("x", jumpdrive.sanitize_coord(x))
meta:set_int("y", jumpdrive.sanitize_coord(y))
meta:set_int("z", jumpdrive.sanitize_coord(z))
-- put wand back
inv:add_item("main", stack)
end
end

View File

@ -0,0 +1,52 @@
jumpdrive.sanitize_coord = function(coord)
return math.max( math.min( coord, 31000 ), -31000 )
end
-- get pos object from pos
jumpdrive.get_meta_pos = function(pos)
local meta = minetest.get_meta(pos);
return {x=meta:get_int("x"), y=meta:get_int("y"), z=meta:get_int("z")}
end
-- set pos object from pos
jumpdrive.set_meta_pos = function(pos, target)
local meta = minetest.get_meta(pos);
meta:set_int("x", target.x)
meta:set_int("y", target.y)
meta:set_int("z", target.z)
end
-- get offset from meta
jumpdrive.get_radius = function(pos)
local meta = minetest.get_meta(pos);
return math.max(math.min(meta:get_int("radius"), jumpdrive.config.max_radius), 1)
end
-- calculates the power requirements for a jump
jumpdrive.calculate_power = function(radius, distance, sourcePos, targetPos)
return 10 * distance * radius
end
-- preflight check, for overriding
jumpdrive.preflight_check = function(source, destination, radius, playername)
return { success=true }
end
jumpdrive.reset_coordinates = function(pos)
local meta = minetest.get_meta(pos)
meta:set_int("x", pos.x)
meta:set_int("y", pos.y)
meta:set_int("z", pos.z)
end
function jumpdrive.get_mapblock_from_pos(pos)
return {
x = math.floor(pos.x / 16),
y = math.floor(pos.y / 16),
z = math.floor(pos.z / 16)
}
end

View File

@ -0,0 +1,57 @@
-- stolen from technic / anchor.lua
local function compute_forceload_positions(pos, meta)
local radius = meta:get_int("radius")
local minpos = vector.subtract(pos, vector.new(radius, radius, radius))
local maxpos = vector.add(pos, vector.new(radius, radius, radius))
local minbpos = {}
local maxbpos = {}
for _, coord in ipairs({"x","y","z"}) do
minbpos[coord] = math.floor(minpos[coord] / 16) * 16
maxbpos[coord] = math.floor(maxpos[coord] / 16) * 16
end
local flposes = {}
for x = minbpos.x, maxbpos.x, 16 do
for y = minbpos.y, maxbpos.y, 16 do
for z = minbpos.z, maxbpos.z, 16 do
table.insert(flposes, vector.new(x, y, z))
end
end
end
return flposes
end
local function currently_forceloaded_positions(meta)
local ser = meta:get_string("forceloaded")
return ser == "" and {} or minetest.deserialize(ser)
end
local function forceload_off(meta)
local flposes = currently_forceloaded_positions(meta)
meta:set_string("forceloaded", "")
for _, p in ipairs(flposes) do
minetest.forceload_free_block(p)
end
end
local function forceload_on(pos, meta)
local want_flposes = compute_forceload_positions(pos, meta)
local have_flposes = {}
for _, p in ipairs(want_flposes) do
if minetest.forceload_block(p) then
table.insert(have_flposes, p)
end
end
meta:set_string("forceloaded", #have_flposes == 0 and "" or minetest.serialize(have_flposes))
end
jumpdrive.anchor_compat = function(from, to)
local to_meta = minetest.get_meta(to)
local from_meta = minetest.get_meta(from)
if from_meta:get_int("enabled") ~= 0 then
-- anchor enabled
forceload_off(from_meta)
forceload_on(to, to_meta)
end
end

View File

@ -0,0 +1,27 @@
jumpdrive.areas_compat = function(pos1, pos2, delta_vector)
local list = areas:getAreasIntersectingArea(pos1, pos2)
local dirty = false
for id, area in pairs(list) do
local xMatch = area.pos1.x >= pos1.x and area.pos2.x <= pos2.x
local yMatch = area.pos1.y >= pos1.y and area.pos2.y <= pos2.y
local zMatch = area.pos1.z >= pos1.z and area.pos2.z <= pos2.z
if xMatch and yMatch and zMatch then
dirty = true
minetest.log("action", "[jumpdrive] moving area " .. id)
areas:move(
id,
area,
vector.add(area.pos1, delta_vector),
vector.add(area.pos2, delta_vector)
)
end
end
if dirty then
areas:save()
end
end

View File

@ -0,0 +1,64 @@
local bed_bottoms = {"beds:bed_bottom", "beds:fancy_bed_bottom"}
-- Calculate a bed's middle position (where players would spawn)
local function calc_bed_middle(bed_pos, facedir)
local dir = minetest.facedir_to_dir(facedir)
local bed_middle = {
x = bed_pos.x + dir.x / 2,
y = bed_pos.y,
z = bed_pos.z + dir.z / 2
}
return bed_middle
end
jumpdrive.beds_compat = function(target_pos1, target_pos2, delta_vector)
if beds == nil or
beds.spawn == nil or
beds.save_spawns == nil then
-- Something is wrong. Don't do anything
return
end
-- Look for beds in target area
local beds_list = minetest.find_nodes_in_area(target_pos1, target_pos2, bed_bottoms)
if next(beds_list) ~= nil then
-- We found some beds!
local source_pos1 = vector.subtract(target_pos1, delta_vector)
local source_pos2 = vector.subtract(target_pos2, delta_vector)
-- Look for players with spawn in source area
local affected_players = {}
for name, pos in pairs(beds.spawn) do
-- pos1 and pos2 must already be sorted
if pos.x >= source_pos1.x and pos.x <= source_pos2.x and
pos.y >= source_pos1.y and pos.y <= source_pos2.y and
pos.z >= source_pos1.z and pos.z <= source_pos2.z then
table.insert(affected_players, name)
end
end
if next(affected_players) ~= nil then
-- Some players seem to be affected.
-- Iterate over all beds
for _, pos in pairs(beds_list) do
local facedir = minetest.get_node(pos).param2
local old_middle = calc_bed_middle(vector.subtract(pos, delta_vector), facedir)
for _, name in ipairs(affected_players) do
local spawn = beds.spawn[name]
if spawn.x == old_middle.x and
spawn.y == old_middle.y and
spawn.z == old_middle.z then
---- Player spawn seems to match old bed position; update
beds.spawn[name] = calc_bed_middle(pos, facedir)
minetest.log("action",
"[jumpdrive] Updated bed spawn for player " .. name)
end
end
end
-- Tell beds mod to save the new spawns.
beds.save_spawns()
end
end
end

View File

@ -0,0 +1,107 @@
local MP = minetest.get_modpath("jumpdrive")
local has_travelnet_mod = minetest.get_modpath("travelnet")
local has_technic_mod = minetest.get_modpath("technic")
local has_locator_mod = minetest.get_modpath("locator")
local has_elevator_mod = minetest.get_modpath("elevator")
local has_display_mod = minetest.get_modpath("display_api")
local has_pipeworks_mod = minetest.get_modpath("pipeworks")
local has_beds_mod = minetest.get_modpath("beds")
-- rope removal crashes with minetest >= 5.2 (get_content_id)
-- isse: https://github.com/minetest-mods/ropes/issues/19
-- local has_ropes_mod = minetest.get_modpath("ropes")
local has_sethome_mod = minetest.get_modpath("sethome")
local has_areas_mod = minetest.get_modpath("areas")
local has_drawers_mod = minetest.get_modpath("drawers")
local has_textline_mod = minetest.get_modpath("textline")
dofile(MP.."/compat/travelnet.lua")
dofile(MP.."/compat/locator.lua")
dofile(MP.."/compat/elevator.lua")
dofile(MP.."/compat/signs.lua")
dofile(MP.."/compat/itemframes.lua")
dofile(MP.."/compat/anchor.lua")
dofile(MP.."/compat/telemosaic.lua")
dofile(MP.."/compat/beds.lua")
dofile(MP.."/compat/ropes.lua")
dofile(MP.."/compat/sethome.lua")
dofile(MP.."/compat/areas.lua")
dofile(MP.."/compat/drawers.lua")
dofile(MP.."/compat/textline.lua")
if has_pipeworks_mod then
dofile(MP.."/compat/teleporttube.lua")
end
jumpdrive.node_compat = function(name, source_pos, target_pos)
if (name == "locator:beacon_1" or name == "locator:beacon_2" or name == "locator:beacon_3") and has_locator_mod then
jumpdrive.locator_compat(source_pos, target_pos)
elseif has_technic_mod and name == "technic:admin_anchor" then
jumpdrive.anchor_compat(source_pos, target_pos)
elseif has_pipeworks_mod and string.find(name, "^pipeworks:teleport_tube") then
jumpdrive.teleporttube_compat(source_pos, target_pos)
elseif name == "telemosaic:beacon" or name == "telemosaic:beacon_protected" then
jumpdrive.telemosaic_compat(source_pos, target_pos)
end
end
jumpdrive.commit_node_compat = function()
if has_pipeworks_mod then
jumpdrive.teleporttube_compat_commit()
end
end
jumpdrive.target_region_compat = function(source_pos1, source_pos2, target_pos1, target_pos2, delta_vector)
-- sync compat functions
if has_travelnet_mod then
jumpdrive.travelnet_compat(target_pos1, target_pos2)
end
if has_elevator_mod then
jumpdrive.elevator_compat(target_pos1, target_pos2)
end
if has_sethome_mod then
jumpdrive.sethome_compat(source_pos1, source_pos2, delta_vector)
end
if has_beds_mod then
jumpdrive.beds_compat(target_pos1, target_pos2, delta_vector)
end
--[[
if has_ropes_mod then
jumpdrive.ropes_compat(target_pos1, target_pos2, delta_vector)
end
--]]
if has_areas_mod then
jumpdrive.areas_compat(source_pos1, source_pos2, delta_vector)
end
-- async compat functions below here
minetest.after(1.0, function()
if has_drawers_mod then
jumpdrive.drawers_compat(target_pos1, target_pos2)
end
if has_display_mod then
jumpdrive.signs_compat(target_pos1, target_pos2)
end
if has_textline_mod then
jumpdrive.textline_compat(target_pos1, target_pos2)
end
end)
end

View File

@ -0,0 +1,9 @@
function jumpdrive.drawers_compat(target_pos1, target_pos2)
local nodes = minetest.find_nodes_in_area(target_pos1, target_pos2, {"group:drawer"})
if nodes then
for _, pos in ipairs(nodes) do
drawers.spawn_visuals(pos)
end
end
end

View File

@ -0,0 +1,18 @@
jumpdrive.elevator_compat = function(pos1, pos2)
-- find potential elevators
local elevator_motors = minetest.find_nodes_in_area(pos1, pos2, "elevator:motor")
for _,pos in ipairs(elevator_motors) do
-- delegate to compat
local def = minetest.registered_nodes["elevator:motor"]
minetest.log("action", "[jumpdrive] Restoring elevator @ " .. pos.x .. "/" .. pos.y .. "/" .. pos.z)
-- function(pos, placer, itemstack)
def.after_place_node(pos, nil, nil)
end
end

View File

@ -0,0 +1,20 @@
local update_item = function(pos, node)
-- TODO
end
jumpdrive.itemframes_compat = function(pos1, pos2)
local nodes = minetest.find_nodes_in_area(pos1, pos2, {"itemframes:pedestal", "itemframes:frame"})
if nodes then
for _,pos in pairs(nodes) do
minetest.log("action", "[jumpdrive] updating itemframe @ " .. minetest.pos_to_string(pos))
local node = minetest.get_node(pos)
update_item(pos, node)
end
end
end

View File

@ -0,0 +1,8 @@
jumpdrive.locator_compat = function(from, to)
local meta = minetest.get_meta(to)
locator.remove_beacon(from)
locator.update_beacon(to, meta)
end

View File

@ -0,0 +1,86 @@
local rope_nodes = { -- Top, middle, bottom
{"ropes:rope_top", "ropes:rope", "ropes:rope_bottom"}, -- Rope boxes
{"ropes:ropeladder_falling", "ropes:ropeladder", "ropes:ropeladder_bottom"}, -- Rope ladders
}
jumpdrive.ropes_compat = function(target_pos1, target_pos2, delta_vector)
if ropes == nil or
ropes.destroy_rope == nil then
-- Something is wrong. Don't do anything
return
end
-- Bottom slice of the target area
local target_bottom_pos1 = target_pos1
local target_bottom_pos2 = {
x = target_pos2.x,
y = target_pos1.y,
z = target_pos2.z
}
-- Top slice of the target area
local target_top_pos1 = {
x = target_pos1.x,
y = target_pos2.y,
z = target_pos1.z
}
local target_top_pos2 = target_pos2
-- For every type of rope
for _, rope_type_nodes in ipairs(rope_nodes) do
-- Look for ropes hanging out of the jump area
local ropes_hanging_out = minetest.find_nodes_in_area(
target_bottom_pos1, target_bottom_pos2,
{rope_type_nodes[1], rope_type_nodes[2]})
for _, pos in ipairs(ropes_hanging_out) do
-- Swap with a proper end node, keeping param2
local end_node = minetest.get_node(pos)
minetest.swap_node(pos, {
name=rope_type_nodes[3],
param2=end_node.param2
})
-- Destroy remainder of the rope below the source area
local remainder_pos = {
x = pos.x - delta_vector.x,
y = pos.y - delta_vector.y - 1,
z = pos.z - delta_vector.z
}
ropes.destroy_rope(remainder_pos, rope_type_nodes)
end
-- Look for ropes hanging into the jump area
local ropes_hanging_in = minetest.find_nodes_in_area(
target_top_pos1, target_top_pos2,
rope_type_nodes)
for _, pos in ipairs(ropes_hanging_in) do
-- Probably there is a loose end above the source area
local end_pos = {
x = pos.x - delta_vector.x,
y = pos.y - delta_vector.y + 1,
z = pos.z - delta_vector.z
}
local end_node = minetest.get_node(end_pos)
if end_node and
(end_node.name == rope_type_nodes[1] or
end_node.name == rope_type_nodes[2]) then
-- Swap with a proper end node, keeping param2
minetest.swap_node(end_pos, {
name=rope_type_nodes[3],
param2=end_node.param2
})
end
-- Destroy remainder of the rope in the target area
ropes.destroy_rope(pos, rope_type_nodes)
end
end
end

View File

@ -0,0 +1,19 @@
jumpdrive.sethome_compat = function(pos1, pos2, delta_vector)
-- move /home positions of online players
for _,player in ipairs(minetest.get_connected_players()) do
local name = player:get_player_name()
local home_pos = sethome.get(name)
if home_pos then
local xMatch = home_pos.x >= pos1.x and home_pos.x <= pos2.x
local yMatch = home_pos.y >= pos1.y and home_pos.y <= pos2.y
local zMatch = home_pos.z >= pos1.z and home_pos.z <= pos2.z
if xMatch and yMatch and zMatch then
local new_pos = vector.add(home_pos, delta_vector)
sethome.set(name, new_pos)
end
end
end
end

View File

@ -0,0 +1,10 @@
jumpdrive.signs_compat = function(pos1, pos2)
local nodes = minetest.find_nodes_in_area(pos1, pos2, {"group:display_api"})
if nodes then
for _,pos in pairs(nodes) do
minetest.log("action", "[jumpdrive] updating display @ " .. minetest.pos_to_string(pos))
display_api.update_entities(pos)
end
end
end

View File

@ -0,0 +1,47 @@
local function unhash_pos(hash)
local pos = {}
local list = string.split(hash, ':')
pos.x = tonumber(list[1])
pos.y = tonumber(list[2])
pos.z = tonumber(list[3])
return pos
end
local function hash_pos(pos)
return math.floor(pos.x + 0.5) .. ':' ..
math.floor(pos.y + 0.5) .. ':' ..
math.floor(pos.z + 0.5)
end
jumpdrive.telemosaic_compat = function(source_pos, target_pos)
-- delegate to compat
minetest.log("action", "[jumpdrive] Trying to rewire telemosaic @ " ..
target_pos.x .. "/" .. target_pos.y .. "/" .. target_pos.z)
local local_meta = minetest.get_meta(target_pos)
local local_hash = local_meta:get_string('telemosaic:dest')
if local_hash ~= nil and local_hash ~= '' then
local local_pos = unhash_pos(local_hash)
minetest.load_area(local_pos)
local node = minetest.get_node(local_pos)
if node.name == "telemosaic:beacon" then
local remote_hash = minetest.get_meta(local_pos):get_string('telemosaic:dest')
if remote_hash == hash_pos(source_pos) then
-- remote beacon points to this beacon, update link
local remote_pos = unhash_pos(remote_hash)
local remote_meta = minetest.get_meta(remote_pos)
minetest.log("action", "[jumpdrive] rewiring telemosaic at " .. minetest.pos_to_string(remote_pos) ..
" to " .. minetest.pos_to_string(target_pos))
remote_meta:set_string("telemosaic:dest", hash_pos(target_pos))
end
end
end
end

View File

@ -0,0 +1,47 @@
if not pipeworks.tptube then
minetest.log("warning", "[jumpdrive] pipeworks teleport patch not applied, tp-tubes don't work as expected!")
end
-- https://gitlab.com/VanessaE/pipeworks/blob/master/teleport_tube.lua
jumpdrive.teleporttube_compat = function(from, to)
if not pipeworks.tptube then
-- only works with the patch from "./patches/pipeworks.patch"
return
end
local from_hash = pipeworks.tptube.hash(from)
local to_hash = pipeworks.tptube.hash(to)
-- swap data
local db = pipeworks.tptube.get_db()
local data = db[from_hash]
if not data then
minetest.log("warning", "[jumpdrive] no tp-tube data found at hash: " ..
from_hash .. " / pos: " .. minetest.pos_to_string(from))
return
end
minetest.log("action", "[jumpdrive] moving tp-tube data from " ..
from_hash .. " to " .. to_hash .. " at pos: " .. minetest.pos_to_string(from))
data.x = to.x
data.y = to.y
data.z = to.z
db[from_hash] = nil
db[to_hash] = data
end
jumpdrive.teleporttube_compat_commit = function()
if not pipeworks.tptube then
-- only works with the patch from "./patches/pipeworks.patch"
return
end
pipeworks.tptube.save_tube_db()
end

View File

@ -0,0 +1,17 @@
jumpdrive.textline_compat = function(target_pos1, target_pos2)
local textline_def = minetest.registered_nodes["textline:lcd"]
if not textline_def then
return
end
local nodes = minetest.find_nodes_in_area(target_pos1, target_pos2, {"textline:lcd"})
if nodes then
for _, pos in ipairs(nodes) do
-- https://github.com/gbl08ma/textline/blob/636c776446c3fc831376335b72bb48281fb6ab11/init.lua#L103
-- invoke prepare_writing() function through place_node callback
textline_def.after_place_node(pos)
end
end
end

View File

@ -0,0 +1,25 @@
jumpdrive.travelnet_compat = function(pos1, pos2)
local pos_list = minetest.find_nodes_in_area(pos1, pos2, {"travelnet:travelnet"})
if pos_list then
for _,pos in pairs(pos_list) do
local meta = minetest.get_meta(pos);
minetest.log("action", "[jumpdrive] Restoring travelnet @ " .. pos.x .. "/" .. pos.y .. "/" .. pos.z)
local owner_name = meta:get_string( "owner" );
local station_name = meta:get_string( "station_name" );
local station_network = meta:get_string( "station_network" );
if (travelnet.targets[owner_name]
and travelnet.targets[owner_name][station_network]
and travelnet.targets[owner_name][station_network][station_name]) then
travelnet.targets[owner_name][station_network][station_name].pos = pos
end
end
if travelnet.save_data ~= nil then
travelnet.save_data()
end
end
end

View File

@ -0,0 +1,20 @@
if minetest.get_modpath("default") then
minetest.register_craft({
output = 'jumpdrive:engine',
recipe = {
{'jumpdrive:backbone', 'default:steelblock', 'jumpdrive:backbone'},
{'default:steelblock', 'default:steelblock', 'default:steelblock'},
{'jumpdrive:backbone', 'default:steelblock', 'jumpdrive:backbone'}
}
})
minetest.register_craft({
output = 'jumpdrive:backbone',
recipe = {
{'default:mese_block', 'default:steelblock', 'default:mese_block'},
{'default:steelblock', 'default:steelblock', 'default:steelblock'},
{'default:mese_block', 'default:steelblock', 'default:mese_block'}
}
})
end

View File

@ -0,0 +1,109 @@
--https://github.com/minetest-mods/technic/blob/master/technic/machines/HV/forcefield.lua
local is_int = function(value)
return type(value) == 'number' and math.floor(value) == value
end
jumpdrive.digiline_effector = function(pos, _, channel, msg)
local msgt = type(msg)
if msgt ~= "table" then
return
end
local meta = minetest.get_meta(pos)
local set_channel = meta:get_string("channel")
if set_channel == "" then
-- backward compatibility with old static channel
set_channel = "jumpdrive"
end
if channel ~= set_channel then
return
end
local radius = jumpdrive.get_radius(pos)
local targetPos = jumpdrive.get_meta_pos(pos)
local distance = vector.distance(pos, targetPos)
local power_req = jumpdrive.calculate_power(radius, distance, pos, targetPos)
if msg.command == "get" then
digilines.receptor_send(pos, digilines.rules.default, set_channel, {
powerstorage = meta:get_int("powerstorage"),
radius = radius,
position = pos,
target = targetPos,
distance = distance,
power_req = power_req
})
elseif msg.command == "reset" then
meta:set_int("x", pos.x)
meta:set_int("y", pos.y)
meta:set_int("z", pos.z)
jumpdrive.update_formspec(meta, pos)
elseif msg.command == "set" then
if msg.key and msg.value then
local value = tonumber(msg.value)
if value == nil then
-- not a number
return
end
-- backward compatibility with old less flexible set command
if msg.key == "x" then
meta:set_int("x", value)
elseif msg.key == "y" then
meta:set_int("y", value)
elseif msg.key == "z" then
meta:set_int("z", value)
elseif msg.key == "radius" then
if value >= 1 and value <= jumpdrive.config.max_radius then
meta:set_int("radius", value)
end
end
else
-- API requires integers for coord values, noop for everything else
if is_int(msg.x) then meta:set_int("x", msg.x) end
if is_int(msg.y) then meta:set_int("y", msg.y) end
if is_int(msg.z) then meta:set_int("z", msg.z) end
if is_int(msg.r) and msg.r <= jumpdrive.config.max_radius then
meta:set_int("radius", msg.r)
end
if msg.formupdate then
jumpdrive.update_formspec(meta, pos)
end
end
elseif msg.command == "simulate" or msg.command == "show" then
local success, resultmsg = jumpdrive.simulate_jump(pos)
digilines.receptor_send(pos, digilines.rules.default, set_channel, {
success=success,
msg=resultmsg
})
elseif msg.command == "jump" then
local success, timeormsg = jumpdrive.execute_jump(pos)
local send_pos = pos
if success then
-- send new message in target pos
send_pos = targetPos
digilines.receptor_send(send_pos, digilines.rules.default, set_channel, {
success = success,
time = timeormsg
})
else
digilines.receptor_send(send_pos, digilines.rules.default, set_channel, {
success = success,
msg = timeormsg
})
end
end
end

View File

@ -0,0 +1,293 @@
# Digilines interface
Digiline commands if the `digilines` mod is available
## Engine
### Query current status/coords
Request coordinates and engine status
```lua
-- request
digiline_send("jumpdrive", {
command = "get"
})
-- response sent back on the same channel
if event.type == "digiline" and event.channel == "jumpdrive" then
event.msg = {
powerstorage = 1000000,
radius = 10,
position = {x=0, y=0, z=0},
target = {x=0, y=0, z=0},
distance = 100,
power_req = 150000
}
end
```
### Reset target coordinates
Resets the target coordinates
```lua
-- request
digiline_send("jumpdrive", {
command = "reset"
})
```
### Set target coordinates
Set the target coordinates
```lua
-- request
digiline_send("jumpdrive", { command = "set", key = "x", value = 1024 })
digiline_send("jumpdrive", { command = "set", key = "y", value = 1024 })
digiline_send("jumpdrive", { command = "set", key = "z", value = 2048 })
digiline_send("jumpdrive", { command = "set", key = "radius", value = 15 })
```
Alternate way to set coordinates
```lua
-- request
digiline_send("jumpdrive", { command = "set", x = 1024, y = 1024, z = 2048, r = 15, formupdate = false })
```
Where
* `x` sets x coordinate
* `y` sets y coordinate
* `z` sets z coordinate
* `r` sets radius
* `formupdate` updates coordinates on formspec
Every value is optional. `x`, `y`, `z` and `r` must be integers. `formupdate` is truth value.
### Simulate jump
Simulate a jump
```lua
-- request
digiline_send("jumpdrive", {
command = "simulate"
})
-- response sent back on the same channel
if event.type == "digiline" and event.channel == "jumpdrive" then
event.msg = {
success = false, -- true if successful
msg = "Protected by xyz!"
}
end
```
### Execute jump
Execute a jump
```lua
-- request
digiline_send("jumpdrive", {
command = "jump"
})
-- response sent back on the same channel
if event.type == "digiline" and event.channel == "jumpdrive" then
event.msg = {
success = true,
time = 1234 -- time used in microseconds
}
end
```
## Fleetcontroller
Fleetcontroller interface
### Query current status/coords
Request coordinates and status
```lua
-- request
digiline_send("fleetcontroller", {
command = "get"
})
-- response sent back on the same channel
if event.type == "digiline" and event.channel == "fleetcontroller" then
event.msg = {
active = true,
engines = {
{
power_req = 10000,
powerstorage = 125000,
radius = 10,
position = { x=0, y=0, z=0 },
target = { x=0, y=0, z=0 },
distance = 2500,
},{
-- etc
}
},
max_power_req = 100000, -- max power of an engine
total_power_req = 12500000, -- total power of all engines
position = { x=0, y=0, z=0 },
target = { x=0, y=0, z=0 },
distance = 2500,
}
end
```
### Reset coordinates
Resets the target coordinates
```lua
-- request
digiline_send("fleetcontroller", {
command = "reset"
})
-- response sent back on the same channel
if event.type == "digiline" and event.channel == "fleetcontroller" then
-- sent if the jump is still in progress
event.msg = {
success = false,
msg = "Operation not completed"
}
end
```
### Set coordinates
Resets the target coordinates
Where
* `x` sets x coordinate
* `y` sets y coordinate
* `z` sets z coordinate
* `formupdate` updates coordinates on formspec
Every value is optional. `x`, `y` and `z` must be integers. `formupdate` is truth value.
```lua
-- request
digiline_send("fleetcontroller", {
command = "set",
x = 0,
y = 100,
z = 1024,
formupdate = false
})
-- response sent back on the same channel
if event.type == "digiline" and event.channel == "fleetcontroller" then
-- sent if the jump is still in progress
event.msg = {
success = false,
msg = "Operation not completed"
}
end
```
Response is only sent when operation fails due to another operation is in progress like simulation or jump.
Error will not be sent for invalid values or missing values because every value is optional.
### Simulate jump
Simulates a jump
```lua
-- request
digiline_send("fleetcontroller", {
command = "simulate"
})
-- response sent back on the same channel
if event.type == "digiline" and event.channel == "fleetcontroller" then
-- sent if the jump is still in progress
event.msg = {
success = false,
msg = "Operation not completed"
}
-- sent on abort
event.msg {
success = false,
index = 1,
count = 10,
msg = "simulation aborted"
}
-- sent if an error occured
event.msg = {
success = false,
pos = { x=0, y=0, z=0 },
msg = "Protected by xyz!"
}
-- sent on success
event.msg = {
success = true,
count = 10,
msgs = {
-- possible warning messages for engines like target in vacuum warning
}
}
end
```
### Execute jump
Executes a jump
```lua
-- request
digiline_send("fleetcontroller", {
command = "jump"
})
-- response sent back on the same channel
if event.type == "digiline" and event.channel == "fleetcontroller" then
-- sent if the jump is still in progress
event.msg = {
success = false,
msg = "Operation not completed"
}
-- sent on abort
event.msg {
success = false,
index = 1,
count = 10,
msg = "jump aborted"
}
-- sent if an error occured
event.msg = {
success = false,
count = 1,
msg = "Protected by xyz!",
msgs = {
-- messages
}
}
-- sent on success
event.msg = {
success = true,
count = 10,
msgs = {
-- messages
},
time = 1234 -- microseconds used
}
end
```

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,268 @@
local has_technic = minetest.get_modpath("technic")
-- TODO: consolidate/move common functions to own module
minetest.register_node("jumpdrive:area_engine", {
description = "Jumpdrive (area enabled)",
tiles = {"jumpdrive_area.png"},
tube = {
insert_object = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:add_item("main", stack)
end,
can_insert = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
stack = stack:peek_item(1)
return inv:room_for_item("main", stack)
end,
input_inventory = "main",
connect_sides = {bottom = 1}
},
connects_to = {"group:technic_hv_cable"},
connect_sides = {"bottom", "top", "left", "right", "front", "back"},
light_source = 13,
groups = {
cracky = 3,
oddly_breakable_by_hand = 3,
tubedevice = 1,
tubedevice_receiver = 1,
technic_machine = 1,
technic_hv = 1
},
sounds = default.node_sound_glass_defaults(),
digiline = {
receptor = {action = function() end},
effector = {
action = jumpdrive.digiline_effector
},
},
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
meta:set_string("owner", placer:get_player_name() or "")
-- default digiline channel
meta:set_string("channel", "jumpdrive")
end,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_int("area_number", 0)
meta:set_int("powerstorage", 0)
jumpdrive.migrate_engine_meta(pos, meta)
meta:set_int("HV_EU_input", 0)
meta:set_int("HV_EU_demand", 0)
jumpdrive.update_area_formspec(meta, pos)
end,
can_dig = function(pos,player)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
local name = player:get_player_name()
return inv:is_empty("main") and
inv:is_empty("upgrade") and
not minetest.is_protected(pos, name)
end,
on_timer = function(pos, elapsed)
local meta = minetest.get_meta(pos)
local store = meta:get_int("powerstorage")
local max_store = meta:get_int("max_powerstorage")
if store >= max_store then
-- internal store is full
return true
end
local inv = meta:get_inventory()
for i=1, inv:get_size("main") do
local stack = inv:get_stack("main", i)
if not stack:is_empty() then
local burn_value = jumpdrive.fuel.get_value(stack:get_name())
if burn_value > 0 then
local store_space = max_store - store
local fuel_value = burn_value * stack:get_count()
if fuel_value > store_space then
stack:set_count(stack:get_count() - math.ceil(store_space / burn_value))
store = max_store
else
stack:clear()
store = store + fuel_value
end
inv:set_stack("main", i, stack)
end
end
end
meta:set_int("powerstorage", store)
if not has_technic then
jumpdrive.update_infotext(meta, pos)
end
-- restart timer
return true
end,
technic_run = jumpdrive.technic_run,
on_receive_fields = function(pos, formname, fields, sender)
local meta = minetest.get_meta(pos);
jumpdrive.migrate_engine_meta(pos, meta)
if not sender then
return
end
local playername = sender:get_player_name()
if minetest.is_protected(pos, sender:get_player_name()) then
-- not allowed
return
end
if fields.read_book then
jumpdrive.read_from_book(pos)
jumpdrive.update_area_formspec(meta, pos)
return
end
if fields.reset then
jumpdrive.reset_coordinates(pos)
jumpdrive.update_area_formspec(meta, pos)
return
end
if fields.write_book then
jumpdrive.write_to_book(pos, sender)
return
end
if fields.set_digiline_channel and fields.digiline_channel then
meta:set_string("channel", fields.digiline_channel)
jumpdrive.update_area_formspec(meta, pos)
return
end
local area_number = tonumber(fields.area_number);
if not area_number then
minetest.chat_send_player(playername, "Area by that id not found!")
return
end
local area_obj = areas.areas[area_number]
if not area_obj then
return
end
if area_obj.owner ~= playername then
minetest.chat_send_player(playername, "You are not the owner of that area!")
return
end
local max_radius = jumpdrive.config.max_area_radius
local distance = vector.distance(area_obj.pos1, area_obj.pos2)
if distance > (max_radius * 2) then
minetest.chat_send_player(playername, "The defined area has a greater diameter than " ..
(max_radius * 2) .. " blocks!")
return
end
local volume = math.abs(area_obj.pos1.x - area_obj.pos2.x) *
math.abs(area_obj.pos1.z - area_obj.pos2.y) *
math.abs(area_obj.pos1.z - area_obj.pos2.z)
if volume > jumpdrive.config.max_area_volume then
minetest.chat_send_player(playername, "The area-volume exceeds the max volume of" ..
jumpdrive.config.max_area_volume .. " blocks!")
return
end
-- update coords
meta:set_int("area_number", area_number)
jumpdrive.update_area_formspec(meta, pos)
if fields.jump then
local success, msg = jumpdrive.execute_jump(pos, sender)
if success then
local time_millis = math.floor(msg / 1000)
minetest.chat_send_player(sender:get_player_name(), "Jump executed in " .. time_millis .. " ms")
else
minetest.chat_send_player(sender:get_player_name(), msg)
end
end
if fields.show then
local success, msg = jumpdrive.simulate_jump(pos, sender, true)
if not success then
minetest.chat_send_player(sender:get_player_name(), msg)
return
end
minetest.chat_send_player(sender:get_player_name(), "Simulation successful")
end
end,
-- inventory protection
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
if player and player:is_player() and minetest.is_protected(pos, player:get_player_name()) then
-- protected
return 0
end
return stack:get_count()
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
if player and player:is_player() and minetest.is_protected(pos, player:get_player_name()) then
-- protected
return 0
end
return stack:get_count()
end,
-- upgrade re-calculation
on_metadata_inventory_put = function(pos, listname)
if listname == "upgrade" then
jumpdrive.upgrade.calculate(pos)
end
end,
on_metadata_inventory_take = function(pos, listname)
if listname == "upgrade" then
jumpdrive.upgrade.calculate(pos)
end
end,
on_punch = function(pos, node, puncher)
if minetest.is_protected(pos, puncher:get_player_name()) then
return
end
local meta = minetest.get_meta(pos);
local radius = meta:get_int("radius")
jumpdrive.show_marker(pos, radius, "green")
end
})
if minetest.get_modpath("technic") then
technic.register_machine("HV", "jumpdrive:engine", technic.receiver)
end

View File

@ -0,0 +1,45 @@
local has_technic = minetest.get_modpath("technic")
local inv_offset = 0
if has_technic then
inv_offset = 1.25
end
jumpdrive.update_area_formspec = function(meta, pos)
local formspec =
"size[8," .. 9.3+inv_offset .. ";]" ..
"field[0.3,0.5;8,1;area_number;Area;" .. meta:get_int("area_number") .. "]" ..
"button_exit[0,1;2,1;jump;Jump]" ..
"button_exit[2,1;2,1;show;Show]" ..
"button_exit[4,1;2,1;save;Save]" ..
"button[6,1;2,1;reset;Reset]" ..
"button[0,2;4,1;write_book;Write to book]" ..
"button[4,2;4,1;read_book;Read from book]" ..
-- main inventory for fuel and books
"list[context;main;0,3.25;8,1;]" ..
-- player inventory
"list[current_player;main;0,".. 4.5+inv_offset .. ";8,4;]" ..
-- digiline channel
"field[4.3," .. 9.02+inv_offset ..";3.2,1;digiline_channel;Digiline channel;" ..
(meta:get_string("channel") or "") .. "]" ..
"button_exit[7," .. 8.7+inv_offset .. ";1,1;set_digiline_channel;Set]" ..
-- listring stuff
"listring[context;main]" ..
"listring[current_player;main]"
if has_technic then
formspec = formspec ..
-- technic upgrades
"label[3,4.7;Upgrades]" ..
"list[context;upgrade;4,4.5;4,1;]"
end
meta:set_string("formspec", formspec)
end

View File

@ -0,0 +1,249 @@
local has_technic = minetest.get_modpath("technic")
minetest.register_node("jumpdrive:engine", {
description = "Jumpdrive",
tiles = {"jumpdrive.png"},
tube = {
insert_object = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:add_item("main", stack)
end,
can_insert = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
stack = stack:peek_item(1)
return inv:room_for_item("main", stack)
end,
input_inventory = "main",
connect_sides = {bottom = 1}
},
connects_to = {"group:technic_hv_cable"},
connect_sides = {"bottom", "top", "left", "right", "front", "back"},
light_source = 13,
groups = {
cracky = 3,
oddly_breakable_by_hand = 3,
tubedevice = 1,
tubedevice_receiver = 1,
technic_machine = 1,
technic_hv = 1
},
sounds = default.node_sound_glass_defaults(),
digiline = {
receptor = {action = function() end},
effector = {
action = jumpdrive.digiline_effector
},
},
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
meta:set_string("owner", placer:get_player_name() or "")
-- default digiline channel
meta:set_string("channel", "jumpdrive")
end,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_int("x", pos.x)
meta:set_int("y", pos.y)
meta:set_int("z", pos.z)
meta:set_int("radius", 5)
meta:set_int("powerstorage", 0)
jumpdrive.migrate_engine_meta(pos, meta)
meta:set_int("HV_EU_input", 0)
meta:set_int("HV_EU_demand", 0)
jumpdrive.update_formspec(meta, pos)
end,
can_dig = function(pos,player)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
local name = player:get_player_name()
return inv:is_empty("main") and
inv:is_empty("upgrade") and
not minetest.is_protected(pos, name)
end,
on_timer = function(pos, elapsed)
local meta = minetest.get_meta(pos)
local store = meta:get_int("powerstorage")
local max_store = meta:get_int("max_powerstorage")
if store >= max_store then
-- internal store is full
return true
end
local inv = meta:get_inventory()
for i=1, inv:get_size("main") do
local stack = inv:get_stack("main", i)
if not stack:is_empty() then
local burn_value = jumpdrive.fuel.get_value(stack:get_name())
if burn_value > 0 then
local store_space = max_store - store
local fuel_value = burn_value * stack:get_count()
if fuel_value > store_space then
stack:set_count(stack:get_count() - math.ceil(store_space / burn_value))
store = max_store
else
stack:clear()
store = store + fuel_value
end
inv:set_stack("main", i, stack)
end
end
end
meta:set_int("powerstorage", store)
if not has_technic then
jumpdrive.update_infotext(meta, pos)
end
-- restart timer
return true
end,
technic_run = jumpdrive.technic_run,
on_receive_fields = function(pos, formname, fields, sender)
local meta = minetest.get_meta(pos);
jumpdrive.migrate_engine_meta(pos, meta)
if not sender then
return
end
if minetest.is_protected(pos, sender:get_player_name()) then
-- not allowed
return
end
if fields.read_book then
jumpdrive.read_from_book(pos)
jumpdrive.update_formspec(meta, pos)
return
end
if fields.reset then
jumpdrive.reset_coordinates(pos)
jumpdrive.update_formspec(meta, pos)
return
end
if fields.write_book then
jumpdrive.write_to_book(pos, sender)
return
end
if fields.set_digiline_channel and fields.digiline_channel then
meta:set_string("channel", fields.digiline_channel)
jumpdrive.update_formspec(meta, pos)
return
end
local x = tonumber(fields.x);
local y = tonumber(fields.y);
local z = tonumber(fields.z);
local radius = tonumber(fields.radius);
if x == nil or y == nil or z == nil or radius == nil or radius < 1 then
return
end
local max_radius = jumpdrive.config.max_radius
if radius > max_radius then
minetest.chat_send_player(sender:get_player_name(), "Invalid jump: max-radius=" .. max_radius)
return
end
-- update coords
meta:set_int("x", jumpdrive.sanitize_coord(x))
meta:set_int("y", jumpdrive.sanitize_coord(y))
meta:set_int("z", jumpdrive.sanitize_coord(z))
meta:set_int("radius", radius)
jumpdrive.update_formspec(meta, pos)
if fields.jump then
local success, msg = jumpdrive.execute_jump(pos, sender)
if success then
local time_millis = math.floor(msg / 1000)
minetest.chat_send_player(sender:get_player_name(), "Jump executed in " .. time_millis .. " ms")
else
minetest.chat_send_player(sender:get_player_name(), msg)
end
end
if fields.show then
local success, msg = jumpdrive.simulate_jump(pos, sender, true)
if not success then
minetest.chat_send_player(sender:get_player_name(), msg)
return
end
minetest.chat_send_player(sender:get_player_name(), "Simulation successful")
end
end,
-- inventory protection
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
if player and player:is_player() and minetest.is_protected(pos, player:get_player_name()) then
-- protected
return 0
end
return stack:get_count()
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
if player and player:is_player() and minetest.is_protected(pos, player:get_player_name()) then
-- protected
return 0
end
return stack:get_count()
end,
-- upgrade re-calculation
on_metadata_inventory_put = function(pos, listname)
if listname == "upgrade" then
jumpdrive.upgrade.calculate(pos)
end
end,
on_metadata_inventory_take = function(pos, listname)
if listname == "upgrade" then
jumpdrive.upgrade.calculate(pos)
end
end,
on_punch = function(pos, node, puncher)
if minetest.is_protected(pos, puncher:get_player_name()) then
return
end
local meta = minetest.get_meta(pos);
local radius = meta:get_int("radius")
jumpdrive.show_marker(pos, radius, "green")
end
})
if minetest.get_modpath("technic") then
technic.register_machine("HV", "jumpdrive:engine", technic.receiver)
end

View File

@ -0,0 +1,48 @@
local has_technic = minetest.get_modpath("technic")
local inv_offset = 0
if has_technic then
inv_offset = 1.25
end
jumpdrive.update_formspec = function(meta, pos)
local formspec =
"size[8," .. 9.3+inv_offset .. ";]" ..
"field[0.3,0.5;2,1;x;X;" .. meta:get_int("x") .. "]" ..
"field[2.3,0.5;2,1;y;Y;" .. meta:get_int("y") .. "]" ..
"field[4.3,0.5;2,1;z;Z;" .. meta:get_int("z") .. "]" ..
"field[6.3,0.5;2,1;radius;Radius;" .. meta:get_int("radius") .. "]" ..
"button_exit[0,1;2,1;jump;Jump]" ..
"button_exit[2,1;2,1;show;Show]" ..
"button_exit[4,1;2,1;save;Save]" ..
"button[6,1;2,1;reset;Reset]" ..
"button[0,2;4,1;write_book;Write to book]" ..
"button[4,2;4,1;read_book;Read from book]" ..
-- main inventory for fuel and books
"list[context;main;0,3.25;8,1;]" ..
-- player inventory
"list[current_player;main;0,".. 4.5+inv_offset .. ";8,4;]" ..
-- digiline channel
"field[4.3," .. 9.02+inv_offset ..";3.2,1;digiline_channel;Digiline channel;" ..
(meta:get_string("channel") or "") .. "]" ..
"button_exit[7," .. 8.7+inv_offset .. ";1,1;set_digiline_channel;Set]" ..
-- listring stuff
"listring[context;main]" ..
"listring[current_player;main]"
if has_technic then
formspec = formspec ..
-- technic upgrades
"label[3,4.7;Upgrades]" ..
"list[context;upgrade;4,4.5;4,1;]"
end
meta:set_string("formspec", formspec)
end

View File

@ -0,0 +1,183 @@
jumpdrive.simulate_jump = function(pos, player, show_marker)
local targetPos = jumpdrive.get_meta_pos(pos)
if jumpdrive.check_mapgen(pos) then
return false, "Error: mapgen was active in this area, please try again later for your own safety!"
end
local meta = minetest.get_meta(pos)
local radius = jumpdrive.get_radius(pos)
local distance = vector.distance(pos, targetPos)
local playername = meta:get_string("owner")
if player ~= nil then
playername = player:get_player_name()
end
local radius_vector = {x=radius, y=radius, z=radius}
local source_pos1 = vector.subtract(pos, radius_vector)
local source_pos2 = vector.add(pos, radius_vector)
local target_pos1 = vector.subtract(targetPos, radius_vector)
local target_pos2 = vector.add(targetPos, radius_vector)
local x_overlap = (target_pos1.x <= source_pos2.x and target_pos1.x >= source_pos1.x) or
(target_pos2.x <= source_pos2.x and target_pos2.x >= source_pos1.x)
local y_overlap = (target_pos1.y <= source_pos2.y and target_pos1.y >= source_pos1.y) or
(target_pos2.y <= source_pos2.y and target_pos2.y >= source_pos1.y)
local z_overlap = (target_pos1.z <= source_pos2.z and target_pos1.z >= source_pos1.z) or
(target_pos2.z <= source_pos2.z and target_pos2.z >= source_pos1.z)
if x_overlap and y_overlap and z_overlap then
return false, "Error: jump into itself! extend your jump target"
end
-- load chunk
minetest.get_voxel_manip():read_from_map(target_pos1, target_pos2)
if show_marker then
jumpdrive.show_marker(targetPos, radius, "red")
jumpdrive.show_marker(pos, radius, "green")
end
local msg = nil
local success = true
local blacklisted_pos_list = minetest.find_nodes_in_area(source_pos1, source_pos2, jumpdrive.blacklist)
for _, nodepos in ipairs(blacklisted_pos_list) do
return false, "Can't jump node @ " .. minetest.pos_to_string(nodepos)
end
if minetest.find_node_near(targetPos, radius, "vacuum:vacuum", true) then
msg = "Warning: Jump-target is in vacuum!"
end
if minetest.find_node_near(targetPos, radius, "ignore", true) then
return false, "Warning: Jump-target is in uncharted area"
end
if jumpdrive.is_area_protected(source_pos1, source_pos2, playername) then
return false, "Jump-source is protected!"
end
if jumpdrive.is_area_protected(target_pos1, target_pos2, playername) then
return false, "Jump-target is protected!"
end
local is_empty, empty_msg = jumpdrive.is_area_empty(target_pos1, target_pos2)
if not is_empty then
msg = "Jump-target is obstructed (" .. empty_msg .. ")"
success = false
end
-- check preflight conditions
local preflight_result = jumpdrive.preflight_check(pos, targetPos, radius, playername)
if not preflight_result.success then
-- check failed in customization
msg = "Preflight check failed!"
if preflight_result.message then
msg = preflight_result.message
end
success = false
end
local power_req = jumpdrive.calculate_power(radius, distance, pos, targetPos)
local powerstorage = meta:get_int("powerstorage")
if powerstorage < power_req then
-- not enough power
msg = "Not enough power: required=" .. math.floor(power_req) .. ", actual: " .. powerstorage .. " EU"
success = false
end
return success, msg
end
-- execute jump
jumpdrive.execute_jump = function(pos, player)
local meta = minetest.get_meta(pos)
local radius = jumpdrive.get_radius(pos)
local targetPos = jumpdrive.get_meta_pos(pos)
local distance = vector.distance(pos, targetPos)
local power_req = jumpdrive.calculate_power(radius, distance, pos, targetPos)
local radius_vector = {x=radius, y=radius, z=radius}
local source_pos1 = vector.subtract(pos, radius_vector)
local source_pos2 = vector.add(pos, radius_vector)
local target_pos1 = vector.subtract(targetPos, radius_vector)
local target_pos2 = vector.add(targetPos, radius_vector)
local success, msg = jumpdrive.simulate_jump(pos, player, false)
if not success then
return false, msg
end
-- consume power from storage
local powerstorage = meta:get_int("powerstorage")
meta:set_int("powerstorage", powerstorage - power_req)
local t0 = minetest.get_us_time()
minetest.sound_play("jumpdrive_engine", {
pos = pos,
max_hear_distance = 50,
gain = 0.7,
})
-- actual move
jumpdrive.move(source_pos1, source_pos2, target_pos1, target_pos2)
local t1 = minetest.get_us_time()
local time_micros = t1 - t0
minetest.log("action", "[jumpdrive] jump took " .. time_micros .. " us")
-- show animation in source
minetest.add_particlespawner({
amount = 200,
time = 2,
minpos = source_pos1,
maxpos = source_pos2,
minvel = {x = -2, y = -2, z = -2},
maxvel = {x = 2, y = 2, z = 2},
minacc = {x = -3, y = -3, z = -3},
maxacc = {x = 3, y = 3, z = 3},
minexptime = 0.1,
maxexptime = 5,
minsize = 1,
maxsize = 1,
texture = "spark.png",
glow = 5,
})
-- show animation in target
minetest.add_particlespawner({
amount = 200,
time = 2,
minpos = target_pos1,
maxpos = target_pos2,
minvel = {x = -2, y = -2, z = -2},
maxvel = {x = 2, y = 2, z = 2},
minacc = {x = -3, y = -3, z = -3},
maxacc = {x = 3, y = 3, z = 3},
minexptime = 0.1,
maxexptime = 5,
minsize = 1,
maxsize = 1,
texture = "spark.png",
glow = 5,
})
return true, time_micros
end

Some files were not shown because too many files have changed in this diff Show More