Comment: | add displacers; add item class mechanism; various tweaks, enhancements, and bugfixes esp. for books and paper |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
93f944b581af9d3a2f8c5ef7d0a27fa6 |
User & Date: | lexi on 2020-08-30 14:45:03 |
Other Links: | manifest | tags |
2020-08-30
| ||
14:46 | rename improperly namespaced files check-in: 76581a64d9 user: lexi tags: trunk | |
14:45 | add displacers; add item class mechanism; various tweaks, enhancements, and bugfixes esp. for books and paper check-in: 93f944b581 user: lexi tags: trunk | |
2020-08-28
| ||
14:08 | add recipes, cookbooks, disassembly (to create recipes from items), attunement, farcasters, and portals; various edits for bug fixes and improvements check-in: 9ef6cbcf31 user: lexi tags: trunk | |
Modified compat.lua from [e7cd5fcdf6] to [b94ab7bfcd].
36 37 38 39 40 41 42 43 44 |
}) minetest.register_alias('new_campfire:ash', 'sorcery:ash') end return { defp = function(name) return minetest.registered_items[name] or minetest.registered_aliases[name] end } |
| |
36 37 38 39 40 41 42 43 44 |
})
minetest.register_alias('new_campfire:ash', 'sorcery:ash')
end
return {
defp = function(name)
return minetest.registered_items[name] or minetest.registered_aliases[name]
end;
}
|
Modified cookbook.lua from [e0a46e6a8e] to [b21ad56f71].
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 .. 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 .. 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 ... 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 ... 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 ... 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 ... 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 |
sorcery.cookbook = {} local constants = { -- do not show recipes for items in these groups exclude_groups = { }; exclude_names = { '_stairs'; '_slab'; 'slope_'; }; -- do not show recipes from this namespace blacklist_mods = { 'group'; -- WHY IS THIS NECESSARY 'moreblocks'; -- too much noise }; recipes_per_cookbook_page = 3; } local slot3x3 = { {0,0}, {1,0}, {2,0}; {0,1}, {1,1}, {2,1}; {0,2}, {1,2}, {2,2}; } ................................................................................ -- ow ow ow ow ow ow ow local names = {} for k in pairs(minetest.registered_items) do local rec = minetest.get_craft_recipe(k) if rec.items ~= nil and (rec.method == kind or (rec.method == 'shapeless' and kind == 'normal')) then -- is this last bit necessary? local excluded = false for _,n in pairs(constants.exclude_names) do if string.find(p,n) then excluded = true break end end if not excluded then for _,g in pairs(constants.exclude_groups) do if minetest.get_item_group(p, g) > 0 then excluded = true break end end end local props = minetest.registered_items[k]._sorcery local module = modofname(k) if not (excluded or sorcery.lib.tbl.has(constants.blacklist_mods,module) or (props and props.recipe and props.recipe.secret) ................................................................................ local col = (j-1) % w if i.items[j] then rec[1 + (row * 3) + col] = i.items[j] end end return rec end local desc_builtin = function(i) local desc = minetest.registered_items[i].description if not desc then return 'Peculiar Item' end local eol = string.find(desc,'\n') if not eol then return desc else return string.sub(desc,1,eol-1) end end; local bookadjs = { -- sets are in reverse order! ................................................................................ local x, y = k.slots[i][1], k.slots[i][2] if ingredients[i] and ingredients[i] ~= '' then local tt if k.indesc then tt = k.indesc(ingredients[i]) else tt = desc_builtin(ingredients[i]) end t = t .. string.format([[ item_image[%f,%f;1,1;%s] tooltip[%f,%f;1,1;%s] ]], x,y, minetest.formspec_escape(ingredients[i]), x,y, minetest.formspec_escape(tt)) else if k.drawslots == nil or k.drawslots then t = string.format('box[%f,%f;0.1,0.1;#00000060]',x+0.45,y+0.45) .. t end end end ................................................................................ dungeon_loot.register { name = 'sorcery:recipe'; chance = 0.9; count = {1,7}; } minetest.register_craft { type = 'fuel', recipe = 'sorcery:recipe', burntime = 3 } minetest.register_craft { type = 'cooking'; recipe = 'sorcery:recipe'; output = 'sorcery:ash'; cooktime = 3; } default.register_craft_metadata_copy('default:paper','sorcery:recipe') -- default.register_craft_metadata_copy('default:book','sorcery:cookbook') for i=1,8 do local rcp = {} for i=1,i do rcp[i] = 'sorcery:recipe' end rcp[#rcp+1]='default:book' minetest.register_craft { type = 'shapeless', recipe = rcp, output = 'sorcery:cookbook'; } rcp[#rcp]='sorcery:cookbook' minetest.register_craft { type = 'shapeless', recipe = rcp, output = 'sorcery:cookbook'; } end local m = sorcery.lib.marshal local encbook, decbook = m.transcoder { pages = m.g.array(8, m.g.struct { kind = m.t.str; name = m.t.str; }) ................................................................................ end uinv:set_stack('main',idx,stack) bookform(stack,user) end) minetest.register_on_craft(function(stack,player,grid,inv) if stack:get_name() ~= 'sorcery:cookbook' then return nil end local oldbook local topic, onetopic = nil, true local recipes = {} for _,s in pairs(grid) do if s:get_name() == 'sorcery:recipe' then recipes[#recipes+1] = s elseif s:get_name() == 'sorcery:cookbook' then oldbook = s end end oldbook = oldbook or stack local bookmeta = oldbook:get_meta() local newbook = not bookmeta:contains('cookbook') local book = bookprops(oldbook) ................................................................................ if topic and newbook then if not onetopic then topic = nil end bookmeta:set_string('description',namebook(topic,player:get_player_name())) bookmeta:set_string('owner',player:get_player_name()) end print('new book',bookmeta:get_string('description')) print('new book',dump(book)) bookmeta:set_string('cookbook', sorcery.lib.str.meta_armor(encbook(book),true)) return oldbook end) if minetest.get_modpath('books') then -- make our own placeable cookbook somehow end |
| | | > > > > > > > > > > > > > > | | > > > > > > > > > > > > > > > > > | > > > > > > | | < < < < < < < < > > > > > > > > > > > > > | > | > > > > > > > > > > > < < |
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 .. 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 .. 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 ... 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 ... 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 ... 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 ... 548 549 550 551 552 553 554 555 556 557 558 559 560 561 |
sorcery.cookbook = {} local constants = { -- do not show recipes for items in these groups exclude_groups = { }; exclude_names = { 'stairs'; 'slab'; 'slope'; }; -- do not show recipes from this namespace blacklist_mods = { 'group'; -- WHY IS THIS NECESSARY 'moreblocks'; -- too much noise }; recipes_per_cookbook_page = 3; group_ids = { wood = { caption = 'Any Wood', cnitem = 'default:wood' }; tree = { caption = 'Any Tree', cnitem = 'default:tree' }; leaves = { caption = 'Any Leaves', cnitem = 'default:leaves' }; stone = { caption = 'Any Stone', cnitem = 'default:stone' }; dye = { caption = 'Any Dye', cnitem = 'dye:black' }; bone = { caption = 'Any Bone', cnitem = 'bonemeal:bone' }; vessel = { caption = 'Any Bottle', cnitem = 'vessels:glass_bottle' }; flower = { caption = 'Any Flower', cnitem = 'flowers:rose' }; mushroom = { caption = 'Any Mushroom', cnitem = 'flowers:mushroom_brown' }; water_bucket = { caption = 'Water Bucket', cnitem = 'bucket:bucket_water' }; sorcery_ley_cable = { caption = 'Cable', cnitem = 'sorcery:cable_vidrium' }; }; } local slot3x3 = { {0,0}, {1,0}, {2,0}; {0,1}, {1,1}, {2,1}; {0,2}, {1,2}, {2,2}; } ................................................................................ -- ow ow ow ow ow ow ow local names = {} for k in pairs(minetest.registered_items) do local rec = minetest.get_craft_recipe(k) if rec.items ~= nil and (rec.method == kind or (rec.method == 'shapeless' and kind == 'normal')) then -- is this last bit necessary? local excluded = false for _,n in pairs(constants.exclude_names) do if string.find(k,n) ~= nil then excluded = true break end end if not excluded then for _,g in pairs(constants.exclude_groups) do if minetest.get_item_group(k, g) > 0 then excluded = true break end end end local props = minetest.registered_items[k]._sorcery local module = modofname(k) if not (excluded or sorcery.lib.tbl.has(constants.blacklist_mods,module) or (props and props.recipe and props.recipe.secret) ................................................................................ local col = (j-1) % w if i.items[j] then rec[1 + (row * 3) + col] = i.items[j] end end return rec end local function group_eval(i) if string.sub(i,1,6) == 'group:' then local g = string.sub(i,7) if constants.group_ids[g] then return constants.group_ids[g].cnitem, constants.group_ids[g].caption end for i,v in pairs(minetest.registered_items) do if minetest.get_item_group(i, g) > 0 then return i, v.description end end return i end return i end local function desc_builtin(i) local desc i, desc = group_eval(i) -- print('describing ',i,dump(minetest.registered_items[i])) if not minetest.registered_items[i] then minetest.log('WARNING: unknown item in recipe ' .. i) return 'Unknown Item' end if not desc then desc = minetest.registered_items[i].description end if not desc then return 'Peculiar Item' end local eol = string.find(desc,'\n') if not eol then return desc else return string.sub(desc,1,eol-1) end end; local bookadjs = { -- sets are in reverse order! ................................................................................ local x, y = k.slots[i][1], k.slots[i][2] if ingredients[i] and ingredients[i] ~= '' then local tt if k.indesc then tt = k.indesc(ingredients[i]) else tt = desc_builtin(ingredients[i]) end t = t .. string.format([[ item_image[%f,%f;1,1;%s] tooltip[%f,%f;1,1;%s] ]], x,y, minetest.formspec_escape(group_eval(ingredients[i])), x,y, minetest.formspec_escape(tt)) else if k.drawslots == nil or k.drawslots then t = string.format('box[%f,%f;0.1,0.1;#00000060]',x+0.45,y+0.45) .. t end end end ................................................................................ dungeon_loot.register { name = 'sorcery:recipe'; chance = 0.9; count = {1,7}; } default.register_craft_metadata_copy('default:paper','sorcery:recipe') -- this seems bugged; it doesn't like it when its item shows up in another -- recipe. so we'll do it manually :/ -- default.register_craft_metadata_copy('default:book','sorcery:cookbook') for i=1,8 do local rcp = {} for i=1,i do rcp[i] = 'sorcery:recipe' end rcp[#rcp+1]='default:book' minetest.register_craft { type = 'shapeless', recipe = rcp, output = 'sorcery:cookbook'; } rcp[#rcp]='sorcery:cookbook' minetest.register_craft { type = 'shapeless', recipe = rcp, output = 'sorcery:cookbook'; } end minetest.register_craft { type = 'shapeless'; recipe = { 'sorcery:cookbook'; 'default:book'; }; output = 'sorcery:cookbook'; }; local m = sorcery.lib.marshal local encbook, decbook = m.transcoder { pages = m.g.array(8, m.g.struct { kind = m.t.str; name = m.t.str; }) ................................................................................ end uinv:set_stack('main',idx,stack) bookform(stack,user) end) minetest.register_on_craft(function(stack,player,grid,inv) -- god this is messy. i'm sorry. minetest made me do it if stack:get_name() ~= 'sorcery:cookbook' then return nil end local oldbook local topic, onetopic = nil, true local recipes = {} local copybook = false local obindex for i,s in pairs(grid) do if s:get_name() == 'sorcery:recipe' then recipes[#recipes+1] = s elseif s:get_name() == 'default:book' then copybook = true elseif s:get_name() == 'sorcery:cookbook' then oldbook = s obindex = i end end if #recipes == 0 and copybook and oldbook then inv:set_stack('craft',obindex,oldbook) local newmeta = stack:get_meta() local copy = function(field) newmeta:set_string(field,oldbook:get_meta():get_string(field)) end copy('cookbook') copy('description') newmeta:set_string('owner',player:get_player_name()) return stack end oldbook = oldbook or stack local bookmeta = oldbook:get_meta() local newbook = not bookmeta:contains('cookbook') local book = bookprops(oldbook) ................................................................................ if topic and newbook then if not onetopic then topic = nil end bookmeta:set_string('description',namebook(topic,player:get_player_name())) bookmeta:set_string('owner',player:get_player_name()) end bookmeta:set_string('cookbook', sorcery.lib.str.meta_armor(encbook(book),true)) return oldbook end) if minetest.get_modpath('books') then -- make our own placeable cookbook somehow end |
Modified data/compat.lua from [04ce335701] to [d448ba2bd2].
1
2
3
4
5
6
7
..
18
19
20
21
22
23
24
25
26
|
local grain = { hardness = 1; value = 1; powder = 'farming:flour'; grindcost = 4; } return { ................................................................................ } }; ley = { ['default:mese'] = { power = 0.25; mode = 'produce'; }; }; } |
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
..
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
-- compatibility tables -- this file is used to hold information that would normally -- be tagged in the _sorcery or _proto fields of an item's -- definition, but cannot be placed there because the item -- is outside the control of the author and its module does -- not cooperate with sorcery. it is used by itemclass.lua -- to seamlessly locate the material properties and -- capabilities of an item. local grain = { hardness = 1; value = 1; powder = 'farming:flour'; grindcost = 4; } return { ................................................................................ } }; ley = { ['default:mese'] = { power = 0.25; mode = 'produce'; }; }; gems = { ['default:mese_crystal'] = { id = 'mese', gem = true; value = 9, raw = true; }; ['default:mese_crystal_fragment'] = { id = 'mese', gem = true; value = 1, raw = true; }; ['default:diamond'] = { id = 'diamond', gem = true; value = 9, raw = true; }; }; } |
Modified data/spells.lua from [26201c3a3e] to [9b1dfc7187].
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
...
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
|
}; dowse = { name = 'dowsing'; leytype = 'cognic'; color = {65,116,255}; affinity = {'acacia','dark','silent'}; uses = 176; desc = 'Send up sparks of radia to indicate nearness or absence of attuned blocks'; }; verdant = { name = 'verdant'; color = {16,29,255}; uses = 48; leytype = 'imperic'; desc = 'Pour life-energy into the soil, causing flowers and trees to spring up at your command'; ................................................................................ if rec then local data = decpos(sorcery.lib.str.meta_dearmor(rec,true)) local srcpos = {x=data.x,y=data.y,z=data.z} local srcnode = minetest.get_node(srcpos) local srcdef = minetest.registered_nodes[srcnode.name] if srcdef and srcdef._sorcery and srcdef._sorcery.attune then if sorcery.attunement.nodeid(srcpos) == data.id then -- check for ink src = { pos = srcpos; props = srcdef._sorcery.attune; } end end end |
|
<
|
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
...
339
340
341
342
343
344
345
346
347
348
349
350
351
352
|
}; dowse = { name = 'dowsing'; leytype = 'cognic'; color = {65,116,255}; affinity = {'acacia','dark','silent'}; uses = 176; desc = 'Send up sparks of radia to indicate nearness or absence of the blocks whose presence the wand is attuned to'; }; verdant = { name = 'verdant'; color = {16,29,255}; uses = 48; leytype = 'imperic'; desc = 'Pour life-energy into the soil, causing flowers and trees to spring up at your command'; ................................................................................ if rec then local data = decpos(sorcery.lib.str.meta_dearmor(rec,true)) local srcpos = {x=data.x,y=data.y,z=data.z} local srcnode = minetest.get_node(srcpos) local srcdef = minetest.registered_nodes[srcnode.name] if srcdef and srcdef._sorcery and srcdef._sorcery.attune then if sorcery.attunement.nodeid(srcpos) == data.id then src = { pos = srcpos; props = srcdef._sorcery.attune; } end end end |
Added displacer.lua version [54869bc440].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 |
local constants = { xmit_wattage = 0.4; -- the amount of power per second needed to transmit an item from -- one displacer to another rcpt_wattage = 0.15; -- the amount of power needed to broadcast a receptor's availability } local gettxr = function(pos) local txrcomps = { 'sorcery:displacer'; 'sorcery:displacer_transmit_gem'; 'sorcery:displacer_transmit_attune'; 'sorcery:displacer_receive_gem'; 'sorcery:displacer_receive_attune'; } local devs = sorcery.lib.node.amass(pos,txrcomps,sorcery.lib.node.offsets.neighbors) local r = { receptacles = {}; connections = {}; counts = { receptacles = 0; transmitters = 0; receptors = 0; }; } local getcode = function(pos) local inv = minetest.get_meta(pos):get_inventory() local code = {} local empty = true for i=1,inv:get_size('code') do if not inv:get_stack('code',i):is_empty() then empty = false end code[i] = inv:get_stack('code',i):get_name() end if empty then return nil else return code end end for pos, dev in pairs(devs) do if dev == 'sorcery:displacer_receive_gem' then r.counts.receptors = r.counts.receptors + 1 r.connections[#r.connections+1] = { pos = pos; mode = 'receive'; code = getcode(pos); -- TODO retrieve code } elseif dev == 'sorcery:displacer_receive_attune' then local tune = sorcery.attunement.verify(pos) if tune then r.counts.receptors = r.counts.receptors + 1 r.connections[#r.connections+1] = { pos = pos; mode = 'receive'; partner = tune.partner; } end elseif dev == 'sorcery:displacer_transmit_gem' then r.counts.transmitters = r.counts.transmitters + 1 r.connections[#r.connections+1] = { pos = pos; mode = 'transmit'; code = getcode(pos); -- TODO retrieve code } elseif dev == 'sorcery:displacer_transmit_attune' then local tune = sorcery.attunement.verify(pos) if tune then r.counts.transmitters = r.counts.transmitters + 1 r.connections[#r.connections+1] = { pos = pos; mode = 'transmit'; partner = tune.partner; } end elseif dev == 'sorcery:displacer' then r.counts.receptacles = r.counts.receptacles + 1 r.receptacles[#r.receptacles+1] = pos end end return r end local autoselect = function(pos) local dev = gettxr(pos) local active if dev.counts.receptors == 0 and dev.counts.transmitters == 1 then active = dev.connections[1].pos end for _,rcp in pairs(dev.receptacles) do local meta = minetest.get_meta(rcp) meta:set_string('active-device',active and minetest.pos_to_string(active) or '') end return active ~= nil end minetest.register_node('sorcery:displacer', { description = 'Displacer Receptacle'; paramtype2 = 'facedir'; on_construct = function(pos) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() minetest.get_node_timer(pos):start(1) inv:set_size('cache', 6) meta:set_string('infotext','displacer') meta:set_string('active-device','') meta:set_string('formspec', [[ formspec_version[3] size[10.25,8] list[context;cache;3.125,0.25;3,2] list[current_player;main;0.25,3;8,4] listring[] ]]) end; -- vararg wrapping necessary to discard the return value, -- as a return value of true will prevent the item from -- being removed from the user's inventory after placement after_place_node = function(...) autoselect(...) end; after_dig_node = function(...) autoselect(...) sorcery.lib.node.purge_container(...) end; on_metadata_inventory_put = function(pos) minetest.get_node_timer(pos):start(1) end; on_timer = function(pos,delta) local meta = minetest.get_meta(pos) if not meta:contains('active-device') then return false end local inv = meta:get_inventory() if inv:is_empty('cache') then return false end local dev = gettxr(pos) local active = minetest.string_to_pos(meta:get_string('active-device')) local ad for _,d in pairs(dev.connections) do if vector.equals(d.pos, active) then ad = d break end end if not ad then meta:set_string('active-device','') return false end local remote if ad.partner then remote = gettxr(ad.partner) elseif ad.code then local net = sorcery.farcaster.junction(pos,constants.xmit_wattage) for _,n in pairs(net) do for _,d in pairs(n.caps.net.devices.consume) do if d.id == 'sorcery:displacer' then local t = gettxr(d.pos) for _,d in pairs(t.connections) do if d.mode == 'receive' and d.code then local match = true for i=1,#d.code do if d.code[i] ~= ad.code[i] then match = false break end end if match then remote = t break end end end end if remote then break end end if remote then break end end end if not remote then return false end local n = sorcery.ley.netcaps(pos,delta,nil,constants.xmit_wattage) if n.self.powerdraw == n.self.maxpower then -- fully powered for transmission; find an object to transmit local transmission for i=1,inv:get_size('cache') do local s = inv:get_stack('cache',i) if not (s:is_empty() or minetest.get_item_group(s:get_name(), 'sorcery_nontranslocatable') ~= 0) then local quantity = 1 local tq = minetest.get_item_group(s:get_name(), 'sorcery_translocate_pack') if tq ~= 0 then quantity = math.min(tq, s:get_count()) end transmission = s:take_item(quantity) inv:set_stack('cache',i,s) break end end if not transmission then return false end -- iterate through available receptacles and see if there's room -- in any of them. otherwise, fail for _,r in pairs(remote.receptacles) do local i = minetest.get_meta(r):get_inventory() transmission = i:add_item('cache',transmission) if transmission:is_empty() then break end end if not transmission:is_empty() then inv:add_item('cache',transmission) end return true elseif n.maxpower >= n.self.maxpower then -- other devices are currently drawing power and might stop, -- making enough available for us; keep iterating just in case return true else -- the system does not have the capability to generate -- sufficient power, no point in continuing to fuck around return false end end; groups = { cracky = 2; sorcery_ley_device = 1; sorcery_magitech = 1; }; tiles = { 'sorcery_displacer_top.png'; 'sorcery_displacer_top.png'; 'sorcery_displacer_side.png'; 'sorcery_displacer_side.png'; 'sorcery_displacer_side.png'; 'sorcery_displacer_front.png'; }; _sorcery = { on_leychange = function(pos) minetest.get_node_timer(pos):start(1) end; ley = { mode = 'consume', affinity = {'mandatic'}; power = function(pos,time) local meta = minetest.get_meta(pos) local power = 0 if meta:contains('active-device') then power = constants.xmit_wattage end local dev = gettxr(pos) power = power + constants.rcpt_wattage * dev.counts.receptors return (power / dev.counts.receptacles) * time end; }; }; }) for mode,m in pairs { gem={ desc = 'Gem-Coded'; construct = function(pos) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() inv:set_size('code',6) meta:set_string('formspec', [[ formspec_version[3] size[10.25,7] list[context;code;1.5,0.25;6,1] list[current_player;main;0.25,1.75;8,4] listring[] ]]) end; allowput = function(pos,list,idx,stack) if list == 'code' then if sorcery.itemclass.get(stack:get_name(),'gem') then return 1 end end return 0 end; }; attune={ desc = 'Attuned'; }; } do for kind,n in pairs { transmit = { name = 'Transmission'; button = function(pos) minetest.sound_play('doors_steel_door_open', {pos = pos}) local n = minetest.get_node(pos) local dev = gettxr(pos) if dev.counts.receptacles > 0 then for _,r in pairs(dev.receptacles) do local m = minetest.get_meta(r) m:set_string('active-device',minetest.pos_to_string(pos)) minetest.get_node_timer(r):start(1) end end end; attune = { target = true, accepts = 'sorcery:displacer'; reciprocal = true; }; }; receive = { name = 'Reception'; attune = { source = true, class = 'sorcery:displacer'; reciprocal = true; } }; } do local id = 'sorcery:displacer_' .. kind .. '_' .. mode minetest.register_node(id, { description = m.desc .. ' ' .. n.name .. ' Module'; paramtype2 = 'facedir'; tiles = { 'sorcery_displacer_top.png'; 'sorcery_displacer_top.png'; 'sorcery_displacer_side.png'; 'sorcery_displacer_side.png'; 'sorcery_displacer_side.png'; 'sorcery_displacer_module_' .. kind .. '.png'; }; on_construct = m.construct; on_rightclick = mode ~= 'gem' and n.button or nil; on_punch = n.button and function(pos,node,puncher) if puncher and puncher:get_wielded_item():is_empty() then n.button(pos) end end or nil; after_place_node = function(...) autoselect(...) end; allow_metadata_inventory_put = m.allowput; _sorcery = { attune = (mode == 'attune') and n.attune or nil; }; after_dig_node = function(...) autoselect(...) sorcery.lib.node.purge_container(...) end; groups = { cracky = 2; sorcery_magitech = 1; }; }) end end |
Modified farcaster.lua from [12914a5106] to [6f8ef41220].
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
attune = {
class = 'sorcery:raycaster', accepts = 'sorcery:raycaster';
source = true, target = true, reciprocal = true;
};
farcaster = {
partner = function(pos)
local tune = sorcery.attunement.verify(pos)
print(' *!* verifying farcaster tuning',tune)
if not tune then return nil end
minetest.load_area(tune.partner)
local vis = false
local ignored
repeat
ignored = false
for _,p in pairs(sorcery.lib.node.offsets.neighbors) do
|
< |
22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
attune = { class = 'sorcery:raycaster', accepts = 'sorcery:raycaster'; source = true, target = true, reciprocal = true; }; farcaster = { partner = function(pos) local tune = sorcery.attunement.verify(pos) if not tune then return nil end minetest.load_area(tune.partner) local vis = false local ignored repeat ignored = false for _,p in pairs(sorcery.lib.node.offsets.neighbors) do |
Modified gems.lua from [2f2f7ff693] to [533039aa40].
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
...
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
if gem.foreign_shard then minetest.clear_craft {output=shardname} else minetest.register_craftitem(shardname, { description = sorcery.lib.str.capitalize(name) .. ' shard'; inventory_image = 'sorcery_gem_' .. name .. '_shard.png'; groups = { sorcery_shard = 1; }; _proto = gem; }) end if not gem.foreign_amulet then minetest.register_craftitem(amuletname, { description = sorcery.lib.str.capitalize(name) .. ' amulet'; inventory_image = sorcery.lib.image('sorcery_amulet.png'):multiply(sorcery.lib.color(gem.tone)):render(); _proto = { id = name; data = gem; }; }) end minetest.register_craft { type = 'shapeless'; recipe = (minetest.get_modpath('xdecor') and { 'xdecor:hammer', itemname; ................................................................................ } end if gem.foreign then return false end minetest.register_craftitem(itemname, { description = sorcery.lib.str.capitalize(name); inventory_image = 'sorcery_gem_' .. name .. '.png'; groups = { sorcery_gem = 1; }; _proto = gem; }) local tools = gem.tools if tools == nil then tools = { 'group:pickaxe'; 'group:pick'; -- FUCK YOU INSTANT_ORES '~default:enchanted_pick_'; -- FUCK YOU XDECOR } end |
|
|
>
>
>
>
>
>
|
|
|
>
>
|
|
>
>
>
>
>
|
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
...
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
if gem.foreign_shard then minetest.clear_craft {output=shardname} else minetest.register_craftitem(shardname, { description = sorcery.lib.str.capitalize(name) .. ' shard'; inventory_image = 'sorcery_gem_' .. name .. '_shard.png'; groups = { gemshard = 1; crystalshard = 1; sorcery_shard = 1; }; _sorcery = { material = { gem = true; id = name, data = gem; raw = true, value = 1; }; }; }) end if not gem.foreign_amulet then minetest.register_craftitem(amuletname, { description = sorcery.lib.str.capitalize(name) .. ' amulet'; inventory_image = sorcery.lib.image('sorcery_amulet.png'):multiply(sorcery.lib.color(gem.tone)):render(); _sorcery = { material = { gem = true, id = name, data = gem; value = (5 * shards_per_gem) + 4; }; }; }) end minetest.register_craft { type = 'shapeless'; recipe = (minetest.get_modpath('xdecor') and { 'xdecor:hammer', itemname; ................................................................................ } end if gem.foreign then return false end minetest.register_craftitem(itemname, { description = sorcery.lib.str.capitalize(name); inventory_image = 'sorcery_gem_' .. name .. '.png'; groups = { gem = 1; crystal = 1; sorcery_gem = 1; }; _sorcery = { material = { id = name, data = gem; raw = true, value = shards_per_gem; }; }; }) local tools = gem.tools if tools == nil then tools = { 'group:pickaxe'; 'group:pick'; -- FUCK YOU INSTANT_ORES '~default:enchanted_pick_'; -- FUCK YOU XDECOR } end |
Modified init.lua from [73a80c3c4b] to [97099862fc].
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
'potions', 'oils', 'greases', 'draughts', 'elixirs', 'philters', 'extracts'; 'register'; } for _,u in pairs { 'attunement'; 'ores'; 'gems'; 'leylines'; 'potions'; 'infuser'; 'altar'; 'wands'; 'tools'; 'crafttools'; 'enchanter'; 'harvester'; 'metallurgy-hot', 'metallurgy-cold'; 'entities'; 'recipes'; 'coins'; 'interop'; 'tnodes'; 'forcefield'; 'farcaster'; 'portal'; 'cookbook'; 'disassembly'; } do sorcery.load(u) end |
| | | | | | | |
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
'potions', 'oils', 'greases', 'draughts', 'elixirs', 'philters', 'extracts'; 'register'; } for _,u in pairs { 'attunement'; 'metal', 'gems'; 'itemclass'; 'leylines'; 'potions', 'infuser'; 'altar'; 'wands'; 'tools', 'crafttools'; 'enchanter'; 'harvester'; 'metallurgy-hot', 'metallurgy-cold'; 'entities'; 'recipes'; 'coins'; 'interop'; 'tnodes'; 'forcefield'; 'farcaster'; 'portal'; 'cookbook', 'writing'; 'disassembly'; 'displacer'; } do sorcery.load(u) end |
Added itemclass.lua version [bee797c513].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
-- in theory, minetest groups are supposed to allow us to -- give consistent, cross-mod classes to items, and easily -- detect whether items fit into a particular class. unfortunately, -- they don't really work for this purpose because we often -- need to attach additional data to items that are outside -- of our control (and the default mod's authors are amazingly -- lax in grouping items; for instance, diamonds and mese -- crystals aren't even part of a 'gem' or 'crystal' group!) -- this module allows us to consistently classify items, and -- easily maintain complex hierarchies of subclasses. whether -- an item belongs to a class can be determined by checking -- its groups, consulting compat tables, calling a custom -- predicate function (possibly to check for a _sorcery -- defprop), or recursing through a list of subclasses. -- this also means that matters of identity are all controlled -- from a central location. sorcery.itemclass = { classes = { -- gem/crystalline and metal/metallic differentiate -- between crafting materials (i.e. gems or ingots -- themselves) and items crafted from those materials. -- the former includes only crafting materials, the -- latter includes both. gem = { compat = 'gems'; groups = { 'gem', 'crystal'; }; predicate = function(name) if minetest.get_item_group(name, 'sorcery_gem') ~= 0 or minetest.get_item_group(name, 'sorcery_shard') ~= 0 then return minetest.registered_items[name]._sorcery.material; end end; }; crystalline = { subclass = {'gem'}; predicate = function(name) local mat = sorcery.matreg.lookup[name] if mat and mat.gem then return mat end end; }; grindable = { compat = 'grindables'; subclass = {'metallic'}; predicate = function(name) local def = minetest.registered_items[name]._sorcery if not def then return nil end def = def.material if def and def.grindvalue then return def end end; }; metal = { predicate = function(name) -- metallookup is a table of 'primary' metal -- items, like ingots, fragments, and powders return sorcery.data.metallookup[name] end; }; metallic = { subclass = {'metal'}; predicate = function(name) -- matreg is a registry binding crafted items, -- like armors and tools, to the material they -- are made out of local mat = sorcery.matreg.lookup[name] if mat and mat.metal then return mat end end; }; }; get = function(name,class) local c = sorcery.itemclass.classes[class] local o if not c then return false end if c.predicate then o = c.predicate(name) if o then return o end end if c.compat then o = sorcery.data.compat[c.compat][name] if o then return o end end if c.subclass then for _,s in pairs(c.subclass) do o = sorcery.itemclass.get(name,s) if o then return o end end end if c.groups then for _,g in pairs(c.groups) do o = minetest.get_item_group(name,g) if o > 0 then return { kind = o } end end o = nil end return false end; } |
Modified leylines.lua from [c6bfabb8a9] to [a383f4a3c9].
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 ... 311 312 313 314 315 316 317 318 319 320 321 322 323 324 ... 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 |
node_box = { type = 'connected'; disconnected = { -0.05, -0.35, -0.40; 0.05, -0.25, 0.40 }; connect_front = { -0.05, -0.35, -0.50; 0.05, -0.25, 0.05 }; connect_back = { -0.05, -0.35, -0.05; 0.05, -0.25, 0.50 }; connect_right = { -0.05, -0.35, -0.05; 0.50, -0.25, 0.05 }; connect_left = { -0.50, -0.35, -0.05; 0.05, -0.25, 0.05 }; connect_top = { -0.05, -0.25, -0.05; 0.05, 0.50, 0.05 }; connect_bottom = { -0.05, -0.50, -0.05; 0.05, -0.35, 0.05 }; }; connects_to = { 'group:sorcery_ley_device', 'default:mese' }; -- harcoding mese is kind of cheating -- figure out a -- better way to do this for the longterm paramtype = 'light'; -- paramtype2 = 'facedir'; ................................................................................ sorcery_ley_device = 1; sorcery_magitech = 1; }; on_construct = function(pos) local meta = minetest.get_meta(pos) meta:set_string('infotext','Condenser') end; _sorcery = { ley = { mode = 'produce'; power = function(pos,time) return sorcery.ley.field_to_current(sorcery.ley.estimate(pos).force, time); end; affinity = function(pos) return sorcery.ley.estimate(pos).aff ................................................................................ local sum = vector.add(pos,p) if not foundp(sum) then checked[#checked + 1] = sum local nodename = minetest.get_node(sum).name if nodename == 'ignore' then minetest.load_area(sum) nodename = minetest.get_node(sum).name print('**** ignorenode, loaded',nodename) end if minetest.get_item_group(nodename,'sorcery_ley_device') ~= 0 or sorcery.data.compat.ley[nodename] then local d = sorcery.ley.sample(pos,1,nodename,{query={mode=true}}) assert(d.mode == 'signal' or d.mode == 'consume' or d.mode == 'produce') |
| > > > > > < |
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 ... 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 ... 380 381 382 383 384 385 386 387 388 389 390 391 392 393 |
node_box = { type = 'connected'; disconnected = { -0.05, -0.35, -0.40; 0.05, -0.25, 0.40 }; connect_front = { -0.05, -0.35, -0.50; 0.05, -0.25, 0.05 }; connect_back = { -0.05, -0.35, -0.05; 0.05, -0.25, 0.50 }; connect_right = { -0.05, -0.35, -0.05; 0.50, -0.25, 0.05 }; connect_left = { -0.50, -0.35, -0.05; 0.05, -0.25, 0.05 }; connect_top = { -0.05, -0.35, -0.05; 0.05, 0.50, 0.05 }; connect_bottom = { -0.05, -0.50, -0.05; 0.05, -0.35, 0.05 }; }; connects_to = { 'group:sorcery_ley_device', 'default:mese' }; -- harcoding mese is kind of cheating -- figure out a -- better way to do this for the longterm paramtype = 'light'; -- paramtype2 = 'facedir'; ................................................................................ sorcery_ley_device = 1; sorcery_magitech = 1; }; on_construct = function(pos) local meta = minetest.get_meta(pos) meta:set_string('infotext','Condenser') end; on_rightclick = function(pos) local c = sorcery.ley.netcaps(pos,1) c.net.devices.signal = nil print('LEYNET', dump(c)) end; _sorcery = { ley = { mode = 'produce'; power = function(pos,time) return sorcery.ley.field_to_current(sorcery.ley.estimate(pos).force, time); end; affinity = function(pos) return sorcery.ley.estimate(pos).aff ................................................................................ local sum = vector.add(pos,p) if not foundp(sum) then checked[#checked + 1] = sum local nodename = minetest.get_node(sum).name if nodename == 'ignore' then minetest.load_area(sum) nodename = minetest.get_node(sum).name end if minetest.get_item_group(nodename,'sorcery_ley_device') ~= 0 or sorcery.data.compat.ley[nodename] then local d = sorcery.ley.sample(pos,1,nodename,{query={mode=true}}) assert(d.mode == 'signal' or d.mode == 'consume' or d.mode == 'produce') |
Name change from ores.lua to metal.lua.
Modified metallurgy-cold.lua from [3d415e629d] to [a94be8d51a].
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
...
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
elseif slot == 'input' then local metal = sorcery.data.metallookup[item:get_name()] local mat = sorcery.matreg.lookup[item:get_name()] local comp = sorcery.data.compat.grindables[item:get_name()] if metal or (mat and mat.metal) or comp then return item:get_count() else mat = item:get_definition()._matprop if mat and mat.grindvalue then return item:get_count() end end end return 0 end ................................................................................ -- allow grinding of armor and tools back to their -- original components local mat = sorcery.matreg.lookup[item:get_name()] if mat and mat.metal then metal = mat end end local mp = item:get_definition()._matprop or sorcery.data.compat.grindables[item:get_name()] or {} if metal then mp = { hardness = mp.hardness or metal.data.hardness; grindvalue = ((mp.grindvalue or metal.value) or (metal and constants.metal_grindvalue)); powder = mp.powder or metal.data.parts.powder; |
|
>
>
|
|
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
...
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
elseif slot == 'input' then local metal = sorcery.data.metallookup[item:get_name()] local mat = sorcery.matreg.lookup[item:get_name()] local comp = sorcery.data.compat.grindables[item:get_name()] if metal or (mat and mat.metal) or comp then return item:get_count() else mat = item:get_definition()._sorcery and item:get_definition()._sorcery.material if mat and mat.grindvalue then return item:get_count() end end end return 0 end ................................................................................ -- allow grinding of armor and tools back to their -- original components local mat = sorcery.matreg.lookup[item:get_name()] if mat and mat.metal then metal = mat end end local mp = (item:get_definition()._sorcery and item:get_definition()._sorcery.material) or sorcery.data.compat.grindables[item:get_name()] or {} if metal then mp = { hardness = mp.hardness or metal.data.hardness; grindvalue = ((mp.grindvalue or metal.value) or (metal and constants.metal_grindvalue)); powder = mp.powder or metal.data.parts.powder; |
Modified portal.lua from [021fb6f980] to [2352fa593a].
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 ... 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 ... 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 ... 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 ... 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 |
minetest.load_area( vector.add(pos, {x = 5, y = 1 + constants.portal_max_height, z = 5}), vector.add(pos, {x = -5, y = -1 - constants.portal_max_height, z = -5}) ) -- starting at a portal node, search connected blocks -- recursively to locate portal pads and their paired -- partners. return a table characterizing the portal -- return false if no portal found -- first search immediate neighbors. the portal node -- can be connected to either reflectors or pads local startpoint, startwithpads for _, d in pairs(sorcery.lib.node.offsets.neighbors) do local sum = vector.add(pos,d) local name = minetest.get_node(sum).name ................................................................................ for _, d in pairs(n.caps.net.devices.consume) do if d.id == 'sorcery:portal_node' and portal_composition(d.pos) then circuit[#circuit+1] = { pos = d.pos; hops = n.hops; route = n.route; } print(' ! found portal node',d.pos) else print(' -- skipping node',d.pos,d.id) end end end return circuit end local portal_disposition = function(dev) ................................................................................ local tune = sorcery.attunement.verify(pos) local partner -- raw position of partner node, if any if tune and tune.partner then minetest.load_area(tune.partner) -- we are attuned to a partner, but is it in the circuit? for _,v in pairs(crc) do if vector.equals(v.pos,tune.partner) then print('found partner in circuit') partner = tune.partner break end end end print("power reqs",cap.self.minpower,cap.self.powerdraw) if cap.self.minpower ~= cap.self.powerdraw then print("not enough power") return true end -- clean out user table for name,user in pairs(portal_context.users) do ................................................................................ local user = portal_context.users[pname] if not vector.equals(pos,user.portal) then user.time = 0 user.portal = pos end local cap = sorcery.ley.netcaps(pos,delta) local jc = (constants.portal_jump_cost_local*delta) print('free power',cap.freepower,jc) if not user.dest and cap.freepower >= jc then user.dest = portal_pick_destination(dev,crc,partner) else print('powerdraw',cap.self.powerdraw) end if not user.dest then goto skippad else minetest.load_area(user.dest) end local fac = (user.time / constants.portal_jump_time); minetest.add_particlespawner { time = 1, amount = 100 + (fac * 200); ................................................................................ mode = 'consume', affinity = {'mandatic'}; power = function(pos,delta) -- return power use if device is currently in process -- of teleporting a player; otherwise, return 0 local cost = constants.portal_node_power for _,u in pairs(portal_context.users) do if u.dest and vector.equals(u.portal, pos) then print('user is on pad',dump(pos)) cost = cost + constants.portal_jump_cost_local end end return cost * delta end; }; |
| < < < < < < < < < |
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 ... 158 159 160 161 162 163 164 165 166 167 168 169 170 171 ... 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 ... 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 ... 436 437 438 439 440 441 442 443 444 445 446 447 448 449 |
minetest.load_area( vector.add(pos, {x = 5, y = 1 + constants.portal_max_height, z = 5}), vector.add(pos, {x = -5, y = -1 - constants.portal_max_height, z = -5}) ) -- starting at a portal node, search connected blocks -- recursively to locate portal pads and their paired -- partners. return a table characterizing the portal -- or return false if no portal found -- first search immediate neighbors. the portal node -- can be connected to either reflectors or pads local startpoint, startwithpads for _, d in pairs(sorcery.lib.node.offsets.neighbors) do local sum = vector.add(pos,d) local name = minetest.get_node(sum).name ................................................................................ for _, d in pairs(n.caps.net.devices.consume) do if d.id == 'sorcery:portal_node' and portal_composition(d.pos) then circuit[#circuit+1] = { pos = d.pos; hops = n.hops; route = n.route; } end end end return circuit end local portal_disposition = function(dev) ................................................................................ local tune = sorcery.attunement.verify(pos) local partner -- raw position of partner node, if any if tune and tune.partner then minetest.load_area(tune.partner) -- we are attuned to a partner, but is it in the circuit? for _,v in pairs(crc) do if vector.equals(v.pos,tune.partner) then partner = tune.partner break end end end if cap.self.minpower ~= cap.self.powerdraw then print("not enough power") return true end -- clean out user table for name,user in pairs(portal_context.users) do ................................................................................ local user = portal_context.users[pname] if not vector.equals(pos,user.portal) then user.time = 0 user.portal = pos end local cap = sorcery.ley.netcaps(pos,delta) local jc = (constants.portal_jump_cost_local*delta) if not user.dest and cap.freepower >= jc then user.dest = portal_pick_destination(dev,crc,partner) end if not user.dest then goto skippad else minetest.load_area(user.dest) end local fac = (user.time / constants.portal_jump_time); minetest.add_particlespawner { time = 1, amount = 100 + (fac * 200); ................................................................................ mode = 'consume', affinity = {'mandatic'}; power = function(pos,delta) -- return power use if device is currently in process -- of teleporting a player; otherwise, return 0 local cost = constants.portal_node_power for _,u in pairs(portal_context.users) do if u.dest and vector.equals(u.portal, pos) then cost = cost + constants.portal_jump_cost_local end end return cost * delta end; }; |
Modified recipes.lua from [e76efbfb0c] to [7adbea13be].
7 8 9 10 11 12 13 14 15 16 17 18 19 20 ... 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 ... 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 ... 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 |
"vessels:glass_bottle" }; output = "sorcery:potion_water 3"; replacements = { { "group:water_bucket", "bucket:bucket_empty" } }; } minetest.register_craft { type = "shapeless"; recipe = { "bucket:bucket_empty"; "sorcery:potion_water"; "sorcery:potion_water"; ................................................................................ }; output = "sorcery:infuser"; } minetest.register_craft { output = "sorcery:displacer"; recipe = { {'sorcery:platinum_ingot','sorcery:leyline_stabilizer','sorcery:platinum_ingot'}; {'sorcery:inverter_coil','sorcery:core_syncretic','sorcery:inverter_coil'}; {'sorcery:platinum_ingot','default:chest','sorcery:platinum_ingot'}; }; } minetest.register_craft { output = "sorcery:displacement_node"; recipe = { {'sorcery:platinum_ingot','sorcery:screw_tungsten','sorcery:platinum_ingot'}; {'basic_materials:copper_wire','sorcery:core_syncretic','doors:trapdoor_steel'}; {'sorcery:platinum_ingot','sorcery:screw_tungsten','sorcery:platinum_ingot'}; }; replacements = { {'basic_materials:copper_wire','basic_materials:empty_spool'}; }; } minetest.register_craft { output = 'sorcery:raycaster'; recipe = { {'sorcery:gem_amethyst', 'sorcery:gem_amethyst', 'sorcery:gem_amethyst'}; {'default:gold_ingot','sorcery:beam_generator','default:gold_ingot'}; {'sorcery:gem_amethyst', 'sorcery:gem_amethyst', 'sorcery:gem_amethyst'}; ................................................................................ groups = { sorcery_magitech = 1; metal = 1; sorcery_magitech_core = 1; }; }); minetest.register_craftitem('sorcery:core_syncretic',{ description = 'Syncresis Core'; inventory_image = 'sorcery_core_sycretic.png'; groups = { sorcery_magitech = 1; metal = 1; sorcery_magitech_core = 1; }; }); minetest.register_craftitem('sorcery:suppression_matrix',{ description = 'Suppression Matrix'; ................................................................................ }; } minetest.register_craft { output = 'sorcery:core_syncretic'; recipe = { {'sorcery:gem_sapphire_shard','default:gold_ingot','sorcery:gem_sapphire_shard'}; {'default:gold_ingot','sorcery:gem_diamond','default:gold_ingot'}; {'sorcery:gem_sapphire_shard','default:gold_ingot','sorcery:gem_sapphire_shard'}; }; } minetest.register_craft { output = 'sorcery:core_mandatic'; recipe = { |
> > > > > > > > > > > < < < < < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | |
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ... 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 ... 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 ... 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 |
"vessels:glass_bottle" }; output = "sorcery:potion_water 3"; replacements = { { "group:water_bucket", "bucket:bucket_empty" } }; } minetest.register_craft { output = 'dye:white 4'; recipe = { {'', 'sorcery:ash', ''}; {'sorcery:ash','basic_materials:paraffin','sorcery:ash'}; {'', 'bucket:bucket_water', ''}; }; replacements = { {'bucket:bucket_water', 'bucket:bucket_empty'}; }; }; minetest.register_craft { type = "shapeless"; recipe = { "bucket:bucket_empty"; "sorcery:potion_water"; "sorcery:potion_water"; ................................................................................ }; output = "sorcery:infuser"; } minetest.register_craft { output = "sorcery:displacer"; recipe = { {'sorcery:platinum_ingot','sorcery:screw_tungsten','sorcery:platinum_ingot'}; {'basic_materials:copper_wire','sorcery:core_syncretic','doors:trapdoor_steel'}; {'sorcery:platinum_ingot','sorcery:screw_tungsten','sorcery:platinum_ingot'}; }; replacements = { {'basic_materials:copper_wire','basic_materials:empty_spool'}; }; } minetest.register_craft { output = "sorcery:displacer_transmit_attune"; recipe = { {'sorcery:platinum_ingot','sorcery:screw_tungsten','sorcery:platinum_ingot'}; {'sorcery:leyline_stabilizer','sorcery:core_mandatic','sorcery:tuning_disc'}; {'sorcery:platinum_ingot','sorcery:screw_tungsten','sorcery:platinum_ingot'}; }; } minetest.register_craft { output = "sorcery:displacer_transmit_gem"; recipe = { {'sorcery:platinum_ingot','sorcery:screw_tungsten','sorcery:platinum_ingot'}; {'sorcery:leyline_stabilizer','sorcery:core_mandatic','sorcery:gem_ruby'}; {'sorcery:platinum_ingot','sorcery:screw_tungsten','sorcery:platinum_ingot'}; }; } minetest.register_craft { output = "sorcery:displacer_receive_attune"; recipe = { {'sorcery:platinum_ingot','sorcery:screw_tungsten','sorcery:platinum_ingot'}; {'sorcery:inverter_coil','sorcery:core_mandatic','sorcery:tuning_disc'}; {'sorcery:platinum_ingot','sorcery:screw_tungsten','sorcery:platinum_ingot'}; }; } minetest.register_craft { output = "sorcery:displacer_receive_gem"; recipe = { {'sorcery:platinum_ingot','sorcery:screw_tungsten','sorcery:platinum_ingot'}; {'sorcery:inverter_coil','sorcery:core_mandatic','sorcery:gem_ruby'}; {'sorcery:platinum_ingot','sorcery:screw_tungsten','sorcery:platinum_ingot'}; }; } minetest.register_craft { output = 'sorcery:raycaster'; recipe = { {'sorcery:gem_amethyst', 'sorcery:gem_amethyst', 'sorcery:gem_amethyst'}; {'default:gold_ingot','sorcery:beam_generator','default:gold_ingot'}; {'sorcery:gem_amethyst', 'sorcery:gem_amethyst', 'sorcery:gem_amethyst'}; ................................................................................ groups = { sorcery_magitech = 1; metal = 1; sorcery_magitech_core = 1; }; }); minetest.register_craftitem('sorcery:core_syncretic',{ description = 'Syncresis Core'; inventory_image = 'sorcery_core_syncretic.png'; groups = { sorcery_magitech = 1; metal = 1; sorcery_magitech_core = 1; }; }); minetest.register_craftitem('sorcery:suppression_matrix',{ description = 'Suppression Matrix'; ................................................................................ }; } minetest.register_craft { output = 'sorcery:core_syncretic'; recipe = { {'sorcery:gem_sapphire_shard','default:gold_ingot','sorcery:gem_sapphire_shard'}; {'default:gold_ingot','default:diamond','default:gold_ingot'}; {'sorcery:gem_sapphire_shard','default:gold_ingot','sorcery:gem_sapphire_shard'}; }; } minetest.register_craft { output = 'sorcery:core_mandatic'; recipe = { |
Modified textures/sorcery_core_syncretic.png from [086b79dff1] to [08f74a08b5].
cannot compute difference between binary files
Added textures/sorcery_displacer_front.png version [51a09bc368].
cannot compute difference between binary files
Added textures/sorcery_displacer_module_receive.png version [99916d60d5].
cannot compute difference between binary files
Added textures/sorcery_displacer_module_transmit.png version [ee8e01ea67].
cannot compute difference between binary files
Added textures/sorcery_displacer_side.png version [fe755fceaa].
cannot compute difference between binary files
Added textures/sorcery_displacer_top.png version [e8a57f9374].
cannot compute difference between binary files
Modified textures/sorcery_tuning_disc.png from [babfdd1af1] to [4820ec8236].
cannot compute difference between binary files
Deleted textures/sorcery_wandworking_station_top.png~ version [197c24c8ba].
cannot compute difference between binary files
Added writing.lua version [d9df5661ad].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
-- this file contains a few enhancements to the normal book and -- paper functionality. it allows authors to disavow their books, -- making them appear as by an "unknown author", by smudging out -- the byline with black dye. it also allows written books to be -- soaked in a bucket of water to wash out the ink and return -- them to a virginal, unwritten state. finally, it makes it so -- that when a book (or any owned item, for that matter) is -- copied, the owner of the new copy is set to the user who -- copied it, allowing users to collaborate on books. local paperburn = function(item,value) minetest.register_craft { type = 'fuel', recipe = item, burntime = 3 * value } minetest.register_craft { type = 'cooking'; recipe = item; output = 'sorcery:ash ' .. tostring(value); cooktime = 3 * value; } end paperburn('default:paper',1) paperburn('sorcery:recipe',1) paperburn('default:book',3) paperburn('sorcery:cookbook',3) paperburn('default:book_written',3) minetest.register_craft { type = "shapeless"; recipe = {"default:book_written", "bucket:bucket_water"}; output = "default:book"; replacements = { {"bucket:bucket_water", "bucket:bucket_empty"} } } minetest.register_craft { type = 'shapeless'; recipe = {"default:book_written", "dye:black"}; output = 'default:book_written'; } minetest.register_on_craft(function(itemstack,player,recipe,pinv) local meta = itemstack:get_meta() if not meta:contains('owner') then return nil end local pname = player:get_player_name() if meta:get_string('owner') ~= pname then meta:set_string('owner', pname) end if itemstack:get_name() == 'default:book_written' then local found_book, found_dye, book_idx = false, false, 0 for i,v in pairs(recipe) do if v:get_name() == 'dye:black' and not found_dye then found_dye = true elseif v:get_name() == 'default:book_written' and not found_book then found_book = v book_idx = i elseif not v:is_empty() then found_book = false break end end if found_book and found_dye then meta:from_table(found_book:get_meta():to_table()) meta:set_string('owner','unknown author') meta:set_string('description','"'..meta:get_string('title')..'"') pinv:set_stack('craft',book_idx,ItemStack()) end end return itemstack end) |