Overview
Comment: | add shelter spell |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
65ce62581424f4c4a9e26419270d2410 |
User & Date: | lexi on 2021-07-23 19:33:02 |
Other Links: | manifest | tags |
Context
2021-07-23
| ||
22:48 | fix textures, add wires, add more magitech parts check-in: 49345366f9 user: lexi tags: trunk | |
19:33 | add shelter spell check-in: 65ce625814 user: lexi tags: trunk | |
2021-07-22
| ||
20:26 | amulets are now made via powder intaglio check-in: 0c88d214a8 user: lexi tags: trunk | |
Changes
Modified data/runes.lua from [829a9ad70b] to [27c07e8c34].
413 413 tone = {159,235,0}; 414 414 minpower = 4; 415 415 rarity = 34; 416 416 amulets = { 417 417 sapphire = { 418 418 name = 'Unsealing'; 419 419 desc = 'Wielding this amulet, a touch of your hand will unravel even the mightiest protective magics, leaving doors unsealed and walls free to tear down'; 420 + cast = function(ctx) 421 + if ctx.target.type ~= 'node' then return false end 422 + local r = 2 + math.floor(ctx.stats.power / 2) 423 + local cast = false 424 + for x = -r,r do 425 + for y = -r,r do 426 + for z = -r,r do 427 + if x^2 + y^2 + z^2 <= r^2 then 428 + local pos = vector.offset(ctx.target.under, x,y,z) 429 + local abv = vector.offset(ctx.target.above, x,y,z) 430 + local meta = minetest.get_meta(pos) 431 + if meta:contains('sorcery_seal_mode') then 432 + meta:set_string('sorcery_seal_mode', '') 433 + meta:set_string('sorcery_wand_key', '') 434 + meta:set_string('owner', '') 435 + sorcery.vfx.enchantment_sparkle({under=pos,above=abv}, sorcery.lib.color(12,38,255)) 436 + cast = true 437 + end 438 + end 439 + end end end 440 + if cast then 441 + minetest.sound_play('sorcery_disjoin',{object=target},true) 442 + end 443 + return cast 444 + end; 420 445 }; 421 446 amethyst = { 422 447 name = 'Purging'; 423 448 desc = 'Free yourself from the grip of any malicious spellwork with a snap of your fingers — interrupting all of your own active spells in the process, including impending translocations'; 424 449 cast = function(ctx) purge(ctx.caster) end; 425 450 }; 426 451 emerald = { ................................................................................ 456 481 subjects = {{player=ctx.caster}}; 457 482 disjunction = true, range = 4 + ctx.stats.power; 458 483 duration = 10 + ctx.stats.power * 3; 459 484 timeline = { 460 485 [0] = function(s,_,tl) 461 486 local ttns = 0.8 462 487 local vel = s.range / ttns 463 - s.visual_caster { 488 + s.visual_subjects { 464 489 amount = 300, time = ttns, glow = 14; 465 490 texture = sorcery.lib.image('sorcery_sputter.png'):glow(sorcery.lib.color(160,255,80)):render(); 466 491 minpos = { x = -0.0, y = h*0.5,z = -0.0 }; 467 492 maxpos = { x = 0.0, y = h*0.5,z = 0.0 }; 468 493 minvel = { x = -vel, y = -0.0, z = -vel }; 469 494 maxvel = { x = vel, y = 0.0, z = vel }; 470 495 minacc = { x = -0.2, y = -0.0, z = -0.2 }; ................................................................................ 663 688 aspect_w = 16, aspect_h = 16; 664 689 } 665 690 } 666 691 end; 667 692 }; 668 693 intervals = { 669 694 {period = 0.1, after = 0.15, fn = function(c) 670 - print('interval running') 671 695 for i = 1,80 do 672 696 local life = 0.2 + math.random() * 2 673 697 local dir = vector.new(math.random()-0.5,0,math.random()-0.5):normalize() 674 698 local pos = epicenter + (dir * (math.random()*radius)) 675 - print('setting particle at',pos) 676 699 minetest.add_particle { 677 700 texture = tex; 678 701 pos = pos; 679 702 expirationtime = life; 680 703 velocity = {x = 0, y = math.random() * 0.3 + 0.1, z = 0}; 681 704 size = 0.4 + math.random() * 3; 682 705 glow = 14; ................................................................................ 1071 1094 }; 1072 1095 genesis = { 1073 1096 name = 'Genesis'; 1074 1097 tone = {235,0,175}; 1075 1098 minpower = 5; 1076 1099 rarity = 23; 1077 1100 amulets = { 1101 + amethyst = { 1102 + name = 'Shelter'; 1103 + desc = 'Pour the power of this amulet into the soil or sand and out will grow a warm and well-lit place of shelter, no matter how far you may be from civilization.'; 1104 + cast = function(ctx) 1105 + local ctr = ctx.caster:get_pos() 1106 + local dim = { rmax = 2 + 6 * (ctx.stats.power*0.1) } 1107 + dim.rx = math.random(math.max(3, dim.rmax - 4), dim.rmax) 1108 + dim.rz = math.random(math.max(3, dim.rmax - 4), dim.rmax) 1109 + dim.y = math.random(4, 7) 1110 + for i = 1,10 do 1111 + if sorcery.lib.node.is_air(ctr) then 1112 + ctr = ctr:offset(0, -1, 0) 1113 + else break end 1114 + end 1115 + local soilp = function(pos) 1116 + local name = minetest.get_node(pos).name 1117 + return minetest.get_item_group(name, 'soil') ~= 0 or 1118 + minetest.get_item_group(name, 'sand') ~= 0 1119 + end 1120 + if not soilp(ctr) then return false end 1121 + -- scan map to determine maximum dimensions 1122 + for x = -dim.rx, dim.rx do 1123 + for z = -dim.rz, dim.rz do 1124 + local pos = ctr:offset(x,0,z) 1125 + if not soilp(pos) then 1126 + dim.rx = math.min(dim.rx, math.abs(x)) 1127 + dim.rz = math.min(dim.rz, math.abs(z)) 1128 + end 1129 + for y = 1, dim.y do 1130 + if not sorcery.lib.node.is_air(pos:offset(0,y,0)) then 1131 + dim.y = math.min(dim.y, y) 1132 + end 1133 + end 1134 + end 1135 + end 1136 + -- bail if not enough room 1137 + if dim.rx < 2 or dim.rz < 2 or dim.y < 2 then 1138 + return false 1139 + end 1140 + local materials = { 1141 + walls = {}; 1142 + corners = {}; 1143 + floor = {}; 1144 + roof = {}; 1145 + door = {}; 1146 + door_lock = {}; 1147 + lamp_floor = {}; 1148 + lamp_ceil = {}; 1149 + lamp_wall = {}; 1150 + lamp_ext = {}; 1151 + } 1152 + local try = function(ary, ...) 1153 + local a = {} 1154 + for _, item in pairs{...} do 1155 + if item and minetest.registered_items[item] then 1156 + table.insert(a, item) 1157 + end 1158 + end 1159 + if next(a) then 1160 + table.insert(ary, a) 1161 + return true 1162 + end 1163 + return false 1164 + end 1165 + for name,tree in pairs(sorcery.data.trees) do 1166 + try(materials.corners, tree.node) 1167 + try(materials.walls, tree.plank) 1168 + try(materials.floor, tree.plank) 1169 + end 1170 + try(materials.roof, 'farming:straw') 1171 + try(materials.floor, 'farming:straw') 1172 + try(materials.roof, 'default:brick') 1173 + try(materials.roof, 'default:desert_stonebrick') 1174 + try(materials.walls, 'default:brick') try(materials.corners, 'default:brick') 1175 + try(materials.walls, 'default:stonebrick') try(materials.corners, 'default:stonebrick') 1176 + try(materials.walls, 'default:cobble', 'default:mossycobble') 1177 + try(materials.walls, 'default:desert_cobble') 1178 + try(materials.walls, 'default:desert_stonebrick') 1179 + 1180 + try(materials.corners, 'default:desert_stonebrick') 1181 + try(materials.corners, 'default:desert_stonebrick') 1182 + try(materials.corners, 'default:desert_stone_block') 1183 + 1184 + try(materials.walls, 'default:sandstone') 1185 + try(materials.walls, 'default:sandstonebrick') 1186 + try(materials.walls, 'default:desert_sandstone') 1187 + try(materials.walls, 'default:desert_sandstone_brick') 1188 + try(materials.walls, 'default:silver_sandstone') 1189 + try(materials.walls, 'default:silver_sandstone_brick') 1190 + 1191 + try(materials.walls, 'default:sandstone', 'default:silver_sandstone', 'default:desert_sandstone') 1192 + try(materials.walls, 'default:sandstonebrick', 'default:silver_sandstone_brick', 'default:desert_sandstone_brick') 1193 + try(materials.roof, 'default:sandstonebrick', 'default:silver_sandstone_brick', 'default:desert_sandstone_brick') 1194 + 1195 + try(materials.corners, 'default:sandstonebrick') 1196 + try(materials.corners, 'default:desert_sandstone_brick') 1197 + try(materials.corners, 'default:silver_sandstone_brick') 1198 + if math.random(1,10) == 7 then 1199 + try(materials.corners, 'default:obsidianbrick') 1200 + end 1201 + 1202 + try(materials.lamp_wall, 'default:torch_wall') 1203 + try(materials.lamp_wall, 'morelights_modern:wall_lamp') 1204 + 1205 + try(materials.lamp_ext, 'default:torch') 1206 + try(materials.lamp_ext, 'morelights_modern:wall_lamp') 1207 + try(materials.lamp_ext, 'morelights_modern:lantern_f') 1208 + 1209 + for _, l in pairs { 1210 + 'default:meselamp'; 1211 + 'morelights_modern:barlight_s'; 1212 + 'morelights_modern:ceilinglight'; 1213 + 'morelights_modern:canlight_d'; 1214 + 'morelights_modern:canlight_l'; 1215 + 'morelights_vintage:hangingbulb'; 1216 + 'morelights_vintage:chandelier'; 1217 + } do try(materials.lamp_ceil, l) end 1218 + 1219 + for _, l in pairs { 1220 + 'default:meselamp'; 1221 + 'morelights_extras:f_block', 1222 + 'morelights_extras:sandstone_block', 1223 + 'morelights_extras:stone_block', 1224 + 'morelights_modern:block', 1225 + 'morelights_vintage:block', 1226 + } do try(materials.lamp_floor, l) end 1227 + 1228 + for _, d in pairs { 1229 + 'doors:door_wood'; 1230 + 'doors:woodglass_door'; 1231 + 'doors:slide_door'; 1232 + 'doors:japanese_door'; 1233 + 'doors:screen_door'; 1234 + 'doors:door_glass'; 1235 + } do try(materials.door, d) end 1236 + 1237 + for _, d in pairs { 1238 + 'doors:door_steel'; 1239 + 'xpanes:door_steel_bar'; 1240 + } do try(materials.door_lock, d) end 1241 + 1242 + 1243 + for k,v in pairs(materials) do 1244 + if next(v) then 1245 + materials[k] = select(2, sorcery.lib.tbl.pick(v)) 1246 + end 1247 + end 1248 + local timeline = {} 1249 + local per = 0.05 1250 + local i = 0 1251 + local spark = function(s,where) 1252 + s.visual { 1253 + amount = 30; 1254 + time = 0.2; 1255 + minpos = where:offset(-0.5, 0.0, -0.5); 1256 + maxpos = where:offset( 0.5, 1.0, 0.5); 1257 + minvel = vector.new(-0.4, -0.2, -0.4); 1258 + maxvel = vector.new( 0.4, 0.2, 0.4); 1259 + minacc = vector.new( 0, 0.2, 0); 1260 + maxacc = vector.new( 0, 0.6, 0); 1261 + minexptime = 0.2, maxexptime = 2.0; 1262 + minsize = 0.3, maxsize = 2; 1263 + texture = sorcery.vfx.glowspark(sorcery.lib.color(255,12,89)):render(); 1264 + glow = minetest.LIGHT_MAX; 1265 + animation = { 1266 + type = 'vertical_frames', length = 3.1; 1267 + aspect_w = 16, aspect_h = 16; 1268 + } 1269 + } 1270 + end 1271 + local setplane = function(y, mcat) 1272 + for x = -dim.rx, dim.rx do 1273 + for z = -dim.rz, dim.rz do 1274 + timeline[{whence=0, secs=per*i}] = function(s) 1275 + local node = select(2, sorcery.lib.tbl.pick(mcat)) 1276 + local p = ctr:offset(x,y,z) 1277 + minetest.set_node(p, {name=node}) 1278 + spark(s,p) 1279 + end 1280 + end 1281 + i = i + 1 1282 + end 1283 + end 1284 + setplane(0, materials.floor) 1285 + local mpick=function(t) 1286 + return select(2, sorcery.lib.tbl.pick(materials[t])) 1287 + end 1288 + local t_supports = per*i 1289 + for y = 1, dim.y-1 do 1290 + local mx,mz = dim.rx, dim.rz 1291 + timeline[{whence=0, secs=per*i}] = function(s) 1292 + for _,where in pairs { 1293 + ctr:offset( mx,y, mz); 1294 + ctr:offset(-mx,y, mz); 1295 + ctr:offset(-mx,y,-mz); 1296 + ctr:offset( mx,y,-mz); 1297 + } do 1298 + minetest.set_node(where, { name = mpick'corners' }) 1299 + end 1300 + end 1301 + i=i+1 1302 + end 1303 + local t_roof = per*i 1304 + setplane(dim.y, materials.roof) 1305 + timeline[{whence=0,secs=per*i - 0.4}] = function(s) 1306 + s.visual { 1307 + time = 30, amount = 2500; 1308 + minpos = ctr:offset(-dim.rx,dim.y - 0.5,-dim.rz); 1309 + maxpos = ctr:offset( dim.rx,dim.y + 0.5, dim.rz); 1310 + minacc = vector.new(0,-0.5,0); 1311 + maxacc = vector.new(0, 0.3,0); 1312 + texture = sorcery.lib.image('sorcery_sputter.png'):glow(255,17,86):render(); 1313 + glow = minetest.LIGHT_MAX; 1314 + minexptime = 2.4, maxexptime = 8; 1315 + minsize = 0.5, maxsize = 3; 1316 + animation = { 1317 + type = 'vertical_frames', length = 1.1; 1318 + aspect_w = 16, aspect_h = 16; 1319 + }; 1320 + } 1321 + end 1322 + local t_walls = per*i 1323 + for y = dim.y-1,1,-1 do 1324 + timeline[{whence=0, secs=per*i}] = function(s) 1325 + local xe, ze = dim.rx-1, dim.rz-1 1326 + for x=-xe,xe do 1327 + minetest.set_node(ctr:offset(x,y, dim.rz), {name=mpick'walls'}) 1328 + minetest.set_node(ctr:offset(x,y,-dim.rz), {name=mpick'walls'}) 1329 + end 1330 + for z=-ze,ze do 1331 + minetest.set_node(ctr:offset(-dim.rx,y,z), {name=mpick'walls'}) 1332 + minetest.set_node(ctr:offset( dim.rx,y,z), {name=mpick'walls'}) 1333 + end 1334 + end 1335 + i=i+1 1336 + end 1337 + local t_built = per*i 1338 + local lighting = math.random(1,2) 1339 + if lighting == 1 then 1340 + local lh = math.ceil(dim.y * .6) 1341 + local wlamps = { 1342 + ctr:offset( dim.rx - 1 , lh,0); 1343 + ctr:offset(-(dim.rx - 1), lh,0); 1344 + ctr:offset(0, lh, dim.rz - 1); 1345 + ctr:offset(0, lh, -(dim.rz - 1)); 1346 + } 1347 + sorcery.lib.tbl.shuffle(wlamps) 1348 + for _, where in pairs(wlamps) do 1349 + i = i + 10 1350 + timeline[{whence=0, secs = per*i}] = function(s) 1351 + spark(s,where) 1352 + local node = select(2,sorcery.lib.tbl.pick(materials.lamp_wall)) 1353 + minetest.sound_play('sorcery_put',{pos=where,gain=0.8},true) 1354 + minetest.set_node(where, { 1355 + name=node; 1356 + param2=minetest.dir_to_wallmounted(vector.normalize(ctr:offset(0,lh,0) - where)*-1); 1357 + }) 1358 + end 1359 + end i=i+1 1360 + elseif lighting == 2 then 1361 + local which = math.random(1,3) 1362 + if which == 1 or which == 2 then 1363 + i = i + 20 1364 + timeline[{whence=0, secs = per*i}] = function(s) 1365 + local where = ctr:offset(0,dim.y,0) 1366 + spark(s,where) 1367 + minetest.sound_play('sorcery_put',{pos=where,gain=0.7},true) 1368 + minetest.item_place(ItemStack(mpick'lamp_ceil'), nil, { 1369 + type = "node"; 1370 + under = where; 1371 + above = where:offset(0,-1,0); 1372 + }) 1373 + end 1374 + end 1375 + if which == 1 or which == 3 then 1376 + i = i + 20 1377 + local flamps = { 1378 + ctr:offset( (dim.rx - 1), 0, (dim.rz - 1)); 1379 + ctr:offset(-(dim.rx - 1), 0, (dim.rz - 1)); 1380 + ctr:offset(-(dim.rx - 1), 0, -(dim.rz - 1)); 1381 + ctr:offset( (dim.rx - 1), 0, -(dim.rz - 1)); 1382 + } 1383 + sorcery.lib.tbl.shuffle(flamps) 1384 + for _, v in pairs(flamps) do 1385 + timeline[{whence=0, secs = per*i}] = function(s) 1386 + local node = select(2,sorcery.lib.tbl.pick(materials.lamp_floor)) 1387 + spark(s,v) 1388 + minetest.sound_play('sorcery_put',{pos=v,gain=0.7},true) 1389 + minetest.set_node(v, {name = node}) 1390 + end 1391 + i = i + 7 1392 + end 1393 + end 1394 + end 1395 + -- install door 1396 + local doorside = ({ 1397 + vector.new( dim.rx,1,0); 1398 + vector.new(0,1, dim.rz); 1399 + vector.new(-dim.rx,1,0); 1400 + vector.new(0,1,-dim.rz); 1401 + })[math.random(1,4)] 1402 + local doorpos 1403 + if math.random(1,3) == 1 then 1404 + if doorside.z ~= 0 then 1405 + doorside.x = doorside.x + math.random(-(dim.rx-1), dim.rx-1) 1406 + elseif doorside.x ~= 0 then 1407 + doorside.z = doorside.z + math.random(-(dim.rz-1), dim.rz-1) 1408 + end 1409 + end 1410 + doorpos = ctr + doorside 1411 + local door = mpick'door' 1412 + i=i+5 1413 + timeline[{whence=0,secs=per*i}] = function(s) 1414 + minetest.remove_node(doorpos) 1415 + minetest.remove_node(doorpos:offset(0,1,0)) 1416 + spark(s, doorpos) 1417 + spark(s, doorpos:offset(0,1,0)) 1418 + minetest.sound_play('sorcery_crunch', {pos = doorpos, gain = 0.9}, true) 1419 + -- this is buggy af and needs to be replaced with a proper impl 1420 +-- local d = ItemStack(door) 1421 +-- d:get_definition().on_place(d, s.caster, { 1422 +-- type = 'node'; 1423 +-- above = doorpos; 1424 +-- under = doorpos:offset(0,-1,0); 1425 +-- }) 1426 + end 1427 + 1428 + sorcery.spell.cast { 1429 + name = 'sorcery:shelter'; 1430 + groups = {'genesis','construct'}; 1431 + caster = ctx.caster; 1432 + anchor = ctr; 1433 + radius = math.max(dim.rz, dim.rx); 1434 + duration = per * i; 1435 + timeline = timeline; 1436 + sounds = { 1437 + [{whence=0,secs=t_supports}] = { 1438 + sound = 'sorcery_slide'; 1439 + where = ctr:offset(0,dim.y,0); 1440 + ephemeral = true, pitch = 0.7; 1441 + }; 1442 + [{whence=0,secs=t_roof}] = { 1443 + sound = 'sorcery_slide'; 1444 + where = ctr:offset(0,dim.y,0); 1445 + ephemeral = true; 1446 + }; 1447 + }; 1448 + } 1449 + end; 1450 + }; 1078 1451 mese = { 1079 1452 mingrade = 4; 1080 1453 name = 'Duplication'; 1081 - desc = 'Bring an exact twin of any object or item into existence, no matter how common or rare it might be'; 1454 + desc = 'Bring an exact twin of any object or item into existence, whether it be a thing quotidian or an impossible rarity'; 1082 1455 cast = function(ctx) 1083 1456 local color = sorcery.lib.color(255,61,205) 1084 1457 local dup, sndpos, anchor, sbj, ty 1085 1458 if ctx.target.type == 'object' and ctx.target.ref:get_luaentity().name == '__builtin:item' then 1086 1459 sorcery.vfx.imbue(color, ctx.target.ref) -- causes graphics card problems??? 1087 1460 sndpos = 'subjects' 1088 1461 sbj = {{player = ctx.target.ref}} ................................................................................ 1132 1505 end 1133 1506 if minetest.get_item_group(ty,'do_not_duplicate') ~= 0 then 1134 1507 return true 1135 1508 end 1136 1509 1137 1510 sorcery.spell.cast { 1138 1511 name = 'sorcery:duplicate'; 1512 + groups = {'genesis'}; 1139 1513 caster = ctx.caster; 1140 1514 duration = math.random(10,20) * ((10 - ctx.stats.power)*0.1); 1141 1515 anchor = anchor; 1142 1516 timeline = { 1143 1517 [{whence=0, secs=1}] = function(s,te,tl) 1144 1518 local mag = sbj and 0.5 or 0.7 1145 1519 local pv = sbj and vector.new(0,0,0) or ctx.target.under
Modified data/trees.lua from [1a5929f3d1] to [e07b7cbc21].
4 4 -- instead of asking for entries here. if your trees are listed here 5 5 -- and you would like control over their properties, please commit 6 6 -- the appropriate interop code to your repository and open an issue 7 7 -- on the sorcery tracker for us to remove them. 8 8 apple = { 9 9 desc = 'Apple'; 10 10 node = 'default:tree'; 11 + plank = 'default:wood'; 11 12 sapling = 'default:sapling'; 12 13 leaves = 'default:leaves'; 13 14 sap = 'Apple Syrup'; 14 15 sapcolor = {218, 238, 66}; 15 16 lathe = { 16 17 cut = { 17 18 {'default:fence_wood', 5, 2};
Modified lib/node.lua from [a6a32274e7] to [1c278a4b1d].
31 31 }; 32 32 nextto = { 33 33 {x = 1, y = 0, z = 0}; 34 34 {x = -1, y = 0, z = 0}; 35 35 {x = 0, y = 0, z = 1}; 36 36 {x = 0, y = 0, z = -1}; 37 37 }; 38 + cardinal = { 39 + {x = 1, y = 0, z = 0}; 40 + {x = -1, y = 0, z = 0}; 41 + {x = 0, y = 0, z = 1}; 42 + {x = 0, y = 0, z = -1}; 43 + }; 38 44 } 39 45 40 46 ofs.adjoining = sorcery.lib.tbl.append(sorcery.lib.tbl.append( 41 47 ofs.neighbors,ofs.planecorners),ofs.cubecorners) 42 48 43 49 local purge_container = function(only, pos,node,meta,user) 44 50 local offset = function(pos,range)