add documentation to /doc folder. add old resources to /mods_disabled folder.
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 166 KiB |
|
@ -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?
|
|
@ -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
|
|
@ -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.
|
Before Width: | Height: | Size: 24 KiB |
|
@ -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
|
Before Width: | Height: | Size: 73 KiB |
|
@ -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.
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
default
|
|
@ -0,0 +1,4 @@
|
|||
local modpath = minetest.get_modpath("abritorch").. DIR_DELIM
|
||||
|
||||
dofile(modpath.."torches.lua")
|
||||
dofile(modpath.."crafting.lua")
|
|
@ -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
|
|
@ -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
|
After Width: | Height: | Size: 53 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
|
@ -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
|
||||
|
|
@ -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>.
|
|
@ -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
|
|
@ -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"}}
|
||||
})
|
|
@ -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,
|
||||
})
|
|
@ -0,0 +1,4 @@
|
|||
name = coins
|
||||
author = FreeGamers.org
|
||||
description = Ore-based currencies.
|
||||
depends = default
|
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.3 KiB |
|
@ -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)
|
||||
|
After Width: | Height: | Size: 5.1 KiB |
|
@ -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
|
|
@ -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 ./
|
|
@ -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"
|
||||
}
|
|
@ -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
|
||||
})
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
if minetest.get_modpath("technic") then
|
||||
table.insert(jumpdrive.blacklist, "technic:forcefield_emitter_on")
|
||||
end
|
||||
|
||||
-- TODO bedrock, advtrains tracks
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
```
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|