From aed732d3ebcfeecfd83ce14ee02c040bc584aea4 Mon Sep 17 00:00:00 2001 From: maikerumine Date: Sat, 22 Oct 2016 14:16:12 -0400 Subject: [PATCH] ESM UPDATE 2.0 major overhaul --- mods/a_inventory_mods/hazmat_suit/README.txt | 10 - mods/a_inventory_mods/hazmat_suit/depends.txt | 2 - .../hazmat_suit/description.txt | 1 - mods/a_inventory_mods/hazmat_suit/init.lua | 126 -- .../textures/hazmat_suit_inv_boots_hazmat.png | Bin 198 -> 0 bytes .../hazmat_suit_inv_chestplate_hazmat.png | Bin 160 -> 0 bytes .../hazmat_suit_inv_helmet_hazmat.png | Bin 248 -> 0 bytes .../hazmat_suit_inv_leggings_hazmat.png | Bin 189 -> 0 bytes .../hazmat_suit_inv_sleeve_hazmat.png | Bin 189 -> 0 bytes .../textures/hazmat_suit_inv_suit_hazmat.png | Bin 302 -> 0 bytes .../textures/hazmat_suit_suit_hazmat.png | Bin 792 -> 0 bytes .../hazmat_suit_suit_hazmat_preview.png | Bin 1005 -> 0 bytes .../a_mapgen_mods/handle_schematics/README.md | 10 + .../analyze_mc_schematic_file.lua | 215 +++ .../handle_schematics/analyze_mts_file.lua | 279 ++++ .../handle_schematics/analyze_we_file.lua | 100 ++ .../handle_schematics/build_chest.lua | 876 +++++++++++ .../build_chest_add_schems_by_directory.lua | 164 ++ .../build_chest_add_schems_from_file.lua | 58 + .../build_chest_handle_replacements.lua | 256 +++ .../build_chest_preview_image.lua | 248 +++ .../handle_schematics/depends.txt | 23 + .../handle_schematics_meta.lua | 162 ++ .../handle_schematics_misc.lua | 107 ++ mods/a_mapgen_mods/handle_schematics/init.lua | 61 + .../a_mapgen_mods/handle_schematics/nodes.lua | 24 + .../handle_schematics/place_buildings.lua | 835 ++++++++++ .../replacements_farming.lua | 171 ++ .../replacements_get_table.lua | 21 + .../replacements_realtest.lua | 82 + .../handle_schematics/replacements_roof.lua | 110 ++ .../handle_schematics/replacements_wood.lua | 234 +++ .../handle_schematics/rotate.lua | 114 ++ .../handle_schematics/save_restore.lua | 91 ++ .../textures/handle_schematics_support.png | Bin 0 -> 261 bytes .../translate_nodenames_for_mc_schematic.lua | 402 +++++ .../handle_schematics/worldedit_file.lua | 138 ++ .../mg_villages/--config -orig.lua | 187 +++ mods/a_mapgen_mods/mg_villages/README.md | 3 + mods/a_mapgen_mods/mg_villages/buildings.lua | 430 +++++ .../mg_villages/chat_commands.lua | 107 ++ mods/a_mapgen_mods/mg_villages/config.lua | 187 +++ mods/a_mapgen_mods/mg_villages/depends.txt | 22 + .../mg_villages/fill_chest--orig.lua | 228 +++ mods/a_mapgen_mods/mg_villages/fill_chest.lua | 283 ++++ .../mg_villages/highlandpools.lua | 234 +++ mods/a_mapgen_mods/mg_villages/init.lua | 75 + .../mg_villages/init_weights.lua | 43 + .../mg_villages/map_of_world.lua | 193 +++ mods/a_mapgen_mods/mg_villages/mapgen.lua | 1215 ++++++++++++++ mods/a_mapgen_mods/mg_villages/name_gen.lua | 90 ++ mods/a_mapgen_mods/mg_villages/nodes.lua | 142 ++ mods/a_mapgen_mods/mg_villages/protection.lua | 307 ++++ .../mg_villages/replacements.lua | 964 ++++++++++++ .../mg_villages/schems/allmende_3_90.mts | Bin 0 -> 207 bytes .../mg_villages/schems/baking_house_1.mts | Bin 0 -> 1095 bytes .../mg_villages/schems/baking_house_2.mts | Bin 0 -> 1179 bytes .../mg_villages/schems/baking_house_3.mts | Bin 0 -> 1206 bytes .../mg_villages/schems/baking_house_4.mts | Bin 0 -> 1323 bytes .../mg_villages/schems/bench_1.mts | Bin 0 -> 127 bytes .../mg_villages/schems/bench_2.mts | Bin 0 -> 114 bytes .../mg_villages/schems/bench_3.mts | Bin 0 -> 165 bytes .../mg_villages/schems/bench_4.mts | Bin 0 -> 152 bytes .../mg_villages/schems/charachoal_hill.mts | Bin 0 -> 375 bytes .../mg_villages/schems/charachoal_hut.mts | Bin 0 -> 470 bytes .../mg_villages/schems/church.mts | Bin 0 -> 864 bytes .../mg_villages/schems/church_1.mts | Bin 0 -> 1557 bytes .../mg_villages/schems/clay_pit_1.mts | Bin 0 -> 220 bytes .../mg_villages/schems/clay_pit_2.mts | Bin 0 -> 86 bytes .../mg_villages/schems/clay_pit_3.mts | Bin 0 -> 191 bytes .../mg_villages/schems/clay_pit_4.mts | Bin 0 -> 355 bytes .../mg_villages/schems/clay_pit_5.mts | Bin 0 -> 207 bytes .../mg_villages/schems/cotton_field.mts | Bin 0 -> 112 bytes .../mg_villages/schems/default_town_farm.mts | Bin 0 -> 541 bytes .../schems/default_town_fountain.mts | Bin 0 -> 442 bytes .../mg_villages/schems/default_town_hotel.mts | Bin 0 -> 610 bytes .../schems/default_town_hotel_(.mts | Bin 0 -> 660 bytes .../schems/default_town_hotel_).mts | Bin 0 -> 327 bytes .../schems/default_town_house_large_1.mts | Bin 0 -> 3074 bytes .../schems/default_town_house_large_2.mts | Bin 0 -> 2486 bytes .../schems/default_town_house_medium.mts | Bin 0 -> 1673 bytes .../schems/default_town_house_small.mts | Bin 0 -> 979 bytes .../schems/default_town_house_tiny_1.mts | Bin 0 -> 581 bytes .../schems/default_town_house_tiny_2.mts | Bin 0 -> 611 bytes .../schems/default_town_house_tiny_3.mts | Bin 0 -> 587 bytes .../mg_villages/schems/default_town_park.mts | Bin 0 -> 420 bytes .../mg_villages/schems/default_town_tower.mts | Bin 0 -> 391 bytes .../mg_villages/schems/default_town_well.mts | Bin 0 -> 408 bytes .../mg_villages/schems/empty_1.mts | Bin 0 -> 93 bytes .../mg_villages/schems/empty_2.mts | Bin 0 -> 111 bytes .../mg_villages/schems/empty_3.mts | Bin 0 -> 141 bytes .../mg_villages/schems/empty_4.mts | Bin 0 -> 115 bytes .../mg_villages/schems/empty_5.mts | Bin 0 -> 146 bytes .../mg_villages/schems/farm_full_1.mts | Bin 0 -> 1218 bytes .../mg_villages/schems/farm_full_2.mts | Bin 0 -> 1692 bytes .../mg_villages/schems/farm_full_3.mts | Bin 0 -> 1629 bytes .../mg_villages/schems/farm_full_4.mts | Bin 0 -> 2240 bytes .../mg_villages/schems/farm_full_5.mts | Bin 0 -> 1840 bytes .../mg_villages/schems/farm_full_6.mts | Bin 0 -> 1604 bytes .../mg_villages/schems/farm_tiny_1.mts | Bin 0 -> 1217 bytes .../mg_villages/schems/farm_tiny_2.mts | Bin 0 -> 1467 bytes .../mg_villages/schems/farm_tiny_3.mts | Bin 0 -> 1809 bytes .../mg_villages/schems/farm_tiny_4.mts | Bin 0 -> 1662 bytes .../mg_villages/schems/farm_tiny_5.mts | Bin 0 -> 1389 bytes .../mg_villages/schems/farm_tiny_6.mts | Bin 0 -> 1434 bytes .../mg_villages/schems/farm_tiny_7.mts | Bin 0 -> 1645 bytes .../mg_villages/schems/field_1.mts | Bin 0 -> 289 bytes .../mg_villages/schems/field_2.mts | Bin 0 -> 264 bytes .../mg_villages/schems/field_3.mts | Bin 0 -> 172 bytes .../mg_villages/schems/field_4.mts | Bin 0 -> 132 bytes .../mg_villages/schems/forge.mts | Bin 0 -> 370 bytes .../mg_villages/schems/forge_1.mts | Bin 0 -> 1021 bytes .../mg_villages/schems/fountain.mts | Bin 0 -> 291 bytes .../mg_villages/schems/grasshut1.mts | Bin 0 -> 253 bytes .../mg_villages/schems/grasshut2.mts | Bin 0 -> 423 bytes .../mg_villages/schems/grasshut3.mts | Bin 0 -> 433 bytes .../mg_villages/schems/grasshut4.mts | Bin 0 -> 340 bytes .../mg_villages/schems/grasshut5.mts | Bin 0 -> 353 bytes .../mg_villages/schems/grasshut6.mts | Bin 0 -> 261 bytes .../mg_villages/schems/grasshutcenter.mts | Bin 0 -> 150 bytes .../mg_villages/schems/hochsitz_1.mts | Bin 0 -> 407 bytes .../mg_villages/schems/hochsitz_2.mts | Bin 0 -> 251 bytes .../mg_villages/schems/hochsitz_3.mts | Bin 0 -> 358 bytes .../mg_villages/schems/hochsitz_4.mts | Bin 0 -> 313 bytes .../mg_villages/schems/house.mts | Bin 0 -> 356 bytes .../mg_villages/schems/house_with_garden.mts | Bin 0 -> 522 bytes .../mg_villages/schems/hut_1.mts | Bin 0 -> 695 bytes .../mg_villages/schems/hut_2.mts | Bin 0 -> 771 bytes mods/a_mapgen_mods/mg_villages/schems/inn.mts | Bin 0 -> 580 bytes .../a_mapgen_mods/mg_villages/schems/lamp.mts | Bin 0 -> 118 bytes .../mg_villages/schems/library.mts | Bin 0 -> 391 bytes .../mg_villages/schems/logcabin1.mts | Bin 0 -> 713 bytes .../mg_villages/schems/logcabin10.mts | Bin 0 -> 596 bytes .../mg_villages/schems/logcabin11.mts | Bin 0 -> 687 bytes .../mg_villages/schems/logcabin2.mts | Bin 0 -> 485 bytes .../mg_villages/schems/logcabin3.mts | Bin 0 -> 616 bytes .../mg_villages/schems/logcabin4.mts | Bin 0 -> 662 bytes .../mg_villages/schems/logcabin5.mts | Bin 0 -> 470 bytes .../mg_villages/schems/logcabin6.mts | Bin 0 -> 633 bytes .../mg_villages/schems/logcabin7.mts | Bin 0 -> 764 bytes .../mg_villages/schems/logcabin8.mts | Bin 0 -> 552 bytes .../mg_villages/schems/logcabin9.mts | Bin 0 -> 745 bytes .../mg_villages/schems/logcabinpub1.mts | Bin 0 -> 954 bytes .../mg_villages/schems/logcabinpub2.mts | Bin 0 -> 1238 bytes .../mg_villages/schems/logcabinpub3.mts | Bin 0 -> 1650 bytes .../mg_villages/schems/lumberjack_1.mts | Bin 0 -> 682 bytes .../mg_villages/schems/lumberjack_10.mts | Bin 0 -> 664 bytes .../mg_villages/schems/lumberjack_11.mts | Bin 0 -> 473 bytes .../mg_villages/schems/lumberjack_12.mts | Bin 0 -> 538 bytes .../mg_villages/schems/lumberjack_13.mts | Bin 0 -> 626 bytes .../mg_villages/schems/lumberjack_14.mts | Bin 0 -> 526 bytes .../mg_villages/schems/lumberjack_15.mts | Bin 0 -> 633 bytes .../mg_villages/schems/lumberjack_16.mts | Bin 0 -> 494 bytes .../mg_villages/schems/lumberjack_2.mts | Bin 0 -> 817 bytes .../mg_villages/schems/lumberjack_3.mts | Bin 0 -> 603 bytes .../mg_villages/schems/lumberjack_4.mts | Bin 0 -> 594 bytes .../mg_villages/schems/lumberjack_5.mts | Bin 0 -> 683 bytes .../mg_villages/schems/lumberjack_6.mts | Bin 0 -> 811 bytes .../mg_villages/schems/lumberjack_7.mts | Bin 0 -> 808 bytes .../mg_villages/schems/lumberjack_8.mts | Bin 0 -> 694 bytes .../mg_villages/schems/lumberjack_9.mts | Bin 0 -> 911 bytes .../schems/lumberjack_church_1.mts | Bin 0 -> 967 bytes .../mg_villages/schems/lumberjack_hotel_1.mts | Bin 0 -> 826 bytes .../mg_villages/schems/lumberjack_pub_1.mts | Bin 0 -> 787 bytes .../schems/lumberjack_sawmill_1.mts | Bin 0 -> 1396 bytes .../mg_villages/schems/lumberjack_school.mts | Bin 0 -> 1294 bytes .../mg_villages/schems/lumberjack_shop_1.mts | Bin 0 -> 1168 bytes .../mg_villages/schems/lumberjack_stable.mts | Bin 0 -> 1290 bytes .../mg_villages/schems/mill_1.mts | Bin 0 -> 811 bytes mods/a_mapgen_mods/mg_villages/schems/pub.mts | Bin 0 -> 906 bytes .../mg_villages/schems/shed_1.mts | Bin 0 -> 292 bytes .../mg_villages/schems/shed_10.mts | Bin 0 -> 506 bytes .../mg_villages/schems/shed_11.mts | Bin 0 -> 451 bytes .../mg_villages/schems/shed_12.mts | Bin 0 -> 559 bytes .../mg_villages/schems/shed_2.mts | Bin 0 -> 496 bytes .../mg_villages/schems/shed_3.mts | Bin 0 -> 539 bytes .../mg_villages/schems/shed_5.mts | Bin 0 -> 402 bytes .../mg_villages/schems/shed_6.mts | Bin 0 -> 370 bytes .../mg_villages/schems/shed_7.mts | Bin 0 -> 445 bytes .../mg_villages/schems/shed_8.mts | Bin 0 -> 533 bytes .../mg_villages/schems/shed_9.mts | Bin 0 -> 620 bytes .../mg_villages/schems/small_house.mts | Bin 0 -> 289 bytes .../mg_villages/schems/taverne_1.mts | Bin 0 -> 2041 bytes .../mg_villages/schems/taverne_2.mts | Bin 0 -> 1247 bytes .../mg_villages/schems/taverne_3.mts | Bin 0 -> 1161 bytes .../mg_villages/schems/taverne_4.mts | Bin 0 -> 942 bytes .../mg_villages/schems/tent_big_1.mts | Bin 0 -> 411 bytes .../mg_villages/schems/tent_big_2.mts | Bin 0 -> 379 bytes .../mg_villages/schems/tent_medium_1.mts | Bin 0 -> 261 bytes .../mg_villages/schems/tent_medium_2.mts | Bin 0 -> 291 bytes .../mg_villages/schems/tent_medium_3.mts | Bin 0 -> 277 bytes .../mg_villages/schems/tent_medium_4.mts | Bin 0 -> 277 bytes .../mg_villages/schems/tent_open_1.mts | Bin 0 -> 181 bytes .../mg_villages/schems/tent_open_2.mts | Bin 0 -> 174 bytes .../mg_villages/schems/tent_open_3.mts | Bin 0 -> 259 bytes .../mg_villages/schems/tent_open_big_1.mts | Bin 0 -> 193 bytes .../mg_villages/schems/tent_open_big_2.mts | Bin 0 -> 193 bytes .../mg_villages/schems/tent_open_big_3.mts | Bin 0 -> 182 bytes .../mg_villages/schems/tent_tiny_1.mts | Bin 0 -> 221 bytes .../mg_villages/schems/tent_tiny_2.mts | Bin 0 -> 164 bytes .../mg_villages/schems/tower.mts | Bin 0 -> 361 bytes .../mg_villages/schems/trader_clay_1.mts | Bin 0 -> 559 bytes .../mg_villages/schems/trader_clay_2.mts | Bin 0 -> 549 bytes .../mg_villages/schems/trader_clay_3.mts | Bin 0 -> 597 bytes .../mg_villages/schems/trader_clay_4.mts | Bin 0 -> 777 bytes .../mg_villages/schems/trader_clay_5.mts | Bin 0 -> 724 bytes .../mg_villages/schems/tree_place_1.mts | Bin 0 -> 171 bytes .../mg_villages/schems/tree_place_10.mts | Bin 0 -> 209 bytes .../mg_villages/schems/tree_place_2.mts | Bin 0 -> 155 bytes .../mg_villages/schems/tree_place_3.mts | Bin 0 -> 157 bytes .../mg_villages/schems/tree_place_4.mts | Bin 0 -> 120 bytes .../mg_villages/schems/tree_place_5.mts | Bin 0 -> 163 bytes .../mg_villages/schems/tree_place_6.mts | Bin 0 -> 212 bytes .../mg_villages/schems/tree_place_7.mts | Bin 0 -> 237 bytes .../mg_villages/schems/tree_place_8.mts | Bin 0 -> 99 bytes .../mg_villages/schems/tree_place_9.mts | Bin 0 -> 301 bytes .../mg_villages/schems/wagon_1.mts | Bin 0 -> 216 bytes .../mg_villages/schems/wagon_10.mts | Bin 0 -> 215 bytes .../mg_villages/schems/wagon_11.mts | Bin 0 -> 210 bytes .../mg_villages/schems/wagon_12.mts | Bin 0 -> 232 bytes .../mg_villages/schems/wagon_2.mts | Bin 0 -> 243 bytes .../mg_villages/schems/wagon_3.mts | Bin 0 -> 189 bytes .../mg_villages/schems/wagon_4.mts | Bin 0 -> 169 bytes .../mg_villages/schems/wagon_5.mts | Bin 0 -> 193 bytes .../mg_villages/schems/wagon_6.mts | Bin 0 -> 160 bytes .../mg_villages/schems/wagon_7.mts | Bin 0 -> 170 bytes .../mg_villages/schems/wagon_8.mts | Bin 0 -> 218 bytes .../mg_villages/schems/wagon_9.mts | Bin 0 -> 177 bytes .../mg_villages/schems/watermill_1.mts | Bin 0 -> 2945 bytes .../mg_villages/schems/weide_1.mts | Bin 0 -> 542 bytes .../mg_villages/schems/weide_2.mts | Bin 0 -> 626 bytes .../mg_villages/schems/weide_3.mts | Bin 0 -> 517 bytes .../mg_villages/schems/weide_4.mts | Bin 0 -> 518 bytes .../mg_villages/schems/weide_5.mts | Bin 0 -> 362 bytes .../mg_villages/schems/weide_6.mts | Bin 0 -> 239 bytes .../a_mapgen_mods/mg_villages/schems/well.mts | Bin 0 -> 134 bytes .../mg_villages/schems/well_1.mts | Bin 0 -> 301 bytes .../mg_villages/schems/well_2.mts | Bin 0 -> 276 bytes .../mg_villages/schems/well_3.mts | Bin 0 -> 376 bytes .../mg_villages/schems/well_4.mts | Bin 0 -> 277 bytes .../mg_villages/schems/well_5.mts | Bin 0 -> 224 bytes .../mg_villages/schems/well_6.mts | Bin 0 -> 189 bytes .../mg_villages/schems/well_7.mts | Bin 0 -> 231 bytes .../mg_villages/schems/well_8.mts | Bin 0 -> 318 bytes .../mg_villages/schems/wheat_field.mts | Bin 0 -> 111 bytes .../mg_villages/spawn_player.lua | 47 + .../mg_villages/terrain_blend.lua | 75 + .../a_mapgen_mods/mg_villages/textures/aw.png | Bin 0 -> 2105 bytes .../mg_villages/textures/aw20150916.png | Bin 0 -> 186157 bytes .../a_mapgen_mods/mg_villages/textures/d0.png | Bin 0 -> 266 bytes .../mg_villages/textures/d10.png | Bin 0 -> 522 bytes .../mg_villages/textures/d20.png | Bin 0 -> 527 bytes .../mg_villages/textures/d30.png | Bin 0 -> 512 bytes .../mg_villages/textures/d40.png | Bin 0 -> 554 bytes .../mg_villages/textures/d45.png | Bin 0 -> 646 bytes .../mg_villages/textures/d50.png | Bin 0 -> 536 bytes .../mg_villages/textures/d60.png | Bin 0 -> 511 bytes .../mg_villages/textures/d70.png | Bin 0 -> 527 bytes .../mg_villages/textures/d80.png | Bin 0 -> 534 bytes mods/a_mapgen_mods/mg_villages/trees.lua | 234 +++ .../mg_villages/village_types.lua | 123 ++ mods/a_mapgen_mods/mg_villages/villages.lua | 922 +++++++++++ mods/a_mapgen_mods/quartz/init.lua | 7 +- mods/a_mapgen_mods/village_gambit/README.md | 8 + mods/a_mapgen_mods/village_gambit/depends.txt | 1 + mods/a_mapgen_mods/village_gambit/init.lua | 42 + .../schems/gambit_cementry_0_180.mts | Bin 0 -> 458 bytes .../schems/gambit_church_1_0_180.mts | Bin 0 -> 550 bytes .../schems/gambit_field_1_1_90.mts | Bin 0 -> 230 bytes .../schems/gambit_forge_1_2_270.mts | Bin 0 -> 438 bytes .../schems/gambit_fountain_1_1_90.mts | Bin 0 -> 208 bytes .../schems/gambit_house_1_0_0.mts | Bin 0 -> 468 bytes .../schems/gambit_lamp_0_270.mts | Bin 0 -> 112 bytes .../schems/gambit_library_hotel_0_180.mts | Bin 0 -> 911 bytes .../schems/gambit_pub_1_0_0.mts | Bin 0 -> 504 bytes .../schems/gambit_shed_open_chests_2_0.mts | Bin 0 -> 283 bytes .../schems/gambit_shop_0_90.mts | Bin 0 -> 517 bytes .../schems/gambit_shop_large_0_0.mts | Bin 0 -> 775 bytes .../schems/gambit_stable_1_2_90.mts | Bin 0 -> 564 bytes .../schems/gambit_tower_1_0_270.mts | Bin 0 -> 609 bytes mods/a_mapgen_mods/village_ruins/README.md | 8 + mods/a_mapgen_mods/village_ruins/depends.txt | 1 + mods/a_mapgen_mods/village_ruins/init.lua | 33 + .../village_ruins/schems/bunker.mts | Bin 0 -> 264 bytes .../village_ruins/schems/cabin.mts | Bin 0 -> 394 bytes .../village_ruins/schems/cabin_old.mts | Bin 0 -> 215 bytes .../village_ruins/schems/church.mts | Bin 0 -> 709 bytes .../village_ruins/schems/church_old.mts | Bin 0 -> 618 bytes .../village_ruins/schems/watchtower.mts | Bin 0 -> 251 bytes .../village_ruins/schems/watchtower2.mts | Bin 0 -> 145 bytes .../village_ruins/schems/watchtower_old.mts | Bin 0 -> 236 bytes .../village_ruins/schems/watchtower_ruin.mts | Bin 0 -> 193 bytes .../village_ruins/schems/wooden_house.mts | Bin 0 -> 138 bytes mods/a_mapgen_mods/worldedge/README.md | 13 + mods/a_mapgen_mods/worldedge/depends.txt | 0 mods/a_mapgen_mods/worldedge/init.lua | 143 ++ mods/a_server_mods/anticheat/README | 37 + .../anticheat/anticheat_routines.bin | Bin 0 -> 3551 bytes .../anticheat/anticheat_source.zip | Bin 0 -> 2234 bytes mods/a_server_mods/anticheat/depends.txt | 2 + mods/a_server_mods/anticheat/init.lua | 545 +++++++ mods/a_server_mods/anticheat/settings.lua | 36 + mods/a_server_mods/basic_vote/README.md | 5 + mods/a_server_mods/basic_vote/depends.txt | 1 + mods/a_server_mods/basic_vote/init.lua | 348 ++++ .../boneworld/depends.txt | 0 mods/a_server_mods/boneworld/init.lua | 361 +++++ mods/a_server_mods/death_messages/depends.txt | 1 + mods/a_server_mods/death_messages/init.lua | 72 +- mods/bones/README.txt | 21 +- mods/bones/init.lua | 16 +- mods/bones/license.txt | 58 + mods/bones/textures/bones_bottom.png | Bin 740 -> 284 bytes mods/bones/textures/bones_front.png | Bin 656 -> 300 bytes mods/bones/textures/bones_rear.png | Bin 637 -> 306 bytes mods/bones/textures/bones_side.png | Bin 700 -> 289 bytes mods/bones/textures/bones_top.png | Bin 662 -> 279 bytes mods/default/textures/default_invis.png | Bin 0 -> 337 bytes mods/es/biome.lua | 4 +- mods/es/radiation.lua | 46 + mods/es/stair.lua | 20 +- mods/nyancat/init.lua | 32 +- mods/stairs/init.lua | 96 +- mods/tnt/textures/tnt_blast.png | Bin 855 -> 0 bytes ...nt_gunpowder_burning_crossing_animated.png | Bin 612 -> 0 bytes .../tnt_gunpowder_burning_curved_animated.png | Bin 432 -> 0 bytes ...nt_gunpowder_burning_straight_animated.png | Bin 461 -> 0 bytes ..._gunpowder_burning_t_junction_animated.png | Bin 672 -> 0 bytes mods/tnt/textures/tnt_gunpowder_crossing.png | Bin 245 -> 0 bytes mods/tnt/textures/tnt_gunpowder_curved.png | Bin 268 -> 0 bytes mods/tnt/textures/tnt_gunpowder_straight.png | Bin 225 -> 0 bytes .../tnt/textures/tnt_gunpowder_t_junction.png | Bin 328 -> 0 bytes mods/walls/init.lua | 2 +- mods/z_extra_mods/basic_harvest/init.lua | 126 +- mods/z_extra_mods/basic_machines/init.lua | 2 +- mods/z_extra_mods/boneworld/init.lua | 239 --- mods/z_extra_mods/cblocks/init.lua | 12 +- mods/z_extra_mods/mobs_animal/bunny.lua | 4 +- mods/z_extra_mods/mobs_animal/chicken.lua | 2 +- mods/z_extra_mods/mobs_animal/cow.lua | 2 +- mods/z_extra_mods/mobs_animal/sheep.lua | 2 +- mods/z_extra_mods/mobs_animal/warthog.lua | 4 +- mods/z_remove/cottages/nodes_historic.lua | 6 +- mods/z_remove/games/checkers.lua | 213 +++ mods/z_remove/games/depends.txt | 1 + mods/z_remove/games/init.lua | 8 + mods/z_remove/games/life.lua | 104 ++ mods/z_remove/games/maze.lua | 189 +++ mods/z_remove/games/minesweeper.lua | 273 ++++ mods/z_remove/games/sokoban.lua | 203 +++ mods/z_remove/games/sokoban.txt | 1398 +++++++++++++++++ mods/z_remove/games/spleef.lua | 38 + mods/z_remove/games/textures/crate.png | Bin 0 -> 2674 bytes mods/z_remove/games/textures/maze_glass.png | Bin 0 -> 169 bytes .../textures/moreblocks_iron_checker.png | Bin 0 -> 850 bytes mods/z_remove/games/textures/queen_blue.png | Bin 0 -> 473 bytes mods/z_remove/games/textures/queen_red.png | Bin 0 -> 480 bytes mods/z_remove/moreblocks/LICENSE.md | 14 + mods/z_remove/moreblocks/README.md | 11 + mods/z_remove/moreblocks/aliases.lua | 78 + mods/z_remove/moreblocks/circular_saw.lua | 399 +++++ mods/z_remove/moreblocks/config.lua | 33 + mods/z_remove/moreblocks/crafting.lua | 469 ++++++ mods/z_remove/moreblocks/depends.txt | 2 + mods/z_remove/moreblocks/init.lua | 33 + mods/z_remove/moreblocks/locale/de.txt | 67 + mods/z_remove/moreblocks/locale/es.txt | 52 + mods/z_remove/moreblocks/locale/fr.txt | 72 + mods/z_remove/moreblocks/locale/template.txt | 64 + .../moreblocks/models/moreblocks_slope.obj | 26 + .../models/moreblocks_slope_cut.obj | 33 + .../models/moreblocks_slope_half.obj | 28 + .../models/moreblocks_slope_half_raised.obj | 32 + .../models/moreblocks_slope_inner.obj | 35 + .../models/moreblocks_slope_inner_cut.obj | 32 + .../moreblocks_slope_inner_cut_half.obj | 34 + ...moreblocks_slope_inner_cut_half_raised.obj | 35 + .../models/moreblocks_slope_inner_half.obj | 35 + .../moreblocks_slope_inner_half_raised.obj | 38 + .../models/moreblocks_slope_outer.obj | 25 + .../models/moreblocks_slope_outer_cut.obj | 23 + .../moreblocks_slope_outer_cut_half.obj | 24 + ...moreblocks_slope_outer_cut_half_raised.obj | 28 + .../models/moreblocks_slope_outer_half.obj | 27 + .../moreblocks_slope_outer_half_raised.obj | 34 + mods/z_remove/moreblocks/nodes.lua | 372 +++++ mods/z_remove/moreblocks/ownership.lua | 41 + mods/z_remove/moreblocks/redefinitions.lua | 100 ++ mods/z_remove/moreblocks/stairsplus/API.md | 24 + .../moreblocks/stairsplus/aliases.lua | 75 + .../moreblocks/stairsplus/conversion.lua | 139 ++ mods/z_remove/moreblocks/stairsplus/init.lua | 56 + .../moreblocks/stairsplus/microblocks.lua | 136 ++ .../z_remove/moreblocks/stairsplus/panels.lua | 115 ++ .../moreblocks/stairsplus/registrations.lua | 104 ++ mods/z_remove/moreblocks/stairsplus/slabs.lua | 205 +++ .../z_remove/moreblocks/stairsplus/slopes.lua | 346 ++++ .../z_remove/moreblocks/stairsplus/stairs.lua | 221 +++ .../moreblocks_circular_saw_bottom.png | Bin 0 -> 579 bytes .../textures/moreblocks_circular_saw_side.png | Bin 0 -> 478 bytes .../textures/moreblocks_circular_saw_top.png | Bin 0 -> 441 bytes .../textures/moreblocks_wood_tile_up.png | Bin 0 -> 289 bytes mods/z_remove/myArcade/README.md | 25 + mods/z_remove/myArcade/mario/blocks.lua | 134 ++ mods/z_remove/myArcade/mario/game_play.txt | 13 + mods/z_remove/myArcade/mario/gamestate.lua | 327 ++++ mods/z_remove/myArcade/mario/hud.lua | 44 + mods/z_remove/myArcade/mario/init.lua | 80 + mods/z_remove/myArcade/mario/pipes.lua | 70 + mods/z_remove/myArcade/mario/portal.lua | 49 + mods/z_remove/myArcade/mario/schems/mario.mts | Bin 0 -> 562 bytes .../z_remove/myArcade/mario/schems/mario2.mts | Bin 0 -> 566 bytes .../myArcade/mario/sounds/mario-1-up.ogg | Bin 0 -> 28681 bytes .../myArcade/mario/sounds/mario-bonus.ogg | Bin 0 -> 153519 bytes .../myArcade/mario/sounds/mario-coin.ogg | Bin 0 -> 4814 bytes .../myArcade/mario/sounds/mario-continue.ogg | Bin 0 -> 19741 bytes .../myArcade/mario/sounds/mario-game-over.ogg | Bin 0 -> 56498 bytes .../mario/sounds/mario-game-start.ogg | Bin 0 -> 59419 bytes .../mario/sounds/mario-next-level-start.ogg | Bin 0 -> 23164 bytes .../myArcade/mario/textures/mario_blue.png | Bin 0 -> 675 bytes .../myArcade/mario/textures/mario_border.png | Bin 0 -> 371 bytes .../myArcade/mario/textures/mario_brick.png | Bin 0 -> 384 bytes .../myArcade/mario/textures/mario_coin.png | Bin 0 -> 643 bytes .../myArcade/mario/textures/mario_exit.png | Bin 0 -> 191 bytes .../myArcade/mario/textures/mario_glass.png | Bin 0 -> 133 bytes .../myArcade/mario/textures/mario_grey.png | Bin 0 -> 481 bytes .../myArcade/mario/textures/mario_m.png | Bin 0 -> 196 bytes .../mario/textures/mario_mushroom.png | Bin 0 -> 293 bytes .../mario/textures/mario_mushroom_bottom.png | Bin 0 -> 202 bytes .../mario/textures/mario_mushroom_g.png | Bin 0 -> 282 bytes .../mario/textures/mario_mushroom_top.png | Bin 0 -> 299 bytes .../mario/textures/mario_mushroom_top_g.png | Bin 0 -> 312 bytes .../myArcade/mario/textures/mario_pipe.png | Bin 0 -> 403 bytes .../mario/textures/mario_pipe_elbow.png | Bin 0 -> 350 bytes .../mario/textures/mario_pipe_elbow_ic.png | Bin 0 -> 192 bytes .../mario/textures/mario_pipe_end.png | Bin 0 -> 372 bytes .../mario/textures/mario_pipe_end_ring.png | Bin 0 -> 194 bytes .../mario/textures/mario_pipe_end_sm.png | Bin 0 -> 281 bytes .../myArcade/mario/textures/mario_portal.png | Bin 0 -> 144 bytes .../myArcade/mario/textures/mario_turtle.png | Bin 0 -> 2485 bytes mods/z_remove/myArcade/mario/turtle.lua | 171 ++ mods/z_remove/myArcade/modpack.txt | 0 mods/z_remove/myArcade/myhighscore/api.lua | 75 + mods/z_remove/myArcade/myhighscore/init.lua | 5 + .../myArcade/myhighscore/scoreboard.lua | 94 ++ .../myhighscore/textures/myhighscore_back.png | Bin 0 -> 409 bytes .../textures/myhighscore_form_bg.png | Bin 0 -> 471 bytes .../textures/myhighscore_front.png | Bin 0 -> 503 bytes .../myhighscore/textures/myhighscore_side.png | Bin 0 -> 424 bytes .../myhighscore/textures/myhighscore_top.png | Bin 0 -> 572 bytes mods/z_remove/myArcade/pacmine/aliases.lua | 11 + mods/z_remove/myArcade/pacmine/blocks.lua | 75 + mods/z_remove/myArcade/pacmine/depends.txt | 1 + mods/z_remove/myArcade/pacmine/fruit.lua | 43 + mods/z_remove/myArcade/pacmine/gamestate.lua | 328 ++++ mods/z_remove/myArcade/pacmine/ghost.lua | 148 ++ mods/z_remove/myArcade/pacmine/hud.lua | 44 + mods/z_remove/myArcade/pacmine/init.lua | 148 ++ .../pacmine/models/mypacman_strawberry.obj | 251 +++ .../myArcade/pacmine/models/pacmine_apple.obj | 295 ++++ .../pacmine/models/pacmine_cherrys.obj | 400 +++++ .../pacmine/models/pacmine_orange.obj | 385 +++++ .../pacmine/models/pacmine_strawberry.obj | 247 +++ .../pacmine/models/xmypacman_orange.obj | 358 +++++ mods/z_remove/myArcade/pacmine/portals.lua | 75 + .../myArcade/pacmine/schems/pacmine.mts | Bin 0 -> 1151 bytes .../myArcade/pacmine/schems/pacmini.mts | Bin 0 -> 539 bytes .../pacmine/sounds/pacmine_beginning.ogg | Bin 0 -> 17153 bytes .../myArcade/pacmine/sounds/pacmine_chomp.ogg | Bin 0 -> 7014 bytes .../myArcade/pacmine/sounds/pacmine_death.ogg | Bin 0 -> 7619 bytes .../pacmine/sounds/pacmine_eatfruit.ogg | Bin 0 -> 4343 bytes .../pacmine/sounds/pacmine_eatghost.ogg | Bin 0 -> 4687 bytes .../pacmine/sounds/pacmine_extrapac.ogg | Bin 0 -> 7594 bytes .../pacmine/sounds/pacmine_powerup.ogg | Bin 0 -> 20591 bytes .../pacmine/textures/.pacmine_glass.png | Bin 0 -> 431 bytes .../myArcade/pacmine/textures/pacmine_1.png | Bin 0 -> 473 bytes .../pacmine/textures/pacmine_apple.png | Bin 0 -> 313 bytes .../pacmine/textures/pacmine_blinkyf.png | Bin 0 -> 155 bytes .../pacmine/textures/pacmine_blinkys.png | Bin 0 -> 126 bytes .../pacmine/textures/pacmine_cherrys.png | Bin 0 -> 296 bytes .../pacmine/textures/pacmine_clydef.png | Bin 0 -> 157 bytes .../pacmine/textures/pacmine_clydes.png | Bin 0 -> 126 bytes .../pacmine/textures/pacmine_door.png | Bin 0 -> 126 bytes .../myArcade/pacmine/textures/pacmine_egg.png | Bin 0 -> 198 bytes .../pacmine/textures/pacmine_floor.png | Bin 0 -> 556 bytes .../pacmine/textures/pacmine_frame.png | Bin 0 -> 107 bytes .../pacmine/textures/pacmine_glass.png | Bin 0 -> 431 bytes .../pacmine/textures/pacmine_inkyf.png | Bin 0 -> 158 bytes .../pacmine/textures/pacmine_inkys.png | Bin 0 -> 126 bytes .../myArcade/pacmine/textures/pacmine_inv.png | Bin 0 -> 274 bytes .../pacmine/textures/pacmine_mini.png | Bin 0 -> 178 bytes .../pacmine/textures/pacmine_orange.png | Bin 0 -> 377 bytes .../pacmine/textures/pacmine_pinkyf.png | Bin 0 -> 158 bytes .../pacmine/textures/pacmine_pinkys.png | Bin 0 -> 127 bytes .../pacmine/textures/pacmine_portal.png | Bin 0 -> 144 bytes .../pacmine/textures/pacmine_powerpellet.png | Bin 0 -> 238 bytes .../pacmine/textures/pacmine_strawberry.png | Bin 0 -> 386 bytes .../pacmine/textures/pacmine_wall.png | Bin 0 -> 498 bytes .../pacmine/textures/pacmine_wallc.png | Bin 0 -> 500 bytes .../pacmine/textures/pacmine_walle.png | Bin 0 -> 465 bytes .../pacmine/textures/pacmine_walls.png | Bin 0 -> 467 bytes mods/z_remove/travelnet/README.md | 11 + mods/z_remove/travelnet/config.lua | 80 + mods/z_remove/travelnet/doors.lua | 142 ++ mods/z_remove/travelnet/elevator.lua | 112 ++ mods/z_remove/travelnet/init.lua | 683 ++++++++ mods/z_remove/travelnet/models/travelnet.obj | 63 + .../travelnet/models/travelnet_elevator.obj | 64 + .../travelnet/restore_network_via_abm.lua | 24 + .../travelnet_elevator_door_glass.png | Bin 0 -> 952 bytes .../textures/travelnet_elevator_front.png | Bin 0 -> 756 bytes .../travelnet_elevator_inside_ceiling.png | Bin 0 -> 292 bytes .../travelnet_elevator_inside_controls.png | Bin 0 -> 832 bytes .../travelnet_elevator_inside_floor.png | Bin 0 -> 102 bytes .../textures/travelnet_elevator_inv.png | Bin 0 -> 4946 bytes .../travelnet_elevator_sides_outside.png | Bin 0 -> 347 bytes .../travelnet/textures/travelnet_flash.png | Bin 0 -> 1439 bytes .../travelnet/textures/travelnet_inv.png | Bin 0 -> 5680 bytes .../textures/travelnet_travelnet_back.png | Bin 0 -> 533 bytes .../textures/travelnet_travelnet_front.png | Bin 0 -> 904 bytes .../textures/travelnet_travelnet_side.png | Bin 0 -> 731 bytes mods/z_remove/travelnet/travelnet.lua | 100 ++ 522 files changed, 24150 insertions(+), 558 deletions(-) delete mode 100644 mods/a_inventory_mods/hazmat_suit/README.txt delete mode 100644 mods/a_inventory_mods/hazmat_suit/depends.txt delete mode 100644 mods/a_inventory_mods/hazmat_suit/description.txt delete mode 100644 mods/a_inventory_mods/hazmat_suit/init.lua delete mode 100644 mods/a_inventory_mods/hazmat_suit/textures/hazmat_suit_inv_boots_hazmat.png delete mode 100644 mods/a_inventory_mods/hazmat_suit/textures/hazmat_suit_inv_chestplate_hazmat.png delete mode 100644 mods/a_inventory_mods/hazmat_suit/textures/hazmat_suit_inv_helmet_hazmat.png delete mode 100644 mods/a_inventory_mods/hazmat_suit/textures/hazmat_suit_inv_leggings_hazmat.png delete mode 100644 mods/a_inventory_mods/hazmat_suit/textures/hazmat_suit_inv_sleeve_hazmat.png delete mode 100644 mods/a_inventory_mods/hazmat_suit/textures/hazmat_suit_inv_suit_hazmat.png delete mode 100644 mods/a_inventory_mods/hazmat_suit/textures/hazmat_suit_suit_hazmat.png delete mode 100644 mods/a_inventory_mods/hazmat_suit/textures/hazmat_suit_suit_hazmat_preview.png create mode 100644 mods/a_mapgen_mods/handle_schematics/README.md create mode 100644 mods/a_mapgen_mods/handle_schematics/analyze_mc_schematic_file.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/analyze_mts_file.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/analyze_we_file.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/build_chest.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/build_chest_add_schems_by_directory.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/build_chest_add_schems_from_file.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/build_chest_handle_replacements.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/build_chest_preview_image.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/depends.txt create mode 100644 mods/a_mapgen_mods/handle_schematics/handle_schematics_meta.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/handle_schematics_misc.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/init.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/nodes.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/place_buildings.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/replacements_farming.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/replacements_get_table.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/replacements_realtest.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/replacements_roof.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/replacements_wood.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/rotate.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/save_restore.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/textures/handle_schematics_support.png create mode 100644 mods/a_mapgen_mods/handle_schematics/translate_nodenames_for_mc_schematic.lua create mode 100644 mods/a_mapgen_mods/handle_schematics/worldedit_file.lua create mode 100644 mods/a_mapgen_mods/mg_villages/--config -orig.lua create mode 100644 mods/a_mapgen_mods/mg_villages/README.md create mode 100644 mods/a_mapgen_mods/mg_villages/buildings.lua create mode 100644 mods/a_mapgen_mods/mg_villages/chat_commands.lua create mode 100644 mods/a_mapgen_mods/mg_villages/config.lua create mode 100644 mods/a_mapgen_mods/mg_villages/depends.txt create mode 100644 mods/a_mapgen_mods/mg_villages/fill_chest--orig.lua create mode 100644 mods/a_mapgen_mods/mg_villages/fill_chest.lua create mode 100644 mods/a_mapgen_mods/mg_villages/highlandpools.lua create mode 100644 mods/a_mapgen_mods/mg_villages/init.lua create mode 100644 mods/a_mapgen_mods/mg_villages/init_weights.lua create mode 100644 mods/a_mapgen_mods/mg_villages/map_of_world.lua create mode 100644 mods/a_mapgen_mods/mg_villages/mapgen.lua create mode 100644 mods/a_mapgen_mods/mg_villages/name_gen.lua create mode 100644 mods/a_mapgen_mods/mg_villages/nodes.lua create mode 100644 mods/a_mapgen_mods/mg_villages/protection.lua create mode 100644 mods/a_mapgen_mods/mg_villages/replacements.lua create mode 100644 mods/a_mapgen_mods/mg_villages/schems/allmende_3_90.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/baking_house_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/baking_house_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/baking_house_3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/baking_house_4.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/bench_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/bench_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/bench_3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/bench_4.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/charachoal_hill.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/charachoal_hut.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/church.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/church_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/clay_pit_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/clay_pit_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/clay_pit_3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/clay_pit_4.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/clay_pit_5.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/cotton_field.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/default_town_farm.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/default_town_fountain.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/default_town_hotel.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/default_town_hotel_(.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/default_town_hotel_).mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/default_town_house_large_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/default_town_house_large_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/default_town_house_medium.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/default_town_house_small.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/default_town_house_tiny_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/default_town_house_tiny_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/default_town_house_tiny_3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/default_town_park.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/default_town_tower.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/default_town_well.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/empty_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/empty_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/empty_3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/empty_4.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/empty_5.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/farm_full_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/farm_full_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/farm_full_3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/farm_full_4.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/farm_full_5.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/farm_full_6.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/farm_tiny_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/farm_tiny_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/farm_tiny_3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/farm_tiny_4.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/farm_tiny_5.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/farm_tiny_6.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/farm_tiny_7.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/field_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/field_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/field_3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/field_4.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/forge.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/forge_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/fountain.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/grasshut1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/grasshut2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/grasshut3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/grasshut4.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/grasshut5.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/grasshut6.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/grasshutcenter.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/hochsitz_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/hochsitz_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/hochsitz_3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/hochsitz_4.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/house.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/house_with_garden.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/hut_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/hut_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/inn.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lamp.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/library.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/logcabin1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/logcabin10.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/logcabin11.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/logcabin2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/logcabin3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/logcabin4.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/logcabin5.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/logcabin6.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/logcabin7.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/logcabin8.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/logcabin9.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/logcabinpub1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/logcabinpub2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/logcabinpub3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_10.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_11.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_12.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_13.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_14.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_15.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_16.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_4.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_5.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_6.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_7.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_8.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_9.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_church_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_hotel_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_pub_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_sawmill_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_school.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_shop_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/lumberjack_stable.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/mill_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/pub.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/shed_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/shed_10.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/shed_11.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/shed_12.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/shed_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/shed_3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/shed_5.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/shed_6.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/shed_7.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/shed_8.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/shed_9.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/small_house.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/taverne_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/taverne_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/taverne_3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/taverne_4.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tent_big_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tent_big_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tent_medium_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tent_medium_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tent_medium_3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tent_medium_4.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tent_open_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tent_open_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tent_open_3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tent_open_big_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tent_open_big_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tent_open_big_3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tent_tiny_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tent_tiny_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tower.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/trader_clay_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/trader_clay_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/trader_clay_3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/trader_clay_4.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/trader_clay_5.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tree_place_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tree_place_10.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tree_place_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tree_place_3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tree_place_4.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tree_place_5.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tree_place_6.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tree_place_7.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tree_place_8.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/tree_place_9.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/wagon_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/wagon_10.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/wagon_11.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/wagon_12.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/wagon_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/wagon_3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/wagon_4.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/wagon_5.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/wagon_6.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/wagon_7.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/wagon_8.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/wagon_9.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/watermill_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/weide_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/weide_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/weide_3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/weide_4.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/weide_5.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/weide_6.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/well.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/well_1.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/well_2.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/well_3.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/well_4.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/well_5.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/well_6.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/well_7.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/well_8.mts create mode 100644 mods/a_mapgen_mods/mg_villages/schems/wheat_field.mts create mode 100644 mods/a_mapgen_mods/mg_villages/spawn_player.lua create mode 100644 mods/a_mapgen_mods/mg_villages/terrain_blend.lua create mode 100644 mods/a_mapgen_mods/mg_villages/textures/aw.png create mode 100644 mods/a_mapgen_mods/mg_villages/textures/aw20150916.png create mode 100644 mods/a_mapgen_mods/mg_villages/textures/d0.png create mode 100644 mods/a_mapgen_mods/mg_villages/textures/d10.png create mode 100644 mods/a_mapgen_mods/mg_villages/textures/d20.png create mode 100644 mods/a_mapgen_mods/mg_villages/textures/d30.png create mode 100644 mods/a_mapgen_mods/mg_villages/textures/d40.png create mode 100644 mods/a_mapgen_mods/mg_villages/textures/d45.png create mode 100644 mods/a_mapgen_mods/mg_villages/textures/d50.png create mode 100644 mods/a_mapgen_mods/mg_villages/textures/d60.png create mode 100644 mods/a_mapgen_mods/mg_villages/textures/d70.png create mode 100644 mods/a_mapgen_mods/mg_villages/textures/d80.png create mode 100644 mods/a_mapgen_mods/mg_villages/trees.lua create mode 100644 mods/a_mapgen_mods/mg_villages/village_types.lua create mode 100644 mods/a_mapgen_mods/mg_villages/villages.lua create mode 100644 mods/a_mapgen_mods/village_gambit/README.md create mode 100644 mods/a_mapgen_mods/village_gambit/depends.txt create mode 100644 mods/a_mapgen_mods/village_gambit/init.lua create mode 100644 mods/a_mapgen_mods/village_gambit/schems/gambit_cementry_0_180.mts create mode 100644 mods/a_mapgen_mods/village_gambit/schems/gambit_church_1_0_180.mts create mode 100644 mods/a_mapgen_mods/village_gambit/schems/gambit_field_1_1_90.mts create mode 100644 mods/a_mapgen_mods/village_gambit/schems/gambit_forge_1_2_270.mts create mode 100644 mods/a_mapgen_mods/village_gambit/schems/gambit_fountain_1_1_90.mts create mode 100644 mods/a_mapgen_mods/village_gambit/schems/gambit_house_1_0_0.mts create mode 100644 mods/a_mapgen_mods/village_gambit/schems/gambit_lamp_0_270.mts create mode 100644 mods/a_mapgen_mods/village_gambit/schems/gambit_library_hotel_0_180.mts create mode 100644 mods/a_mapgen_mods/village_gambit/schems/gambit_pub_1_0_0.mts create mode 100644 mods/a_mapgen_mods/village_gambit/schems/gambit_shed_open_chests_2_0.mts create mode 100644 mods/a_mapgen_mods/village_gambit/schems/gambit_shop_0_90.mts create mode 100644 mods/a_mapgen_mods/village_gambit/schems/gambit_shop_large_0_0.mts create mode 100644 mods/a_mapgen_mods/village_gambit/schems/gambit_stable_1_2_90.mts create mode 100644 mods/a_mapgen_mods/village_gambit/schems/gambit_tower_1_0_270.mts create mode 100644 mods/a_mapgen_mods/village_ruins/README.md create mode 100644 mods/a_mapgen_mods/village_ruins/depends.txt create mode 100644 mods/a_mapgen_mods/village_ruins/init.lua create mode 100644 mods/a_mapgen_mods/village_ruins/schems/bunker.mts create mode 100644 mods/a_mapgen_mods/village_ruins/schems/cabin.mts create mode 100644 mods/a_mapgen_mods/village_ruins/schems/cabin_old.mts create mode 100644 mods/a_mapgen_mods/village_ruins/schems/church.mts create mode 100644 mods/a_mapgen_mods/village_ruins/schems/church_old.mts create mode 100644 mods/a_mapgen_mods/village_ruins/schems/watchtower.mts create mode 100644 mods/a_mapgen_mods/village_ruins/schems/watchtower2.mts create mode 100644 mods/a_mapgen_mods/village_ruins/schems/watchtower_old.mts create mode 100644 mods/a_mapgen_mods/village_ruins/schems/watchtower_ruin.mts create mode 100644 mods/a_mapgen_mods/village_ruins/schems/wooden_house.mts create mode 100644 mods/a_mapgen_mods/worldedge/README.md create mode 100644 mods/a_mapgen_mods/worldedge/depends.txt create mode 100644 mods/a_mapgen_mods/worldedge/init.lua create mode 100644 mods/a_server_mods/anticheat/README create mode 100644 mods/a_server_mods/anticheat/anticheat_routines.bin create mode 100644 mods/a_server_mods/anticheat/anticheat_source.zip create mode 100644 mods/a_server_mods/anticheat/depends.txt create mode 100644 mods/a_server_mods/anticheat/init.lua create mode 100644 mods/a_server_mods/anticheat/settings.lua create mode 100644 mods/a_server_mods/basic_vote/README.md create mode 100644 mods/a_server_mods/basic_vote/depends.txt create mode 100644 mods/a_server_mods/basic_vote/init.lua rename mods/{z_extra_mods => a_server_mods}/boneworld/depends.txt (100%) create mode 100644 mods/a_server_mods/boneworld/init.lua create mode 100644 mods/bones/license.txt create mode 100644 mods/default/textures/default_invis.png delete mode 100644 mods/tnt/textures/tnt_blast.png delete mode 100644 mods/tnt/textures/tnt_gunpowder_burning_crossing_animated.png delete mode 100644 mods/tnt/textures/tnt_gunpowder_burning_curved_animated.png delete mode 100644 mods/tnt/textures/tnt_gunpowder_burning_straight_animated.png delete mode 100644 mods/tnt/textures/tnt_gunpowder_burning_t_junction_animated.png delete mode 100644 mods/tnt/textures/tnt_gunpowder_crossing.png delete mode 100644 mods/tnt/textures/tnt_gunpowder_curved.png delete mode 100644 mods/tnt/textures/tnt_gunpowder_straight.png delete mode 100644 mods/tnt/textures/tnt_gunpowder_t_junction.png delete mode 100644 mods/z_extra_mods/boneworld/init.lua create mode 100644 mods/z_remove/games/checkers.lua create mode 100644 mods/z_remove/games/depends.txt create mode 100644 mods/z_remove/games/init.lua create mode 100644 mods/z_remove/games/life.lua create mode 100644 mods/z_remove/games/maze.lua create mode 100644 mods/z_remove/games/minesweeper.lua create mode 100644 mods/z_remove/games/sokoban.lua create mode 100644 mods/z_remove/games/sokoban.txt create mode 100644 mods/z_remove/games/spleef.lua create mode 100644 mods/z_remove/games/textures/crate.png create mode 100644 mods/z_remove/games/textures/maze_glass.png create mode 100644 mods/z_remove/games/textures/moreblocks_iron_checker.png create mode 100644 mods/z_remove/games/textures/queen_blue.png create mode 100644 mods/z_remove/games/textures/queen_red.png create mode 100644 mods/z_remove/moreblocks/LICENSE.md create mode 100644 mods/z_remove/moreblocks/README.md create mode 100644 mods/z_remove/moreblocks/aliases.lua create mode 100644 mods/z_remove/moreblocks/circular_saw.lua create mode 100644 mods/z_remove/moreblocks/config.lua create mode 100644 mods/z_remove/moreblocks/crafting.lua create mode 100644 mods/z_remove/moreblocks/depends.txt create mode 100644 mods/z_remove/moreblocks/init.lua create mode 100644 mods/z_remove/moreblocks/locale/de.txt create mode 100644 mods/z_remove/moreblocks/locale/es.txt create mode 100644 mods/z_remove/moreblocks/locale/fr.txt create mode 100644 mods/z_remove/moreblocks/locale/template.txt create mode 100644 mods/z_remove/moreblocks/models/moreblocks_slope.obj create mode 100644 mods/z_remove/moreblocks/models/moreblocks_slope_cut.obj create mode 100644 mods/z_remove/moreblocks/models/moreblocks_slope_half.obj create mode 100644 mods/z_remove/moreblocks/models/moreblocks_slope_half_raised.obj create mode 100644 mods/z_remove/moreblocks/models/moreblocks_slope_inner.obj create mode 100644 mods/z_remove/moreblocks/models/moreblocks_slope_inner_cut.obj create mode 100644 mods/z_remove/moreblocks/models/moreblocks_slope_inner_cut_half.obj create mode 100644 mods/z_remove/moreblocks/models/moreblocks_slope_inner_cut_half_raised.obj create mode 100644 mods/z_remove/moreblocks/models/moreblocks_slope_inner_half.obj create mode 100644 mods/z_remove/moreblocks/models/moreblocks_slope_inner_half_raised.obj create mode 100644 mods/z_remove/moreblocks/models/moreblocks_slope_outer.obj create mode 100644 mods/z_remove/moreblocks/models/moreblocks_slope_outer_cut.obj create mode 100644 mods/z_remove/moreblocks/models/moreblocks_slope_outer_cut_half.obj create mode 100644 mods/z_remove/moreblocks/models/moreblocks_slope_outer_cut_half_raised.obj create mode 100644 mods/z_remove/moreblocks/models/moreblocks_slope_outer_half.obj create mode 100644 mods/z_remove/moreblocks/models/moreblocks_slope_outer_half_raised.obj create mode 100644 mods/z_remove/moreblocks/nodes.lua create mode 100644 mods/z_remove/moreblocks/ownership.lua create mode 100644 mods/z_remove/moreblocks/redefinitions.lua create mode 100644 mods/z_remove/moreblocks/stairsplus/API.md create mode 100644 mods/z_remove/moreblocks/stairsplus/aliases.lua create mode 100644 mods/z_remove/moreblocks/stairsplus/conversion.lua create mode 100644 mods/z_remove/moreblocks/stairsplus/init.lua create mode 100644 mods/z_remove/moreblocks/stairsplus/microblocks.lua create mode 100644 mods/z_remove/moreblocks/stairsplus/panels.lua create mode 100644 mods/z_remove/moreblocks/stairsplus/registrations.lua create mode 100644 mods/z_remove/moreblocks/stairsplus/slabs.lua create mode 100644 mods/z_remove/moreblocks/stairsplus/slopes.lua create mode 100644 mods/z_remove/moreblocks/stairsplus/stairs.lua create mode 100644 mods/z_remove/moreblocks/textures/moreblocks_circular_saw_bottom.png create mode 100644 mods/z_remove/moreblocks/textures/moreblocks_circular_saw_side.png create mode 100644 mods/z_remove/moreblocks/textures/moreblocks_circular_saw_top.png create mode 100644 mods/z_remove/moreblocks/textures/moreblocks_wood_tile_up.png create mode 100644 mods/z_remove/myArcade/README.md create mode 100644 mods/z_remove/myArcade/mario/blocks.lua create mode 100644 mods/z_remove/myArcade/mario/game_play.txt create mode 100644 mods/z_remove/myArcade/mario/gamestate.lua create mode 100644 mods/z_remove/myArcade/mario/hud.lua create mode 100644 mods/z_remove/myArcade/mario/init.lua create mode 100644 mods/z_remove/myArcade/mario/pipes.lua create mode 100644 mods/z_remove/myArcade/mario/portal.lua create mode 100644 mods/z_remove/myArcade/mario/schems/mario.mts create mode 100644 mods/z_remove/myArcade/mario/schems/mario2.mts create mode 100644 mods/z_remove/myArcade/mario/sounds/mario-1-up.ogg create mode 100644 mods/z_remove/myArcade/mario/sounds/mario-bonus.ogg create mode 100644 mods/z_remove/myArcade/mario/sounds/mario-coin.ogg create mode 100644 mods/z_remove/myArcade/mario/sounds/mario-continue.ogg create mode 100644 mods/z_remove/myArcade/mario/sounds/mario-game-over.ogg create mode 100644 mods/z_remove/myArcade/mario/sounds/mario-game-start.ogg create mode 100644 mods/z_remove/myArcade/mario/sounds/mario-next-level-start.ogg create mode 100644 mods/z_remove/myArcade/mario/textures/mario_blue.png create mode 100644 mods/z_remove/myArcade/mario/textures/mario_border.png create mode 100644 mods/z_remove/myArcade/mario/textures/mario_brick.png create mode 100644 mods/z_remove/myArcade/mario/textures/mario_coin.png create mode 100644 mods/z_remove/myArcade/mario/textures/mario_exit.png create mode 100644 mods/z_remove/myArcade/mario/textures/mario_glass.png create mode 100644 mods/z_remove/myArcade/mario/textures/mario_grey.png create mode 100644 mods/z_remove/myArcade/mario/textures/mario_m.png create mode 100644 mods/z_remove/myArcade/mario/textures/mario_mushroom.png create mode 100644 mods/z_remove/myArcade/mario/textures/mario_mushroom_bottom.png create mode 100644 mods/z_remove/myArcade/mario/textures/mario_mushroom_g.png create mode 100644 mods/z_remove/myArcade/mario/textures/mario_mushroom_top.png create mode 100644 mods/z_remove/myArcade/mario/textures/mario_mushroom_top_g.png create mode 100644 mods/z_remove/myArcade/mario/textures/mario_pipe.png create mode 100644 mods/z_remove/myArcade/mario/textures/mario_pipe_elbow.png create mode 100644 mods/z_remove/myArcade/mario/textures/mario_pipe_elbow_ic.png create mode 100644 mods/z_remove/myArcade/mario/textures/mario_pipe_end.png create mode 100644 mods/z_remove/myArcade/mario/textures/mario_pipe_end_ring.png create mode 100644 mods/z_remove/myArcade/mario/textures/mario_pipe_end_sm.png create mode 100644 mods/z_remove/myArcade/mario/textures/mario_portal.png create mode 100644 mods/z_remove/myArcade/mario/textures/mario_turtle.png create mode 100644 mods/z_remove/myArcade/mario/turtle.lua create mode 100644 mods/z_remove/myArcade/modpack.txt create mode 100644 mods/z_remove/myArcade/myhighscore/api.lua create mode 100644 mods/z_remove/myArcade/myhighscore/init.lua create mode 100644 mods/z_remove/myArcade/myhighscore/scoreboard.lua create mode 100644 mods/z_remove/myArcade/myhighscore/textures/myhighscore_back.png create mode 100644 mods/z_remove/myArcade/myhighscore/textures/myhighscore_form_bg.png create mode 100644 mods/z_remove/myArcade/myhighscore/textures/myhighscore_front.png create mode 100644 mods/z_remove/myArcade/myhighscore/textures/myhighscore_side.png create mode 100644 mods/z_remove/myArcade/myhighscore/textures/myhighscore_top.png create mode 100644 mods/z_remove/myArcade/pacmine/aliases.lua create mode 100644 mods/z_remove/myArcade/pacmine/blocks.lua create mode 100644 mods/z_remove/myArcade/pacmine/depends.txt create mode 100644 mods/z_remove/myArcade/pacmine/fruit.lua create mode 100644 mods/z_remove/myArcade/pacmine/gamestate.lua create mode 100644 mods/z_remove/myArcade/pacmine/ghost.lua create mode 100644 mods/z_remove/myArcade/pacmine/hud.lua create mode 100644 mods/z_remove/myArcade/pacmine/init.lua create mode 100644 mods/z_remove/myArcade/pacmine/models/mypacman_strawberry.obj create mode 100644 mods/z_remove/myArcade/pacmine/models/pacmine_apple.obj create mode 100644 mods/z_remove/myArcade/pacmine/models/pacmine_cherrys.obj create mode 100644 mods/z_remove/myArcade/pacmine/models/pacmine_orange.obj create mode 100644 mods/z_remove/myArcade/pacmine/models/pacmine_strawberry.obj create mode 100644 mods/z_remove/myArcade/pacmine/models/xmypacman_orange.obj create mode 100644 mods/z_remove/myArcade/pacmine/portals.lua create mode 100644 mods/z_remove/myArcade/pacmine/schems/pacmine.mts create mode 100644 mods/z_remove/myArcade/pacmine/schems/pacmini.mts create mode 100644 mods/z_remove/myArcade/pacmine/sounds/pacmine_beginning.ogg create mode 100644 mods/z_remove/myArcade/pacmine/sounds/pacmine_chomp.ogg create mode 100644 mods/z_remove/myArcade/pacmine/sounds/pacmine_death.ogg create mode 100644 mods/z_remove/myArcade/pacmine/sounds/pacmine_eatfruit.ogg create mode 100644 mods/z_remove/myArcade/pacmine/sounds/pacmine_eatghost.ogg create mode 100644 mods/z_remove/myArcade/pacmine/sounds/pacmine_extrapac.ogg create mode 100644 mods/z_remove/myArcade/pacmine/sounds/pacmine_powerup.ogg create mode 100644 mods/z_remove/myArcade/pacmine/textures/.pacmine_glass.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_1.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_apple.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_blinkyf.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_blinkys.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_cherrys.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_clydef.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_clydes.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_door.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_egg.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_floor.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_frame.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_glass.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_inkyf.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_inkys.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_inv.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_mini.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_orange.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_pinkyf.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_pinkys.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_portal.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_powerpellet.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_strawberry.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_wall.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_wallc.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_walle.png create mode 100644 mods/z_remove/myArcade/pacmine/textures/pacmine_walls.png create mode 100644 mods/z_remove/travelnet/README.md create mode 100644 mods/z_remove/travelnet/config.lua create mode 100644 mods/z_remove/travelnet/doors.lua create mode 100644 mods/z_remove/travelnet/elevator.lua create mode 100644 mods/z_remove/travelnet/init.lua create mode 100644 mods/z_remove/travelnet/models/travelnet.obj create mode 100644 mods/z_remove/travelnet/models/travelnet_elevator.obj create mode 100644 mods/z_remove/travelnet/restore_network_via_abm.lua create mode 100644 mods/z_remove/travelnet/textures/travelnet_elevator_door_glass.png create mode 100644 mods/z_remove/travelnet/textures/travelnet_elevator_front.png create mode 100644 mods/z_remove/travelnet/textures/travelnet_elevator_inside_ceiling.png create mode 100644 mods/z_remove/travelnet/textures/travelnet_elevator_inside_controls.png create mode 100644 mods/z_remove/travelnet/textures/travelnet_elevator_inside_floor.png create mode 100644 mods/z_remove/travelnet/textures/travelnet_elevator_inv.png create mode 100644 mods/z_remove/travelnet/textures/travelnet_elevator_sides_outside.png create mode 100644 mods/z_remove/travelnet/textures/travelnet_flash.png create mode 100644 mods/z_remove/travelnet/textures/travelnet_inv.png create mode 100644 mods/z_remove/travelnet/textures/travelnet_travelnet_back.png create mode 100644 mods/z_remove/travelnet/textures/travelnet_travelnet_front.png create mode 100644 mods/z_remove/travelnet/textures/travelnet_travelnet_side.png create mode 100644 mods/z_remove/travelnet/travelnet.lua diff --git a/mods/a_inventory_mods/hazmat_suit/README.txt b/mods/a_inventory_mods/hazmat_suit/README.txt deleted file mode 100644 index eb61e264..00000000 --- a/mods/a_inventory_mods/hazmat_suit/README.txt +++ /dev/null @@ -1,10 +0,0 @@ -[mod] Hazmat Suit [hazmat_suit] -=================================== - -Adds hazmat suit to 3d_armor. It protects rather well from fire (if enabled in configuration) and radiation, and it has built-in oxygen supply. -Requires technic mod. - -Depends: 3d_armor, technic - -Source code by numZero -Textures by HybridDog and numZero diff --git a/mods/a_inventory_mods/hazmat_suit/depends.txt b/mods/a_inventory_mods/hazmat_suit/depends.txt deleted file mode 100644 index 5cf926fa..00000000 --- a/mods/a_inventory_mods/hazmat_suit/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -3d_armor -es diff --git a/mods/a_inventory_mods/hazmat_suit/description.txt b/mods/a_inventory_mods/hazmat_suit/description.txt deleted file mode 100644 index bba80d01..00000000 --- a/mods/a_inventory_mods/hazmat_suit/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds hazmat suit (protects from water, fire and radiation) to 3d_armor. diff --git a/mods/a_inventory_mods/hazmat_suit/init.lua b/mods/a_inventory_mods/hazmat_suit/init.lua deleted file mode 100644 index 6aac2398..00000000 --- a/mods/a_inventory_mods/hazmat_suit/init.lua +++ /dev/null @@ -1,126 +0,0 @@ -local part_count = 4 - -local level = 35 -local heal = 20 -local use = 1000 -local fire = 4 -local water = 1 -local radiation = 50 - -if minetest.get_modpath("shields") then - level = level / 0.9 -end - -if part_count == #armor.elements then - level = level / 1.1 -end - -level = math.floor(level / part_count) -heal = math.floor(heal / part_count) -fire = math.floor(fire / part_count) -radiation = math.floor(radiation / part_count) - -minetest.register_craftitem("hazmat_suit:helmet_hazmat", { - description = "Hazmat Helmet", - inventory_image = "hazmat_suit_inv_helmet_hazmat.png", - stack_max = 1, -}) - -minetest.register_craftitem("hazmat_suit:chestplate_hazmat", { - description = "Hazmat Chestplate", - inventory_image = "hazmat_suit_inv_chestplate_hazmat.png", - stack_max = 1, -}) - -minetest.register_craftitem("hazmat_suit:sleeve_hazmat", { - description = "Hazmat Sleeve", - inventory_image = "hazmat_suit_inv_sleeve_hazmat.png", - stack_max = 1, -}) - -minetest.register_craftitem("hazmat_suit:leggings_hazmat", { - description = "Hazmat Leggins", - inventory_image = "hazmat_suit_inv_leggings_hazmat.png", - stack_max = 1, -}) - -minetest.register_craftitem("hazmat_suit:boots_hazmat", { - description = "Hazmat Boots", - inventory_image = "hazmat_suit_inv_boots_hazmat.png", - stack_max = 1, -}) - -minetest.register_tool("hazmat_suit:suit_hazmat", { - description = "Hazmat Suit", - inventory_image = "hazmat_suit_inv_suit_hazmat.png", - groups = { - armor_head = level, - armor_torso = level, - armor_legs = level, - armor_feet = level, - armor_heal = heal, - armor_use = use, - armor_fire = fire, - armor_water = water, - armor_radiation = radiation, - }, - wear = 0, -}) - -minetest.register_craft({ - output = "hazmat_suit:helmet_hazmat", - recipe = { - {"", "es:infinium_ingot", ""}, - {"es:infinium_ingot", "default:glass", "es:infinium_ingot"}, - {"es:rubber", "es:rubber", "es:rubber"}, - }, -}) - -minetest.register_craft({ - output = "hazmat_suit:chestplate_hazmat", - recipe = { - {"es:purpellium_ingot", "dye:yellow", "es:purpellium_ingot"}, - {"es:infinium_ingot", "es:purpellium_ingot", "es:infinium_ingot"}, - {"es:purpellium_ingot", "es:infinium_ingot", "es:purpellium_ingot"}, - }, -}) - -minetest.register_craft({ - output = "hazmat_suit:sleeve_hazmat", - recipe = { - {"es:rubber", "dye:yellow"}, - {"", "es:infinium_ingot"}, - {"", "es:rubber"}, - }, -}) - -minetest.register_craft({ - output = "hazmat_suit:leggings_hazmat", - recipe = { - {"es:rubber", "es:purpellium_ingot", "es:rubber"}, - {"es:infinium_ingot", "es:rubber", "es:infinium_ingot"}, - {"es:purpellium_ingot", "", "es:purpellium_ingot"}, - }, -}) - -minetest.register_craft({ - output = "hazmat_suit:boots_hazmat", - recipe = { - {"", "", ""}, - {"es:rubber", "", "es:rubber"}, - {"es:infinium_ingot", "", "es:infinium_ingot"}, - }, -}) - -minetest.register_craft({ - output = "hazmat_suit:suit_hazmat", - type = "shapeless", - recipe = { - "hazmat_suit:helmet_hazmat", - "hazmat_suit:chestplate_hazmat", - "hazmat_suit:leggings_hazmat", - "hazmat_suit:boots_hazmat", - "hazmat_suit:sleeve_hazmat", - "hazmat_suit:sleeve_hazmat", - }, -}) diff --git a/mods/a_inventory_mods/hazmat_suit/textures/hazmat_suit_inv_boots_hazmat.png b/mods/a_inventory_mods/hazmat_suit/textures/hazmat_suit_inv_boots_hazmat.png deleted file mode 100644 index 5f737e7c24847668986a1627bbd0f5761441a9fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 198 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHVEbxddW?DoV@XL#AbIA@nUues{Xik6k|4ie28Oc9XDxs{ z#w2fd7iK{opHD!JzNd?02*>s0gagbHQ&}XYIPjDoW1F!2yIVwojI^}0nKNes*|`@V#R275N`m}? zfi%PB$!W8I6l0RNy9-Ny#?3$=C(P5uF@)oKa>4<&n3x4ysySyI4dP?rOK9unp7Ag) zDd$ZbQ<86fq)3XmY+hvvavFoDtDnm{r-UW|7r8~^ diff --git a/mods/a_inventory_mods/hazmat_suit/textures/hazmat_suit_inv_leggings_hazmat.png b/mods/a_inventory_mods/hazmat_suit/textures/hazmat_suit_inv_leggings_hazmat.png deleted file mode 100644 index 1ca9d253e5aaeadc5caec794ea4b851093ecd3bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#K8Lt~v1s@tCNZE8Pk>K|E08ueHa@;c`0f_bIr75!Kt5whkY6x^!?PP{AWo9E zy9?ugCf$2Lj+Up3V+hCfFU$Y{ diff --git a/mods/a_inventory_mods/hazmat_suit/textures/hazmat_suit_inv_sleeve_hazmat.png b/mods/a_inventory_mods/hazmat_suit/textures/hazmat_suit_inv_sleeve_hazmat.png deleted file mode 100644 index 0503bb0509e6343d58b149ce0d5f1d62fa30fb81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`>?NMQuIvw3xOmmH0tEEbfkK6z zE{-7*qJr9yBS7pDr?80aNjBRom&XUB j8_ap;*;XGj_`%4qrAz9Nlgr;$pydpnu6{1-oD!M z4j2wEkZ;le0081iL_t(I%dL|!4uU`wL?4ED01YNk(0GKcyn~emrB|@DB$oCz#Lm*f z$|IOqaRd@W0f|NqV2o>_5G5Z$<5as-{GFLUYak%nT3X`!!;?|wT6}=#yLi6K*NC>3 zR!S8rlv27%mHBCqZQHu;F+=ix%x?5LtwR2K78hJO3$yGQU@Huk)8sdQRMvmF7uqL&z zwu!H~RH1f2uA)(qUaKqdVHh_5OhFKc=f5ks1HRu+squ%W7XSbN07*qoM6N<$f`!+9 AlK=n! diff --git a/mods/a_inventory_mods/hazmat_suit/textures/hazmat_suit_suit_hazmat.png b/mods/a_inventory_mods/hazmat_suit/textures/hazmat_suit_suit_hazmat.png deleted file mode 100644 index 97311fec578abf4a042496906013c77317582011..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 792 zcmV+z1LypSP) z4Iwb%GeMdF00PWOL_t(&-tAbuZrd;rJ{dwEAcX_igO@(St(h{{1=0eVx<;>%QOM{= zusjs#n4twMKZ1cSz9%TWWUv7T@BXDaM21l2VGzFtlz#Zzp(2bKK*R}3QVWdTF;&;z8$>ap?P=0x8# z1j#!tH?0d#M1c@O1VO;=Q;s2`P_4nlkF%c603q&_oDR&O7$07p!vQjMAp#IlLC83c z1pq*rrh#SwFqxw@_M4n-C!sJA70g@;pJf?jS(Yopw1&$IxYijTz*zuCS(X6+z<4}1 z&MAZbtT;fA>%Lh1*Z22UT=4nfoprsdUZC^W`T5ox!gD$_pFF(`|0ekTPlwM{py(?9 zpe-yPB_lw@+(X+izmCzX)c#E5stJZoCnFs0c8%$KIA?+sa?r7EUjZ(8ZqAvoI^UGY zm=dA#^y2RWTu{pnn^`J50ZsB6zYGKKZ)@+Tj{34@4imS(El zyahD^g;n9pMgi_xsm)b7bCud$YmC{TFWHc!Ui_>|Y83GucUgFC1q=oQ0Uah+di)m_ Wza2MaLq(ea0000<7gR`t)ijzKbqY!5BlvT2{y)U~tSJ_t7TE8I}o*O>cG zFy}kx69*k3g9pML8wGn5tQ&XkoVoY!-&-%99p1nB%$so2Q*Zv|70K}4IQw?tsh|JE zmDzk5m>d{57#I~8+S2ZP*WVBkn_m0h|NTBmMgh3Y8fKeIHv4mLYrTKIy1zC~-GJ!^ zs{#W{0|P<{7S4j}$Nc|toB0Zt${#wL7L01(m*jc-@8(U;+n*b)47Uf>5QogB=X>to z_w7@yZ@loC<<+jfTXiog>R+B`-m%j*#Ek*2y1{-^y!eN|$Jd{`zFzP5-Hey_&vPV* z!(I29VY$=s+sU;RzfE6$o4xF1jcv&u`>$XBudKg+@kIg))b~KsEUIN6Ts^JtX@B7A z)6Gk6^Phd3yk454et-9x{rMS^hmp)|a6DO8-*Dsc!`*k+eg1kgC+y3&;QR3h{xWXh zh8cID^TluGmUZ?0bJN>fo;_TeZ~yIk_ul;tf(P^%7@>i8jnS{Q@A`4M^Z)*QOuuqJ ze$B4<`+3{vu5Vu_eIv)r)4u-A|AQZXioD~8`-QRKpOwQOn=R2V>>4*7-(7rPUZG^q z|FgfJBL~O5HOy1=OwRlNwP8RG+tP;pN&Vm3r~KQ4EPOzj%T9m6y4T6`_b0si%`$CW zZuEJ$C%|EnU^Q3nug~AD_usE&hC2NJsk*R&KXS%8{0}yz+`njxgN@xNAP1AJF diff --git a/mods/a_mapgen_mods/handle_schematics/README.md b/mods/a_mapgen_mods/handle_schematics/README.md new file mode 100644 index 00000000..15bd4f81 --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/README.md @@ -0,0 +1,10 @@ + +This mod is not finished yet. + +Create a file named + list_of_schematics.txt +in the folder containing this mod (not the world!). +Each line of the file ought to contain the name and full path to a schematic. +Those will be offered to you in the build chest's menu under "main". + +Type "/giveme handle_schematics:build" to get a build chest. diff --git a/mods/a_mapgen_mods/handle_schematics/analyze_mc_schematic_file.lua b/mods/a_mapgen_mods/handle_schematics/analyze_mc_schematic_file.lua new file mode 100644 index 00000000..fb0d4826 --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/analyze_mc_schematic_file.lua @@ -0,0 +1,215 @@ + +-- This code is used to read Minecraft schematic files. +-- +-- The .schematic file format is described here: +-- http://minecraft.gamepedia.com/Schematic_file_format?cookieSetup=true +-- It is based on the NBT format, which is described here: +-- http://minecraft.gamepedia.com/NBT_Format?cookieSetup=true + + +-- position in the decompressed string data_stream +local curr_index = 1; + +-- helper arry so that the values do not have to be calculated anew each time +local pot256 = { 1 }; +for i=1,8 do + pot256[ #pot256+1 ] = pot256[ #pot256 ] * 256; +end + +-- read length bytes from data_stream and turn it into an integer value +local read_signed = function( data_stream, length) + local res = 0; + for i=length,1,-1 do + res = res + (string.byte( data_stream, curr_index )* pot256[ i ]); + -- move one further + curr_index = curr_index+1; + end + return res; +end + +-- this table will collect the few tags we're actually intrested in +local mc_schematic_data = {}; + +-- this will be a recursive function +local read_tag; + +-- needs to be defined now because it will contain a recursive function +local read_one_tag; + +-- read payload of one tag (= a data element in a NBT data structure) +read_one_tag = function( data_stream, tag, title_tag ) + if( tag<= 0 or not(data_stream)) then + return; + elseif( tag==1 ) then -- TAG_BYTE: 1 byte + return read_signed( data_stream, 1 ); + elseif( tag==2 ) then -- TAG_SHORT: 2 bytes + return read_signed( data_stream, 2 ); + elseif( tag==3 ) then -- TAG_INT: 4 bytes + return read_signed( data_stream, 4 ); + elseif( tag==4 ) then -- TAG_LONG: 8 bytes + return read_signed( data_stream, 8 ); + elseif( tag==5 ) then -- TAG_FLOAT: 4 bytes + return read_signed( data_stream, 4 ); -- the float values are unused here + elseif( tag==6 ) then -- TAG_DOUBLE: 8 bytes + return read_signed( data_stream, 8 ); -- the float values are unused here + elseif( tag==7 ) then -- TAG_Byte_Array + local size = read_signed( data_stream, 4 ); -- TAG_INT + local res = {}; + for i=1,size do + -- a Byte_Array does not contain any sub-tags + res[i] = read_one_tag( data_stream, 1, nil ); -- read TAG_BYTE + end + return res; + + elseif( tag==8 ) then -- TAG_String + local size = read_signed( data_stream, 2); + local res = string.sub( data_stream, curr_index, curr_index+size-1 ); + -- move on in the data stream + curr_index = curr_index + size; + return res; + + elseif( tag==9 ) then -- TAG_List + -- these exact values are not particulary intresting + local tagtyp = read_signed( data_stream, 1 ); -- TAG_BYTE + local size = read_signed( data_stream, 4 ); -- TAG_INT + local res = {}; + for i=1,size do + -- we need to pass title_tag on to the "child" + res[i] = read_one_tag( data_stream, tagtyp, title_tag ); + end + return res; + + elseif( tag==10 ) then -- TAG_Compound + return read_tag( data_stream, title_tag ); + + elseif( tag==11 ) then -- TAG_Int_Array + local size = read_signed( data_stream, 4 ); -- TAG_INT + local res = {}; + for i=1,size do + -- a Int_Array does not contain any sub-tags + res[i] = read_one_tag( data_stream, 3, nil ); -- TAG_INT + end + return res; + end +end + + +-- read tag type, tag name and call read_one_tag to get the payload; +read_tag = function( data_stream, title_tag ) + local schematic_data = {}; + while( data_stream ) do + local tag = string.byte( data_stream, curr_index); + -- move on in the data stream + curr_index = curr_index + 1; + if( not( tag ) or tag <= 0 ) then + return; + end + local tag_name_length = string.byte( data_stream, curr_index ) * 256 + string.byte(data_stream, curr_index + 1); + -- move 2 further + curr_index = curr_index + 2; + local tag_name = string.sub( data_stream, curr_index, curr_index+tag_name_length-1 ); + -- move on... + curr_index = curr_index + tag_name_length; + --print('[analyze_mc_schematic_file] Found: Tag '..tostring( tag )..' <'..tostring( tag_name )..'>'); + local res = read_one_tag( data_stream, tag, tag_name ); + -- Entities and TileEntities are ignored + if( title_tag == 'Schematic' + and( tag_name == 'Width' + or tag_name == 'Height' + or tag_name == 'Length' + or tag_name == 'Materials' -- "Classic" or "Alpha" (=Survival) + or tag_name == 'Blocks' + or tag_name == 'Data' + )) then + mc_schematic_data[ tag_name ] = res; + end + end + return; +end + + +handle_schematics.analyze_mc_schematic_file = function( path ) + -- these files are usually compressed; there is no point to start if the + -- decompress function is missing + if( minetest.decompress == nil) then + return nil; + end + + local file, err = save_restore.file_access(path..'.schematic', "rb") + if (file == nil) then +-- print('[analyze_mc_schematic_file] ERROR: NO such file: '..tostring( path..'.schematic')); + return nil + end + + local compressed_data = file:read( "*all" ); + --local data_string = minetest.decompress(compressed_data, "deflate" ); +local data_string = compressed_data; -- TODO +print('FILE SIZE: '..tostring( string.len( data_string ))); -- TODO + file.close(file) + + + -- we use this (to this file) global variable to store gathered information; + -- doing so inside the recursive functions proved problematic + mc_schematic_data = {}; + -- this index will iterate through the schematic data + curr_index = 1; + -- actually analyze the data + read_tag( data_string, nil ); + + if( not( mc_schematic_data.Width ) + or not( mc_schematic_data.Height ) + or not( mc_schematic_data.Length ) + or not( mc_schematic_data.Blocks ) + or not( mc_schematic_data.Data )) then + print('[analyze_mc_schematic_file] ERROR: Failed to analyze '..tostring( path..'.schematic')); + return nil; + end + + local translation_function = handle_schematics.findMC2MTConversion; + if( minetest.get_modpath('mccompat')) then + translation_function = mccompat.findMC2MTConversion; + end + + local max_msg = 40; -- just for error handling + local size = {x=mc_schematic_data.Width, y=mc_schematic_data.Height, z=mc_schematic_data.Length}; + local scm = {}; + local nodenames = {}; + local nodenames_id = {}; + for y=1,size.y do + scm[y] = {}; + for x=1,size.x do + scm[y][x] = {}; + for z =1,size.z do + local new_node = translation_function( + -- (Y×length + Z)×width + X. + mc_schematic_data.Blocks[ ((y-1)*size.z + (z-1) )*size.x + (size.x-x) +1], + mc_schematic_data.Data[ ((y-1)*size.z + (z-1) )*size.x + (size.x-x) +1] ); + -- some MC nodes store the information about a node in TWO block and data fields (doors, large flowers, ...) + if( new_node[3] and new_node[3]~=0 ) then + new_node = translation_function( + -- (Y×length + Z)×width + X. + mc_schematic_data.Blocks[ ((y-1)*size.z + (z-1) )*size.x + (size.x-x) +1], + mc_schematic_data.Data[ ((y-1)*size.z + (z-1) )*size.x + (size.x-x) +1], + mc_schematic_data.Blocks[ ((y-1+new_node[3])*size.z + (z-1) )*size.x + (size.x-x) +1], + mc_schematic_data.Data[ ((y-1+new_node[3])*size.z + (z-1) )*size.x + (size.x-x) +1] ); + end + if( not( nodenames_id[ new_node[1]] )) then + nodenames_id[ new_node[1] ] = #nodenames + 1; + nodenames[ nodenames_id[ new_node[1] ]] = new_node[1]; + end + -- print a few warning messages in case something goes wrong - but do not exaggerate + if( not( new_node[2] and max_msg>0)) then +-- print('[handle_schematics:schematic] MISSING param2: '..minetest.serialize( new_node )); + new_node[2]=0; + max_msg=max_msg-1; + end + -- save some space by not saving air + if( new_node[1] ~= 'air' ) then + scm[y][x][z] = { nodenames_id[ new_node[1]], new_node[2]}; + end + end + end + end + return { size = { x=size.x, y=size.y, z=size.z}, nodenames = nodenames, on_constr = {}, after_place_node = {}, rotated=90, burried=0, scm_data_cache = scm, metadata = {}}; +end + diff --git a/mods/a_mapgen_mods/handle_schematics/analyze_mts_file.lua b/mods/a_mapgen_mods/handle_schematics/analyze_mts_file.lua new file mode 100644 index 00000000..9a456438 --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/analyze_mts_file.lua @@ -0,0 +1,279 @@ + +--[[ taken from src/mg_schematic.cpp: + Minetest Schematic File Format + + All values are stored in big-endian byte order. + [u32] signature: 'MTSM' + [u16] version: 3 + [u16] size X + [u16] size Y + [u16] size Z + For each Y: + [u8] slice probability value + [Name-ID table] Name ID Mapping Table + [u16] name-id count + For each name-id mapping: + [u16] name length + [u8[] ] name + ZLib deflated { + For each node in schematic: (for z, y, x) + [u16] content + For each node in schematic: + [u8] probability of occurance (param1) + For each node in schematic: + [u8] param2 + } + + Version changes: + 1 - Initial version + 2 - Fixed messy never/always place; 0 probability is now never, 0xFF is always + 3 - Added y-slice probabilities; this allows for variable height structures +--]] + +--handle_schematics = {} + +-- taken from https://github.com/MirceaKitsune/minetest_mods_structures/blob/master/structures_io.lua (Taokis Sructures I/O mod) +-- gets the size of a structure file +-- nodenames: contains all the node names that are used in the schematic +-- on_constr: lists all the node names for which on_construct has to be called after placement of the schematic +handle_schematics.analyze_mts_file = function( path ) + local size = { x = 0, y = 0, z = 0, version = 0 } + local version = 0; + + local file, err = save_restore.file_access(path..'.mts', "rb") + if (file == nil) then + return nil + end +--print('[handle_schematics] Analyzing .mts file '..tostring( path..'.mts' )); +--if( not( string.byte )) then +-- print( '[handle_schematics] Error: string.byte undefined.'); +-- return nil; +--end + + -- thanks to sfan5 for this advanced code that reads the size from schematic files + local read_s16 = function(fi) + return string.byte(fi:read(1)) * 256 + string.byte(fi:read(1)) + end + + local function get_schematic_size(f) + -- make sure those are the first 4 characters, otherwise this might be a corrupt file + if f:read(4) ~= "MTSM" then + return nil + end + -- advance 2 more characters + local version = read_s16(f); --f:read(2) + -- the next characters here are our size, read them + return read_s16(f), read_s16(f), read_s16(f), version + end + + size.x, size.y, size.z, size.version = get_schematic_size(file) + + -- read the slice probability for each y value that was introduced in version 3 + if( size.version >= 3 ) then + -- the probability is not very intresting for buildings so we just skip it + file:read( size.y ); + end + + + -- this list is not yet used for anything + local nodenames = {}; + -- this list is needed for calling on_construct after place_schematic + local on_constr = {}; + -- nodes that require after_place_node to be called + local after_place_node = {}; + + -- after that: read_s16 (2 bytes) to find out how many diffrent nodenames (node_name_count) are present in the file + local node_name_count = read_s16( file ); + + for i = 1, node_name_count do + + -- the length of the next name + local name_length = read_s16( file ); + -- the text of the next name + local name_text = file:read( name_length ); + + table.insert( nodenames, name_text ); + -- in order to get this information, the node has to be defined and loaded + if( minetest.registered_nodes[ name_text ] and minetest.registered_nodes[ name_text ].on_construct) then + table.insert( on_constr, name_text ); + end + -- some nodes need after_place_node to be called for initialization + if( minetest.registered_nodes[ name_text ] and minetest.registered_nodes[ name_text ].after_place_node) then + table.insert( after_place_node, name_text ); + end + end + + local rotated = 0; + local burried = 0; + local parts = path:split('_'); + if( parts and #parts > 2 ) then + if( parts[#parts]=="0" or parts[#parts]=="90" or parts[#parts]=="180" or parts[#parts]=="270" ) then + rotated = tonumber( parts[#parts] ); + burried = tonumber( parts[ #parts-1 ] ); + if( not( burried ) or burried>20 or burried<0) then + burried = 0; + end + end + end + + -- decompression was recently added; if it is not yet present, we need to use normal place_schematic + if( minetest.decompress == nil) then + file.close(file); + return nil; -- normal place_schematic is no longer supported as minetest.decompress is now part of the release version of minetest +-- return { size = { x=size.x, y=size.y, z=size.z}, nodenames = nodenames, on_constr = on_constr, after_place_node = after_place_node, rotated=rotated, burried=burried, scm_data_cache = nil }; + end + + local compressed_data = file:read( "*all" ); + local data_string = minetest.decompress(compressed_data, "deflate" ); + file.close(file) + + local ids = {}; + local needs_on_constr = {}; + local is_air = 0; + -- translate nodenames to ids + for i,v in ipairs( nodenames ) do + ids[ i ] = minetest.get_content_id( v ); + needs_on_constr[ i ] = false; + if( minetest.registered_nodes[ v ] and minetest.registered_nodes[ v ].on_construct ) then + needs_on_constr[ i ] = true; + end + if( v == 'air' ) then + is_air = i; + end + end + + local p2offset = (size.x*size.y*size.z)*3; + local i = 1; + local scm = {}; + for z = 1, size.z do + for y = 1, size.y do + for x = 1, size.x do + if( not( scm[y] )) then + scm[y] = {}; + end + if( not( scm[y][x] )) then + scm[y][x] = {}; + end + local id = string.byte( data_string, i ) * 256 + string.byte( data_string, i+1 ); + i = i + 2; + local p2 = string.byte( data_string, p2offset + math.floor(i/2)); + id = id+1; + + if( id ~= is_air ) then + scm[y][x][z] = {id, p2}; + end + end + end + end + + return { size = { x=size.x, y=size.y, z=size.z}, nodenames = nodenames, on_constr = on_constr, after_place_node = after_place_node, rotated=rotated, burried=burried, scm_data_cache = scm }; +end + + + +handle_schematics.store_mts_file = function( path, data ) + + data.nodenames[ #data.nodenames+1 ] = 'air'; + + local file, err = save_restore.file_access(path..'.mts', "wb") + if (file == nil) then + return nil + end + + local write_s16 = function( fi, a ) + fi:write( string.char( math.floor( a/256) )); + fi:write( string.char( a%256 )); + end + + data.size.version = 3; -- we only support version 3 of the .mts file format + + file:write( "MTSM" ); + write_s16( file, data.size.version ); + write_s16( file, data.size.x ); + write_s16( file, data.size.y ); + write_s16( file, data.size.z ); + + + -- set the slice probability for each y value that was introduced in version 3 + if( data.size.version >= 3 ) then + -- the probability is not very intresting for buildings so we just skip it + for i=1,data.size.y do + file:write( string.char(255) ); + end + end + + -- set how many diffrent nodenames (node_name_count) are present in the file + write_s16( file, #data.nodenames ); + + for i = 1, #data.nodenames do + -- the length of the next name + write_s16( file, string.len( data.nodenames[ i ] )); + file:write( data.nodenames[ i ] ); + end + + -- this string will later be compressed + local node_data = ""; + + -- actual node data + for z = 1, data.size.z do + for y = 1, data.size.y do + for x = 1, data.size.x do + local a = data.scm_data_cache[y][x][z]; + if( a and type( a ) == 'table') then + node_data = node_data..string.char( math.floor( a[1]/256) )..string.char( a[1]%256-1); + else + node_data = node_data..string.char( 0 )..string.char( #data.nodenames-1 ); + end + end + end + end + + -- probability of occurance + for z = 1, data.size.z do + for y = 1, data.size.y do + for x = 1, data.size.x do + node_data = node_data..string.char( 255 ); + end + end + end + + -- param2 + for z = 1, data.size.z do + for y = 1, data.size.y do + for x = 1, data.size.x do + local a = data.scm_data_cache[y][x][z]; + if( a and type( a) == 'table' ) then + node_data = node_data..string.char( a[2] ); + else + node_data = node_data..string.char( 0 ); + end + end + end + end + + local compressed_data = minetest.compress( node_data, "deflate" ); + file:write( compressed_data ); + file.close(file); + print('SAVING '..path..'.mts (converted from .we).'); +end + + +-- read .mts and .we files +handle_schematics.analyze_file = function( file_name, origin_offset, store_as_mts ) + local res = handle_schematics.analyze_mts_file( file_name ); + -- alternatively, read the mts file + if( not( res )) then + res = handle_schematics.analyze_we_file( file_name, origin_offset ); + if( not( res )) then + res = handle_schematics.analyze_mc_schematic_file( file_name ); + end + -- print error message only if all import methods failed + if( not( res )) then + print('[handle_schematics] ERROR: Failed to import file \"'..tostring( file_name )..'\"[.mts|.we|.wem|.schematic]'); + -- convert to .mts for later usage + elseif( store_as_mts ) then + handle_schematics.store_mts_file( store_as_mts, res ); + end + end + return res; +end diff --git a/mods/a_mapgen_mods/handle_schematics/analyze_we_file.lua b/mods/a_mapgen_mods/handle_schematics/analyze_we_file.lua new file mode 100644 index 00000000..20f134c8 --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/analyze_we_file.lua @@ -0,0 +1,100 @@ +handle_schematics.analyze_we_file = function(scm, we_origin) + local c_ignore = minetest.get_content_id("ignore") + + -- this table will contain the nodes read + local nodes = {} + + -- check if it is a worldedit file + -- (no idea why reading that is done in such a complicated way; a simple deserialize and iteration over all nodes ought to do as well) + local f, err = save_restore.file_access( scm..".we", "r") + if not f then + f, err = save_restore.file_access( scm..".wem", "r") + if not f then +-- error("Could not open schematic '" .. scm .. ".we': " .. err) + return nil; + end + end + + local value = f:read("*a") + f:close() + + local nodes = worldedit_file.load_schematic(value, we_origin) + + -- create a list of nodenames + local nodenames = {}; + local nodenames_id = {}; + for i,ent in ipairs( nodes ) do + if( ent and ent.name and not( nodenames_id[ ent.name ])) then + nodenames_id[ ent.name ] = #nodenames + 1; + nodenames[ nodenames_id[ ent.name ] ] = ent.name; + end + end + + scm = {} + local maxx, maxy, maxz = -1, -1, -1 + local all_meta = {}; + for i = 1, #nodes do + local ent = nodes[i] + ent.x = ent.x + 1 + ent.y = ent.y + 1 + ent.z = ent.z + 1 + if ent.x > maxx then + maxx = ent.x + end + if ent.y > maxy then + maxy = ent.y + end + if ent.z > maxz then + maxz = ent.z + end + if scm[ent.y] == nil then + scm[ent.y] = {} + end + if scm[ent.y][ent.x] == nil then + scm[ent.y][ent.x] = {} + end + if ent.param2 == nil then + ent.param2 = 0 + end + -- metadata is only of intrest if it is not empty + if( ent.meta and (ent.meta.fields or ent.meta.inventory)) then + local has_meta = false; + for _,v in pairs( ent.meta.fields ) do + has_meta = true; + end + for _,v in pairs(ent.meta.inventory) do + has_meta = true; + end + if( has_meta == true ) then + all_meta[ #all_meta+1 ] = { + x=ent.x, + y=ent.y, + z=ent.z, + fields = ent.meta.fields, + inventory = ent.meta.inventory}; + end + end + + + scm[ent.y][ent.x][ent.z] = { nodenames_id[ ent.name ], ent.param2 }; + + end + + for y = 1, maxy do + if scm[y] == nil then + scm[y] = {} + end + for x = 1, maxx do + if scm[y][x] == nil then + scm[y][x] = {} + end + end + end + + local size = {}; + size.y = math.max(maxy,0); + size.x = math.max(maxx,0); + size.z = math.max(maxz,0); + + return { size = { x=size.x, y=size.y, z=size.z}, nodenames = nodenames, on_constr = {}, after_place_node = {}, rotated=0, burried=0, scm_data_cache = scm, metadata = all_meta }; +end diff --git a/mods/a_mapgen_mods/handle_schematics/build_chest.lua b/mods/a_mapgen_mods/handle_schematics/build_chest.lua new file mode 100644 index 00000000..4cf3a245 --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/build_chest.lua @@ -0,0 +1,876 @@ +----------------------------------------------------------------------------------------------------------------- +-- interface for manual placement of houses +----------------------------------------------------------------------------------------------------------------- + + +-- functions specific to the build_chest are now stored in this table +build_chest = {}; + +-- scaffolding that will be placed instead of other nodes in order to show +-- how large the building will be +build_chest.SUPPORT = 'build_chest:support'; + + +-- contains information about all the buildings +build_chest.building = {}; + +-- returns the id under which the building is stored +build_chest.add_building = function( file_name, data ) + if( not( file_name ) or not( data )) then + return; + end + build_chest.building[ file_name ] = data; +end + +-- that many options can be shown simultaneously on one menu page +build_chest.MAX_OPTIONS = 24; -- 3 columns with 8 entries each + + +build_chest.menu = {}; +build_chest.menu.main = {}; + +-- create a tree structure for the menu +build_chest.add_entry = function( path ) + if( not( path ) or #path<1 ) then + return; + end + + local sub_menu = build_chest.menu; + for i,v in ipairs( path ) do + if( not( sub_menu[ v ] )) then + sub_menu[ v ] = {}; + end + sub_menu = sub_menu[ v ]; + end +end + +-- add a menu entry that will always be available +build_chest.add_entry( {'save a building'} ); + +-- needed for saving buildings +build_chest.end_pos_list = {}; + +--dofile( minetest.get_modpath( minetest.get_current_modname()).."/build_chest_handle_replacements.lua"); +--dofile( minetest.get_modpath( minetest.get_current_modname()).."/build_chest_preview_image.lua"); +--dofile( minetest.get_modpath( minetest.get_current_modname()).."/build_chest_add_schems.lua"); + + + + +build_chest.read_building = function( building_name ) + -- read data + local res = handle_schematics.analyze_file( building_name, nil, nil ); + if( not( res )) then + return; + end + build_chest.building[ building_name ].size = res.size; + build_chest.building[ building_name ].nodenames = res.nodenames; + build_chest.building[ building_name ].rotated = res.rotated; + build_chest.building[ building_name ].burried = res.burried; + build_chest.building[ building_name ].metadata = res.metadata; + -- scm_data_cache is not stored as that would take up too much storage space + --build_chest.building[ building_name ].scm_data_cache = res.scm_data_cache; + + -- create a statistic about how often each node occours + build_chest.building[ building_name ].statistic = handle_schematics.count_nodes( res ); + + build_chest.building[ building_name ].preview = build_chest.preview_image_create_views( res, + build_chest.building[ building_name ].orients ); + return res; +end + + + +build_chest.get_start_pos = function( pos ) + -- rotate the building so that it faces the player + local node = minetest.get_node( pos ); + local meta = minetest.get_meta( pos ); + + local building_name = meta:get_string( 'building_name' ); + if( not( building_name )) then + return "No building_name provided."; + end + if( not( build_chest.building[ building_name ] )) then + return "No data found for this building."; + end + + if( not( build_chest.building[ building_name ].size )) then + if( not( build_chest.read_building( building_name ))) then + return "Unable to read data file of this building."; + end + end + local selected_building = build_chest.building[ building_name ]; + + local mirror = 0; -- place_schematic does not support mirroring + + local start_pos = {x=pos.x, y=pos.y, z=pos.z}; + -- yoff(set) from mg_villages (manually given) + if( selected_building.yoff ) then + start_pos.y = start_pos.y + selected_building.yoff -1; + end + + -- make sure the building always extends forward and to the right of the player + local param2_rotated = handle_schematics.translate_param2_to_rotation( node.param2, mirror, start_pos, + selected_building.size, selected_building.rotated, selected_building.burried, selected_building.orients, + selected_building.yoff ); + + -- save the data for later removal/improvement of the building in the chest + meta:set_string( 'start_pos', minetest.serialize( param2_rotated.start_pos )); + meta:set_string( 'end_pos', minetest.serialize( param2_rotated.end_pos )); + meta:set_string( 'rotate', tostring(param2_rotated.rotate )); + meta:set_int( 'mirror', mirror ); + -- no replacements yet + meta:set_string( 'replacements', minetest.serialize( {} )); + return start_pos; +end + + + + +build_chest.show_size_data = function( building_name ) + + if( not( building_name ) + or building_name == '' + or not( build_chest.building[ building_name ] ) + or not( build_chest.building[ building_name ].size )) then + return ""; + end + + local size = build_chest.building[ building_name ].size; + -- show which building has been selected + return "label[0.3,9.5;Selected building:]".. + "label[2.3,9.5;"..minetest.formspec_escape(building_name).."]".. + -- size of the building + "label[0.3,9.8;Size ( wide x length x height ):]".. + "label[4.3,9.8;"..tostring( size.x )..' x '..tostring( size.z )..' x '..tostring( size.y ).."]"; +end + + +-- helper function for update_formspec that handles saving of a building +handle_schematics.update_formspec_save_building = function( formspec, meta, player, fields, pos ) + local saved_as_filename = meta:get_string('saved_as_filename'); + if( saved_as_filename and saved_as_filename ~= "" ) then + local p1str = meta:get_string('p1'); + local p2str = meta:get_string('p2'); + + return formspec.. + "label[2.0,3;This area has been saved to the file]".. + "label[2.5,3.3;"..minetest.formspec_escape( saved_as_filename ).."]".. + "label[2.0,3.6;The area extends from]".. + "label[2.5,3.9;"..minetest.formspec_escape( p1str ).."]".. + "label[2.0,4.2;to the point]".. + "label[2.5,4.5;"..minetest.formspec_escape( p2str ).."]".. + "button[5,8.0;3,0.5;back;Back]"; + end + + local end_pos_mark = build_chest.end_pos_list[ player:get_player_name() ]; + if( end_pos_mark + and end_pos_mark.x==pos.x + and end_pos_mark.y==pos.y + and end_pos_mark.z==pos.z ) then + + return formspec.. + "label[2,3.0;This chest marks the end position of your building. Please put another]".. + "label[2,3.3;build chest in front of your building and save it with that chest.]".. + "button[5,8.0;3,0.5;back;Back]"; + end + + if( end_pos_mark and end_pos_mark.start_pos ) then + + if( end_pos_mark.start_pos.x == pos.x + and end_pos_mark.start_pos.y == pos.y + and end_pos_mark.start_pos.z == pos.z ) then + local p2 = {x=end_pos_mark.x, y=end_pos_mark.y, z=end_pos_mark.z}; + local p1 = {x=end_pos_mark.start_pos.x, y=end_pos_mark.start_pos.y, z=end_pos_mark.start_pos.z}; + local height = math.abs( p1.y - p2.y )+1; + local width = 0; + local length = 0; + if( end_pos_mark.param2==0 or end_pos_mark.param2==2 ) then + -- adjust p1 and p2 so that only the area we really care about is marked + if( p1.z > p2.z ) then + p1.z = p1.z-1; + p2.z = p2.z+1; + else + p1.z = p1.z+1; + p2.z = p2.z-1; + end + width = math.abs( p1.x - p2.x )+1; + length = math.abs( p1.z - p2.z )+1; + else + if( p1.x > p2.x ) then + p1.x = p1.x-1; + p2.x = p2.x+1; + else + p1.x = p1.x+1; + p2.x = p2.x-1; + end + length = math.abs( p1.x - p2.x )+1; + width = math.abs( p1.z - p2.z )+1; + end + return formspec.. + -- p1 and p2 are passed on as inputs in order to avoid any unwanted future interferences + -- with any other build chests + "field[40,40;0.1,0.1;save_as_p1;;"..minetest.pos_to_string(p1).."]".. + "field[40,40;0.1,0.1;save_as_p2;;"..minetest.pos_to_string(p2).."]".. + + "label[2,2.4;How high is your building? This does *not* include the height offset below. The]".. + "label[2,2.7;default value is calculated from the height difference between start and end position.]".. + "label[2,3.15;Total height of your building:]".. + "field[6,3.5;1,0.5;save_as_height;;"..tostring(height).."]".. + + -- note: in mg_villages, yoff has to be 0 in order to include the ground floor as well; + -- "1" means the building without floor; here, "1" means a floating building + "label[2,3.8;The hight offset sets how deep your building will be burried in the ground. Examples:]".. + "label[2.5,4.1;A value of -4 will include a cellar which extends 4 nodes below this build chest.]".. + "label[2.5,4.4;A value of -1 will include the floor below the chest, but no cellar.]".. + "label[2.5,4.7;A positive value will make your building float in the air.]".. + "label[2,5.15;Add height offset:]".. + "field[6,5.5;1,0.5;save_as_yoff;;0]".. + + "label[2,5.8;Without the changes entered in the input form above, your building will extend from]".. + "label[2.5,6.1;"..minetest.formspec_escape( + minetest.pos_to_string( p1 ).." to ".. + minetest.pos_to_string( p2 ).." and span a volume of ".. + -- x and z are swpapped here if rotated by 90 or 270 degree + tostring(width )..' (width) x '.. + tostring(length)..' (depth) x '.. + tostring(height)..' (height)').."]".. + + "label[2,6.7;Please enter a descriptive filename. Allowed charcters: ".. + minetest.formspec_escape("a-z, A-Z, 0-9, -, _, .").."]".. + "label[2,7.15;Save schematic as:]".. + "field[6,7.5;4,0.5;save_as_filename;;]".. + + "button[2,8.0;3,0.5;abort_set_start_pos;Abort]".. + "button[6,8.0;3,0.5;save_as;Save building now]"; + else + return formspec.. + "label[3,3;You have selected another build chest as start position.]".. + "button[5,8.0;3,0.5;back;Back]".. + "button[5,5.0;3,0.5;abort_set_start_pos;Reset start position]"; + end + end + + if( fields.error_msg ) then + return formspec.. + "label[4,4.5;Error while trying to set the start position:]".. + "textarea[4,5;6,2;error_msg;;".. + minetest.formspec_escape( fields.error_msg ).."]".. + "button[5,8.0;3,0.5;back;Back]"; + end + + return formspec.. + "label[2.5,2.2;First, let us assume that you are facing the front of this build chest.]".. + + "label[2,3.1;Are you looking at the BACKSIDE of your building, and does said backside stretch]".. + "label[2,3.4;to the right and in front of you? Then click on the button below:]".. + "button[4,4;5,0.5;set_end_pos;Set this position as new end position]".. + + "label[2,5.2;Have you set the end position with another build chest using the method above]".. + "label[2,5.5;in the meantime? And are you now looking at the FRONT of your building, which]".. + "label[2,5.8;streches in front of you and to the right? Then click on Proceed:]".. + "button[5,6.4;3,0.5;set_start_pos;Proceed with saving]".. + + "label[4,7.4;If this confuses you, you can also abort the process.]".. + "button[5,8.0;3,0.5;back;Abort]"; +end + + + +build_chest.update_formspec = function( pos, page, player, fields ) + + -- information about the village the build chest may belong to and about the owner + local meta = minetest.get_meta( pos ); + local village_name = meta:get_string( 'village' ); + local village_pos = minetest.deserialize( meta:get_string( 'village_pos' )); + local owner_name = meta:get_string( 'owner' ); + local building_name = meta:get_string('building_name' ); + + -- distance from village center + local distance = math.floor( math.sqrt( (village_pos.x - pos.x ) * (village_pos.x - pos.x ) + + (village_pos.y - pos.y ) * (village_pos.x - pos.y ) + + (village_pos.z - pos.z ) * (village_pos.x - pos.z ) )); + + -- the statistic is needed for all the replacements later on as it also contains the list of nodenames + if( building_name and building_name~=""and not( build_chest.building[ building_name ].size )) then + build_chest.read_building( building_name ); + end + + if( page == 'please_remove' ) then + if( build_chest.stages_formspec_page_please_remove ) then + return build_chest.stages_formspec_page_please_remove( building_name, owner_name, village_name, village_pos, distance ); + end + elseif( page == 'finished' ) then + if( build_chest.stages_formspec_page_finished ) then + return build_chest.stages_formspec_page_finished( building_name, owner_name, village_name, village_pos, distance ); + end + elseif( page ~= 'main' ) then + -- if in doubt, return the old formspec + return meta:get_string('formspec'); + end + + + -- create the header + local formspec = "size[13,10]".. + "label[3.3,0.0;Building box]".. + "label[0.3,0.4;Located at:]" .."label[3.3,0.4;"..(minetest.pos_to_string( pos ) or '?')..", which is "..tostring( distance ).." m away]" + .."label[7.3,0.4;from the village center]".. + "label[0.3,0.8;Part of village:]" .."label[3.3,0.8;"..(village_name or "?").."]" + .."label[7.3,0.8;located at "..(minetest.pos_to_string( village_pos ) or '?').."]".. + "label[0.3,1.2;Owned by:]" .."label[3.3,1.2;"..(owner_name or "?").."]".. + "label[3.3,1.6;Click on a menu entry to select it:]".. + build_chest.show_size_data( building_name ); + + local current_path = minetest.deserialize( meta:get_string( 'current_path' ) or 'return {}' ); + if( #current_path > 0 ) then + formspec = formspec.."button[9.9,0.4;2,0.5;back;Back]"; + end + + + -- offer a menu to set the positions for saving a building + if( #current_path > 0 and current_path[1]=='save a building' ) then + return handle_schematics.update_formspec_save_building( formspec, meta, player, fields, pos); + end + + + -- the building has been placed; offer to restore a backup + local backup_file = meta:get_string('backup'); + if( backup_file and backup_file ~= "" ) then + return formspec.."button[3,3;3,0.5;restore_backup;Restore original landscape]"; + end + + -- offer diffrent replacement groups + if( fields.set_wood and fields.set_wood ~= "" ) then + return formspec.. + "label[1,2.2;Select replacement for "..tostring( fields.set_wood )..".]".. + "label[1,2.5;Trees, saplings and other blocks will be replaced accordingly as well.]".. + -- invisible field that encodes the value given here + "field[-20,-20;0.1,0.1;set_wood;;"..minetest.formspec_escape( fields.set_wood ).."]".. + build_chest.replacements_get_group_list_formspec( pos, 'wood', 'wood_selection' ); + end + + if( fields.set_farming and fields.set_farming ~= "" ) then + return formspec.. + "label[1,2.5;Select the fruit the farm is going to grow:]".. + -- invisible field that encodes the value given here + "field[-20,-20;0.1,0.1;set_farming;;"..minetest.formspec_escape( fields.set_farming ).."]".. + build_chest.replacements_get_group_list_formspec( pos, 'farming', 'farming_selection' ); + end + + if( fields.set_roof and fields.set_roof ~= "" ) then + return formspec.. + "label[1,2.5;Select a roof type for the house:]".. + -- invisible field that encodes the value given here + "field[-20,-20;0.1,0.1;set_roof;;"..minetest.formspec_escape( fields.set_roof ).."]".. + build_chest.replacements_get_group_list_formspec( pos, 'roof', 'roof_selection' ); + end + + if( fields.preview and building_name ) then + return formspec..build_chest.preview_image_formspec( building_name, + minetest.deserialize( meta:get_string( 'replacements' )), fields.preview); + end + + + -- show list of all node names used + local start_pos = meta:get_string('start_pos'); + if( building_name and building_name ~= '' and start_pos and start_pos ~= '' and meta:get_string('replacements')) then + return formspec..build_chest.replacements_get_list_formspec( pos ); + end + + -- find out where we currently are in the menu tree + local menu = build_chest.menu; + for i,v in ipairs( current_path ) do + if( menu and menu[ v ] ) then + menu = menu[ v ]; + end + end + + -- all submenu points at this menu position are options that need to be shown + local options = {}; + for k,v in pairs( menu ) do + table.insert( options, k ); + end + + -- handle if there are multiple files under the same menu point + if( #options == 0 and build_chest.building[ current_path[#current_path]] ) then + options = {current_path[#current_path]}; + end + + -- we have found an end-node - a particular building + if( #options == 1 and options[1] and build_chest.building[ options[1]] ) then + -- a building has been selected + meta:set_string( 'building_name', options[1] ); + local start_pos = build_chest.get_start_pos( pos ); + if( type(start_pos)=='table' and start_pos and start_pos.x and build_chest.building[ options[1]].size) then + -- size information has just been read; we can now display it + formspec = formspec..build_chest.show_size_data( building_name ); + + -- do replacements for realtest where necessary (this needs to be done only once) + local replacements = {}; + replacements_group['realtest'].replace( replacements ); + meta:set_string( 'replacements', minetest.serialize( replacements )); + + return formspec..build_chest.replacements_get_list_formspec( pos ); + elseif( type(start_pos)=='string' ) then + return formspec.."label[3,3;Error reading building data:]".. + "label[3.5,3.5;"..start_pos.."]"; + else + return formspec.."label[3,3;Error reading building data.]"; + end + end + table.sort( options ); + + local page_nr = meta:get_int( 'page_nr' ); + -- if the options do not fit on a single page, split them up + if( #options > build_chest.MAX_OPTIONS ) then + if( not( page_nr )) then + page_nr = 0; + end + local new_options = {}; + local new_index = build_chest.MAX_OPTIONS*page_nr; + for i=1,build_chest.MAX_OPTIONS do + if( options[ new_index+i ] ) then + new_options[ i ] = options[ new_index+i ]; + end + end + + -- we need to add prev/next buttons to the formspec + formspec = formspec.."label[7.5,1.5;"..minetest.formspec_escape( + "Showing "..tostring( new_index+1 ).. + '-'..tostring( math.min( new_index+build_chest.MAX_OPTIONS, #options)).. + '/'..tostring( #options )).."]"; + if( page_nr > 0 ) then + formspec = formspec.."button[9.5,1.5;1,0.5;prev;prev]"; + end + if( build_chest.MAX_OPTIONS*(page_nr+1) < #options ) then + formspec = formspec.."button[11,1.5;1,0.5;next;next]"; + end + options = new_options; + end + + + -- found an end node of the menu graph +-- elseif( build_chest.stages_formspec_page_first_stage ) then +-- return build_chest.stages_formspec_page_first_stage( v.menu_path[( #current_path )], player, pos, meta, ); +-- end + + -- show the menu with the next options + local i = 0; + local x = 0; + local y = 0; + if( #options < 9 ) then + x = x + 4; + end + -- order alphabeticly + table.sort( options, function(a,b) return a < b end ); + + for index,k in ipairs( options ) do + + i = i+1; + + -- new column + if( y==8 ) then + x = x+4; + y = 0; + end + + formspec = formspec .."button["..(x)..","..(y+2.5)..";4,0.5;selection;"..k.."]" + y = y+1; + --x = x+4; + end + + return formspec; +end + + + +build_chest.on_receive_fields = function(pos, formname, fields, player) + + local meta = minetest.get_meta(pos); + + local owner = meta:get_string('owner'); + local pname = player:get_player_name(); + + -- make sure not everyone can mess up the build chest + if( owner and owner ~= '' and owner ~= pname + and minetest.is_protected( pos, pname )) then + minetest.chat_send_player( pname, + "Sorry. This build chest belongs to "..tostring( owner ).." and only ".. + "accepts input from its owner or other players who can build here."); + return; + end + + local building_name = meta:get_string('building_name' ); + -- the statistic is needed for all the replacements later on as it also contains the list of nodenames + if( building_name and building_name~=""and not( build_chest.building[ building_name ].size )) then + build_chest.read_building( building_name ); + end + +-- general menu handling + -- back button selected + if( fields.back ) then + + local current_path = minetest.deserialize( meta:get_string( 'current_path' ) or 'return {}' ); + + table.remove( current_path ); -- revert latest selection + meta:set_string( 'current_path', minetest.serialize( current_path )); + meta:set_string( 'building_name', ''); + meta:set_int( 'replace_row', 0 ); + meta:set_int( 'page_nr', 0 ); + meta:set_string( 'saved_as_filename', nil); + + -- menu entry selected + elseif( fields.selection ) then + + local current_path = minetest.deserialize( meta:get_string( 'current_path' ) or 'return {}' ); + table.insert( current_path, fields.selection ); + meta:set_string( 'current_path', minetest.serialize( current_path )); + + -- if there are more menu items than can be shown on one page: show previous page + elseif( fields.prev ) then + local page_nr = meta:get_int( 'page_nr' ); + if( not( page_nr )) then + page_nr = 0; + end + page_nr = math.max( page_nr - 1 ); + meta:set_int( 'page_nr', page_nr ); + + -- if there are more menu items than can be shown on one page: show next page + elseif( fields.next ) then + local page_nr = meta:get_int( 'page_nr' ); + if( not( page_nr )) then + page_nr = 0; + end + meta:set_int( 'page_nr', page_nr+1 ); + +-- specific to the build chest + -- the player has choosen a material from the list; ask for a replacement + elseif( fields.build_chest_replacements ) then + local event = minetest.explode_table_event( fields.build_chest_replacements ); + local building_name = meta:get_string('building_name'); + if( event and event.row and event.row > 0 + and building_name + and build_chest.building[ building_name ] ) then + + meta:set_int('replace_row', event.row ); + end + + -- the player has asked for a particular replacement + elseif( fields.store_replacement + and fields.replace_row_with and fields.replace_row_with ~= "" + and fields.replace_row_material and fields.replace_row_material ~= "") then + + build_chest.replacements_apply( pos, meta, fields.replace_row_material, fields.replace_row_with ); + + elseif( fields.replace_rest_with_air ) then + build_chest.replacements_replace_rest_with_air( pos, meta ); + + elseif( fields.wood_selection ) then + build_chest.replacements_apply_for_group( pos, meta, 'wood', fields.wood_selection, fields.set_wood ); + fields.set_wood = nil; + + elseif( fields.farming_selection ) then + build_chest.replacements_apply_for_group( pos, meta, 'farming', fields.farming_selection, fields.set_farming ); + fields.set_farming = nil; + + elseif( fields.roof_selection ) then + build_chest.replacements_apply_for_group( pos, meta, 'roof', fields.roof_selection, fields.set_roof ); + fields.set_roof = nil; + + + elseif( fields.proceed_with_scaffolding ) then + local building_name = meta:get_string('building_name'); + local start_pos = minetest.deserialize( meta:get_string('start_pos')); + local end_pos = minetest.deserialize( meta:get_string('end_pos')); + local filename = meta:get_string('backup' ); + if( not( filename ) or filename == "" ) then + local base_filename = 'backup_'.. + meta:get_string('owner')..'_'.. + tostring( start_pos.x )..':'..tostring( start_pos.y )..':'..tostring( start_pos.z )..'_'.. + '0_0'; + + -- store a backup of the original landscape + -- /backup_PLAYERNAME_x_y_z_burried_rotation.mts + handle_schematics.create_schematic_with_meta( start_pos, end_pos, base_filename ); + meta:set_string('backup', base_filename ); + -- clear metadata so that the new building can be placed + handle_schematics.clear_meta( start_pos, end_pos ); + + minetest.chat_send_player( pname, 'CREATING backup schematic for this place in \"schems/'..base_filename..'.mts\".'); + end + +-- TODO: use scaffolding here (exchange some replacements) + local replacement_list = minetest.deserialize( meta:get_string( 'replacements' )); + local rotate = meta:get_string('rotate'); + local mirror = meta:get_string('mirror'); + local axis = build_chest.building[ building_name ].axis; + local no_plotmarker = 1; + -- actually place the building + --minetest.place_schematic( start_pos, building_name..'.mts', rotate, replacement_list, true ); +mirror = nil; + fields.error_msg = handle_schematics.place_building_from_file( start_pos, end_pos, building_name, replacement_list, rotate, axis, mirror, no_plotmarker ); + if( fields.error_msg ) then + fields.error_msg = 'Error: '..tostring( fields.error_msg ); + end + + -- restore the original landscape + elseif( fields.restore_backup ) then + local start_pos = minetest.deserialize( meta:get_string('start_pos')); + local end_pos = minetest.deserialize( meta:get_string('end_pos')); + local backup_file = meta:get_string( 'backup' ); + if( start_pos and end_pos and start_pos.x and end_pos.x and backup_file and backup_file ~= "" ) then + if( save_restore.file_exists( 'schems/'..backup_file..'.mts' )) then + filename = minetest.get_worldpath()..'/schems/'..backup_file..'.mts'; + minetest.place_schematic( start_pos, filename, "0", {}, true ); + -- no rotation needed - the metadata can be applied as-is (with the offset applied) + handle_schematics.restore_meta( backup_file, nil, start_pos, end_pos, 0, nil); + meta:set_string('backup', nil ); + end + end + + + -- store a new end position + elseif( fields.set_end_pos ) then + local node = minetest.get_node( pos ); + if( node and node.param2 ) then + build_chest.end_pos_list[ pname ] = {x=pos.x, y=pos.y, z=pos.z, param2=node.param2 }; + end + + + elseif( fields.set_start_pos ) then + local error_msg = ""; + local end_pos = build_chest.end_pos_list[ pname ]; + if( not( end_pos )) then + error_msg = "Please mark the end position of your building first!"; + else + local node = minetest.get_node( pos ); + if( not( node ) or not( node.param2 )) then + error_msg = "A strange error happened."; + elseif( (node.param2 == 0 and end_pos.param2 ~= 2) + or (node.param2 == 1 and end_pos.param2 ~= 3) + or (node.param2 == 2 and end_pos.param2 ~= 0) + or (node.param2 == 3 and end_pos.param2 ~= 1)) then + error_msg = "One build chest needs to point to the front of your building, and ".. + "the other one to the backside. This does not seem to be the case."; + + elseif( (node.param2 == 2 and ( pos.x < end_pos.x or pos.z < end_pos.z )) -- x and z need to get larger + or (node.param2 == 3 and ( pos.x < end_pos.x or pos.z > end_pos.z )) -- x gets larger, z gets smaller + or (node.param2 == 0 and ( pos.x > end_pos.x or pos.z > end_pos.z )) -- x and z need to get smaller + or (node.param2 == 1 and ( pos.x > end_pos.x or pos.z < end_pos.z )) -- x gets smaller, z gets larger + ) then + error_msg = "The end position does not fit to the orientation of this build chest."; + + -- the chest takes up one node as well + elseif( math.abs(pos.x-end_pos.x)<1) then + error_msg = "Start- and end position share the same x value."; + + elseif( math.abs(pos.z-end_pos.z)<1) then + error_msg = "Start- and end position share the same z value."; + + -- all ok; we may proceed + else + error_msg = ""; + build_chest.end_pos_list[ pname ].start_pos = {x=pos.x, y=pos.y, z=pos.z, param2=node.param2 }; + end + fields.error_msg = error_msg; + end + + -- in case the player selected the wrong chest for the save dialog + elseif( fields.abort_set_start_pos ) then + local end_pos = build_chest.end_pos_list[ pname ]; + if( end_pos ) then + build_chest.end_pos_list[ pname ].start_pos = nil; + end + + + elseif( fields.save_as ) then + if( fields.save_as_p1 and fields.save_as_p2 and fields.save_as_filename ) then + -- restore p1 and p2, the positions of the area that is to be saved + local p1 = minetest.string_to_pos( fields.save_as_p1 ); + local p2 = minetest.string_to_pos( fields.save_as_p2 ); + + -- take height changes into account + if( fields.save_as_height ) then + local new_height = tonumber( fields.save_as_height ); + -- the new height is measured from the start position as well + if( new_height and new_height ~= (math.abs(p1.y-p2.y)+1)) then + p2.y = p1.y+new_height; + end + end + + local burried = 0; + if( fields.save_as_yoff ) then + burried = tonumber( fields.save_as_yoff ); + if( not( burried )) then + burried = 0; + end + -- the yoffset is applied to the start position + p1.y = p1.y + burried; + -- TODO: real negative values are not supported by analyze_mts_file + if( burried ~= 0 ) then + burried = -1*burried; + end + end + + -- create an automatic filename if none is provided + local filename = fields.save_as_filename; + -- TODO: check the input if it contains only allowed chars (a-z, A-Z, 0-9, -, _, .) + if( not( filename )) then + filename = pname..'_'..tostring( p1 )..'_'..tostring(p2); + end + + -- param2 needs to be translated init initial rotation as well + local node = minetest.get_node( pos ); + if( node.param2 == 0 ) then + filename = filename..'_'..burried..'_90'; + elseif( node.param2 == 3 ) then + filename = filename..'_'..burried..'_180'; + elseif( node.param2 == 1 ) then + filename = filename..'_'..burried..'_0'; + elseif( node.param2 == 2 ) then + filename = filename..'_'..burried..'_270'; + end + -- TODO: forbid overwriting existing files? + local worldpath = minetest.get_worldpath(); + local filename_complete = worldpath..'/schems/'..filename..'.mts'; + + handle_schematics.create_schematic_with_meta( p1, p2, filename ); + + -- store that we have saved this area + meta:set_string('saved_as_filename', filename); + meta:set_string('p1', minetest.pos_to_string( p1 )); + meta:set_string('p2', minetest.pos_to_string( p2 )); + -- forget the end position + build_chest.end_pos_list[ pname ] = nil; + + -- add this chest to the menu + local worldnameparts = string.split( worldpath, '/worlds/' ); + if( not( worldnameparts ) or #worldnameparts < 1 ) then + worldnameparts = {'unkown world'}; + end + build_chest.add_entry( {'main','worlds', worldnameparts[ #worldnameparts], 'schems', filename, worldpath..'/schems/'..filename}); + build_chest.add_building( worldpath..'/schems/'..filename, {scm=filename, typ='nn'}); + + minetest.chat_send_player( pname, + 'Created schematic \''..tostring( filename )..'\'. Saved area from '.. + minetest.pos_to_string( p1 )..' to '.. + minetest.pos_to_string( p2 )); + end + end + -- the final build stage may offer further replacements + if( build_chest.stages_on_receive_fields ) then + build_chest.stages_on_receive_fields(pos, formname, fields, player, meta); + end + + local formspec = build_chest.update_formspec( pos, 'main', player, fields ); + -- add the position information so that we can show the formspec directly and still find out + -- which build chest was responsible + formspec = formspec.."field[20,20;0.1,0.1;pos2str;Pos;"..minetest.pos_to_string( pos ).."]"; + -- save the formspec data to the chest + meta:set_string( 'formspec', formspec ); + -- show the formspec directly to the player to make it react more smoothly + minetest.show_formspec( pname, "handle_schematics:build", formspec ); +end + + + +minetest.register_node("handle_schematics:build", { --TODO + description = "Building-Spawner", + tiles = {"default_chest_side.png", "default_chest_top.png", "default_chest_side.png", + "default_chest_side.png", "default_chest_side.png", "default_chest_front.png"}, +-- drawtype = 'signlike', +-- paramtype = "light", +-- paramtype2 = "wallmounted", +-- sunlight_propagates = true, +-- walkable = false, +-- selection_box = { +-- type = "wallmounted", +-- }, + + paramtype2 = "facedir", + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + legacy_facedir_simple = true, + after_place_node = function(pos, placer, itemstack) + + -- TODO: check if placement is allowed + + local meta = minetest.get_meta( pos ); + meta:set_string( 'current_path', minetest.serialize( {} )); + meta:set_string( 'village', 'BEISPIELSTADT' ); --TODO + meta:set_string( 'village_pos', minetest.serialize( {x=1,y=2,z=3} )); -- TODO + meta:set_string( 'owner', placer:get_player_name()); + + meta:set_string('formspec', build_chest.update_formspec( pos, 'main', placer, {} )); + end, + on_receive_fields = function( pos, formname, fields, player ) + return build_chest.on_receive_fields(pos, formname, fields, player); + end, + -- taken from towntest + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + if from_list=="needed" or to_list=="needed" then return 0 end + return count + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if listname=="needed" then return 0 end + return stack:get_count() + end, + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + if listname=="needed" then return 0 end +-- if listname=="lumberjack" then return 0 end + return stack:get_count() + end, + + can_dig = function(pos,player) + local meta = minetest.get_meta( pos ); + local inv = meta:get_inventory(); + local owner_name = meta:get_string( 'owner' ); + local building_name = meta:get_string( 'building_name' ); + local name = player:get_player_name(); + + if( not( meta ) or not( owner_name )) then + return true; + end + if( owner_name ~= name ) then + minetest.chat_send_player(name, "This building chest belongs to "..tostring( owner_name )..". You can't take it."); + return false; + end + if( building_name ~= nil and building_name ~= "" ) then + minetest.chat_send_player(name, "This building chest has been assigned to a building project. You can't take it away now."); + return false; + end + return true; + end, + + -- have all materials been supplied and the remaining parts removed? + on_metadata_inventory_take = function(pos, listname, index, stack, player) + local meta = minetest.get_meta( pos ); + local inv = meta:get_inventory(); + local stage = meta:get_int( 'building_stage' ); + + if( inv:is_empty( 'needed' ) and inv:is_empty( 'main' )) then + if( stage==nil or stage < 6 ) then + build_chest.update_needed_list( pos, stage+1 ); -- request the material for the very first building step + else + -- TODO: show this update directly to the player via minetest.show_formspec( pname, formname, formspec ); + meta:set_string( 'formspec', build_chest.update_formspec( pos, 'finished', player, {} )); + end + end + end, + + on_metadata_inventory_put = function(pos, listname, index, stack, player) + return build_chest.on_metadata_inventory_put( pos, listname, index, stack, player ); + end, + +}) + + +-- a player clicked on something in a formspec he was shown +handle_schematics.form_input_handler = function( player, formname, fields) + if(formname == "handle_schematics:build" and fields and fields.pos2str) then + local pos = minetest.string_to_pos( fields.pos2str ); + build_chest.on_receive_fields(pos, formname, fields, player); + end +end + +-- make sure we receive player input; needed for showing formspecs directly (which is in turn faster than just updating the node) +minetest.register_on_player_receive_fields( handle_schematics.form_input_handler ); diff --git a/mods/a_mapgen_mods/handle_schematics/build_chest_add_schems_by_directory.lua b/mods/a_mapgen_mods/handle_schematics/build_chest_add_schems_by_directory.lua new file mode 100644 index 00000000..4359d647 --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/build_chest_add_schems_by_directory.lua @@ -0,0 +1,164 @@ +local build_chest_add_files_to_menu_from_directory = function( schem, path, entry_name, backup_name, menu_path_list) + -- we need the filename without extension (*.mts, *.we, *.wem) + local schemname = schem; + local i = string.find( schem, '.mts', -4 ); + if( i ) then + schemname = string.sub( schem, 1, i-1 ); + else + i = string.find( schem, '.we', -3 ); + if( i ) then + schemname = string.sub( schem, 1, i-1 ); + else + i = string.find( schem, '.wem', -4 ); + if( i ) then + schemname = string.sub( schem, 1, i-1 ); + else + return; + end + end + end + + -- only add known file types + if( not( schemname )) then + return; + end + + i = string.find( schemname, 'backup_' ); + menu_path_list[ #menu_path_list+1 ] = schemname; + menu_path_list[ #menu_path_list+1 ] = path..schemname; + -- probably one of those automatic backups of the landscape + if( i and i==1 and backup_name) then + menu_path_list[1] = backup_name; + -- normal entry + else + menu_path_list[1] = entry_name; + end + build_chest.add_entry( menu_path_list); + build_chest.add_building( path..schemname, {scm=schemname, typ='nn'}); +end + + +-- search for mods and modpacks containing schematics in any form +local build_chest_check_all_directories_mods_and_modpacks = function( path, menu_title, gamename ) + local d2 = minetest.get_dir_list( path..'/mods', true ); + for _,modname in ipairs( d2 ) do + local d3 = minetest.get_dir_list( path..'/mods/'..modname, true ); + for _,subdir in ipairs( d3 ) do + if( subdir ~= 'textures' and subdir ~= 'sounds' and subdir ~= 'models' and subdir ~= '.git' and subdir ~= 'locale') then + local d4 = minetest.get_dir_list( path..'/mods/'..modname..'/'..subdir, false ); + for _,filename in ipairs( d4 ) do + build_chest_add_files_to_menu_from_directory( + filename, + path..'/mods/'..modname..'/'..subdir..'/', + menu_title, + nil, + {'OVERWRITE THIS', gamename, modname} ); + end + -- it might be a modpack + d4 = minetest.get_dir_list( path..'/mods/'..modname..'/'..subdir, true ); + for _,subsubdir in ipairs( d4 ) do + if( subsubdir ~= 'textures' and subsubdir ~= 'sounds' and subsubdir ~= 'models' and subsubdir ~= '.git' and subsubdir ~= 'locale') then + local d5 = minetest.get_dir_list( path..'/mods/'..modname..'/'..subdir..'/'..subsubdir, false ); + for _,filename in ipairs( d5 ) do + build_chest_add_files_to_menu_from_directory( + filename, + path..'/mods/'..modname..'/'..subdir..'/'..subsubdir..'/', + menu_title, + nil, + -- folders from modpacks get marked with a *..* + {'OVERWRITE THIS', gamename, '*'..subdir..'*'} ); + end + end + end + end + end + end +end + + +local build_chest_check_all_directories = function() + -- find the name of the directory directly above the current worldpath + local worldpath = minetest.get_worldpath(); + + local p = 1; + local last_found = 1; + while( last_found ) do + p = last_found; + last_found = string.find( worldpath, '/', last_found+1 ); + end + -- abort on Windows + if( p == 1 ) then + return; + end + worldpath = string.sub( worldpath, 1, p ); + +--[[ + local p = 1; + while( not( string.find( worldpath, '/', -1*p ))) do + p = p+1; + end + local found = 1; + for p=string.len( worldpath ),1,-1 do + if( p>found + and (string.byte( worldpath, p )=='/' + or string.byte( worldpath, p )=='\\')) then + found = p; + end + end +--]] + worldpath = string.sub( worldpath, 1, string.len( worldpath )-p ); + + + -- locate .mts, .wem and .we files in the worlds/WORLDNAME/schems/* folders + local d1 = minetest.get_dir_list( worldpath, true ); + for _,worldname in ipairs( d1 ) do + -- get list of subdirectories + local d2 = minetest.get_dir_list( worldpath..'/'..worldname, true ); + for _,subdir in ipairs( d2 ) do + if( subdir=='schems' ) then + local d3 = minetest.get_dir_list( worldpath..'/'..worldname..'/schems', false ); + for _,filename in ipairs( d3 ) do + build_chest_add_files_to_menu_from_directory( + filename, + worldpath..'/'..worldname..'/schems/', + 'import from world', + 'landscape backups', + {'OVERWRITE THIS', worldname }); + end + end + end + end + + local main_path = string.sub( worldpath, 1, string.len(worldpath)-string.len('/worlds')); + + -- search in MODS/* subfolder + build_chest_check_all_directories_mods_and_modpacks( main_path, 'import from mod', 'mods' ); + + -- search in all GAMES/* folders for mods containing schematics + local game_path = main_path..'/games'; + d1 = minetest.get_dir_list( game_path, true ); + for _,gamename in ipairs( d1 ) do + build_chest_check_all_directories_mods_and_modpacks( game_path..'/'..gamename, 'import from game', gamename ); + end +end + + +-- TODO: hopfefully, security will get more relaxed regarding reading directories in the future +-- if security is enabled, our options to get schematics are a bit limited +if( minetest.setting_getbool( 'secure.enable_security' )) then + local worldpath = minetest.get_worldpath(); + local d3 = minetest.get_dir_list( worldpath..'/schems', false ); + if( d3 ) then + for _,filename in ipairs( d3 ) do + build_chest_add_files_to_menu_from_directory( + filename, + worldpath..'/schems/', + 'import from world', + 'landscape backups', + {'OVERWRITE THIS', '-current world-' }); + end + end +else + -- check worlds, mods and games folders for schematics and add them to the menu + build_chest_check_all_directories() +end diff --git a/mods/a_mapgen_mods/handle_schematics/build_chest_add_schems_from_file.lua b/mods/a_mapgen_mods/handle_schematics/build_chest_add_schems_from_file.lua new file mode 100644 index 00000000..883c223f --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/build_chest_add_schems_from_file.lua @@ -0,0 +1,58 @@ + + +build_chest.add_files_to_menu = function( path, add_path ) + local file,err = io.open( path, "rb") + if (file == nil) then + return; + end + + local text = file:read("*a"); + file:close(); + + for schem_file_name in string.gmatch(text, "([^\r\n]*)[\r\n]*") do + if( schem_file_name and schem_file_name ~= "" ) then + local help = string.split( schem_file_name, '/', true, -1, false); + + local i = #help; + local found = 1; + -- search from the end of the file name for the first occourance of "mods" or "worlds" + -- as that will be the path where we will put it into the menu + while (i>1 and found==1) do + if( help[i]=='mods' or help[i]=='worlds' ) then + found = i; + end + i = i-1; + end + + local name = help[#help]; + local length1 = string.len( name ); + local length2 = string.len( schem_file_name ); + -- remove the file name extension + if( string.sub( name, -4 )=='.mts' ) then + name = string.sub( name, 1, length1-4 ); + schem_file_name = string.sub( schem_file_name, 1, length2-4 ); + elseif( string.sub( name, -3 )=='.we' ) then + name = string.sub( name, 1, length1-3 ); + schem_file_name = string.sub( schem_file_name, 1, length2-3 ); + elseif( string.sub( name, -10 )==".schematic" ) then + name = string.sub( name, 1, length1-10); + schem_file_name = string.sub( schem_file_name, 1, length2-10); + end + help[#help] = name; + + -- build the new menu path + local menu_path = {'main'}; + for j=(i+1),#help do + table.insert( menu_path, help[j] ); + end + schem_file_name = add_path..schem_file_name; + table.insert( menu_path, schem_file_name ); + + build_chest.add_entry( menu_path ); + build_chest.add_building( schem_file_name, {scm=help[#help], typ='nn'}); + + end + end +end + +build_chest.add_files_to_menu( minetest.get_modpath( minetest.get_current_modname()).."/list_of_schematics.txt", ""); diff --git a/mods/a_mapgen_mods/handle_schematics/build_chest_handle_replacements.lua b/mods/a_mapgen_mods/handle_schematics/build_chest_handle_replacements.lua new file mode 100644 index 00000000..f09e0a3d --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/build_chest_handle_replacements.lua @@ -0,0 +1,256 @@ +------------------------------------------------------------- +--- contains the handling of replacements for the build chest +------------------------------------------------------------- + +-- internal function +build_chest.replacements_get_extra_buttons = function( group, name, types_found_list, button_name, extra_buttons ) + -- find out if there are any nodes that may need a group replacement + local found_type = ""; + for k,w in ipairs( replacements_group[ group ].all ) do + -- we have found the full block of that group type + if( name == w ) then + found_type = w; + -- no primary node found; there may still be subordinate types + else + for nr,t in ipairs( replacements_group[ group ].data[ w ] ) do + if( name==t and not( types_found_list[ w ])) then + found_type = w; + end + end + end + end + if( found_type ~= "" and not( types_found_list[ found_type ])) then + extra_buttons.offset = extra_buttons.offset + 1; + extra_buttons.text = extra_buttons.text.."button[9.9,".. + tostring( (extra_buttons.offset*0.9)+2.8 )..";3.0,0.5;".. + tostring( button_name )..";".. + minetest.formspec_escape( found_type ).."]"; + -- remember that we found and offered this type already; avoid duplicates + types_found_list[ found_type ] = 1; + end + return extra_buttons; +end + + + +build_chest.replacements_get_list_formspec = function( pos, selected_row ) + if( not( pos )) then + return ""; + end + local meta = minetest.env:get_meta( pos ); + local replacements = minetest.deserialize( meta:get_string( 'replacements' )); + local building_name = meta:get_string( 'building_name' ); + if( not( building_name ) or not( build_chest.building[ building_name ])) then + return ""; + end + local replace_row = meta:get_int('replace_row'); + + local formspec = "tableoptions[" .. + "color=#ff8000;" .. + "background=#0368;" .. + "border=true;" .. + --"highlight=#00008040;" .. + "highlight=#aaaaaaaa;" .. + "highlight_text=#7fffff]" .. + "tablecolumns[" .. + "color;" .. + "text,width=1,align=right;" .. + "color;" .. + "text,width=5;" .. + "color;" .. + "text,width=1;" .. + "color;" .. + "text,width=5]" .. +-- "tabheader[".. +-- "1,1;columns;amount,original material,,target material;1;true;true]".. + "table[".. + "0.5,2.7;9.4,6.8;build_chest_replacements;"; + + local j=1; + local may_proceed = true; + local replace_row_material = nil; + local replace_row_with = ""; + -- make sure the statistic has been created + if( not( build_chest.building[ building_name ].statistic )) then + if( not( build_chest.read_building( building_name ))) then + return "label[2,2;Error: Unable to read building file.]"; + end + end + + -- used for setting wood type or plant(farming) type etc. + local extra_buttons = { text = "", offset = 0}; + -- there may be wood types that only occour as stairs and/or slabs etc., without full blocks + local types_found_list_wood = {}; + local types_found_list_farming = {}; + local types_found_list_roof = {}; + + local not_the_first_entry = false; + for i,v in ipairs( build_chest.building[ building_name ].statistic ) do + local name = build_chest.building[ building_name ].nodenames[ v[1]]; + -- nodes that are to be ignored do not need to be replaced + if( name ~= 'air' and name ~= 'ignore' and name ~= 'mg:ignore' and v[2] and v[2]>0) then + local anz = v[2]; + -- find out if this node name gets replaced + local repl = name; + for j,r in ipairs( replacements ) do + if( r and r[1]==name ) then + repl = r[2]; + end + end + + -- avoid empty lines at the end + if( not_the_first_entry ) then + formspec = formspec..','; + end + + formspec = formspec..'#fff,'..tostring( anz )..','; + if( name == repl and repl and minetest.registered_nodes[ repl ]) then + formspec = formspec.."#0ff,,#fff,,"; + else + if( name and minetest.registered_nodes[ name ] ) then + formspec = formspec.."#0f0,"; -- green + else + formspec = formspec.."#ff0,"; -- yellow + end + formspec = formspec..name..',#fff,'..minetest.formspec_escape('-->')..','; + end + + if( repl and (minetest.registered_nodes[ repl ] or repl=='air') ) then + formspec = formspec.."#0f0,"..repl; -- green + else + formspec = formspec.."#ff0,?"; -- yellow + may_proceed = false; -- we need a replacement for this material + end + + if( j == replace_row ) then + replace_row_material = name; + if( repl ~= name ) then + replace_row_with = repl; + end + end + + extra_buttons = build_chest.replacements_get_extra_buttons( 'wood', name, types_found_list_wood, 'set_wood', extra_buttons ); + extra_buttons = build_chest.replacements_get_extra_buttons( 'farming', name, types_found_list_farming, 'set_farming', extra_buttons ); + extra_buttons = build_chest.replacements_get_extra_buttons( 'roof', name, types_found_list_farming, 'set_roof', extra_buttons ); + + j=j+1; + + not_the_first_entry = true; + end + end + formspec = formspec.."]"; + -- add the proceed-button as soon as all unkown materials have been replaced + if( may_proceed ) then + formspec = formspec.."button[9.9,9.0;2.0,0.5;proceed_with_scaffolding;Proceed]"; + else + formspec = formspec.."button[9.9,9.0;3.2,0.5;replace_rest_with_air;Suggest air for unknown]"; + end + formspec = formspec.."button[9.9,1.0;2.0,0.5;preview;Preview]"; + if( extra_buttons.text and extra_buttons.text ~= "" ) then + formspec = formspec..extra_buttons.text.. + "label[9.9,2.8;Replace by type:]"; + end + if( replace_row_material ) then + formspec = formspec.. + "label[0.5,2.1;Replace ".. + minetest.formspec_escape( replace_row_material ).."]".. + "label[6.5,2.1;with:]".. + "field[7.5,2.4;4,0.5;replace_row_with;;".. + minetest.formspec_escape( replace_row_with ).."]".. + "field[-10,-10;0.1,0.1;replace_row_material;;".. + minetest.formspec_escape( replace_row_material ).."]".. + "button[11.1,2.1;1,0.5;store_replacement;Store]"; + end + return formspec; +end + + +-- set replacements for all unknown nodes to air so that the building can be spawned +build_chest.replacements_replace_rest_with_air = function( pos, meta ) + local building_name = meta:get_string( 'building_name' ); + if( not( building_name ) or not( build_chest.building[ building_name ])) then + return; + end + local replacements_orig = minetest.deserialize( meta:get_string( 'replacements' )); + for i,v in ipairs( build_chest.building[ building_name ].statistic ) do + local name = build_chest.building[ building_name ].nodenames[ v[1]]; + -- nodes that are to be ignored do not need to be replaced + if( name ~= 'air' and name ~= 'ignore' and name ~= 'mg:ignore' and v[2] and v[2]>0) then + -- find out if this node name gets replaced + local repl = name; + for j,r in ipairs( replacements_orig ) do + if( r and r[1]==name ) then + repl = r[2]; + -- set replacements for inexisting nodes to air + if( not( minetest.registered_nodes[ repl ] )) then + r[2] = 'air'; + end + end + end + + -- replace nodes that do not exist with air + if( not( repl ) or not( minetest.registered_nodes[ repl ])) then + table.insert( replacements_orig, { name, 'air' }); + end + end + end + -- store the new set of replacements + meta:set_string( 'replacements', minetest.serialize( replacements_orig )); +end + + + +build_chest.replacements_apply = function( pos, meta, old_material, new_material ) + -- a new value has been entered - we do not need to remember the row any longer + meta:set_int('replace_row', 0 ); + local found = false; + -- only accept replacements which can actually be placed + if( new_material=='air' or minetest.registered_nodes[ new_material ] ) then + local replacements_orig = minetest.deserialize( meta:get_string( 'replacements' )); + for i,v in ipairs(replacements_orig) do + if( v and v[1]==old_material ) then + v[2] = new_material; + found = true; + end + end + if( not( found )) then + table.insert( replacements_orig, { old_material, new_material }); + end + -- store the new set of replacements + meta:set_string( 'replacements', minetest.serialize( replacements_orig )); + end +end + + +build_chest.replacements_get_group_list_formspec = function( pos, group, button_name ) + local formspec = ""; + for i,v in ipairs( replacements_group[ group ].found ) do + formspec = formspec.."item_image_button["..tostring(((i-1)%8)+1)..",".. + tostring(3+math.floor((i-1)/8))..";1,1;".. + tostring( v )..";"..tostring( button_name )..";"..tostring(i).."]"; + end + return formspec; +end + + +build_chest.replacements_apply_for_group = function( pos, meta, group, selected, old_material ) + local nr = tonumber( selected ); + if( not(nr) or nr <= 0 or nr > #replacements_group[ group ].found ) then + return; + end + + local new_material = replacements_group[ group ].found[ nr ]; + if( old_material and old_material == new_material ) then + return; + end + + local replacements = minetest.deserialize( meta:get_string( 'replacements' )); + if( not( replacements )) then + replacements = {}; + end + replacements_group[ group ].replace_material( replacements, old_material, new_material ); + + -- store the new set of replacements + meta:set_string( 'replacements', minetest.serialize( replacements )); +end + diff --git a/mods/a_mapgen_mods/handle_schematics/build_chest_preview_image.lua b/mods/a_mapgen_mods/handle_schematics/build_chest_preview_image.lua new file mode 100644 index 00000000..82eae3e3 --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/build_chest_preview_image.lua @@ -0,0 +1,248 @@ + +build_chest.preview_image_draw_tile = function( content_id, image, x, z, dx, dz, tile_nr ) + if( not( image )) then + local node_name = minetest.get_name_from_content_id( content_id ); + if( not( node_name )) then + return ''; + end + local node_def = minetest.registered_nodes[ node_name ]; + if( not( node_def )) then + return ''; + end + local tiles = node_def.tiles; + if( not( tiles )) then + tiles = node_def.tile_images; + end + local tile = nil; + if( tiles ~= nil ) then + if( not(tile_nr) or tile_nr > #tiles or tile_nr < 1 ) then + tile_nr = 1; + end + tile = tiles[tile_nr]; + end + if type(tile)=="table" then + tile=tile["name"] + end + image = tile; + if( not( image )) then + image = "unknown_object.png"; + end + end + return "image["..tostring(x)..",".. tostring(z) ..";"..dx..','..dz..";" .. image .."]"; +end + + + +-- creates a 2d preview image (or rather, the data structure for it) of the building +-- internal function +build_chest.preview_image_create_one_view = function( data, side ) + local params = {1, data.size.x, 1, 1, data.size.z, 1, 0, 0}; + if( side==1 ) then + params = {1, data.size.x, 1, 1, data.size.z, 1, 0, 0}; + elseif( side==2 ) then + params = {1, data.size.z, 1, 1, data.size.x, 1, 1, 1}; + elseif( side==3 ) then + params = {1, data.size.x, 1, data.size.z, 0, -1, 0, 1}; + elseif( side==4 ) then + params = {1, data.size.z, 1, data.size.x, 0, -1, 1, 0}; + end + + -- do not create preview images for buildings that are too big + if( params[2] * params[4] > 2500 ) then + return nil; + end + local preview = {}; + for y = 1, data.size.y do + preview[ y ] = {}; + for x = params[1], params[2], params[3] do + local found = nil; + local z = params[4]; + local target_x = x; + if( params[8]==1 ) then + target_x = math.max( params[1],params[2] )- x; + end + while( not( found ) and z~= params[5]) do + local node = -1; + if( params[7]==0 ) then + node = data.scm_data_cache[y][x][z]; + else + node = data.scm_data_cache[y][z][x]; + end + if( node and node[1] + and data.nodenames[ node[1] ] + and data.nodenames[ node[1] ] ~= 'air' + and data.nodenames[ node[1] ] ~= 'ignore' + and data.nodenames[ node[1] ] ~= 'mg:ignore' + and data.nodenames[ node[1] ] ~= 'default:torch' ) then + -- a preview node is only set if there's no air there + preview[y][target_x] = node[1]; + found = 1; + end + z = z+params[6]; + end + if( not( found )) then + preview[y][target_x] = -1; + end + end + end + return preview; +end + +-- internal function +build_chest.preview_image_create_view_from_top = function( data ) + -- no view from top if the image is too big + if( data.size.z * data.size.y > 2500 ) then + return nil; + end + + local preview = {}; + for z = 1, data.size.z do + preview[ z ] = {}; + for x = 1, data.size.x do + local found = nil; + local y = data.size.y; + while( not( found ) and y > 1) do + local node = data.scm_data_cache[y][x][z]; + if( node and node[1] + and data.nodenames[ node[1] ] + and data.nodenames[ node[1] ] ~= 'air' + and data.nodenames[ node[1] ] ~= 'ignore' + and data.nodenames[ node[1] ] ~= 'mg:ignore' + and data.nodenames[ node[1] ] ~= 'default:torch' ) then + -- a preview node is only set if there's no air there + preview[z][x] = node[1]; + found = 1; + end + y = y-1; + end + if( not( found )) then + preview[z][x] = -1; + end + end + end + return preview; +end + + +-- function called by the build chest to display one view +build_chest.preview_image_formspec = function( building_name, replacements, side_name ) + if( not( building_name ) + or not( build_chest.building[ building_name ] ) + or not( build_chest.building[ building_name ].preview )) then + return ""; + end + + local side_names = {"front","right","back","left","top"}; + local side = 1; + for i,v in ipairs( side_names ) do + if( side_name and side_name==v ) then + side = i; + end + end + + local formspec = ""; + for i=1,5 do + if( i ~= side ) then + formspec = formspec.."button["..tostring(3.3+1.2*(i-1)).. + ",2.2;1,0.5;preview;"..side_names[i].."]"; + else + formspec = formspec.."label["..tostring(3.3+1.2*(i-1))..",2.2;"..side_names[i].."]"; + end + end + + local data = build_chest.building[ building_name ]; + + -- the draw_tile function is based on content_id + local content_ids = {}; + for i,v in ipairs( data.nodenames ) do + local found = false; + for j,w in ipairs( replacements ) do + if( w and w[1] and w[1]==v) then + found = true; + if( minetest.registered_nodes[ w[2]] ) then + content_ids[ i ] = minetest.get_content_id( w[2] ); + end + end + end + if( not( found )) then + if( minetest.registered_nodes[ v ]) then + content_ids[ i ] = minetest.get_content_id( v ); + elseif( v ~= 'air' ) then + content_ids[ i ] = -1; + end + end + end + + local scale = 0.5; + + local tile_nr = 3; -- view from the side + if( side ~= 5 ) then + local scale_y = 6.0/data.size.y; + local scale_z = 10.0/data.size.z; + if( scale_y > scale_z) then + scale = scale_z; + else + scale = scale_y; + end + else + local scale_x = 10.0/data.size.x; -- only relevant for view from top + local scale_z = 6.0/data.size.z; + if( scale_x > scale_z) then + scale = scale_z; + else + scale = scale_x; + end + tile_nr = 1; -- view from top + end + + if( not( side )) then + side = 1; + end + local preview = data.preview[ side ]; + if( not( preview )) then + formspec = formspec.."label[3,3;Sorry, this schematic is too big for a preview image.]"; + return formspec; + end + for y,y_values in ipairs( preview ) do + for l,v in ipairs( y_values ) do + -- air, ignore and mg:ignore are not stored + if( v and content_ids[ v ]==-1 ) then + formspec = formspec..build_chest.preview_image_draw_tile( nil, "unknown_node.png", (l*scale), 9-(y*scale), scale*1.3, scale*1.2, tile_nr); + elseif( v and v>0 and content_ids[v]) then + formspec = formspec..build_chest.preview_image_draw_tile( content_ids[ v ], nil, (l*scale), 9-(y*scale), scale*1.3, scale*1.2, tile_nr); + end + end + end + return formspec; +end + + +-- create all five preview images +build_chest.preview_image_create_views = function( res, orients ) + + -- create a 2d overview image (or rather, the data structure for it) + local preview = { + build_chest.preview_image_create_one_view( res, 2 ), + build_chest.preview_image_create_one_view( res, 1 ), + build_chest.preview_image_create_one_view( res, 4 ), + build_chest.preview_image_create_one_view( res, 3 )}; + + -- the building might be stored in rotated form + if( orients and #orients and orients[1] ) then + if( orients[1]==1 ) then + preview = {preview[2],preview[3],preview[4],preview[1]}; + elseif( orients[1]==2 ) then + preview = {preview[3],preview[4],preview[1],preview[2]}; + elseif( orients[1]==3 ) then + preview = {preview[4],preview[1],preview[2],preview[3]}; + end + end + -- ...and add a preview image from top + preview[5] = build_chest.preview_image_create_view_from_top( res ); + return preview; +end + + + + +-- this function makes sure that the building will always extend to the right and in front of the build chest diff --git a/mods/a_mapgen_mods/handle_schematics/depends.txt b/mods/a_mapgen_mods/handle_schematics/depends.txt new file mode 100644 index 00000000..7404eac4 --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/depends.txt @@ -0,0 +1,23 @@ +default? +doors? +farming? +wool? +stairs? +cottages? +moretrees? +trees? +forest? +dryplants? +cavestuff? +snow? +moresnow? +darkage? +ethereal? +deco? +metals? +grounds? +moreblocks? +bell? +mobf_trader? +docfarming? +mccompat? diff --git a/mods/a_mapgen_mods/handle_schematics/handle_schematics_meta.lua b/mods/a_mapgen_mods/handle_schematics/handle_schematics_meta.lua new file mode 100644 index 00000000..7762c5c6 --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/handle_schematics_meta.lua @@ -0,0 +1,162 @@ + + +handle_schematics.sort_pos_get_size = function( p1, p2 ) + local res = {x=p1.x, y=p1.y, z=p1.z, + sizex = math.abs( p1.x - p2.x )+1, + sizey = math.abs( p1.y - p2.y )+1, + sizez = math.abs( p1.z - p2.z )+1}; + if( p2.x < p1.x ) then + res.x = p2.x; + end + if( p2.y < p1.y ) then + res.y = p2.y; + end + if( p2.z < p1.z ) then + res.z = p2.z; + end + return res; +end + + + +local handle_schematics_get_meta_table = function( pos, all_meta, start_pos ) + local m = minetest.get_meta( pos ):to_table(); + local empty_meta = true; + + -- the inventory part contains functions and cannot be fed to minetest.serialize directly + local invlist = {}; + local count_inv = 0; + local inv_is_empty = true; + for name, list in pairs( m.inventory ) do + invlist[ name ] = {}; + count_inv = count_inv + 1; + for i, stack in ipairs(list) do + if( not( stack:is_empty())) then + invlist[ name ][ i ] = stack:to_string(); + empty_meta = false; + inv_is_empty = false; + end + end + end + -- the fields part at least is unproblematic + local count_fields = 0; + if( empty_meta and m.fields ) then + for k,v in pairs( m.fields ) do + empty_meta = false; + count_fields = count_fields + 1; + end + end + + -- ignore default:sign_wall without text on it + if( count_inv==0 + and count_fields<=3 and m.fields.formspec and m.fields.infotext + and m.fields.formspec == "field[text;;${text}]" + and m.fields.infotext == "\"\"") then + -- also consider signs empty if their text has been set once and deleted afterwards + if( not( m.fields.text ) or m.fields.text == "" ) then +print('SKIPPING empty sign AT '..minetest.pos_to_string( pos)..' while saving metadata.'); + empty_meta = true; + end + + elseif( count_inv > 0 and inv_is_empty + and count_fields>0 and m.fields.formspec ) then + + local n = minetest.get_node( pos ); + if( n and n.name + and (n.name=='default:chest' or n.name=='default:chest_locked' or n.name=='default:bookshelf' + or n.name=='default:furnace' or n.name=='default:furnace_active' + or n.name=='cottages:shelf' or n.name=='cottages:anvil' or n.name=='cottages:threshing_floor' )) then +print('SKIPPING empty '..tostring(n.name)..' AT '..minetest.pos_to_string( pos )..' while saving metadata.'); + empty_meta = true; + end + end + + + -- only save if there is something to be saved + if( not( empty_meta )) then + -- positions are stored as relative positions + all_meta[ #all_meta+1 ] = { + x=pos.x-start_pos.x, + y=pos.y-start_pos.y, + z=pos.z-start_pos.z, + fields = m.fields, + inventory = invlist}; + end +end + +-- reads metadata values from start_pos to end_pos and stores them in a file +handle_schematics.save_meta = function( start_pos, end_pos, filename ) + local all_meta = {}; + local p = handle_schematics.sort_pos_get_size( start_pos, end_pos ); + + if( minetest.find_nodes_with_meta ) then + for _,pos in ipairs( minetest.find_nodes_with_meta( start_pos, end_pos )) do + handle_schematics_get_meta_table( pos, all_meta, p ); + end + else + for x=p.x, p.x+p.sizex do + for y=p.y, p.y+p.sizey do + for z=p.z, p.z+p.sizez do + handle_schematics_get_meta_table( {x=x-p.x, y=y-p.y, z=z-p.z}, all_meta, p ); + end + end + end + end + + if( #all_meta > 0 ) then + save_restore.save_data( 'schems/'..filename..'.meta', all_meta ); + end +end + +-- all metadata values will be deleted when this function is called, +-- making the area ready for new voxelmanip/schematic data +handle_schematics.clear_meta = function( start_pos, end_pos ) + local empty_meta = { inventory = {}, fields = {} }; + + if( minetest.find_nodes_with_meta ) then + for _,pos in ipairs( minetest.find_nodes_with_meta( start_pos, end_pos )) do + local meta = minetest.get_meta( pos ); + meta:from_table( empty_meta ); + end + end +end + + +-- restore metadata from file +-- TODO: use relative instead of absolute positions (already done for .we files) +-- TODO: handle mirror +handle_schematics.restore_meta = function( filename, all_meta, start_pos, end_pos, rotate, mirror ) + + if( not( all_meta ) and filename ) then + all_meta = save_restore.restore_data( 'schems/'..filename..'.meta' ); + end + for _,pos in ipairs( all_meta ) do + local p = {}; + if( rotate == 0 ) then + p = {x=start_pos.x+pos.x-1, y=start_pos.y+pos.y-1, z=start_pos.z+pos.z-1}; + elseif( rotate == 1 ) then + p = {x=start_pos.x+pos.z-1, y=start_pos.y+pos.y-1, z=end_pos.z -pos.x+1}; + elseif( rotate == 2 ) then + p = {x=end_pos.x -pos.x+1, y=start_pos.y+pos.y-1, z=end_pos.z -pos.z+1}; + elseif( rotate == 3 ) then + p = {x=end_pos.x -pos.z+1, y=start_pos.y+pos.y-1, z=start_pos.z+pos.x-1}; + end + local meta = minetest.get_meta( p ); + meta:from_table( {inventory = pos.inventory, fields = pos.fields }); + end +end + + +-- return true on success; will overwrite existing files +handle_schematics.create_schematic_with_meta = function( p1, p2, base_filename ) + + -- create directory for the schematics (same path as WorldEdit uses) + save_restore.create_directory( '/schems' ); + local complete_filename = minetest.get_worldpath()..'/schems/'..base_filename..'.mts'; + -- actually create the schematic + minetest.create_schematic( p1, p2, nil, complete_filename, nil); + -- save metadata; the file will only be created if there is any metadata that is to be saved + handle_schematics.save_meta( p1, p2, base_filename ); + + return save_restore.file_exists( complete_filename ); +end diff --git a/mods/a_mapgen_mods/handle_schematics/handle_schematics_misc.lua b/mods/a_mapgen_mods/handle_schematics/handle_schematics_misc.lua new file mode 100644 index 00000000..64360a92 --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/handle_schematics_misc.lua @@ -0,0 +1,107 @@ + +-- helper function; sorts by the second element of the table +local function handle_schematics_comp(a,b) + if (a[2] > b[2]) then + return true; + end +end + +-- create a statistic about how frequent each node name occoured +handle_schematics.count_nodes = function( data ) + local statistic = {}; + -- make sure all node names are counted (air may sometimes be included without occouring) + for id=1, #data.nodenames do + statistic[ id ] = { id, 0}; + end + + for z = 1, data.size.z do + for y = 1, data.size.y do + for x = 1, data.size.x do + + local a = data.scm_data_cache[y][x][z]; + if( a ) then + local id = 0; + if( type( a )=='table' ) then + id = a[1]; + else + id = a; + end + if( statistic[ id ] and statistic[ id ][ 2 ] ) then + statistic[ id ] = { id, statistic[ id ][ 2 ]+1 }; + end + end + end + end + end + table.sort( statistic, handle_schematics_comp ); + return statistic; +end + + +-- this function makes sure that the building will always extend to the right and in front of the build chest +handle_schematics.translate_param2_to_rotation = function( param2, mirror, start_pos, orig_max, rotated, burried, orients, yoff ) + + -- mg_villages stores available rotations of buildings in orients={0,1,2,3] format + if( orients and #orients and orients[1]~=0) then + -- reset rotated - else we'd apply it twice + rotated = 0; + if( orients[1]==1 ) then + rotated = rotated + 90; + elseif( orients[1]==2 ) then + rotated = rotated + 180; + elseif( orients[1]==3 ) then + rotated = rotated + 270; + end + if( rotated >= 360 ) then + rotated = rotated % 360; + end + end + + local max = {x=orig_max.x, y=orig_max.y, z=orig_max.z}; + -- if the schematic has been saved in a rotated way, swapping x and z may be necessary + if( rotated==90 or rotated==270) then + max.x = orig_max.z; + max.z = orig_max.x; + end + + -- the building may have a cellar or something alike + if( burried and burried ~= 0 and yoff == nil ) then + start_pos.y = start_pos.y - burried; + end + + -- make sure the building always extends forward and to the right of the player + local rotate = 0; + if( param2 == 0 ) then rotate = 270; if( mirror==1 ) then start_pos.x = start_pos.x - max.x + max.z; end -- z gets larger + elseif( param2 == 1 ) then rotate = 0; start_pos.z = start_pos.z - max.z; -- x gets larger + elseif( param2 == 2 ) then rotate = 90; start_pos.z = start_pos.z - max.x; + if( mirror==0 ) then start_pos.x = start_pos.x - max.z; -- z gets smaller + else start_pos.x = start_pos.x - max.x; end + elseif( param2 == 3 ) then rotate = 180; start_pos.x = start_pos.x - max.x; -- x gets smaller + end + + if( param2 == 1 or param2 == 0) then + start_pos.z = start_pos.z + 1; + elseif( param2 == 1 or param2 == 2 ) then + start_pos.x = start_pos.x + 1; + end + if( param2 == 1 ) then + start_pos.x = start_pos.x + 1; + end + + rotate = rotate + rotated; + -- make sure the rotation does not reach or exceed 360 degree + if( rotate >= 360 ) then + rotate = rotate - 360; + end + -- rotate dimensions when needed + if( param2==0 or param2==2) then + local tmp = max.x; + max.x = max.z; + max.z = tmp; + end + + return { rotate=rotate, start_pos = {x=start_pos.x, y=start_pos.y, z=start_pos.z}, + end_pos = {x=(start_pos.x+max.x-1), y=(start_pos.y+max.y-1), z=(start_pos.z+max.z-1) }, + max = {x=max.x, y=max.y, z=max.z}}; +end + diff --git a/mods/a_mapgen_mods/handle_schematics/init.lua b/mods/a_mapgen_mods/handle_schematics/init.lua new file mode 100644 index 00000000..663ecc0a --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/init.lua @@ -0,0 +1,61 @@ + +handle_schematics = {} + +handle_schematics.modpath = minetest.get_modpath( "handle_schematics"); + +-- adds worldedit_file.* namespace +-- deserialize worldedit savefiles +dofile(handle_schematics.modpath.."/worldedit_file.lua") + +-- uses handle_schematics.* namespace +-- reads and analyzes .mts files (minetest schematics) +dofile(handle_schematics.modpath.."/analyze_mts_file.lua") +-- reads and analyzes worldedit files +dofile(handle_schematics.modpath.."/analyze_we_file.lua") +-- reads and analyzes Minecraft schematic files +dofile(handle_schematics.modpath.."/translate_nodenames_for_mc_schematic.lua") +dofile(handle_schematics.modpath.."/analyze_mc_schematic_file.lua") +-- handles rotation and mirroring +dofile(handle_schematics.modpath.."/rotate.lua") +-- count nodes, take param2 into account for rotation etc. +dofile(handle_schematics.modpath.."/handle_schematics_misc.lua") + +-- store and restore metadata +dofile(handle_schematics.modpath.."/save_restore.lua"); +dofile(handle_schematics.modpath.."/handle_schematics_meta.lua"); + +-- uses replacements_group.* namespace +-- these functions are responsible for the optional dependencies; they check +-- which nodes are available and may be offered as possible replacements +replacements_group = {}; +-- the replacement groups do add some non-ground nodes; needed by mg_villages +replacements_group.node_is_ground = {} +dofile(handle_schematics.modpath.."/replacements_wood.lua") +dofile(handle_schematics.modpath.."/replacements_realtest.lua") +dofile(handle_schematics.modpath.."/replacements_farming.lua") +dofile(handle_schematics.modpath.."/replacements_roof.lua") + +-- transforms the replacement list into a table; +-- also creates a replacement if needed and replaces default:torch +dofile(handle_schematics.modpath.."/replacements_get_table.lua") + +-- uses build_chest.* namespace +-- a chest for spawning buildings manually +dofile(handle_schematics.modpath.."/build_chest.lua") +-- makes the replacements from replacements_group.* available to the build chest +dofile(handle_schematics.modpath.."/build_chest_handle_replacements.lua"); +-- creates 2d previews of the schematic from left/right/back/front/top +dofile(handle_schematics.modpath.."/build_chest_preview_image.lua"); +-- reads a file and adds the files listed there as menu entries +dofile(handle_schematics.modpath.."/build_chest_add_schems_from_file.lua"); +-- locate schematics through directories +dofile(handle_schematics.modpath.."/build_chest_add_schems_by_directory.lua"); + +-- the main functionality of the mod; +-- provides the function handle_schematics.place_building_from_file +-- (and also place_buildings for mg_villages) +dofile(handle_schematics.modpath.."/place_buildings.lua") + +-- dofile(handle_schematics.modpath.."/fill_chest.lua") + +dofile(handle_schematics.modpath.."/nodes.lua") diff --git a/mods/a_mapgen_mods/handle_schematics/nodes.lua b/mods/a_mapgen_mods/handle_schematics/nodes.lua new file mode 100644 index 00000000..bbf301e1 --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/nodes.lua @@ -0,0 +1,24 @@ + + + +--------------------------------------------------------------------------------------- +-- helper node that is used during construction of a house; scaffolding +--------------------------------------------------------------------------------------- + +minetest.register_node("handle_schematics:support", { + description = "support structure for buildings", + tiles = {"handle_schematics_support.png"}, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + walkable = false, + climbable = true, + paramtype = "light", + drawtype = "plantlike", +}) + + +minetest.register_craft({ + output = "handle_schematics:support", + recipe = { + {"default:stick", "", "default:stick", } + } +}) diff --git a/mods/a_mapgen_mods/handle_schematics/place_buildings.lua b/mods/a_mapgen_mods/handle_schematics/place_buildings.lua new file mode 100644 index 00000000..b8be6d9d --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/place_buildings.lua @@ -0,0 +1,835 @@ +-- TODO: this function also occours in replacements.lua +handle_schematics.get_content_id_replaced = function( node_name, replacements ) + if( not( node_name ) or not( replacements ) or not(replacements.table )) then + return minetest.get_content_id( 'ignore' ); + end + if( replacements.table[ node_name ]) then + return minetest.get_content_id( replacements.table[ node_name ] ); + else + return minetest.get_content_id( node_name ); + end +end + +-- either uses get_node_or_nil(..) or the data from voxelmanip +-- the function might as well be local (only used by *.mg_drop_moresnow) +handle_schematics.get_node_somehow = function( x, y, z, a, data, param2_data ) + if( a and data and param2_data ) then + return { content = data[a:index(x, y, z)], param2 = param2_data[a:index(x, y, z)] }; + end + -- no voxelmanip; get the node the normal way + local node = minetest.get_node_or_nil( {x=x, y=y, z=z} ); + if( not( node ) ) then + return { content = moresnow.c_ignore, param2 = 0 }; + end + return { content = minetest.get_content_id( node.name ), param2 = node.param2, name = node.name }; +end + + +-- "drop" moresnow snow on diffrent shapes; works for voxelmanip and node-based setting +handle_schematics.mg_drop_moresnow = function( x, z, y_top, y_bottom, a, data, param2_data) + + -- this only works if moresnow is installed + if( not( handle_schematics.moresnow_installed )) then + return; + end + + local y = y_top; + local node_above = handle_schematics.get_node_somehow( x, y+1, z, a, data, param2_data ); + local node_below = nil; + while( y >= y_bottom ) do + + node_below = handle_schematics.get_node_somehow( x, y, z, a, data, param2_data ); + if( node_above.content == moresnow.c_air + and node_below.content + and node_below.content ~= moresnow.c_ignore + and node_below.content ~= moresnow.c_air ) then + + -- turn water into ice, but don't drop snow on it + if( node_below.content == minetest.get_content_id("default:water_source") + or node_below.content == minetest.get_content_id("default:river_water_source")) then + return { height = y, suggested = {new_id = minetest.get_content_id('default:ice'), param2 = 0 }}; + end + + -- if the node below drops snow when digged (i.e. is either snow or a moresnow node), we're finished + local get_drop = minetest.get_name_from_content_id( node_below.content ); + if( get_drop ) then + get_drop = minetest.registered_nodes[ get_drop ]; + if( get_drop and get_drop.drop and type( get_drop.drop )=='string' and get_drop.drop == 'default:snow') then + return; + end + end + if( not(node_below.content) + or node_below.content == moresnow.c_snow ) then + return; + end + + local suggested = moresnow.suggest_snow_type( node_below.content, node_below.param2 ); + + -- c_snow_top and c_snow_fence can only exist when the node 2 below is a solid one + if( suggested.new_id == moresnow.c_snow_top + or suggested.new_id == moresnow.c_snow_fence) then + local node_below2 = handle_schematics.get_node_somehow( x, y-1, z, a, data, param2_data); + if( node_below2.content ~= moresnow.c_ignore + and node_below2.content ~= moresnow.c_air ) then + local suggested2 = moresnow.suggest_snow_type( node_below2.content, node_below2.param2 ); + + if( suggested2.new_id == moresnow.c_snow ) then + return { height = y+1, suggested = suggested }; + end + end + -- it is possible that this is not the right shape; if so, the snow will continue to fall down + elseif( suggested.new_id ~= moresnow.c_ignore ) then + + return { height = y+1, suggested = suggested }; + end + -- TODO return; -- abort; there is no fitting moresnow shape for the node below + end + y = y-1; + node_above = node_below; + end +end + + +-- helper function for generate_building +-- places a marker that allows players to buy plots with houses on them (in order to modify the buildings) +local function generate_building_plotmarker( pos, minp, maxp, data, param2_data, a, cid, building_nr_in_bpos, village_id, filename) + -- position the plot marker so that players can later buy this plot + building in order to modify it + -- pos.o contains the original orientation (determined by the road and the side the building is + local p = {x=pos.x, y=pos.y+1, z=pos.z}; + if( pos.o == 0 ) then + p.x = p.x - 1; + p.z = p.z + pos.bsizez - 1; + elseif( pos.o == 2 ) then + p.x = p.x + pos.bsizex; + elseif( pos.o == 1 ) then + p.z = p.z + pos.bsizez; + p.x = p.x + pos.bsizex - 1; + elseif( pos.o == 3 ) then + p.z = p.z - 1; + end + -- actually position the marker + if( p.x >= minp.x and p.x <= maxp.x and p.z >= minp.z and p.z <= maxp.z and p.y >= minp.y and p.y <= maxp.y) then + if( handle_schematics.moresnow_installed + and data[ a:index(p.x, p.y, p.z)] == cid.c_snow + and p.y1, 5->2, 3->3, 4->0 } + new_nodes[ i ].change_param2[2] = 1; + new_nodes[ i ].change_param2[5] = 2; + new_nodes[ i ].change_param2[3] = 3; + new_nodes[ i ].change_param2[4] = 0; + new_nodes[ i ].paramtype2 = 'facedir'; + -- ..except if they are stairs or ladders + elseif( string.sub( node_name, 1, 7 ) == 'stairs:' or string.sub( node_name, 1, 6 ) == 'doors:') then + new_nodes[ i ].paramtype2 = 'facedir'; + -- normal nodes + elseif( regnode and regnode.paramtype2 and (regnode.paramtype2=='facedir' or regnode.paramtype2=='wallmounted')) then + new_nodes[ i ].paramtype2 = regnode.paramtype2; + end + + -- we tried our best, but the replacement node is not defined + elseif( new_node_name ~= 'mg:ignore' ) then + local msg = 'ERROR: Did not find a suitable replacement for '..tostring( node_name )..' (suggested but inexistant: '.. + tostring( new_node_name )..'). Building: '..tostring( binfo_scm )..'.'; + if( mg_villages and mg_villages.print ) then + mg_villages.print( mg_villages.DEBUG_LEVEL_WARNING, msg ); + else + print( msg ); + end + msg = nil; + new_nodes[ i ].ignore = 1; -- keep the old content + else -- handle mg:ignore + new_nodes[ i ].ignore = 1; + end + + + end + return new_nodes; +end + + +local function generate_building(pos, minp, maxp, data, param2_data, a, extranodes, replacements, cid, extra_calls, building_nr_in_bpos, village_id, binfo_extra, road_node, keep_ground) + + local binfo = binfo_extra; + if( not( binfo ) and mg_villages) then + binfo = mg_villages.BUILDINGS[pos.btype] + end + local scm + + -- the building got removed from mg_villages.BUILDINGS in the meantime + if( not( binfo )) then + return; + end + + -- schematics of .mts type are not handled here; they need to be placed using place_schematics + if( binfo.is_mts and binfo.is_mts == 1 ) then + return; + end + + + -- roads are very simple structures that are not stored as schematics + if( pos.btype == 'road' ) then + handle_schematics.place_road( minp, maxp, data, param2_data, a, road_node, pos, cid.c_air ); + return; + end + + + if( not( pos.no_plotmarker )) then + generate_building_plotmarker( pos, minp, maxp, data, param2_data, a, cid, building_nr_in_bpos, village_id, binfo.scm ); + end + + -- skip building if it is not located at least partly in the area that is currently beeing generated + if( pos.x > maxp.x or pos.x + pos.bsizex < minp.x + or pos.z > maxp.z or pos.z + pos.bsizez < minp.z ) then + return; + end + + + if( pos.btype and + (( binfo.sizex ~= pos.bsizex and binfo.sizex ~= pos.bsizez ) + or ( binfo.sizez ~= pos.bsizex and binfo.sizez ~= pos.bsizez ) + or not( binfo.scm_data_cache ))) then + if( mg_villages and mg_villages.print ) then + mg_villages.print( mg_villages.DEBUG_LEVEL_WARNING, + 'ERROR: This village was created using diffrent buildings than those known know. Cannot place unknown building.'); + else + print( 'ERROR: Size information about this building differs. Cannot place building.'); + end + return; + end + + if( binfo.scm_data_cache )then + scm = binfo.scm_data_cache; + else + scm = binfo.scm + end + + -- the fruit is set per building, not per village as the other replacements + if( binfo.farming_plus and binfo.farming_plus == 1 and pos.fruit and mg_villages) then + mg_villages.get_fruit_replacements( replacements, pos.fruit); + end + + local c_ignore = minetest.get_content_id("ignore") + local c_air = minetest.get_content_id("air") + local c_snow = minetest.get_content_id( "default:snow"); + local c_dirt = minetest.get_content_id( "default:dirt" ); + local c_dirt_with_grass = minetest.get_content_id( "default:dirt_with_grass" ); + local c_dirt_with_snow = minetest.get_content_id( "default:dirt_with_snow" ); + + local scm_x = 0; + local scm_z = 0; + local step_x = 1; + local step_z = 1; + local scm_z_start = 0; + + if( pos.brotate == 2 ) then + scm_x = pos.bsizex+1; + step_x = -1; + end + if( pos.brotate == 1 ) then + scm_z = pos.bsizez+1; + step_z = -1; + scm_z_start = scm_z; + end + + local mirror_x = false; + local mirror_z = false; + if( pos.mirror ) then + if( binfo.axis and binfo.axis == 1 ) then + mirror_x = true; + mirror_z = false; + else + mirror_x = false; + mirror_z = true; + end + end + + -- translate all nodenames and apply the replacements + local new_nodes = generate_building_translate_nodenames( binfo.nodenames, replacements, cid, binfo.scm, mirror_x, mirror_z ); + + for x = 0, pos.bsizex-1 do + scm_x = scm_x + step_x; + scm_z = scm_z_start; + for z = 0, pos.bsizez-1 do + scm_z = scm_z + step_z; + + local xoff = scm_x; + local zoff = scm_z; + if( pos.brotate == 2 ) then + if( mirror_x ) then + xoff = pos.bsizex - scm_x + 1; + end + if( mirror_z ) then + zoff = scm_z; + else + zoff = pos.bsizez - scm_z + 1; + end + elseif( pos.brotate == 1 ) then + if( mirror_x ) then + xoff = pos.bsizez - scm_z + 1; + else + xoff = scm_z; + end + if( mirror_z ) then + zoff = pos.bsizex - scm_x + 1; + else + zoff = scm_x; + end + elseif( pos.brotate == 3 ) then + if( mirror_x ) then + xoff = pos.bsizez - scm_z + 1; + else + xoff = scm_z; + end + if( mirror_z ) then + zoff = scm_x; + else + zoff = pos.bsizex - scm_x + 1; + end + elseif( pos.brotate == 0 ) then + if( mirror_x ) then + xoff = pos.bsizex - scm_x + 1; + end + if( mirror_z ) then + zoff = pos.bsizez - scm_z + 1; + end + end + + local has_snow = false; + local ground_type = c_dirt_with_grass; + for y = 0, binfo.ysize-1 do + local ax = pos.x+x; + local ay = pos.y+y+binfo.yoff; + local az = pos.z+z; + if (ax >= minp.x and ax <= maxp.x) and (ay >= minp.y and ay <= maxp.y) and (az >= minp.z and az <= maxp.z) then + + local new_content = c_air; + local t = scm[y+1][xoff][zoff]; + + local node_content = data[a:index(ax, ay, az)]; + if( binfo.yoff+y == 0 ) then + -- no snow on the gravel roads + if( node_content == c_dirt_with_snow or data[a:index(ax, ay+1, az)]==c_snow) then + has_snow = true; + end + + ground_type = node_content; + end + + if( not( t )) then + if( node_content ~= cid.c_plotmarker + and (not(handle_schematics.moresnow_installed) or not(moresnow) or node_content ~= moresnow.c_snow_top )) then + data[ a:index(ax, ay, az)] = cid.c_air; + end + else + local n = new_nodes[ t[1] ]; -- t[1]: id of the old node + if( not( n.ignore )) then + new_content = n.new_content; + else + new_content = node_content; + end + + -- replace all dirt and dirt with grass at that x,z coordinate with the stored ground grass node; + if( n.is_grass and keep_ground) then + new_content = ground_type; + end + + if( n.on_construct ) then + if( not( extra_calls.on_constr[ new_content ] )) then + extra_calls.on_constr[ new_content ] = { {x=ax, y=ay, z=az}}; + else + table.insert( extra_calls.on_constr[ new_content ], {x=ax, y=ay, z=az}); + end + end + + -- do not overwrite plotmarkers + if( new_content ~= cid.c_air or node_content ~= cid.c_plotmarker ) then + data[ a:index(ax, ay, az)] = new_content; + end + + -- store that a tree is to be grown there + if( n.is_tree ) then + table.insert( extra_calls.trees, {x=ax, y=ay, z=az, typ=new_content, snow=has_snow}); + + -- we're dealing with a chest that might need filling + elseif( n.is_chestlike ) then + table.insert( extra_calls.chests, {x=ax, y=ay, z=az, typ=new_content, bpos_i=building_nr_in_bpos, typ_name=n.special_chest}); + + -- the sign may require some text to be written on it + elseif( n.is_sign ) then + table.insert( extra_calls.signs, {x=ax, y=ay, z=az, typ=new_content, bpos_i=building_nr_in_bpos}); + end + + -- handle rotation + if( n.paramtype2 ) then + local param2 = t[2]; + if( n.change_param2 and n.change_param2[ t[2] ]) then + param2 = n.change_param2[ param2 ]; + end + + local np2 = 0; + if( mirror_x ) then + np2 = handle_schematics.rotation_table[ n.paramtype2 ][ param2+1 ][ pos.brotate+1 ][ 2 ]; + elseif( mirror_z ) then + np2 = handle_schematics.rotation_table[ n.paramtype2 ][ param2+1 ][ pos.brotate+1 ][ 3 ]; + else + np2 = handle_schematics.rotation_table[ n.paramtype2 ][ param2+1 ][ pos.brotate+1 ][ 1 ]; + end + +--[[ + local param2list = handle_schematics.get_param2_rotated( n.paramtype2, param2); + local np2 = param2list[ pos.brotate + 1]; + -- mirror + if( mirror_x ) then + if( #param2list==5) then + np2 = handle_schematics.mirror_facedir[ ((pos.brotate+1)%2)+1 ][ np2+1 ]; + elseif( #param2list<5 + and ((pos.brotate%2==1 and (np2==4 or np2==5)) + or (pos.brotate%2==0 and (np2==2 or np2==3)))) then + np2 = param2list[ (pos.brotate + 2)%4 +1]; + end + + elseif( mirror_z ) then + if( #param2list==5) then + np2 = handle_schematics.mirror_facedir[ (pos.brotate %2)+1 ][ np2+1 ]; + elseif( #param2list<5 + and ((pos.brotate%2==0 and (np2==4 or np2==5)) + or (pos.brotate%2==1 and (np2==2 or np2==3)))) then + np2 = param2list[ (pos.brotate + 2)%4 +1]; + end + end +--]] + + param2_data[a:index(ax, ay, az)] = np2; + else + param2_data[a:index(ax, ay, az)] = t[2]; + end + end + end + end + + local ax = pos.x + x; + local az = pos.z + z; + local y_top = pos.y+binfo.yoff+binfo.ysize; + if( y_top+1 > maxp.y ) then + y_top = maxp.y-1; + end + local y_bottom = pos.y+binfo.yoff; + if( y_bottom < minp.y ) then + y_bottom = minp.y; + end + if( has_snow and ax >= minp.x and ax <= maxp.x and az >= minp.z and az <= maxp.z ) then + local res = handle_schematics.mg_drop_moresnow( ax, az, y_top, y_bottom-1, a, data, param2_data); + if( res and (data[ a:index(ax, res.height, az)]==cid.c_air + or data[ a:index(ax, res.height, az)]==cid.c_water )) then + data[ a:index(ax, res.height, az)] = res.suggested.new_id; + param2_data[a:index(ax, res.height, az)] = res.suggested.param2; + has_snow = false; + end + end + end + end +end + + + +-- actually place the buildings (at least those which came as .we files; .mts files are handled later on) +-- this code was also responsible for tree placement; +-- place_buildings is used by mg_villages exclusively. It calls the local function generate_building and +-- therefore resides in this file. +handle_schematics.place_buildings = function(village, minp, maxp, data, param2_data, a, cid, village_id) + -- this function is only relevant for mg_villages + if( not( mg_villages )) then + return; + end + local vx, vz, vs, vh = village.vx, village.vz, village.vs, village.vh + local village_type = village.village_type; + + local bpos = village.to_add_data.bpos; + + local replacements = mg_villages.get_replacement_table( village.village_type, nil, village.to_add_data.replacements ); + + cid.c_chest = handle_schematics.get_content_id_replaced( 'default:chest', replacements ); + cid.c_chest_locked = handle_schematics.get_content_id_replaced( 'default:chest_locked', replacements ); + cid.c_chest_shelf = handle_schematics.get_content_id_replaced( 'cottages:shelf', replacements ); + cid.c_chest_ash = handle_schematics.get_content_id_replaced( 'trees:chest_ash', replacements ); + cid.c_chest_aspen = handle_schematics.get_content_id_replaced( 'trees:chest_aspen', replacements ); + cid.c_chest_birch = handle_schematics.get_content_id_replaced( 'trees:chest_birch', replacements ); + cid.c_chest_maple = handle_schematics.get_content_id_replaced( 'trees:chest_maple', replacements ); + cid.c_chest_chestnut = handle_schematics.get_content_id_replaced( 'trees:chest_chestnut', replacements ); + cid.c_chest_pine = handle_schematics.get_content_id_replaced( 'trees:chest_pine', replacements ); + cid.c_chest_spruce = handle_schematics.get_content_id_replaced( 'trees:chest_spruce', replacements ); + cid.c_sign = handle_schematics.get_content_id_replaced( 'default:sign_wall', replacements ); +--print('REPLACEMENTS: '..minetest.serialize( replacements.table )..' CHEST: '..tostring( minetest.get_name_from_content_id( cid.c_chest ))); -- TODO + + local extranodes = {} + local extra_calls = { on_constr = {}, trees = {}, chests = {}, signs = {}, traders = {} }; + + for i, pos in ipairs(bpos) do + -- roads are only placed if there are at least mg_villages.MINIMAL_BUILDUNGS_FOR_ROAD_PLACEMENT buildings in the village + if( not(pos.btype) or pos.btype ~= 'road' or village.anz_buildings > mg_villages.MINIMAL_BUILDUNGS_FOR_ROAD_PLACEMENT )then + -- replacements are in table format for mapgen-based building spawning + local road_material = mg_villages.road_node; + if( pos.road_material ) then + road_material = pos.road_material; + end + generate_building(pos, minp, maxp, data, param2_data, a, extranodes, replacements, cid, extra_calls, i, village_id, nil, road_material, true ) + end + end + + -- replacements are in list format for minetest.place_schematic(..) type spawning + return { extranodes = extranodes, bpos = bpos, replacements = replacements.list, dirt_roads = village.to_add_data.dirt_roads, + plantlist = village.to_add_data.plantlist, extra_calls = extra_calls }; +end + + + +-- place a schematic manually +-- +-- pos needs to contain information about how to place the building: +-- pos.x, pos.y, pos.z where the building is to be placed +-- pos.btype determines which building will be placed; if not set, binfo_extra needs to be provided +-- pos.brotate contains a value of 0-3, which determines the rotation of the building +-- pos.bsizex size of the building in x direction +-- pos.bsizez size of the building in z direction +-- pos.mirror if set, the building will be mirrored +-- pos.no_plotmarker optional; needs to be set in order to avoid the generation of a plotmarker +-- building_nr optional; used for plotmarker +-- village_id optional; used for plotmarker +-- pos.fruit optional; determines the fruit a farm is going to grow (if binfo.farming_plus is set) + +-- binfo contains general information about a building: +-- binfo.sizex size of the building in x direction +-- binfo.sizez +-- binfo.ysize +-- binfo.yoff how deep is the building burried? +-- binfo.nodenames list of the node names beeing used by the building +-- binfo.scm name of the file containing the schematic; only needed for an error message +-- binfo.scm_data_cache contains actual information about the nodes beeing used (the data) +-- binfo.is_mts optional; if set to 1, the function will abort +-- binfo.farming_plus optional; if set, pos.fruit needs to be set as well +-- binfo.axis optional; relevant for some mirroring operations +-- +-- replacement_list contains replacements in the same list format as place_schematic uses +-- +handle_schematics.place_building_using_voxelmanip = function( pos, binfo, replacement_list) + + if( not( replacement_list ) or type( replacement_list ) ~= 'table' ) then + return; + end + + -- if not defined, the building needs to start at pos.x,pos.y,pos.z - without offset + if( not( binfo.yoff )) then + binfo.yoff = 0; + end + +-- TODO: calculate the end position from the given data + -- get a suitable voxelmanip object + -- (taken from minetest_game/mods/default/trees.lua) + local vm = minetest.get_voxel_manip() + local minp, maxp = vm:read_from_map( + {x = pos.x, y = pos.y, z = pos.z}, + {x = pos.x+pos.bsizex, y = pos.y+binfo.ysize, z = pos.z+pos.bsizez} -- TODO + ) + local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) + local data = vm:get_data() + local param2_data = vm:get_param2_data(); + + + -- translate the replacement_list into replacements.ids and replacements.table format + -- the first two parameters are nil because we do not want a new replacement list to be generated + local replacements = handle_schematics.get_replacement_table( nil, nil, replacement_list ); + + -- only very few nodes are actually used from the cid table (content ids) + local cid = {}; + cid.c_air = minetest.get_content_id( 'air' ); + cid.c_dirt = handle_schematics.get_content_id_replaced( 'default:dirt', replacements ); + cid.c_dirt_with_grass = handle_schematics.get_content_id_replaced( 'default:dirt_with_grass',replacements ); + cid.c_sapling = handle_schematics.get_content_id_replaced( 'default:sapling', replacements ); + cid.c_jsapling = handle_schematics.get_content_id_replaced( 'default:junglesapling', replacements ); + cid.c_psapling = handle_schematics.get_content_id_replaced( 'default:pine_sapling', replacements ); + cid.c_savannasapling = handle_schematics.get_content_id_replaced( 'mg:savannasapling', replacements ); + cid.c_pinesapling = handle_schematics.get_content_id_replaced( 'mg:pinesapling', replacements ); + cid.c_plotmarker = handle_schematics.get_content_id_replaced( 'mg_villages:plotmarker', replacements ); + + cid.c_chest = handle_schematics.get_content_id_replaced( 'default:chest', replacements ); + cid.c_chest_locked = handle_schematics.get_content_id_replaced( 'default:chest_locked', replacements ); + cid.c_chest_shelf = handle_schematics.get_content_id_replaced( 'cottages:shelf', replacements ); + cid.c_chest_ash = handle_schematics.get_content_id_replaced( 'trees:chest_ash', replacements ); + cid.c_chest_aspen = handle_schematics.get_content_id_replaced( 'trees:chest_aspen', replacements ); + cid.c_chest_birch = handle_schematics.get_content_id_replaced( 'trees:chest_birch', replacements ); + cid.c_chest_maple = handle_schematics.get_content_id_replaced( 'trees:chest_maple', replacements ); + cid.c_chest_chestnut = handle_schematics.get_content_id_replaced( 'trees:chest_chestnut', replacements ); + cid.c_chest_pine = handle_schematics.get_content_id_replaced( 'trees:chest_pine', replacements ); + cid.c_chest_spruce = handle_schematics.get_content_id_replaced( 'trees:chest_spruce', replacements ); + cid.c_sign = handle_schematics.get_content_id_replaced( 'default:sign_wall', replacements ); + + -- for roads + cid.c_sign = handle_schematics.get_content_id_replaced( 'default:gravel', replacements ); + + local extranodes = {} + local extra_calls = { on_constr = {}, trees = {}, chests = {}, signs = {}, traders = {} }; + + -- last parameter false -> place dirt nodes instead of trying to keep the ground nodes + generate_building(pos, minp, maxp, data, param2_data, a, extranodes, replacements, cid, extra_calls, pos.building_nr, pos.village_id, binfo, cid.c_gravel, false); + + -- store the changed map data + vm:set_data(data); + vm:set_param2_data(param2_data); + vm:write_to_map(); + vm:update_liquids(); + vm:update_map(); + +-- TODO: do the calls for the extranodes as well + -- replacements are in list format for minetest.place_schematic(..) type spawning + return { extranodes = extranodes, replacements = replacements.list, extra_calls = extra_calls }; +end + + + +-- places a building read from file "building_name" on the map between start_pos and end_pos using luavoxelmanip +-- returns error message on failure and nil on success +handle_schematics.place_building_from_file = function( start_pos, end_pos, building_name, replacement_list, rotate, axis, mirror, no_plotmarker ) + if( not( building_name )) then + return "No file name given. Cannot find the schematic."; + end + + local binfo = handle_schematics.analyze_file( building_name, nil, nil ); + if( not( binfo )) then + return "Failed to import schematic. Only .mts and .we are supported!"; + end + + -- nodenames and scm_data_cache can be used directly; + -- the size dimensions need to be renamed + binfo.sizex = binfo.size.x; + binfo.sizez = binfo.size.z; + binfo.ysize = binfo.size.y; + + -- this value has already been taken care of when determining start_pos + binfo.yoff = 0; + -- file name of the scm; only used for error messages + binfo.scm = building_name; + -- this is relevant for mirroring operations + binfo.axis = axis; + + + if( not( rotate ) or rotate=="0" ) then + start_pos.brotate = 0; + elseif( rotate=="90" ) then + start_pos.brotate = 1; + elseif( rotate=="180" ) then + start_pos.brotate = 2; + elseif( rotate=="270" ) then + start_pos.brotate = 3; + end + + if( start_pos.brotate > 3 ) then + start_pos.brotate = start_pos.brotate % 4; + end + + + -- determine the size of the bulding from the place we assigned to it... + start_pos.bsizex = math.abs(end_pos.x - start_pos.x)+1; + start_pos.bsizez = math.abs(end_pos.z - start_pos.z)+1; + + -- otpional; if set, the building will be mirrored + start_pos.mirror = mirror; + -- do not generate a plot marker as this is not part of a village; + -- otherwise, building_nr and village_id would have to be provided + start_pos.no_plotmarker = no_plotmarker; + + -- all those calls to on_construct need to be done now + local res = handle_schematics.place_building_using_voxelmanip( start_pos, binfo, replacement_list); + if( not(res) or not( res.extra_calls )) then + return; + end + + -- call on_construct where needed; + -- trees, chests and signs receive no special treatment here + for k, v in pairs( res.extra_calls.on_constr ) do + local node_name = minetest.get_name_from_content_id( k ); + if( minetest.registered_nodes[ node_name ].on_construct ) then + for _, pos in ipairs(v) do + minetest.registered_nodes[ node_name ].on_construct( pos ); + end + end + end + + if( binfo.metadata ) then + -- if it is a .we/.wem file, metadata was included directly + handle_schematics.restore_meta( nil, binfo.metadata, start_pos, end_pos, start_pos.brotate, mirror); + else + -- .mts files come with extra .meta file (if such a .meta file was created) + -- TODO: restore metadata for .mts files + --handle_schematics.restore_meta( filename, nil, binfo.metadata, start_pos, end_pos, start_pos.brotate, mirror); + end +end + + + +-- add the dirt roads +handle_schematics.place_dirt_roads = function(village, minp, maxp, data, param2_data, a, c_road_node) + local c_air = minetest.get_content_id( 'air' ); + for _, pos in ipairs(village.to_add_data.dirt_roads) do + handle_schematics.place_road( minp, maxp, data, param2_data, a, c_road_node, pos, c_air ); + end +end + +handle_schematics.place_road = function(minp, maxp, data, param2_data, a, c_road_node, pos, c_air ) + local param2 = 0; + if( pos.bsizex > 2 and pos.bsizex > pos.bsizez) then + param2 = 1; + end + +--[[ + local is_main_road = false; + local c_road_node = minetest.get_content_id('default:coalblock'); + local c_middle_wool = minetest.get_content_id('default:clay'); + local slab_stone = minetest.get_content_id('stairs:slab_stone'); + if( pos.bsizex > 2 and pos.bsizez > 2 ) then + is_main_road = true; + end +--]] + + if( not(pos.y >= minp.y and pos.y <= maxp.y-2)) then + return; + end + for x = math.max( pos.x, minp.x ), math.min( pos.x+pos.bsizex-1, maxp.x ) do + for z = math.max( pos.z, minp.z ), math.min( pos.z+pos.bsizez-1, maxp.z ) do + -- roads have a height of 1 block + data[ a:index( x, pos.y, z)] = c_road_node; + param2_data[ a:index( x, pos.y, z)] = param2; + -- ...with air above + data[ a:index( x, pos.y+1, z)] = c_air; + data[ a:index( x, pos.y+2, z)] = c_air; + +--[[ + if( (param2==0 and (x==pos.x or x==pos.x+8) and is_main_road) + or (param2==1 and (z==pos.z or z==pos.z+8) and is_main_road)) then + data[ a:index( x, pos.y+1, z )] = slab_stone; + elseif((param2==0 and (x==pos.x+4 ) and is_main_road) + or (param2==1 and (z==pos.z+4 ) and is_main_road)) then + data[ a:index( x, pos.y, z )] = c_middle_wool; + end +--]] + end + end +end + + +if( minetest.get_modpath('moresnow' )) then + handle_schematics.moresnow_installed = true; +end diff --git a/mods/a_mapgen_mods/handle_schematics/replacements_farming.lua b/mods/a_mapgen_mods/handle_schematics/replacements_farming.lua new file mode 100644 index 00000000..3763139b --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/replacements_farming.lua @@ -0,0 +1,171 @@ + +replacements_group['farming'] = {} + +-- this contains a list of all found/available nodenames that may act as a replacement frming nodes +replacements_group['farming'].found = {}; +-- contains a list of *all* known farming names - even of mods that may not be installed +replacements_group['farming'].all = {}; + +-- contains information about how a particular node is called if a particular farming mod is used; +replacements_group['farming'].data = {}; + +-- names of traders for the diffrent fruits +replacements_group['farming'].traders = {}; + + +replacements_group['farming'].replace_material = function( replacements, old_material, new_material ) + + if( not( old_material ) or not( replacements_group['farming'].data[ old_material ]) + or not( new_material ) or not( replacements_group['farming'].data[ new_material ]) + or old_material == new_material ) then + return replacements; + end + + local old_nodes = replacements_group['farming'].data[ old_material ]; + local new_nodes = replacements_group['farming'].data[ new_material ]; + for i=1,#old_nodes do + local old = old_nodes[i]; + local new = old; + if( i<=#new_nodes and new_nodes[i] and minetest.registered_nodes[ new_nodes[i]] ) then + new = new_nodes[i]; + local found = false; + for i,v in ipairs(replacements) do + if( v and v[1]==old ) then + v[2] = new; + found = true; + end + end + if( not( found )) then + table.insert( replacements, { old, new }); + end + -- default to the last growth stage + elseif( i>#new_nodes and minetest.registered_nodes[ new_nodes[ #new_nodes ]]) then + table.insert( replacements, { old, new_nodes[ #new_nodes ] }); + end + end + return replacements; +end + + +--------------------- +-- internal functions +--------------------- +replacements_group['farming'].add_material = function( fruit, fruit_item, prefix, seperator, postfix ) + + local is_loaded = false; + if( minetest.registered_items[ fruit_item ] + and minetest.registered_nodes[ prefix..fruit..seperator.."1"..postfix ] ) then + is_loaded = true; + table.insert( replacements_group['farming'].found, fruit_item ); + end + table.insert( replacements_group['farming'].all, fruit_item ); + + local data = {}; + -- handle seeds + if( minetest.registered_items[ prefix..fruit..'_seed' ]) then + data[1] = prefix..fruit..'_seed'; + elseif( minetest.registered_items[ prefix..fruit..'seed' ]) then + data[1] = prefix..fruit..'seed'; + else + data[1] = fruit_item; + end + for i=1,8 do + local node_name = prefix..fruit..seperator..tostring(i)..postfix; + if( is_loaded and minetest.registered_nodes[ node_name ]) then + table.insert( data, node_name ); + -- if the mod is not loaded, we do not know how many growth stages it has; + -- in order to be on the safe side, store them all + elseif( not( is_loaded )) then + table.insert( data, node_name ); + end + end + -- the last plant stage (the one that gives the fruit) usually has no number + local node_name = prefix..fruit; + if( is_loaded and minetest.registered_nodes[ node_name ]) then + table.insert( data, node_name ); + elseif( not( is_loaded )) then + table.insert( data, node_name ); + end + replacements_group['farming'].data[ fruit_item ] = data; + + -- farming nodes do not count as ground (except for soil - which is not handled here) + local c_ignore = minetest.get_content_id( 'ignore' ); + for _,v in ipairs( data ) do + local id = minetest.get_content_id( v ); + if( id and id ~= c_ignore ) then + replacements_group.node_is_ground[ id ] = false; + end + end + + + if( is_loaded and minetest.get_modpath('mobf_trader') and mobf_trader and mobf_trader.add_trader ) then + + -- TODO: use replacements for the payments where needed + local goods = { + { fruit_item.." 1", "default:coal_lump 3", "default:wood 8"}, + { fruit_item.." 10", "default:steel_ingot 2", "default:chest_locked 1"}}; + if( fruit_item ~= data[1] ) then + table.insert( goods, { data[1].." 1", "farming:scarecrow", "farming:scarecrow_light 1"}); + table.insert( goods, { data[1].." 2", "default:dirt 20", "default:bucket_water", "default:steel_ingot 4", "default:leaves 99" }); + end + table.insert( goods, {"farming:hoe_wood 1","default:wood 10", "default:cobble 10"}); + + mobf_trader.add_trader( mobf_trader.npc_trader_prototype, + "farmer growing "..fruit.."s", -- not always the right grammatical form + fruit.."_farmer_v", + goods, + { "farmer" }, + {'kuhhaendler.png', 'bauer_in_sonntagskleidung.png', 'baeuerin.png', 'wheat_farmer_by_addi.png', 'tomatenhaendler.png'} + ); + + replacements_group['farming'].traders[ fruit_item ] = fruit..'_farmer_v'; + end +end + + + + +-- create a list of all available fruit types +replacements_group['farming'].construct_farming_type_list = function() + + -- farming from minetest_game + replacements_group['farming'].add_material( 'wheat', 'farming:wheat', 'farming:', '_', '' ); + replacements_group['farming'].add_material( 'cotton', 'farming:cotton', 'farming:', '_', '' ); + replacements_group['farming'].add_material( 'pumpkin','farming:pumpkin', 'farming:', '_', '' ); + + -- RealTest + replacements_group['farming'].add_material( 'flax', 'farming:string', 'farming:', '_', '' ); + replacements_group['farming'].add_material( 'spelt', 'farming:wheat', 'farming:', '_', '' ); + replacements_group['farming'].add_material( 'soy', 'farming:soy', 'farming:', '_', '' ); + + + -- diffrent versions of farming_plus: + -- PilzAdam: https://forum.minetest.net/viewtopic.php?t=2787 + -- TenPlus1: https://forum.minetest.net/viewtopic.php?t=9019 + -- MTDad: https://forum.minetest.net/viewtopic.php?t=10187 + local fruits = { 'strawberry', 'raspberry', + 'carrot', 'rhubarb', 'cucumber', + 'pumpkin', 'melon', + 'orange', 'lemon', 'peach', 'walnut', + 'potato','potatoe', -- diffrent mods spell them diffrently + 'tomato', 'corn' + }; + for i,fruit in ipairs( fruits ) do + if( minetest.registered_nodes[ 'farming_plus:'..fruit ] + and minetest.registered_nodes[ 'farming_plus:'..fruit..'_1' ] + and minetest.registered_items[ 'farming_plus:'..fruit..'_item' ] ) then + replacements_group['farming'].add_material( fruit, 'farming_plus:'..fruit..'_item', 'farming_plus:', '_', '' ); + end + end + -- coffee beans from farming_plus/farming_plusplus + replacements_group['farming'].add_material( 'coffee', 'farming_plus:coffee_beans', 'farming_plus:', '_', '' ); + + -- Docfarming: https://forum.minetest.net/viewtopic.php?t=3948 + fruits = {'carrot','corn','potato','raspberry'}; + for i,fruit in ipairs( fruits ) do + replacements_group['farming'].add_material( fruit, 'docfarming:'..fruit, 'docfarming:', '', '' ); + end +end + +-- create the list of known farming fruits +replacements_group['farming'].construct_farming_type_list(); diff --git a/mods/a_mapgen_mods/handle_schematics/replacements_get_table.lua b/mods/a_mapgen_mods/handle_schematics/replacements_get_table.lua new file mode 100644 index 00000000..c07e81a5 --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/replacements_get_table.lua @@ -0,0 +1,21 @@ +-- mapgen based replacements work best using a table, while minetest.place_schematic(..) based spawning needs a list +handle_schematics.get_replacement_table = function( housetype, pr, replacements ) + + local rtable = {}; + local ids = {}; + if( not( replacements ) and mg_villages and mg_villages.get_replacement_list) then + replacements = mg_villages.get_replacement_list( housetype, pr ); + end + -- it is very problematic if the torches on houses melt snow and cause flooding; thus, we use a torch that is not hot + if( minetest.registered_nodes[ 'mg_villages:torch']) then + table.insert( replacements, {'default:torch', 'mg_villages:torch'}); + end + for i,v in ipairs( replacements ) do + if( v and #v == 2 ) then + rtable[ v[1] ] = v[2]; + ids[ minetest.get_content_id( v[1] )] = minetest.get_content_id( v[2] ); + end + end + return { table = rtable, list = replacements, ids = ids }; +end + diff --git a/mods/a_mapgen_mods/handle_schematics/replacements_realtest.lua b/mods/a_mapgen_mods/handle_schematics/replacements_realtest.lua new file mode 100644 index 00000000..7ba3261f --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/replacements_realtest.lua @@ -0,0 +1,82 @@ +replacements_group['realtest'] = {} + +-- parameter: replacements, name_in_default, name_in_realtest, to_realtest=true/false +replacements_group['realtest'].stairs = function( repl, def, rt, to_realtest) + if( to_realtest ) then + if( def ~= rt ) then + table.insert( repl, {'default:'..def, 'default:'..rt}); + end + table.insert( repl, {'stairs:stair_'..def, 'default:'..rt..'_stair'}); + table.insert( repl, {'stairs:slab_'..def, 'default:'..rt..'_slab'}); + else + if( def ~= rt ) then + table.insert( repl, {'default:'..rt, 'default:'..def}); + end + table.insert( repl, {'default:'..rt..'_stair', 'stairs:stair_'..def}); + table.insert( repl, {'default:'..rt..'_stair_upside_down','stairs:stair_'..def}); + -- upside-down-slab + table.insert( repl, {'default:'..rt..'_slab_r', 'stairs:slab_'..def}); + table.insert( repl, {'default:'..rt..'_slab', 'stairs:slab_'..def}); + end + return repl; +end + +replacements_group['realtest'].replace = function( replacements ) + + local repl = {}; + local to_realtest = false; + if( not( minetest.registered_nodes[ 'default:furnace' ]) + and minetest.registered_nodes[ 'oven:oven' ]) then + to_realtest = true; + elseif( minetest.registered_nodes[ 'default:furnace' ] + and not( minetest.registered_nodes[ 'oven:oven' ])) then + to_realtest = false; + else + -- else no replacements required + return; + end + + replacements_group['realtest'].stairs( repl, 'stone', 'stone', to_realtest ); + replacements_group['realtest'].stairs( repl, 'cobble', 'stone_flat', to_realtest ); + replacements_group['realtest'].stairs( repl, 'stonebrick', 'stone_bricks', to_realtest ); + replacements_group['realtest'].stairs( repl, 'desert_stone', 'desert_stone', to_realtest ); + replacements_group['realtest'].stairs( repl, 'desert_cobble', 'desert_stone_flat', to_realtest ); + replacements_group['realtest'].stairs( repl, 'desert_stonebrick', 'desert_stone_bricks',to_realtest ); + replacements_group['realtest'].stairs( repl, 'brick', 'brick', to_realtest ); + + if( to_realtest ) then + table.insert( repl, {'default:furnace', 'oven:oven'}); + table.insert( repl, {'default:clay', 'grounds:clay'}); + -- Realtest does not know about these nodes yet + table.insert( repl, {'farming:soil_wet', 'farming:soil'}); + table.insert( repl, {'farming:desert_sand_soil', 'farming:soil'}); + table.insert( repl, {'farming:desert_sand_soil_wet','farming:soil'}); + for i=1,5 do + table.insert( repl, {'default:grass_'..i,'air' }); + end + table.insert( repl, {'default:apple', 'air' }); + table.insert( repl, {'default:obsidian_glass', 'default:glass' }); + else + table.insert( repl, {'oven:oven', 'default:furnace'}); + table.insert( repl, {'grounds:clay', 'default:clay'}); + table.insert( repl, {'farming:soil', 'farming:soil_wet'}); + end + + + for i,v in ipairs( repl ) do + if( v and v[2] and minetest.registered_nodes[ v[2]] ) then + local found = false; + for j,w in ipairs( replacements ) do + if( w and w[1] and w[1]==v[1] ) then + w[2] = v[2]; + found = true; + end + end + if( not( found )) then + table.insert( replacements, {v[1],v[2]} ); + end + end + end + return replacements; +end + diff --git a/mods/a_mapgen_mods/handle_schematics/replacements_roof.lua b/mods/a_mapgen_mods/handle_schematics/replacements_roof.lua new file mode 100644 index 00000000..44e32151 --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/replacements_roof.lua @@ -0,0 +1,110 @@ + +replacements_group['roof'] = {} + +-- this contains a list of all found/available nodenames that may act as a replacement frming nodes +replacements_group['roof'].found = {}; +-- contains a list of *all* known roof names - even of mods that may not be installed +replacements_group['roof'].all = {}; + +-- contains information about how a particular node is called if a particular roof mod is used; +replacements_group['roof'].data = {}; + + +replacements_group['roof'].replace_material = function( replacements, old_material, new_material ) + + if( not( old_material ) or not( replacements_group['roof'].data[ old_material ]) + or not( new_material ) or not( replacements_group['roof'].data[ new_material ]) + or old_material == new_material ) then + return replacements; + end + + local old_nodes = replacements_group['roof'].data[ old_material ]; + local new_nodes = replacements_group['roof'].data[ new_material ]; + for i=1,#old_nodes do + local old = old_nodes[i]; + local new = old; + if( i<=#new_nodes and new_nodes[i] and minetest.registered_nodes[ new_nodes[i]] ) then + new = new_nodes[i]; + local found = false; + for i,v in ipairs(replacements) do + if( v and v[1]==old ) then + v[2] = new; + found = true; + end + end + if( not( found )) then + table.insert( replacements, { old, new }); + end + end + end + return replacements; +end + + +--------------------- +-- internal functions +--------------------- +replacements_group['roof'].add_material = function( nodelist ) + + local is_loaded = false; + if( minetest.registered_items[ nodelist[1] ] ) then + is_loaded = true; + table.insert( replacements_group['roof'].found, nodelist[1] ); + end + table.insert( replacements_group['roof'].all, nodelist[1]); + + replacements_group['roof'].data[ nodelist[1] ] = nodelist; +end + + + + +-- create a list of all available fruit types +replacements_group['roof'].construct_roof_type_list = function() + + -- roof from cottages + local roofs = {'straw', 'reet', 'wood', 'slate', 'red', 'brown', 'black'}; + for i,v in ipairs( roofs ) do + replacements_group['roof'].add_material( { + 'cottages:roof_connector_'..v, + 'cottages:roof_flat_'..v, + '', -- no full block available + 'cottages:roof_'..v + } ); + end + + + -- from dryplants + roofs = {'reed', 'wetreed'}; + for i,v in ipairs( roofs ) do + replacements_group['roof'].add_material( { + 'dryplants:'..v..'_roof', + 'dryplants:'..v..'_slab', + 'dryplants:'..v, + 'dryplants:'..v..'_roof', + 'dryplants:'..v..'_roof_corner', + 'dryplants:'..v..'_roof_corner_2' + } ); + end + -- roof from homedecor + roofs = {'wood', 'terracotta', 'asphalt', 'glass'}; + for i,v in ipairs( roofs ) do + replacements_group['roof'].add_material( { + 'homedecor:shingle_side_'..v, + 'homedecor:shingles_'..v, + '', + 'homedecor:shingles_'..v, + 'homedecor:shingle_inner_corner_'..v, + 'homedecor:shingle_outer_corner_'..v, + } ); + end + + replacements_group['roof'].data[ 'homedecor:shingle_side_glass' ][2] = 'homedecor:skylight'; + replacements_group['roof'].data[ 'homedecor:shingle_side_glass' ][4] = 'homedecor:skylight'; + replacements_group['roof'].data[ 'homedecor:shingle_side_asphalt'][3] = 'streets:asphalt'; + + -- TODO: slopes from technic or other slopes mods? +end + +-- create the list of known roof fruits +replacements_group['roof'].construct_roof_type_list(); diff --git a/mods/a_mapgen_mods/handle_schematics/replacements_wood.lua b/mods/a_mapgen_mods/handle_schematics/replacements_wood.lua new file mode 100644 index 00000000..483162c8 --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/replacements_wood.lua @@ -0,0 +1,234 @@ +replacements_group['wood'] = {} + +-- this contains a list of all found/available nodenames that may act as a replacement for default:wood +replacements_group['wood'].found = {}; +-- contains a list of *all* known wood names - even of mods that may not be installed +replacements_group['wood'].all = {}; + +-- contains information about how a particular node is called if a particular wood is used; +replacements_group['wood'].data = {}; + +-- names of traders for the diffrent wood types +replacements_group['wood'].traders = {}; + + +------------------------------------------------------------------------------ +-- external function; call it in order to replace old_wood with new_wood; +-- other nodes (trees, saplings, fences, doors, ...) are replaced accordingly, +-- depending on what new_wood has to offer +------------------------------------------------------------------------------ +replacements_group['wood'].replace_material = function( replacements, old_wood, new_wood ) + + if( not( old_wood ) or not( replacements_group['wood'].data[ old_wood ]) + or not( new_wood ) or not( replacements_group['wood'].data[ new_wood ]) + or old_wood == new_wood ) then + return replacements; + end + + local old_nodes = replacements_group['wood'].data[ old_wood ]; + local new_nodes = replacements_group['wood'].data[ new_wood ]; + for i=3,#old_nodes do + local old = old_nodes[i]; + local new = old; + if( i<=#new_nodes and new_nodes[i] and minetest.registered_nodes[ new_nodes[i]] ) then + new = new_nodes[i]; + local found = false; + for i,v in ipairs(replacements) do + if( v and v[1]==old ) then + v[2] = new; + found = true; + end + end + if( not( found )) then + table.insert( replacements, { old, new }); + end + end + end + return replacements; +end + + +--------------------- +-- internal functions +--------------------- +-- wood (and its corresponding tree trunk) is a very good candidate for replacement in most houses +-- helper function for replacements_group['wood'].get_wood_type_list +replacements_group['wood'].add_material = function( candidate_list, mod_prefix, w_pre, w_post, t_pre, t_post, l_pre, l_post, + s_pre, s_post, stair_pre, stair_post, slab_pre, slab_post, + fence_pre, fence_post, gate_pre, gate_post ) + if( not( candidate_list )) then + return; + end + for _,v in ipairs( candidate_list ) do + local is_loaded = false; + local wood_name = mod_prefix..w_pre..v..w_post; + -- create a complete list of all possible wood names + table.insert( replacements_group['wood'].all, wood_name ); + -- create a list of all *installed* wood types + if( minetest.registered_nodes[ wood_name ]) then + table.insert( replacements_group['wood'].found, wood_name ); + is_loaded = true; + end + + -- there is no check if the node names created here actually exist + local data = { v, -- 1. base name of the node + mod_prefix, -- 2. mod name + wood_name, -- 3. replacement for default:wood + mod_prefix..t_pre..v..t_post, -- 4. " " for default:tree + mod_prefix..l_pre..v..l_post, -- 5. " " for default:leaves + mod_prefix..s_pre..v..s_post, -- 6. " " for default:sapling + stair_pre..v..stair_post, -- 7. " " for stairs:stair_wood + slab_pre..v..slab_post, -- 8. " " for stairs:slab_wood + fence_pre..v..fence_post, -- 9. " " for default:fence_wood + gate_pre..v..gate_post..'_open', -- 10. " " for cottages:gate_open + gate_pre..v..gate_post..'_closed',-- 11. " " for cottages:gate_closed + }; + + -- normal wood does have a number of nodes which might get replaced by more specialized wood types + if( mod_prefix=='default:' and v=='' ) then + local w = 'wood'; + data[10] = 'cottages:gate_open'; + data[11] = 'cottages:gate_closed'; + data[12] = 'default:ladder'; + data[13] = 'doors:door_'..w..'_t_1'; + data[14] = 'doors:door_'..w..'_t_2'; + data[15] = 'doors:door_'..w..'_b_1'; + data[16] = 'doors:door_'..w..'_b_2'; + data[17] = 'default:bookshelf'; + data[18] = 'default:chest'; + data[19] = 'default:chest_locked'; + data[20] = 'stairs:stair_'..w..'upside_down'; + data[21] = 'stairs:slab_'..w..'upside_down'; + data[22] = 'doors:trapdoor_open'; + data[23] = 'doors:trapdoor'; + -- realtest has some further replacements + elseif( mod_prefix=='trees:' and w_post=='_planks' and t_post=='_log' ) then + data[12] = 'trees:'..v..'_ladder'; + data[13] = 'doors:door_'..v..'_t_1'; + data[14] = 'doors:door_'..v..'_t_2'; + data[15] = 'doors:door_'..v..'_b_1'; + data[16] = 'doors:door_'..v..'_b_2'; + data[17] = 'decorations:bookshelf_'..v; + data[18] = 'trees:'..v..'_chest'; + data[19] = 'trees:'..v..'_chest_locked'; + data[20] = 'trees:'..v..'_planks_stair_upside_down'; + data[21] = 'trees:'..v..'_planks_slab_upside_down'; + data[22] = 'hatches:'..v..'_hatch_opened_top'; + data[23] = 'hatches:'..v..'_hatch_opened_bottom'; + end + replacements_group['wood'].data[ wood_name ] = data; + + -- none of the wood nodes counts as ground + local c_ignore = minetest.get_content_id( 'ignore' ); + for _,v in ipairs( data ) do + local id = minetest.get_content_id( v ); + if( id and id ~= c_ignore ) then + replacements_group.node_is_ground[ id ] = false; + end + end + + if( is_loaded and minetest.get_modpath('mobf_trader') and mobf_trader and mobf_trader.add_trader ) then + -- TODO: check if all offered payments exist + local goods = { + { data[3].." 4", "default:dirt 24", "default:cobble 24"}, + { data[4].." 4", "default:apple 2", "default:coal_lump 4"}, + { data[4].." 8", "default:pick_stone 1", "default:axe_stone 1"}, + { data[4].." 12", "default:cobble 80", "default:steel_ingot 1"}, + { data[4].." 36", "bucket:bucket_empty 1", "bucket:bucket_water 1"}, + { data[4].." 42", "default:axe_steel 1", "default:mese_crystal 4"}, + + { data[6].." 1", "default:mese 10", "default:steel_ingot 48"}, + -- leaves are a cheaper way of getting saplings + { data[5].." 10", "default:cobble 1", "default:dirt 2"} + }; + + mobf_trader.add_trader( mobf_trader.npc_trader_prototype, + "Trader of "..( v or "unknown" ).." wood", + v.."_wood_v", + goods, + { "lumberjack" }, + { 'holzfaeller.png' } + ); + + replacements_group['wood'].traders[ wood_name ] = v..'_wood_v'; + end + end +end + +-- TODO: there are also upside-down variants sometimes +-- TODO: moreblocks - those may be installed and offer further replacements + +-- create a list of all available wood types +replacements_group['wood'].construct_wood_type_list = function() + + -- https://github.com/minetest/minetest_game + -- default tree and jungletree; no gates available + replacements_group['wood'].add_material( {'', 'jungle' }, 'default:', '','wood','', 'tree', '','leaves', '','sapling', + 'stairs:stair_', 'wood', 'stairs:slab_', 'wood', 'default:fence_','wood', 'NONE', '' ); + -- default:pine_needles instead of leaves; no gates available + replacements_group['wood'].add_material( {'pine' }, 'default:', '','wood','', 'tree', '','_needles','','_sapling', + 'stairs:stair_', 'wood', 'stairs:slab_', 'wood', 'default:fence_','wood', 'NONE','' ); + + -- https://github.com/Novatux/mg + -- trees from nores mapgen + replacements_group['wood'].add_material( {'savanna', 'pine' },'mg:', '','wood','', 'tree', '','leaves', '','sapling', + 'stairs:stair_','wood', 'stairs:slab_','wood', 'NONE','', 'NONE',''); + + + -- https://github.com/VanessaE/moretrees + -- minus the jungletree (already in default) + local moretrees_treelist = {"beech","apple_tree","oak","sequoia","birch","palm","spruce","pine","willow","acacia","rubber_tree","fir" }; + replacements_group['wood'].add_material( moretrees_treelist, 'moretrees:', '', '_planks', '','_trunk', '','_leaves','','_sapling', + 'moretrees:stair_','_planks', 'moretrees:slab_','_planks', 'NONE','', 'NONE',''); + + + -- https://github.com/tenplus1/ethereal + -- ethereal does not have a common naming convention for leaves + replacements_group['wood'].add_material( {'acacia','redwood'},'ethereal:', '','_wood', '','_trunk', '','_leaves', '','_sapling', + 'stairs:stair_','_wood', 'stairs:slab_','_wood', 'ethereal:fence_','', 'ethereal:','gate'); + -- frost has another sapling type... + replacements_group['wood'].add_material( {'frost'}, 'ethereal:', '','_wood', '','_tree', '','_leaves', '','_tree_sapling', + 'stairs:stair_','_wood', 'stairs:slab_','_wood', 'ethereal:fence_','wood', 'ethereal:','woodgate' ); + -- those tree types do not use typ_leaves, but typleaves instead... + replacements_group['wood'].add_material( {'yellow'}, 'ethereal:', '','_wood', '','_trunk', '','leaves', '','_tree_sapling', + 'stairs:stair_','_wood', 'stairs:slab_','_wood', 'ethereal:fence_','wood', 'ethereal:','gate' ); + -- banana has a diffrent fence type.... + replacements_group['wood'].add_material( {'banana'}, 'ethereal:', '','_wood', '','_trunk', '','leaves', '','_tree_sapling', + 'stairs:stair_','_wood', 'stairs:slab_','_wood', 'ethereal:fence_', '', 'ethereal:','gate' ); + -- palm has another name for the sapling again... + replacements_group['wood'].add_material( {'palm'}, 'ethereal:', '','_wood', '','_trunk', '','leaves', '','_sapling', + 'stairs:stair_','_wood', 'stairs:slab_','_wood', 'ethereal:fence_', '', 'ethereal:','gate' ); + -- the leaves are called willow_twig here... + replacements_group['wood'].add_material( {'willow'}, 'ethereal:', '','_wood', '','_trunk', '','_twig', '','_sapling', + 'stairs:stair_','_wood', 'stairs:slab_','_wood', 'ethereal:fence_', '', 'ethereal:','gate' ); + -- mushroom has its own name; it works quite well as a wood replacement; the red cap is used as leaves + -- the stairs are also called slightly diffrently (end in _trunk instead of _wood) + replacements_group['wood'].add_material( {'mushroom'}, 'ethereal:', '','_pore', '','_trunk', '','', '','_sapling', + 'stairs:stair_','_trunk', 'stairs:slab_','_trunk', 'ethereal:fence_', '', 'ethereal:','gate' ); + + + -- https://github.com/VanessaE/realtest_game + local realtest_trees = {'ash','aspen','birch','maple','chestnut','pine','spruce'}; + replacements_group['wood'].add_material( realtest_trees, 'trees:', '','_planks', '','_log', '','_leaves', '','_sapling', + 'trees:','_planks_stair', 'trees:','_planks_slab', 'fences:','_fence', 'NONE','' ); + + + -- https://github.com/Gael-de-Sailly/Forest + local forest_trees = {'oak','birch','willow','fir','mirabelle','cherry','plum','beech','ginkgo','lavender'}; + replacements_group['wood'].add_material( forest_trees, 'forest:', '', '_wood', '','_tree', '','_leaves', '','_sapling', + 'stairs:stair_','_wood', 'stairs:slab_','_wood', 'NONE','', 'NONE','' ); + + -- https://github.com/bas080/trees + replacements_group['wood'].add_material( {'mangrove','palm','conifer'},'trees:', 'wood_','', 'tree_','', 'leaves_','', 'sapling_','', + 'stairs:stair_','_wood', 'stairs:slab_','_wood', 'NONE','', 'NONE','' ); + + + -- https://github.com/PilzAdam/farming_plus + -- TODO: this does not come with its own wood... banana and cocoa trees (only leaves, sapling and fruit) + -- TODO: farming_plus:TREETYP_sapling farming_plus:TREETYP_leaves farming_plus:TREETYP + -- TODO: in general: add fruits as replacements for apples +end + +-- actually construct the data structure once +replacements_group['wood'].construct_wood_type_list(); + diff --git a/mods/a_mapgen_mods/handle_schematics/rotate.lua b/mods/a_mapgen_mods/handle_schematics/rotate.lua new file mode 100644 index 00000000..91d6abd6 --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/rotate.lua @@ -0,0 +1,114 @@ +local rotate_facedir = function(facedir) + return ({1, 2, 3, 0, + 13, 14, 15, 12, + 17, 18, 19, 16, + 9, 10, 11, 8, + 5, 6, 7, 4, + 21, 22, 23, 20})[facedir+1] +end + + +-- accessd through handle_schematics.mirror_facedir[ (rotation%2)+1 ][ facedir+1 ] +handle_schematics.mirror_facedir = + {{ 2, 1, 0, 3, -- 0, 1, 2, 3 + 8, 9, 10, 11, -- 4, 5, 6, 7 + 4, 5, 6, 7, -- 8, 9,10,11 + 12, 13, 14, 15, --12,13,14,15 + 16, 17, 18, 19, --16,17,18,19 + 22, 21, 20, 23 --20,21,22,23 + }, + { 0, 3, 2, 1, -- 0, 1, 2, 3 + 4, 7, 6, 5, -- 4, 5, 6, 7 + 8, 9, 10, 11, -- 8, 9,10,11 + 16, 17, 18, 19, --12,13,14,15 + 12, 15, 14, 13, --16,17,18,19 + 20, 23, 22, 21 --20,21,22,23 + }}; + +local rotate_wallmounted = function(wallmounted) + return ({0, 1, 5, 4, 2, 3})[wallmounted+1] +end + +handle_schematics.get_param2_rotated = function( paramtype2, p2 ) + local p2r = {}; + p2r[ 1 ] = p2; + if( paramtype2 == 'wallmounted' ) then + for i = 2,4 do + p2r[ i ] = rotate_wallmounted( p2r[ i-1 ]); + end + elseif( paramtype2 == 'facedir' ) then + for i = 2,4 do + p2r[ i ] = rotate_facedir( p2r[ i-1 ]); + end + p2r[5]=1; -- indicate that it is wallmounted + else + return { p2, p2, p2, p2 }; + end + return p2r; +end + + +handle_schematics.mirrored_node = {}; + +handle_schematics.add_mirrored_node_type = function( name, mirrored_name ) + handle_schematics.mirrored_node[ name ] = mirrored_name; + local id = minetest.get_content_id( name ); + local id_mi = minetest.get_content_id( mirrored_name ); + local c_ignore = minetest.get_content_id( 'ignore' ); + if( id and id_mi and id ~= c_ignore and id_mi ~= c_ignore ) then + handle_schematics.mirrored_node[ id ] = id_mi; + end +end + +local door_materials = {'wood','steel','glass','obsidian_glass'}; +for _,material in ipairs( door_materials ) do + handle_schematics.add_mirrored_node_type( 'doors:door_'..material..'_b_1', 'doors:door_'..material..'_b_2' ); + handle_schematics.add_mirrored_node_type( 'doors:door_'..material..'_t_1', 'doors:door_'..material..'_t_2' ); + handle_schematics.add_mirrored_node_type( 'doors:door_'..material..'_b_2', 'doors:door_'..material..'_b_1' ); + handle_schematics.add_mirrored_node_type( 'doors:door_'..material..'_t_2', 'doors:door_'..material..'_t_1' ); +end + + + + +handle_schematics.rotation_table = {}; +handle_schematics.rotation_table[ 'facedir' ] = {}; +handle_schematics.rotation_table[ 'wallmounted' ] = {}; + + +for paramtype2,v in pairs( handle_schematics.rotation_table ) do + for param2 = 0,23 do + + if( param2 < 6 or paramtype2 == 'facedir' ) then + local param2list = handle_schematics.get_param2_rotated( paramtype2, param2); + + handle_schematics.rotation_table[ paramtype2 ][ param2+1 ] = {}; + + for rotation = 0,3 do + local np2 = param2list[ rotation + 1]; + local mirror_x = np2; + local mirror_z = np2; + + -- mirror_x + if( #param2list==5) then + mirror_x = handle_schematics.mirror_facedir[ (( rotation +1)%2)+1 ][ np2+1 ]; + elseif( #param2list<5 + and (( rotation%2==1 and (np2==4 or np2==5)) + or ( rotation%2==0 and (np2==2 or np2==3)))) then + mirror_x = param2list[ ( rotation + 2)%4 +1]; + end + + -- mirror_z + if( #param2list==5) then + mirror_z = handle_schematics.mirror_facedir[ (rotation %2)+1 ][ np2+1 ]; + elseif( #param2list<5 + and (( rotation%2==0 and (np2==4 or np2==5)) + or ( rotation%2==1 and (np2==2 or np2==3)))) then + mirror_z = param2list[ ( rotation + 2)%4 +1]; + end + + handle_schematics.rotation_table[ paramtype2 ][ param2+1 ][ rotation+1 ] = { np2, mirror_x, mirror_z }; + end + end + end +end diff --git a/mods/a_mapgen_mods/handle_schematics/save_restore.lua b/mods/a_mapgen_mods/handle_schematics/save_restore.lua new file mode 100644 index 00000000..3ac27cd7 --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/save_restore.lua @@ -0,0 +1,91 @@ + +-- reserve the namespace +save_restore = {} + +-- TODO: if this gets more versatile, add sanity checks for filename +-- TODO: apart from allowing filenames, schems/ also needs to be allowed + +-- TODO: save and restore ought to be library functions and not implemented in each individual mod! +save_restore.save_data = function( filename, data ) + + local path = minetest.get_worldpath()..'/'..filename; + + local file = io.open( path, 'w' ); + if( file ) then + file:write( minetest.serialize( data )); + file:close(); + else + print("[save_restore] Error: Savefile '"..tostring( path ).."' could not be written."); + end +end + + +save_restore.restore_data = function( filename ) + local path = minetest.get_worldpath()..'/'..filename; + local file = io.open( path, 'r' ); + if( file ) then + local data = file:read("*all"); + file:close(); + return minetest.deserialize( data ); + else + print("[save_restore] Error: Savefile '"..tostring( path ).."' not found."); + return {}; -- return empty table + end +end + + + +save_restore.file_exists = function( filename ) + + local path = minetest.get_worldpath()..'/'..filename; + + local file = save_restore.file_access( path, 'r' ); + if( file ) then + file:close(); + return true; + end + return; +end + + +save_restore.create_directory = function( filename ) + + local path = minetest.get_worldpath()..'/'..filename; + + if( not( save_restore.file_exists( filename ))) then + if( minetest.mkdir ) then + minetest.mkdir( minetest.get_worldpath().."/schems"); + else + os.execute("mkdir \""..minetest.get_worldpath().."/schems".. "\""); + end + end +end + + +-- we only need the function io.open in a version that can read schematic files from diffrent places, +-- even if a secure environment is enforced; this does require an exception for the mod +local ie_io_open = io.open; +if( minetest.request_insecure_environment ) then + local ie, req_ie = _G, minetest.request_insecure_environment + if req_ie then ie = req_ie() end + if ie then + ie_io_open = ie.io.open; + end +end + +-- only a certain type of files can be read and written +save_restore.file_access = function( path, params ) + if( (params=='r' or params=='rb') + and ( string.find( path, '.mts', -4 ) + or string.find( path, '.schematic', -11 ) + or string.find( path, '.we', -3 ) + or string.find( path, '.wem', -4 ) )) then + return ie_io_open( path, params ); + elseif( (params=='w' or params=='wb') + and ( string.find( path, '.mts', -4 ) + or string.find( path, '.schematic', -11 ) + or string.find( path, '.we', -3 ) + or string.find( path, '.wem', -4 ) )) then + return ie_io_open( path, params ); + end +end diff --git a/mods/a_mapgen_mods/handle_schematics/textures/handle_schematics_support.png b/mods/a_mapgen_mods/handle_schematics/textures/handle_schematics_support.png new file mode 100644 index 0000000000000000000000000000000000000000..b5abf1e9e20a4e789038b830a870ac57247b6d74 GIT binary patch literal 261 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv4DbnYjZ>9K){rdHk(p>FJJmvd zx|8-yC+#^-TAMxe_xc*|@He{o`^IIUV$K4O$YKTtZeb8+WSBKa0w~B{;_2(kexIF@ zSI%%ny6{Y(P`RgzV+hA}*VBf4hYSQF)MR}@U(cg^f= 4 then + return {name.. "upside_down", mc2mtFacedir(blockdata - 4)} + else + return {name, mc2mtFacedir(blockdata)} + end +end + + +-- returns {translated_node_name, translated_param2} +handle_schematics.findMC2MTConversion = function(blockid, blockdata) + if (blockid == 0 ) then + return {"air",0}; + -- fallback + elseif( not( conversionTable[ blockid ])) then + return { "minecraft:"..tostring( blockid )..'_'..tostring( blockdata ), 0}; + end + local conv = conversionTable[ blockid ]; + if( conv[1] == P2_IGNORE ) then + return { conv[2], 0}; + elseif( conv[1] == P2_COPY ) then + return { conv[2], blockdata}; + elseif( conv[1] == P2_CONVERT) then + return { conv[2], mc2mtFacedir(blockdata)}; + elseif( conv[1] == P2_STAIR ) then + return mc2mtstairs(conv[2], blockdata); + elseif( conv[1] == P2_SELECT + and conv[2][ blockdata ] ) then + return { conv[2][ blockdata ], 0}; + elseif( conv[1] == P2_SELECT + and not(conv[2][ blockdata ] )) then + return { conv[2][0], 0}; + else + return { conv[2], 0 }; + end + return {air, 0}; +end diff --git a/mods/a_mapgen_mods/handle_schematics/worldedit_file.lua b/mods/a_mapgen_mods/handle_schematics/worldedit_file.lua new file mode 100644 index 00000000..e5005379 --- /dev/null +++ b/mods/a_mapgen_mods/handle_schematics/worldedit_file.lua @@ -0,0 +1,138 @@ +------------------------------------------------------------------------------------------ +-- This is the file +-- https://github.com/Uberi/Minetest-WorldEdit/blob/master/worldedit/serialization.lua +-- Changes: +-- * worldedit namespace renamed to worldeit_file +-- * eliminiated functions that are not needed +-- * made function load_schematic non-local +-- * originx, originy and originz are now passed as parameters to worldedit_file.load_schematic; +-- they are required for an old file format +------------------------------------------------------------------------------------------ + +worldedit_file = {} -- add the namespace + +--- Schematic serialization and deserialiation. +-- @module worldedit.serialization + +worldedit_file.LATEST_SERIALIZATION_VERSION = 5 +local LATEST_SERIALIZATION_HEADER = worldedit_file.LATEST_SERIALIZATION_VERSION .. ":" + + +--[[ +Serialization version history: + 1: Original format. Serialized Lua table with a weird linked format... + 2: Position and node seperated into sub-tables in fields `1` and `2`. + 3: List of nodes, one per line, with fields seperated by spaces. + Format: + 4: Serialized Lua table containing a list of nodes with `x`, `y`, `z`, + `name`, `param1`, `param2`, and `meta` fields. + 5: Added header and made `param1`, `param2`, and `meta` fields optional. + Header format: ,,...: +--]] + + +--- Reads the header of serialized data. +-- @param value Serialized WorldEdit data. +-- @return The version as a positive natural number, or 0 for unknown versions. +-- @return Extra header fields as a list of strings, or nil if not supported. +-- @return Content (data after header). +function worldedit_file.read_header(value) + if value:find("^[0-9]+[%-:]") then + local header_end = value:find(":", 1, true) + local header = value:sub(1, header_end - 1):split(",") + local version = tonumber(header[1]) + table.remove(header, 1) + local content = value:sub(header_end + 1) + return version, header, content + end + -- Old versions that didn't include a header with a version number + if value:find("([+-]?%d+)%s+([+-]?%d+)%s+([+-]?%d+)") and not value:find("%{") then -- List format + return 3, nil, value + elseif value:find("^[^\"']+%{%d+%}") then + if value:find("%[\"meta\"%]") then -- Meta flat table format + return 2, nil, value + end + return 1, nil, value -- Flat table format + elseif value:find("%{") then -- Raw nested table format + return 4, nil, value + end + return nil +end + + +--- Loads the schematic in `value` into a node list in the latest format. +-- Contains code based on [table.save/table.load](http://lua-users.org/wiki/SaveTableToFile) +-- by ChillCode, available under the MIT license. +-- @return A node list in the latest format, or nil on failure. +function worldedit_file.load_schematic(value, we_origin) + local version, header, content = worldedit_file.read_header(value) + local nodes = {} + if version == 1 or version == 2 then -- Original flat table format + local tables = minetest.deserialize(content) + if not tables then return nil end + + -- Transform the node table into an array of nodes + for i = 1, #tables do + for j, v in pairs(tables[i]) do + if type(v) == "table" then + tables[i][j] = tables[v[1]] + end + end + end + nodes = tables[1] + + if version == 1 then --original flat table format + for i, entry in ipairs(nodes) do + local pos = entry[1] + entry.x, entry.y, entry.z = pos.x, pos.y, pos.z + entry[1] = nil + local node = entry[2] + entry.name, entry.param1, entry.param2 = node.name, node.param1, node.param2 + entry[2] = nil + end + end + elseif version == 3 or version=="3" then -- List format + if( not( we_origin ) or #we_origin <3) then + we_origin = { 0, 0, 0 }; + end + for x, y, z, name, param1, param2 in content:gmatch( + "([+-]?%d+)%s+([+-]?%d+)%s+([+-]?%d+)%s+" .. + "([^%s]+)%s+(%d+)%s+(%d+)[^\r\n]*[\r\n]*") do + param1, param2 = tonumber(param1), tonumber(param2) + table.insert(nodes, { + x = we_origin[1] + tonumber(x), + y = we_origin[2] + tonumber(y), + z = we_origin[3] + tonumber(z), + name = name, + param1 = param1 ~= 0 and param1 or nil, + param2 = param2 ~= 0 and param2 or nil, + }) + end + elseif version == 4 or version == 5 then -- Nested table format + if not jit then + -- This is broken for larger tables in the current version of LuaJIT + nodes = minetest.deserialize(content) + else + -- XXX: This is a filthy hack that works surprisingly well - in LuaJIT, `minetest.deserialize` will fail due to the register limit + nodes = {} + content = content:gsub("return%s*{", "", 1):gsub("}%s*$", "", 1) -- remove the starting and ending values to leave only the node data + local escaped = content:gsub("\\\\", "@@"):gsub("\\\"", "@@"):gsub("(\"[^\"]*\")", function(s) return string.rep("@", #s) end) + local startpos, startpos1, endpos = 1, 1 + while true do -- go through each individual node entry (except the last) + startpos, endpos = escaped:find("},%s*{", startpos) + if not startpos then + break + end + local current = content:sub(startpos1, startpos) + local entry = minetest.deserialize("return " .. current) + table.insert(nodes, entry) + startpos, startpos1 = endpos, endpos + end + local entry = minetest.deserialize("return " .. content:sub(startpos1)) -- process the last entry + table.insert(nodes, entry) + end + else + return nil + end + return nodes +end diff --git a/mods/a_mapgen_mods/mg_villages/--config -orig.lua b/mods/a_mapgen_mods/mg_villages/--config -orig.lua new file mode 100644 index 00000000..b01dc72d --- /dev/null +++ b/mods/a_mapgen_mods/mg_villages/--config -orig.lua @@ -0,0 +1,187 @@ +----------------------------------------------------------------------------- +-- configuration values which you can adjust according to your liking +----------------------------------------------------------------------------- +-- set to false if you do not want to have any villages spawning +mg_villages.ENABLE_VILLAGES = true; + +-- generate one random building for each mg_villages.INVERSE_HOUSE_DENSITY th mapchunk; +-- set to 0 in order to disable spawning of these lone buildings outside villages +mg_villages.INVERSE_HOUSE_DENSITY = 4; + +-- cover some villages with artificial snow; probability: 1/mg_villages.artificial_snow_probability +mg_villages.artificial_snow_probability = 10; + +-- if set to true, soil around villaes will get special soil-snow instead of plant + snow cover +mg_villages.use_soil_snow = false; + +-- only place roads if there are at least that many buildings in the village +mg_villages.MINIMAL_BUILDUNGS_FOR_ROAD_PLACEMENT = 4; + + +-- players without the mg_villages priv can only see villages which are less than that many blocks away +-- from them when using the /vmap command +mg_villages.VILLAGE_DETECT_RANGE = 400; + +-- if set to true, only players which have the mg_villages priv can use the "/visit " +-- command which allows teleporting to the village with the given number +mg_villages.REQUIRE_PRIV_FOR_TELEPORT = false; + +-- if set to true, players cannot modify spawned villages without buying the house from the village first +mg_villages.ENABLE_PROTECTION = true; + +-- the first village - the one the player spawns in - will be of this type +mg_villages.FIRST_VILLAGE_TYPE = 'medieval'; + +-- the mapgen will disregard mapchunks where min.y > mg_villages.MAX_HEIGHT_TREATED; +-- you can set this value to 64 if you have a slow machine and a mapgen which does not create extreme mountains +-- (or if you don't care if extreme mountains may create burried villages occasionally) +mg_villages.MAX_HEIGHT_TREATED = 200; + +-- choose the debug level you want +mg_villages.DEBUG_LEVEL = mg_villages.DEBUG_LEVEL_NORMAL + +-- if set to true (or anything else but nil or false), highlandpools by paramat (see +-- https://forum.minetest.net/viewtopic.php?t=8400) will be created +mg_villages.CREATE_HIGHLANDPOOLS = true + +-- background image for the /vmap command +-- RealTest comes with a diffrent texture +if( minetest.get_modpath('grounds') and minetest.get_modpath('joiner_table')) then + mg_villages.MAP_BACKGROUND_IMAGE = "default_dirt_grass.png"; +elseif( minetest.registered_nodes[ 'default:dirt_with_grass'] ) then + mg_villages.MAP_BACKGROUND_IMAGE = "default_grass.png"; +else + mg_villages.MAP_BACKGROUND_IMAGE = ""; +end + +-- if set to true, the outer buildings in medieval villages will be fields; this is not very convincing yet +-- currently not really used; does not look as good as expected +mg_villages.medieval_subtype = false; + +-- set this to true if you want to use normal lava - but beware: charachoal villages may cause bushfires! +--mg_villages.use_normal_unsafe_lava = false; + +----------------------------------------------------------------------------- +-- decrese these values slightly if you want MORE trees around your villages; +-- increase it if you want to DECREASE the amount of trees around villages +----------------------------------------------------------------------------- +-- on average, every n.th node inside a village area may be one of these trees - and it will be a relatively dense packed forrest +mg_villages.sapling_probability = {}; + +mg_villages.sapling_probability[ minetest.get_content_id( 'default:sapling' ) ] = 25; -- suitable for a relatively dense forrest of normal trees +mg_villages.sapling_probability[ minetest.get_content_id( 'default:junglesapling' ) ] = 40; -- jungletrees are a bit bigger and need more space +mg_villages.sapling_probability[ minetest.get_content_id( 'default:pinesapling' ) ] = 30; +if( minetest.get_modpath( 'mg' )) then + mg_villages.sapling_probability[ minetest.get_content_id( 'mg:savannasapling' ) ] = 30; + mg_villages.sapling_probability[ minetest.get_content_id( 'mg:pinesapling' ) ] = 35; +end +mg_villages.moretrees_treelist = nil; +if( minetest.get_modpath( 'moretrees' )) then + mg_villages.moretrees_treelist = moretrees.treelist; + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:birch_sapling_ongen' ) ] = 200; + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:spruce_sapling_ongen' ) ] = 200; + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:fir_sapling_ongen' ) ] = 90; + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:jungletree_sapling_ongen' ) ] = 200; + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:beech_sapling_ongen' ) ] = 30; + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:apple_sapling_ongen' ) ] = 380; + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:oak_sapling_ongen' ) ] = 380; -- ca 20x20; height: 10 + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:sequoia_sapling_ongen' ) ] = 90; -- ca 10x10 + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:palm_sapling_ongen' ) ] = 90; + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:pine_sapling_ongen' ) ] = 200; + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:willow_sapling_ongen' ) ] = 380; + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:rubber_tree_sapling_ongen' ) ] = 380; +end + + +----------------------------------------------------------------------------- +-- no need to change this, unless you add new farming_plus fruits +----------------------------------------------------------------------------- +-- the schematics for buildings of type 'farm_tiny' grow cotton; the farming_plus fruits would be far more fitting +mg_villages.fruit_list = {'carrot','potatoe','orange','rhubarb','strawberry','tomato','cotton'}; +-- is farming_plus available? If not, we can't use this +if( not( minetest.get_modpath("farming_plus"))) then + mg_villages.fruit_list = nil; +end + + +----------------------------------------------------------------------------- +-- players can buy plots in villages with houses on for this price; +-- set according to your liking +----------------------------------------------------------------------------- +-- how much does the player have to pay for a plot with a building? +mg_villages.prices = { + empty = "default:copper_ingot 1", -- plot to build on + + -- building types which usually have inhabitants (and thus allow the player + -- who bought the building to modifiy the entire village area minus other + -- buildings) + tent = "default:copper_ingot 1", + hut = "default:copper_ingot 1", + farm_full = "default:gold_ingot 4", + farm_tiny = "default:gold_ingot 2", + lumberjack = "default:gold_ingot 2", + house = "default:gold_ingot 2", + house_large = "default:gold_ingot 4", + tavern = "default:gold_ingot 12", + trader = "default:gold_ingot 2", + + -- more or less community buildings + well = "default:gold_ingot 1", + village_square = "default:goldblock 1", + secular = "default:goldblock 2", -- secular buildings, such as libraries ec. + church = "default:goldblock 10", + + -- places for mobs to work at; usually without inhabitants + tower = "default:copper_ingot 1", + shed = "default:copper_ingot 2", + pit = "default:copper_ingot 3", -- claytrader pit + mill = "default:gold_ingot 10", + forge = "default:gold_ingot 10", + bakery = "default:gold_ingot 10", + shop = "default:gold_ingot 20", + sawmill = "default:gold_ingot 30", + + -- decoration + wagon = "default:tree 10", + bench = "default:tree 4", + + -- seperate fields + pasture = "default:copper_ingot 2", + field = "default:copper_ingot 2", + + -- chateaus are expensive + chateau = "default:diamondblock 5", +} + + +----------------------------------------------------------------------------- +-- The values below seldom need adjustment; don't change them unless you +-- know exactly what you are doing. +----------------------------------------------------------------------------- +-- if set to false, villages will not be integrated into the terrain - which looks very bad +mg_villages.ENABLE_TERRAIN_BLEND = true; +-- if set to false, holes digged by cavegen and mudflow inside the village will not be repaired; houses will be destroyed +mg_villages.UNDO_CAVEGEN_AND_MUDFLOW = true; + +-- internal variables for village generation + +mg_villages.VILLAGE_CHECK_RADIUS = 2 +mg_villages.VILLAGE_CHECK_COUNT = 1 +--mg_villages.VILLAGE_CHANCE = 28 +--mg_villages.VILLAGE_MIN_SIZE = 20 +--mg_villages.VILLAGE_MAX_SIZE = 40 +mg_villages.VILLAGE_CHANCE = 28 +-- min and max size are only used in case of them beeing not provided by the village type (see buildings.lua) +mg_villages.VILLAGE_MIN_SIZE = 25 +mg_villages.VILLAGE_MAX_SIZE = 90 --55 +mg_villages.FIRST_ROADSIZE = 3 +mg_villages.BIG_ROAD_CHANCE = 0 + +-- Enable that for really big villages (there are also really slow to generate) +--[[mg_villages.VILLAGE_CHECK_RADIUS = 3 +mg_villages.VILLAGE_CHECK_COUNT = 3 +mg_villages.VILLAGE_CHANCE = 28 +mg_villages.VILLAGE_MIN_SIZE = 100 +mg_villages.VILLAGE_MAX_SIZE = 150 +mg_villages.FIRST_ROADSIZE = 5 +mg_villages.BIG_ROAD_CHANCE = 50]] diff --git a/mods/a_mapgen_mods/mg_villages/README.md b/mods/a_mapgen_mods/mg_villages/README.md new file mode 100644 index 00000000..a11c85c0 --- /dev/null +++ b/mods/a_mapgen_mods/mg_villages/README.md @@ -0,0 +1,3 @@ +This is a continuation of my (Sokomines) fork of Nores mg mapgen. +The fork can be found under https://github.com/Sokomine/mg + diff --git a/mods/a_mapgen_mods/mg_villages/buildings.lua b/mods/a_mapgen_mods/mg_villages/buildings.lua new file mode 100644 index 00000000..a205e516 --- /dev/null +++ b/mods/a_mapgen_mods/mg_villages/buildings.lua @@ -0,0 +1,430 @@ +-- scm="bla" Name of the file that holds the buildings' schematic. Supported types: .we and .mts (omit the extension!) +-- sizex, sizez, ysize: obsolete +-- yoff=0 how deep is the building burried? +-- pervillage=1 Never generate more than this amount of this building and this type (if set) of building per village. +-- axis=1 Building needs to be mirrored along the x-axis instead of the z-axis because it is initially rotated +-- inh=2 maximum amount of inhabitants the building may hold (usually amount of beds present) +-- if set to i.e. -1, this indicates that a mob is WORKING, but not LIVING here +-- we_origin Only needed for very old .we files (savefile format version 3) which do not start at 0,0,0 but have an offset. +-- price Stack that has to be paid in order to become owner of the plot the building stands on and the building; +-- overrides mg_villages.prices[ building_typ ]. + +mg_villages.all_buildings_list = {} + +local buildings = { + +-- the houses the mod came with + {yoff= 0, scm="house", orients={2}, typ='house', weight={nore=1, single=2 }, inh=4}, + {yoff= 0, scm="wheat_field", typ='field', weight={nore=1 }, inh=-1}, + {yoff= 0, scm="cotton_field", typ='field', weight={nore=1 }, inh=-1}, + {yoff= 1, scm="lamp", no_rotate=true, typ='deco', weight={nore=1/5 }}, + {yoff=-5, scm="well", no_rotate=true, pervillage=1, typ='well', weight={nore=1 }}, + {yoff= 0, scm="fountain", pervillage=3, typ='fountain', weight={nore=1/4 }, axis=1}, + {yoff= 0, scm="small_house", orients={3}, typ='house', weight={nore=1, single=2 }, axis=1, inh=2}, + {yoff= 0, scm="house_with_garden", orients={1}, typ='house', weight={nore=1, single=2 }, axis=1, inh=3}, + {yoff= 0, scm="church", orients={3}, pervillage=1, typ='church', weight={nore=1 }, axis=1, inh=-1}, + {yoff= 0, scm="tower", orients={0}, typ='tower', weight={nore=1/7, single=1 }, inh=-1}, + {yoff= 0, scm="forge", orients={0}, pervillage=2, typ='forge', weight={nore=1, single=1/3 }, inh=-1}, + {yoff= 0, scm="library", orients={1}, pervillage=2, typ='secular', weight={nore=1 }, axis=1, inh=-1}, + {yoff= 0, scm="inn", orients={1}, pervillage=4, typ='tavern', weight={nore=1/2, single=1/3 }, axis=1, inh=-1}, -- has room for 4 guests + {yoff= 0, scm="pub", orients={3}, pervillage=2, typ='tavern', weight={nore=1/3, single=1/3 }, axis=1, inh=-1}, + + +-- log cabins by Sokomine (requiring cottages, glasspanes) + {yoff= 0, scm="logcabin1", orients={1}, weight={logcabin=1, single=1}, axis=1, inh=2, typ='hut'}, + {yoff= 0, scm="logcabin2", orients={1}, weight={logcabin=1, single=1}, axis=1, inh=2, typ='hut'}, + {yoff= 0, scm="logcabin3", orients={1}, weight={logcabin=1, single=1}, axis=1, inh=3, typ='hut'}, + {yoff= 0, scm="logcabin4", orients={1}, weight={logcabin=1, single=1}, axis=1, inh=3, typ='hut'}, + {yoff= 0, scm="logcabin5", orients={1}, weight={logcabin=1, single=1}, axis=1, inh=1, typ='hut'}, + {yoff= 0, scm="logcabin6", orients={1}, weight={logcabin=1, single=1}, axis=1, inh=1, typ='hut'}, + {yoff= 0, scm="logcabin7", orients={1}, weight={logcabin=1, single=1}, axis=1, inh=2, typ='hut'}, + {yoff= 0, scm="logcabin8", orients={1}, weight={logcabin=1, single=1}, axis=1, inh=2, typ='hut'}, + {yoff= 0, scm="logcabin9", orients={1}, weight={logcabin=1, single=1}, axis=1, inh=1, typ='hut'}, + {yoff= 0, scm="logcabin10", orients={2}, weight={logcabin=1, single=1}, inh=3, typ='hut'}, + {yoff= 0, scm="logcabin11", orients={2}, weight={logcabin=1, single=1}, inh=6, typ='hut'}, + {yoff= 0, scm="logcabinpub1", orients={1}, weight={logcabin=1/6, single=1}, pervillage=1, typ='tavern', axis=1, inh=1}, -- +5 guests + {yoff= 0, scm="logcabinpub2", orients={1}, weight={logcabin=1/6, single=1}, pervillage=1, typ='tavern', axis=1, inh=2}, -- +8 guests + {yoff= 0, scm="logcabinpub3", orients={1}, weight={logcabin=1/6, single=1}, pervillage=1, typ='tavern', axis=1, inh=2}, -- +12 guest + +-- grass huts (requiring cottages, dryplants, cavestuff/undergrowth, plantlife) + {yoff= 0, scm="grasshut1", orients={2}, weight={grasshut=1, single=1}, inh=3, typ='hut'}, + {yoff= 0, scm="grasshut2", orients={2}, weight={grasshut=1, single=1}, inh=10, typ='hut'}, -- community hut for meetings + {yoff= 0, scm="grasshut3", orients={2}, weight={grasshut=1, single=1}, inh=3, typ='hut'}, + {yoff= 0, scm="grasshut4", orients={2}, weight={grasshut=1, single=1}, inh=3, typ='hut'}, + {yoff= 0, scm="grasshut5", orients={2}, weight={grasshut=1, single=1}, inh=1, typ='hut'}, + {yoff= 0, scm="grasshut6", orients={2}, weight={grasshut=1, single=1}, inh=3, typ='hut'}, + {yoff= 0, scm="grasshutcenter", orients={2}, pervillage=1, weight={grasshut=2}, typ = 'tavern'}, -- open meeting place + +-- for the buildings below, sizex, sizez and ysize are read from the file directly; + +-- schematics from Sokomines villages mod (requires cottages) + {scm="church_1", yoff= 0, orients={0}, farming_plus=0, avoid='', typ='church', weight={medieval=4 }, pervillage=1, inh=-1}, +-- {scm="church_2_twoelk", yoff= 0, orients={0}, farming_plus=0, avoid='', typ='church', weight={medieval=4}, pervillage=1}, + {scm="forge_1", yoff= 0, orients={0}, farming_plus=0, avoid='', typ='forge', weight={medieval=2, single=1/2}, pervillage=1, inh=-1}, + {scm="mill_1", yoff= 0, orients={0}, farming_plus=0, avoid='', typ='mill', weight={medieval=2 }, pervillage=1, inh=-1}, + {scm="watermill_1", yoff=-3, orients={1}, farming_plus=0, avoid='', typ='mill', weight={medieval=2 }, pervillage=1, inh=-2}, + {scm="hut_1", yoff= 0, orients={0}, farming_plus=0, avoid='', typ='hut', weight={medieval=1, single=1 }, inh=1}, + {scm="hut_2", yoff= 0, orients={0}, farming_plus=0, avoid='', typ='hut', weight={medieval=1, single=1 }, inh=2}, + {scm="farm_full_1", yoff= 0, orients={0}, farming_plus=0, avoid='', typ='farm_full', weight={medieval=1/4, single=1 }, inh=2}, + {scm="farm_full_2", yoff= 0, orients={0}, farming_plus=0, avoid='', typ='farm_full', weight={medieval=1/4, single=1 }, inh=5}, + {scm="farm_full_3", yoff= 0, orients={0}, farming_plus=0, avoid='', typ='farm_full', weight={medieval=1/4, single=1 }, inh=5}, + {scm="farm_full_4", yoff= 0, orients={0}, farming_plus=0, avoid='', typ='farm_full', weight={medieval=1/4, single=1 }, inh=8}, + {scm="farm_full_5", yoff= 0, orients={0}, farming_plus=0, avoid='', typ='farm_full', weight={medieval=1/4, single=1 }, inh=5}, + {scm="farm_full_6", yoff= 0, orients={0}, farming_plus=0, avoid='', typ='farm_full', weight={medieval=1/4, single=1 }, inh=5}, + {scm="farm_tiny_1", yoff= 0, orients={0}, farming_plus=1, avoid='', typ='farm_tiny', weight={medieval=1, single=1 }, inh=2}, + {scm="farm_tiny_2", yoff= 0, orients={0}, farming_plus=1, avoid='', typ='farm_tiny', weight={medieval=1, single=1 }, inh=6}, + {scm="farm_tiny_3", yoff= 0, orients={0}, farming_plus=1, avoid='', typ='farm_tiny', weight={medieval=1, single=1 }, inh=4}, + {scm="farm_tiny_4", yoff= 0, orients={0}, farming_plus=1, avoid='', typ='farm_tiny', weight={medieval=1, single=1 }, inh=4}, + {scm="farm_tiny_5", yoff= 0, orients={0}, farming_plus=1, avoid='', typ='farm_tiny', weight={medieval=1, single=1 }, inh=4}, + {scm="farm_tiny_6", yoff= 0, orients={0}, farming_plus=1, avoid='', typ='farm_tiny', weight={medieval=1, single=1 }, inh=4}, + {scm="farm_tiny_7", yoff= 0, orients={0}, farming_plus=1, avoid='', typ='farm_tiny', weight={medieval=1, single=1 }, inh=7}, + {scm="taverne_1", yoff= 0, orients={0}, farming_plus=1, avoid='', typ='tavern', weight={medieval=1/2, single=1 }, pervillage=1, inh=6}, -- 19 beds: 10 guest, 3 worker, 6 family + {scm="taverne_2", yoff= 0, orients={0}, farming_plus=0, avoid='', typ='tavern', weight={medieval=1/2, single=1/3}, pervillage=1, inh=2}, -- no guests + {scm="taverne_3", yoff= 0, orients={0}, farming_plus=0, avoid='', typ='tavern', weight={medieval=1/2, single=1/3}, pervillage=1, inh=2}, -- no guests + {scm="taverne_4", yoff= 0, orients={0}, farming_plus=0, avoid='', typ='tavern', weight={medieval=1/2, single=1/3}, pervillage=1, inh=1}, -- no guests + + {scm="well_1", yoff= 0, orients={0}, farming_plus=0, avoid='well', typ='well', weight={medieval=1/12, single=1/2}, pervillage=4}, + {scm="well_2", yoff= 0, orients={0}, farming_plus=0, avoid='well', typ='well', weight={medieval=1/12, single=1/2}, pervillage=4}, + {scm="well_3", yoff= 0, orients={0}, farming_plus=0, avoid='well', typ='well', weight={medieval=1/12, single=1/2}, pervillage=4}, + {scm="well_4", yoff= 0, orients={0}, farming_plus=0, avoid='well', typ='well', weight={medieval=1/12, single=1/2}, pervillage=4}, + {scm="well_5", yoff= 0, orients={0}, farming_plus=0, avoid='well', typ='well', weight={medieval=1/12, single=1/2}, pervillage=4}, + {scm="well_6", yoff= 0, orients={0}, farming_plus=0, avoid='well', typ='well', weight={medieval=1/12, single=1/2}, pervillage=4}, + {scm="well_7", yoff= -1, orients={0}, farming_plus=0, avoid='well', typ='well', weight={medieval=1/12, single=1/2}, pervillage=4}, + {scm="well_8", yoff= 0, orients={0}, farming_plus=0, avoid='well', typ='well', weight={medieval=1/12, single=1/2}, pervillage=4}, + + {scm="allmende_3_90", yoff=-2, orients={0}, farming_plus=0, avoid='', typ='allmende', weight={medieval=3,taoki=3,nore=3,logcabin=1,grasshut=1}, pervillage=1}, + + {scm="tree_place_1", yoff= 1, orients={0}, farming_plus=0, avoid='', typ='village_square', weight={medieval=1/12}, pervillage=1}, + {scm="tree_place_2", yoff= 1, orients={0}, farming_plus=0, avoid='', typ='village_square', weight={medieval=1/12}, pervillage=1}, + {scm="tree_place_3", yoff= 1, orients={0}, farming_plus=0, avoid='', typ='village_square', weight={medieval=1/12}, pervillage=1}, + {scm="tree_place_4", yoff= 1, orients={0}, farming_plus=0, avoid='', typ='village_square', weight={medieval=1/12}, pervillage=1}, + {scm="tree_place_5", yoff= 1, orients={0}, farming_plus=0, avoid='', typ='village_square', weight={medieval=1/12}, pervillage=1}, + {scm="tree_place_6", yoff= 1, orients={0}, farming_plus=0, avoid='', typ='village_square', weight={medieval=1/12}, pervillage=1}, + {scm="tree_place_7", yoff= 1, orients={0}, farming_plus=0, avoid='', typ='village_square', weight={medieval=1/12}, pervillage=1}, + {scm="tree_place_8", yoff= 1, orients={0}, farming_plus=0, avoid='', typ='village_square', weight={medieval=1/12}, pervillage=1}, + {scm="tree_place_9", yoff= 1, orients={0}, farming_plus=0, avoid='', typ='village_square', weight={medieval=1/12}, pervillage=1}, + {scm="tree_place_10", yoff= 1, orients={0}, farming_plus=0, avoid='', typ='village_square', weight={medieval=1/12}, pervillage=1}, + + {scm="wagon_1", yoff= 0, orients={0,1,2,3}, farming_plus=0, avoid='', typ='wagon', weight={medieval=1/12,tent=1/3}, axis=1}, + {scm="wagon_2", yoff= 0, orients={0,1,2,3}, farming_plus=0, avoid='', typ='wagon', weight={medieval=1/12,tent=1/3}, axis=1}, + {scm="wagon_3", yoff= 0, orients={0,1,2,3}, farming_plus=0, avoid='', typ='wagon', weight={medieval=1/12,tent=1/3}, axis=1}, + {scm="wagon_4", yoff= 0, orients={0,1,2,3}, farming_plus=0, avoid='', typ='wagon', weight={medieval=1/12,tent=1/3}, axis=1}, + {scm="wagon_5", yoff= 0, orients={0,1,2,3}, farming_plus=0, avoid='', typ='wagon', weight={medieval=1/12,tent=1/3}, axis=1}, + {scm="wagon_6", yoff= 0, orients={0,1,2,3}, farming_plus=0, avoid='', typ='wagon', weight={medieval=1/12,tent=1/3}, axis=1}, + {scm="wagon_7", yoff= 0, orients={0,1,2,3}, farming_plus=0, avoid='', typ='wagon', weight={medieval=1/12,tent=1/3}, axis=1}, + {scm="wagon_8", yoff= 0, orients={0,1,2,3}, farming_plus=0, avoid='', typ='wagon', weight={medieval=1/12,tent=1/3}, axis=1}, + {scm="wagon_9", yoff= 0, orients={0,1,2,3}, farming_plus=0, avoid='', typ='wagon', weight={medieval=1/12,tent=1/3}, axis=1}, + {scm="wagon_10", yoff= 0, orients={0,1,2,3}, farming_plus=0, avoid='', typ='wagon', weight={medieval=1/12,tent=1/3}, axis=1}, + {scm="wagon_11", yoff= 0, orients={0,1,2,3}, farming_plus=0, avoid='', typ='wagon', weight={medieval=1/12,tent=1/3}, axis=1}, + {scm="wagon_12", yoff= 0, orients={0,1,2,3}, farming_plus=0, avoid='', typ='wagon', weight={medieval=1/12,tent=1/3}, axis=1}, + + {scm="bench_1", yoff= 0, orients={0,1,2}, farming_plus=0, avoid='', typ='bench', weight={medieval=1/12}, nomirror=1}, + {scm="bench_2", yoff= 0, orients={0,1,2}, farming_plus=0, avoid='', typ='bench', weight={medieval=1/12}, nomirror=1}, + {scm="bench_3", yoff= 0, orients={0,1,2}, farming_plus=0, avoid='', typ='bench', weight={medieval=1/12}, nomirror=1}, + {scm="bench_4", yoff= 0, orients={0,1,2}, farming_plus=0, avoid='', typ='bench', weight={medieval=1/12}, nomirror=1}, + + {scm="shed_1", yoff= 0, orients={0,1,2}, farming_plus=0, avoid='', typ='shed', weight={medieval=1/10}}, + {scm="shed_2", yoff= 0, orients={0,1,2}, farming_plus=0, avoid='', typ='shed', weight={medieval=1/10}}, + {scm="shed_3", yoff= 0, orients={0,1,2}, farming_plus=0, avoid='', typ='shed', weight={medieval=1/10}}, + {scm="shed_5", yoff= 0, orients={0,1,2}, farming_plus=0, avoid='', typ='shed', weight={medieval=1/10}}, + {scm="shed_6", yoff= 0, orients={0,1,2}, farming_plus=0, avoid='', typ='shed', weight={medieval=1/10}}, + {scm="shed_7", yoff= 0, orients={0,1,2}, farming_plus=0, avoid='', typ='shed', weight={medieval=1/10}}, + {scm="shed_8", yoff= 0, orients={0,1,2}, farming_plus=0, avoid='', typ='shed', weight={medieval=1/10}}, + {scm="shed_9", yoff= 0, orients={0,1,2}, farming_plus=0, avoid='', typ='shed', weight={medieval=1/10}}, + {scm="shed_10", yoff= 0, orients={0,1,2}, farming_plus=0, avoid='', typ='shed', weight={medieval=1/10}}, + {scm="shed_11", yoff= 0, orients={0,1,2}, farming_plus=0, avoid='', typ='shed', weight={medieval=1/10}}, + {scm="shed_12", yoff= 0, orients={0,1,2}, farming_plus=0, avoid='', typ='shed', weight={medieval=1/10}}, + + {scm="weide_1", yoff= 0, orients={0,1,2,3}, farming_plus=0, avoid='pasture', typ='pasture', weight={medieval=1/6}, pervillage=8}, + {scm="weide_2", yoff= 0, orients={0,1,2,3}, farming_plus=0, avoid='pasture', typ='pasture', weight={medieval=1/6}, pervillage=8}, + {scm="weide_3", yoff= 0, orients={0,1,2,3}, farming_plus=0, avoid='pasture', typ='pasture', weight={medieval=1/6}, pervillage=8}, + {scm="weide_4", yoff= 0, orients={0,1,2,3}, farming_plus=0, avoid='pasture', typ='pasture', weight={medieval=1/6}, pervillage=8}, + {scm="weide_5", yoff= 0, orients={0,1,2,3}, farming_plus=0, avoid='pasture', typ='pasture', weight={medieval=1/6}, pervillage=8}, + {scm="weide_6", yoff= 0, orients={0,1,2,3}, farming_plus=0, avoid='pasture', typ='pasture', weight={medieval=1/6}, pervillage=8}, + + {scm="field_1", yoff=-2, orients={0,1,2,3}, farming_plus=0, avoid='field', typ='field', weight={medieval=1/6}, pervillage=8}, + {scm="field_2", yoff=-2, orients={0,1,2,3}, farming_plus=0, avoid='field', typ='field', weight={medieval=1/6}, pervillage=8}, + {scm="field_3", yoff=-2, orients={0,1,2,3}, farming_plus=0, avoid='field', typ='field', weight={medieval=1/6}, pervillage=8}, + {scm="field_4", yoff=-2, orients={0,1,2,3}, farming_plus=0, avoid='field', typ='field', weight={medieval=1/6}, pervillage=8}, + + -- hut and hills for charachoal burners; perhaps they could live together with lumberjacks? + {scm="charachoal_hut", yoff= 0, orients={0,1,2}, farming_plus=0, avoid='', typ='hut', weight={charachoal=1, single=5}, inh=2, nomirror=1}, + {scm="charachoal_hill", yoff= 0, orients={0,1,2,3}, farming_plus=0, avoid='', typ='hut', weight={charachoal=2 }, inh=-1, nomirror=1}, + + -- lumberjacks; they require the cottages mod + {scm="lumberjack_1", yoff= 1, orients={1}, avoid='', typ='lumberjack', weight={lumberjack=1, single=3}, axis=1, inh=3}, + {scm="lumberjack_2", yoff= 1, orients={1}, avoid='', typ='lumberjack', weight={lumberjack=1, single=3}, axis=1, inh=4}, + {scm="lumberjack_3", yoff= 1, orients={1,2,3}, avoid='', typ='lumberjack', weight={lumberjack=1, single=3}, inh=3}, + {scm="lumberjack_4", yoff= 1, orients={1}, avoid='', typ='lumberjack', weight={lumberjack=1, single=3}, axis=1, inh=4}, + {scm="lumberjack_5", yoff= 1, orients={1}, avoid='', typ='lumberjack', weight={lumberjack=1, single=3}, axis=1, inh=9}, + {scm="lumberjack_6", yoff= 1, orients={1}, avoid='', typ='lumberjack', weight={lumberjack=1, single=3}, axis=1, inh=5}, + {scm="lumberjack_7", yoff= 1, orients={1}, avoid='', typ='lumberjack', weight={lumberjack=1, single=3}, axis=1, inh=5}, + {scm="lumberjack_8", yoff= 1, orients={1}, avoid='', typ='lumberjack', weight={lumberjack=1, single=3}, axis=1, inh=9}, + {scm="lumberjack_9", yoff= 1, orients={1}, avoid='', typ='lumberjack', weight={lumberjack=1, single=3}, axis=1, inh=5}, + {scm="lumberjack_10", yoff= 1, orients={1}, avoid='', typ='lumberjack', weight={lumberjack=1, single=3}, axis=1, inh=2}, + {scm="lumberjack_11", yoff= 0, orients={1}, avoid='', typ='lumberjack', weight={lumberjack=1, single=3}, axis=1, inh=2}, + {scm="lumberjack_12", yoff= 1, orients={1}, avoid='', typ='lumberjack', weight={lumberjack=1, single=3}, axis=1, inh=3}, + {scm="lumberjack_13", yoff= 1, orients={1}, avoid='', typ='lumberjack', weight={lumberjack=1, single=3}, axis=1, inh=3}, + {scm="lumberjack_14", yoff= 1, orients={1}, avoid='', typ='lumberjack', weight={lumberjack=1, single=3}, axis=1, inh=2}, + {scm="lumberjack_15", yoff= 1, orients={1}, avoid='', typ='lumberjack', weight={lumberjack=1, single=3}, axis=1, inh=2}, + {scm="lumberjack_16", yoff= 0, orients={1}, avoid='', typ='lumberjack', weight={lumberjack=1, single=3}, axis=1, inh=2}, + {scm="lumberjack_school", yoff= 1, orients={1}, avoid='', typ='school', weight={lumberjack=2 }, axis=1, inh=1}, + {scm="lumberjack_stable", yoff= 0, orients={3}, avoid='', typ='lumberjack', weight={lumberjack=1, single=3}, axis=1, inh=-1}, + {scm="lumberjack_pub_1", yoff= 1, orients={1}, avoid='', typ='tavern', weight={lumberjack=3, single=1}, pervillage=1, axis=1, inh=-1}, + {scm="lumberjack_church_1", yoff= 1, orients={1}, avoid='', typ='church', weight={lumberjack=3}, pervillage=1, axis=1, inh=-1}, + {scm="lumberjack_hotel_1", yoff= 1, orients={1}, avoid='', typ='house', weight={lumberjack=1, single=1}, axis=1, inh=16}, -- all 16 are guests + {scm="lumberjack_shop_1", yoff= 1, orients={1}, avoid='', typ='shop', weight={lumberjack=1}, pervillage=1, axis=1, inh=-1}, + {scm="lumberjack_sawmill_1",yoff=-7, orients={1}, avoid='', typ='sawmill', weight={lumberjack=2, single=1}, pervillage=1, axis=1, inh=-1}, + + +-- {scm="cow_trader_1", yoff= 0, orients={4}, avoid='', typ='trader', weight={lumberjack=1}}, + + -- clay traders depend on cottages as well + {scm="trader_clay_1", yoff= 1, orients={1}, avoid='', typ='trader', weight={claytrader=3, single=3}, axis=1, inh=1}, -- poor guy who has to live in that small thing + {scm="trader_clay_2", yoff= 1, orients={3}, avoid='', typ='trader', weight={claytrader=3, single=3}, axis=1, inh=1}, -- not that he'll live very comftable there... + {scm="trader_clay_3", yoff= 1, orients={0}, avoid='', typ='trader', weight={claytrader=3, single=3}, inh=2}, + {scm="trader_clay_4", yoff= 1, orients={2}, avoid='', typ='trader', weight={claytrader=3, single=3}, inh=2}, + {scm="trader_clay_5", yoff= 1, orients={1}, avoid='', typ='trader', weight={claytrader=3, single=3}, axis=1, inh=2}, + + {scm="clay_pit_1", yoff=-3, orients={0,1,2,3}, avoid='', typ='pit', weight={claytrader=1}}, + {scm="clay_pit_2", yoff=-2, orients={0,1,2,3}, avoid='', typ='pit', weight={claytrader=1}}, + {scm="clay_pit_3", yoff=-7, orients={0,1,2,3}, avoid='', typ='pit', weight={claytrader=1}}, + {scm="clay_pit_4", yoff= 0, orients={0,1,2,3}, avoid='', typ='pit', weight={claytrader=1}}, + {scm="clay_pit_5", yoff= 1, orients={0,1,2,3}, avoid='', typ='pit', weight={claytrader=1}}, + + + -- Houses from Taokis Structure I/O Mod (see https://forum.minetest.net/viewtopic.php?id=5524) + {scm="default_town_farm", yoff= -1, orients={1}, farming_plus=0, avoid='', typ='field', weight={taoki=1, single=1}, axis=1}, + {scm="default_town_house_large_1", yoff= -4, orients={1}, farming_plus=0, avoid='', typ='house', weight={taoki=1/4, single=1}, axis=1, inh=10}, + {scm="default_town_house_large_2", yoff= -4, orients={1}, farming_plus=0, avoid='', typ='house', weight={taoki=1/4, single=1}, axis=1, inh=8}, + {scm="default_town_house_medium", yoff= -4, orients={1}, farming_plus=0, avoid='', typ='house', weight={taoki=1/2, single=1}, axis=1, inh=6}, + {scm="default_town_house_small", yoff= -4, orients={1}, farming_plus=0, avoid='', typ='house', weight={taoki=1, single=1}, axis=1, inh=4}, + {scm="default_town_house_tiny_1", yoff= 1, orients={1}, farming_plus=0, avoid='', typ='house', weight={taoki=1, single=1}, axis=1, inh=3}, + {scm="default_town_house_tiny_2", yoff= 1, orients={1}, farming_plus=0, avoid='', typ='house', weight={taoki=1, single=1}, axis=1, inh=3}, + {scm="default_town_house_tiny_3", yoff= 1, orients={1}, farming_plus=0, avoid='', typ='house', weight={taoki=1, single=1}, axis=1, inh=2}, + {scm="default_town_park", yoff= 1, orients={1}, farming_plus=0, avoid='', typ='deco', weight={taoki=1 }, axis=1}, + {scm="default_town_tower", yoff= 1, orients={1}, farming_plus=0, avoid='', typ='tower', weight={taoki=1/6, single=1}, axis=1, inh=-1}, + {scm="default_town_well", yoff= -6, orients={1}, farming_plus=0, avoid='', typ='well', weight={taoki=1/4 }, axis=1}, + {scm="default_town_fountain", yoff= 1, orients={1}, farming_plus=0, avoid='', typ='fountain',weight={taoki=1/4 }, axis=1}, + -- the hotel seems to be only the middle section of the building; it's build for another spawning algorithm +-- {scm="default_town_hotel", yoff= -1, orients={1}, farming_plus=0, avoid='', typ='house', weight={taoki=1/5}}, + + {scm="tent_tiny_1", yoff=0, orients={3}, farming_plus=0, avoid='', typ='tent', weight={tent=1, single=1}, inh=1}, + {scm="tent_tiny_2", yoff=0, orients={3}, farming_plus=0, avoid='', typ='tent', weight={tent=1, single=1}, inh=1}, + {scm="tent_big_1", yoff=0, orients={3}, farming_plus=0, avoid='', typ='tent', weight={tent=1, single=1}}, -- no sleeping place + {scm="tent_big_2", yoff=0, orients={3}, farming_plus=0, avoid='', typ='tent', weight={tent=1, single=1}, inh=2}, + {scm="tent_medium_1", yoff=0, orients={3}, farming_plus=0, avoid='', typ='tent', weight={tent=1/2, single=1}, inh=3}, + {scm="tent_medium_2", yoff=0, orients={3}, farming_plus=0, avoid='', typ='tent', weight={tent=1/2, single=1}, inh=3}, + {scm="tent_medium_3", yoff=0, orients={3}, farming_plus=0, avoid='', typ='tent', weight={tent=1/2, single=1}, inh=3}, + {scm="tent_medium_4", yoff=0, orients={3}, farming_plus=0, avoid='', typ='tent', weight={tent=1/2, single=1}, inh=3}, + {scm="tent_open_1", yoff=0, orients={3}, farming_plus=0, avoid='', typ='tent', weight={tent=1/5}}, + {scm="tent_open_2", yoff=0, orients={3}, farming_plus=0, avoid='', typ='tent', weight={tent=1/5}}, + {scm="tent_open_3", yoff=0, orients={3}, farming_plus=0, avoid='', typ='tent', weight={tent=1/5}}, + {scm="tent_open_big_1", yoff=0, orients={3}, farming_plus=0, avoid='', typ='tent', weight={tent=1/5}}, + {scm="tent_open_big_2", yoff=0, orients={3}, farming_plus=0, avoid='', typ='tent', weight={tent=1/5}}, + {scm="tent_open_big_3", yoff=0, orients={3}, farming_plus=0, avoid='', typ='tent', weight={tent=1/5}}, + + {scm="hochsitz_1", yoff=0, orients={0,1,2,3}, farming_plus=0, avoid='', typ='tower', weight={tower=1, single=1/3}, nomirror=1}, + {scm="hochsitz_2", yoff=0, orients={0,1,2,3}, farming_plus=0, avoid='', typ='tower', weight={tower=1, single=1/3}, nomirror=1}, + {scm="hochsitz_3", yoff=0, orients={0,1,2,3}, farming_plus=0, avoid='', typ='tower', weight={tower=1, single=1/3}, nomirror=1}, + {scm="hochsitz_4", yoff=0, orients={0,1,2,3}, farming_plus=0, avoid='', typ='tower', weight={tower=1, single=1/3}, nomirror=1}, + + {scm="chateau_without_garden", yoff=-1,orients={0,1,2,3}, farming_plus=0, avoid='', typ='chateau', weight={chateau=1,single=8}, pervillage=1, inh=8}, + + {scm="baking_house_1", yoff=0, orients={0}, farming_plus=0, avoid='', typ='bakery', weight={medieval=1/4}, pervillage=1, inh=-1}, + {scm="baking_house_2", yoff=0, orients={0}, farming_plus=0, avoid='', typ='bakery', weight={medieval=1/4}, pervillage=1, inh=-1}, + {scm="baking_house_3", yoff=0, orients={0}, farming_plus=0, avoid='', typ='bakery', weight={medieval=1/4}, pervillage=1, inh=-1}, + {scm="baking_house_4", yoff=0, orients={0}, farming_plus=0, avoid='', typ='bakery', weight={medieval=1/4}, pervillage=1, inh=-1}, + + {scm="empty_1", yoff=0, typ='empty', inh=0, pervillage=2, + weight={nore=1/8,taoki=1/8,medieval=1/8,charachoal=1/8,lumberjack=1/8,claytrader=1/8,logcabin=1/8,canadian=1/8,grasshut=1/8,tent=1/8}}, + {scm="empty_2", yoff=0, typ='empty', inh=0, pervillage=2, + weight={nore=1/8,taoki=1/8,medieval=1/8,charachoal=1/8,lumberjack=1/8,claytrader=1/8,logcabin=1/8,canadian=1/8,grasshut=1/8,tent=1/8}}, + {scm="empty_3", yoff=0, typ='empty', inh=0, pervillage=2, + weight={nore=1/8,taoki=1/8,medieval=1/8,charachoal=1/8,lumberjack=1/8,claytrader=1/8,logcabin=1/8,canadian=1/8,grasshut=1/8,tent=1/8}}, + {scm="empty_4", yoff=0, typ='empty', inh=0, pervillage=2, + weight={nore=1/8,taoki=1/8,medieval=1/8,charachoal=1/8,lumberjack=1/8,claytrader=1/8,logcabin=1/8,canadian=1/8,grasshut=1/8,tent=1/8}}, + {scm="empty_5", yoff=0, typ='empty', inh=0, pervillage=2, + weight={nore=1/8,taoki=1/8,medieval=1/8,charachoal=1/8,lumberjack=1/8,claytrader=1/8,logcabin=1/8,canadian=1/8,grasshut=1/8,tent=1/8}}, +} + + +-- read the data files and fill in information like size and nodes that need on_construct to be called after placing; +-- skip buildings that cannot be used due to missing mods +mg_villages.add_building = function( building_data ) + + local file_name = building_data.mts_path .. building_data.scm; + -- a building will only be used if it is used by at least one supported village type (=mods required for that village type are installed) + local is_used = false; + for typ,weight in pairs( building_data.weight ) do + if( typ and weight and typ ~= 'single' and mg_villages.village_type_data[ typ ] and mg_villages.village_type_data[ typ ].supported ) then + is_used = true; + end + -- add the building to the menu list for the build chest ("single" would be too many houses) + -- the empty plots are added to each village and of no intrest here + if( build_chest and build_chest.add_entry and typ and typ ~= 'single' and (not( building_data.typ ) or building_data.typ ~= 'empty')) then + build_chest.add_entry( {'main','mg_villages', typ, building_data.scm, file_name }); + end + end + -- buildings as such may have a type as well + if( build_chest and build_chest.add_entry and building_data.typ ) then + build_chest.add_entry( {'main','mg_villages', building_data.typ, building_data.scm, file_name }); + end + -- store information about all buildings - no matter weather they can be used or not - for later presentation in the build_chest's menu + if( build_chest and build_chest.add_building ) then + build_chest.add_building( file_name, building_data ); + end + + + if( not( is_used )) then + -- do nothing; skip this file + mg_villages.print(mg_villages.DEBUG_LEVEL_INFO, 'SKIPPING '..tostring( building_data.scm )..' due to village type not supported.'); + -- building cannot be used + building_data.not_available = 1; + return false; + end + + + -- determine the size of the building + local res = nil; + -- read the size of the building; + -- convert to .mts for later usage if necessary + res = handle_schematics.analyze_file( file_name, building_data.we_origin, building_data.mts_path .. building_data.scm ); + + if( not( res )) then + mg_villages.print(mg_villages.DEBUG_LEVEL_WARNING, 'SKIPPING '..tostring( building_data.scm )..' due to import failure.'); + building_data.not_available = 1; + return false; + -- provided the file could be analyzed successfully (now covers both .mts and .we files) + elseif( res and res.size and res.size.x ) then + + -- the file has to be placed with minetest.place_schematic(...) + building_data.is_mts = 1; + + building_data.sizex = res.size.x; + building_data.sizez = res.size.z; + building_data.ysize = res.size.y; + + -- some buildings may be rotated + if( not( building_data.orients ) and res.rotated ) then + building_data.orients = {}; + if( res.rotated == 0 ) then + building_data.orients[1] = 0; + elseif( res.rotated == 90 ) then + building_data.axis = 1; -- important when mirroring + building_data.orients[1] = 1; + elseif( res.rotated == 180 ) then + building_data.orients[1] = 2; + elseif( res.rotated == 270 ) then + building_data.orients[1] = 3; + building_data.axis = 1; -- important when mirroring + end + end + + if( not( building_data.yoff ) and res.burried ) then + building_data.yoff = 1-res.burried; + end + + -- we do need at least the list of nodenames which will need on_constr later on + building_data.rotated = res.rotated; + building_data.nodenames = res.nodenames; + building_data.on_constr = res.on_constr; + building_data.after_place_node = res.after_place_node; + + if( res.scm_data_cache ) then + building_data.scm_data_cache = res.scm_data_cache; + building_data.is_mts = 0; + end + + -- missing data regarding building size - do not use this building for anything + elseif( not( building_data.sizex ) or not( building_data.sizez ) + or building_data.sizex == 0 or building_data.sizez==0) then + + -- no village will use it + mg_villages.print( mg_villages.DEBUG_LEVEL_INFO, 'No schematic found for building \''..tostring( building_data.scm )..'\'. Will not use that building.'); + building_data.weight = {}; + building_data.not_available = 1; + return false; + + else + -- the file has to be handled by worldedit; it is no .mts file + building_data.is_mts = 0; + end + + + if( not( building_data.weight ) or type( building_data.weight ) ~= 'table' ) then + mg_villages.print( mg_villages.DEBUG_LEVEL_WARNING, 'SKIPPING '..tostring( building_data.scm )..' due to missing weight information.'); + building_data.not_available = 1; + return false; + end + + + -- handle duplicates; make sure buildings always get the same number; + -- check if the building has been used in previous runs and got an ID there + + -- create a not very unique, but for this case sufficient "id"; + -- (buildings with the same size and name are considered to be drop-in-replacements + local building_id = building_data.sizex..'x'..building_data.sizez..'_'..building_data.scm; + -- if the building is new, it will get the next free id + local building_nr = #mg_villages.all_buildings_list + 1; + for i,v in ipairs( mg_villages.all_buildings_list ) do + if( v==building_id ) then + -- we found the building + building_nr = i; + end + end + + -- if it is a new building, then save the list + if( building_nr == #mg_villages.all_buildings_list+1 ) then + mg_villages.all_buildings_list[ building_nr ] = building_id; + -- save information about previously imported buildings + save_restore.save_data( 'mg_villages_all_buildings_list.data', mg_villages.all_buildings_list ); + end + + -- determine the internal number for the building; this number is used as a key and can be found in the mg_all_villages.data file + if( not( mg_villages.BUILDINGS )) then + mg_villages.BUILDINGS = {}; + end + -- actually store the building data + mg_villages.BUILDINGS[ building_nr ] = minetest.deserialize( minetest.serialize( building_data )); + + + -- create lists for all village types containing the buildings which may be used for that village + for typ, data in pairs( mg_villages.village_type_data ) do + local total_weight = 0; + if( not( data.building_list ) or not( data.max_weight_list )) then + data.building_list = {}; + data.max_weight_list = {}; + elseif( #data.max_weight_list > 0 ) then + -- get the last entry - that one will determine the current total_weight + total_weight = data.max_weight_list[ #data.max_weight_list ]; + end + + if( building_data.weight[ typ ] and building_data.weight[ typ ] > 0 ) then + local index = #data.building_list+1; + data.building_list[ index ] = building_nr; + data.max_weight_list[ index ] = total_weight + building_data.weight[ typ ]; + end + end + + -- print it for debugging usage + --print( building_data.scm .. ': '..tostring(building_data.sizex)..' x '..tostring(building_data.sizez)..' x '..tostring(building_data.ysize)..' h'); + return true; +end + + +-- this list contains some information about previously imported buildings so that they will get the same id +mg_villages.all_buildings_list = save_restore.restore_data( 'mg_villages_all_buildings_list.data' ); + +-- import all the buildings +mg_villages.BUILDINGS = {}; +local mts_path = mg_villages.modpath.."/schems/"; +-- determine the size of the given houses and other necessary values +for i,v in ipairs( buildings ) do + v.mts_path = mts_path; + mg_villages.add_building( v, i ); +end +buildings = nil; + +-- roads are built in a diffrent way +mg_villages.BUILDINGS["road"] = {yoff = 0, ysize = 2, scm = {}} diff --git a/mods/a_mapgen_mods/mg_villages/chat_commands.lua b/mods/a_mapgen_mods/mg_villages/chat_commands.lua new file mode 100644 index 00000000..b9dfa9e6 --- /dev/null +++ b/mods/a_mapgen_mods/mg_villages/chat_commands.lua @@ -0,0 +1,107 @@ + +minetest.register_privilege("mg_villages", { description = "Allows to teleport to villages via /vist ", give_to_singleplayer = false}); + +-- this function is only used for the chat command currently +mg_villages.list_villages_formspec = function( player, formname, fields ) + + if( not( player ) or fields.quit) then + return + end + local pname = player:get_player_name(); + local ppos = player:getpos(); + + + local radius = 1000000; + -- without the special priv, players can only obtain informatoin about villages which are very close by + if( not( minetest.check_player_privs( pname, {mg_villages=true}))) then + radius = mg_villages.VILLAGE_DETECT_RANGE; + end + + local formspec = 'size[12,12]'.. + 'button_exit[4.0,1.5;2,0.5;quit;Quit]'.. + 'tablecolumns[' .. + 'text,align=right;'.. -- village number + 'text,align=right;'.. -- distance from player + 'text,align=center;'.. -- name of village + 'text,align=center;'.. -- typ of village + 'text,align=right;'.. -- x + 'text,align=right;'.. -- y + 'text,align=right;'.. -- z + 'text,align=right;'.. -- size + 'text,align=right;'.. -- #houses where inhabitants may live or work + 'text,align=right]'.. + 'table[0.1,2.7;11.4,8.8;'..formname..';'; + + for k,v in pairs( mg_villages.all_villages ) do + + local dx = math.abs( v.vx - ppos.x ); + local dz = math.abs( v.vz - ppos.z ); + -- distance in y direction is less relevant here and may be ignored + if( dx + dz < radius ) then + local dist = math.sqrt( dx * dx + dz * dz ); + local is_full_village = 'village'; + if( v.is_single_house ) then + is_full_village = ''; + end + formspec = formspec.. + v.nr..','.. + tostring( math.floor( dist ))..','.. + tostring( v.name or 'unknown' )..','.. + v.village_type..','.. + tostring( v.vx )..','.. + tostring( v.vh )..','.. + tostring( v.vz )..','.. + tostring( v.vs )..','.. + tostring( v.anz_buildings )..','.. + tostring( is_full_village )..','; + end + end + + formspec = formspec..';]'.. + 'tabheader[0.1,2.2;spalte;Nr,Dist,Name of village,Type of village,_X_,_H_,_Z_,Size,Buildings;;true;true]'; + + minetest.show_formspec( pname, formname, formspec ); +end + + +minetest.register_chatcommand( 'villages', { + description = "Shows a list of all known villages.", + privs = {}, + func = function(name, param) + mg_villages.list_villages_formspec( minetest.get_player_by_name( name ), "mg:village_list", {}); + end +}); + + +minetest.register_chatcommand( 'visit', { + description = "Teleports you to a known village.", + params = "", + privs = {}, + func = function(name, param) + + + if( mg_villages.REQUIRE_PRIV_FOR_TELEPORT and not( minetest.check_player_privs( name, {mg_villages=true}))) then + minetest.chat_send_player( name, "You need the 'mg_villages' priv in order to teleport to villages using this command."); + return; + end + + if( not( param ) or param == "" ) then + minetest.chat_send_player( name, "Which village do you want to visit? Please provide the village number!"); + return; + end + + local nr = tonumber( param ); + for id, v in pairs( mg_villages.all_villages ) do + -- we have found the village + if( v and v.nr == nr ) then + + minetest.chat_send_player( name, "Initiating transfer to village no. "..tostring( v.nr )..", called "..( tostring( v.name or 'unknown')).."."); + local player = minetest.get_player_by_name( name ); + player:moveto( { x=v.vx, y=(v.vh+1), z=v.vz }, false); + return; + end + end + -- no village found + minetest.chat_send_player( name, "There is no village with the number "..tostring( param ).." (yet?)."); + end +}); diff --git a/mods/a_mapgen_mods/mg_villages/config.lua b/mods/a_mapgen_mods/mg_villages/config.lua new file mode 100644 index 00000000..42529a81 --- /dev/null +++ b/mods/a_mapgen_mods/mg_villages/config.lua @@ -0,0 +1,187 @@ +----------------------------------------------------------------------------- +-- configuration values which you can adjust according to your liking +----------------------------------------------------------------------------- +-- set to false if you do not want to have any villages spawning +mg_villages.ENABLE_VILLAGES = true; + +-- generate one random building for each mg_villages.INVERSE_HOUSE_DENSITY th mapchunk; +-- set to 0 in order to disable spawning of these lone buildings outside villages +mg_villages.INVERSE_HOUSE_DENSITY = 0; + +-- cover some villages with artificial snow; probability: 1/mg_villages.artificial_snow_probability +mg_villages.artificial_snow_probability = 0; + +-- if set to true, soil around villaes will get special soil-snow instead of plant + snow cover +mg_villages.use_soil_snow = false; + +-- only place roads if there are at least that many buildings in the village +mg_villages.MINIMAL_BUILDUNGS_FOR_ROAD_PLACEMENT = 4; + + +-- players without the mg_villages priv can only see villages which are less than that many blocks away +-- from them when using the /vmap command +mg_villages.VILLAGE_DETECT_RANGE = 400; + +-- if set to true, only players which have the mg_villages priv can use the "/visit " +-- command which allows teleporting to the village with the given number +mg_villages.REQUIRE_PRIV_FOR_TELEPORT = false; + +-- if set to true, players cannot modify spawned villages without buying the house from the village first +mg_villages.ENABLE_PROTECTION = false; + +-- the first village - the one the player spawns in - will be of this type +mg_villages.FIRST_VILLAGE_TYPE = 'ruins'; + +-- the mapgen will disregard mapchunks where min.y > mg_villages.MAX_HEIGHT_TREATED; +-- you can set this value to 64 if you have a slow machine and a mapgen which does not create extreme mountains +-- (or if you don't care if extreme mountains may create burried villages occasionally) +mg_villages.MAX_HEIGHT_TREATED = 64; + +-- choose the debug level you want +mg_villages.DEBUG_LEVEL = mg_villages.DEBUG_LEVEL_NORMAL + +-- if set to true (or anything else but nil or false), highlandpools by paramat (see +-- https://forum.minetest.net/viewtopic.php?t=8400) will be created +mg_villages.CREATE_HIGHLANDPOOLS = true + +-- background image for the /vmap command +-- RealTest comes with a diffrent texture +if( minetest.get_modpath('grounds') and minetest.get_modpath('joiner_table')) then + mg_villages.MAP_BACKGROUND_IMAGE = "default_dirt_grass.png"; +elseif( minetest.registered_nodes[ 'default:dirt_with_grass'] ) then + mg_villages.MAP_BACKGROUND_IMAGE = "default_grass.png"; +else + mg_villages.MAP_BACKGROUND_IMAGE = ""; +end + +-- if set to true, the outer buildings in medieval villages will be fields; this is not very convincing yet +-- currently not really used; does not look as good as expected +mg_villages.medieval_subtype = false; + +-- set this to true if you want to use normal lava - but beware: charachoal villages may cause bushfires! +mg_villages.use_normal_unsafe_lava = true; + +----------------------------------------------------------------------------- +-- decrese these values slightly if you want MORE trees around your villages; +-- increase it if you want to DECREASE the amount of trees around villages +----------------------------------------------------------------------------- +-- on average, every n.th node inside a village area may be one of these trees - and it will be a relatively dense packed forrest +mg_villages.sapling_probability = {}; + +mg_villages.sapling_probability[ minetest.get_content_id( 'default:sapling' ) ] = 10; -- suitable for a relatively dense forrest of normal trees +mg_villages.sapling_probability[ minetest.get_content_id( 'default:junglesapling' ) ] = 10; -- jungletrees are a bit bigger and need more space +mg_villages.sapling_probability[ minetest.get_content_id( 'default:pinesapling' ) ] = 10; +if( minetest.get_modpath( 'mg' )) then + mg_villages.sapling_probability[ minetest.get_content_id( 'mg:savannasapling' ) ] = 10; + mg_villages.sapling_probability[ minetest.get_content_id( 'mg:pinesapling' ) ] = 10; +end +mg_villages.moretrees_treelist = nil; +if( minetest.get_modpath( 'moretrees' )) then + mg_villages.moretrees_treelist = moretrees.treelist; + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:birch_sapling_ongen' ) ] = 200; + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:spruce_sapling_ongen' ) ] = 200; + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:fir_sapling_ongen' ) ] = 90; + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:jungletree_sapling_ongen' ) ] = 200; + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:beech_sapling_ongen' ) ] = 30; + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:apple_sapling_ongen' ) ] = 380; + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:oak_sapling_ongen' ) ] = 380; -- ca 20x20; height: 10 + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:sequoia_sapling_ongen' ) ] = 90; -- ca 10x10 + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:palm_sapling_ongen' ) ] = 90; + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:pine_sapling_ongen' ) ] = 200; + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:willow_sapling_ongen' ) ] = 380; + mg_villages.sapling_probability[ minetest.get_content_id( 'moretrees:rubber_tree_sapling_ongen' ) ] = 380; +end + + +----------------------------------------------------------------------------- +-- no need to change this, unless you add new farming_plus fruits +----------------------------------------------------------------------------- +-- the schematics for buildings of type 'farm_tiny' grow cotton; the farming_plus fruits would be far more fitting +mg_villages.fruit_list = {'carrot','potatoe','orange','rhubarb','strawberry','tomato','cotton'}; +-- is farming_plus available? If not, we can't use this +if( not( minetest.get_modpath("farming_plus"))) then + mg_villages.fruit_list = nil; +end + + +----------------------------------------------------------------------------- +-- players can buy plots in villages with houses on for this price; +-- set according to your liking +----------------------------------------------------------------------------- +-- how much does the player have to pay for a plot with a building? +mg_villages.prices = { + empty = "default:copper_ingot 1", -- plot to build on + + -- building types which usually have inhabitants (and thus allow the player + -- who bought the building to modifiy the entire village area minus other + -- buildings) + tent = "default:copper_ingot 1", + hut = "default:copper_ingot 1", + farm_full = "default:gold_ingot 4", + farm_tiny = "default:gold_ingot 2", + lumberjack = "default:gold_ingot 2", + house = "default:gold_ingot 2", + house_large = "default:gold_ingot 4", + tavern = "default:gold_ingot 12", + trader = "default:gold_ingot 2", + + -- more or less community buildings + well = "default:gold_ingot 1", + village_square = "default:goldblock 1", + secular = "default:goldblock 2", -- secular buildings, such as libraries ec. + church = "default:goldblock 10", + + -- places for mobs to work at; usually without inhabitants + tower = "default:copper_ingot 1", + shed = "default:copper_ingot 2", + pit = "default:copper_ingot 3", -- claytrader pit + mill = "default:gold_ingot 10", + forge = "default:gold_ingot 10", + bakery = "default:gold_ingot 10", + shop = "default:gold_ingot 20", + sawmill = "default:gold_ingot 30", + + -- decoration + wagon = "default:tree 10", + bench = "default:tree 4", + + -- seperate fields + pasture = "default:copper_ingot 2", + field = "default:copper_ingot 2", + + -- chateaus are expensive + chateau = "default:diamondblock 5", +} + + +----------------------------------------------------------------------------- +-- The values below seldom need adjustment; don't change them unless you +-- know exactly what you are doing. +----------------------------------------------------------------------------- +-- if set to false, villages will not be integrated into the terrain - which looks very bad +mg_villages.ENABLE_TERRAIN_BLEND = true; +-- if set to false, holes digged by cavegen and mudflow inside the village will not be repaired; houses will be destroyed +mg_villages.UNDO_CAVEGEN_AND_MUDFLOW =true; + +-- internal variables for village generation + +mg_villages.VILLAGE_CHECK_RADIUS = 2 +mg_villages.VILLAGE_CHECK_COUNT = 1 +--mg_villages.VILLAGE_CHANCE = 28 +--mg_villages.VILLAGE_MIN_SIZE = 20 +--mg_villages.VILLAGE_MAX_SIZE = 40 +mg_villages.VILLAGE_CHANCE = 28 +-- min and max size are only used in case of them beeing not provided by the village type (see buildings.lua) +mg_villages.VILLAGE_MIN_SIZE = 25 +mg_villages.VILLAGE_MAX_SIZE = 90 --55 +mg_villages.FIRST_ROADSIZE = 3 +mg_villages.BIG_ROAD_CHANCE = 0 + +-- Enable that for really big villages (there are also really slow to generate) +--[[mg_villages.VILLAGE_CHECK_RADIUS = 3 +mg_villages.VILLAGE_CHECK_COUNT = 3 +mg_villages.VILLAGE_CHANCE = 28 +mg_villages.VILLAGE_MIN_SIZE = 100 +mg_villages.VILLAGE_MAX_SIZE = 150 +mg_villages.FIRST_ROADSIZE = 5 +mg_villages.BIG_ROAD_CHANCE = 50]] diff --git a/mods/a_mapgen_mods/mg_villages/depends.txt b/mods/a_mapgen_mods/mg_villages/depends.txt new file mode 100644 index 00000000..ff5b910e --- /dev/null +++ b/mods/a_mapgen_mods/mg_villages/depends.txt @@ -0,0 +1,22 @@ +handle_schematics +default +doors? +farming? +wool? +stairs? +cottages? +moretrees? +trees? +forest? +dryplants? +cavestuff? +snow? +moresnow? +darkage? +ethereal? +deco? +metals? +grounds? +moreblocks? +bell? +mg? diff --git a/mods/a_mapgen_mods/mg_villages/fill_chest--orig.lua b/mods/a_mapgen_mods/mg_villages/fill_chest--orig.lua new file mode 100644 index 00000000..fbb3f8cf --- /dev/null +++ b/mods/a_mapgen_mods/mg_villages/fill_chest--orig.lua @@ -0,0 +1,228 @@ +-- TODO: refill chest after some time? +-- TODO: alert NPC that something was taken + +mg_villages.random_chest_content = {}; + +-- add random chest content +local ADD_RCC = function( data ) + if( data and #data>3 and ( minetest.registered_nodes[ data[1] ] or minetest.registered_items[ data[1] ]) ) then + table.insert( mg_villages.random_chest_content, data ); + end +end + +-- things that can be found in private, not locked chests belonging to npc +-- contains tables of the following structure: { node_name, probability (in percent, 100=always, 0=never), max_amount, repeat (for more than one stack) } +mg_villages.random_chest_content = {}; + +ADD_RCC({"default:pick_stone", 10, 1, 3, farm_tiny=1, farm_full=1, shed=1, lumberjack=1, hut=1, chest_work=1, lumberjack=1 }); +ADD_RCC({"default:pick_steel", 5, 1, 2, forge=1 }); +ADD_RCC({"default:pick_mese", 2, 1, 2, forge=1, lumberjack=1 }); +ADD_RCC({"default:shovel_stone", 5, 1, 3, farm_tiny=1, farm_full=1, shed=1, lumberjack=1, hut=1, chest_work=1 }); +ADD_RCC({"default:shovel_steel", 5, 1, 2, forge=1 }); +ADD_RCC({"default:axe_stone", 5, 1, 3, farm_tiny=1, farm_full=1, chest_work=1, lumberjack=1 }); +ADD_RCC({"default:axe_steel", 5, 1, 2, forge=1, lumberjack=1 }); +ADD_RCC({"default:sword_wood", 1, 1, 3, guard=1 }); +ADD_RCC({"default:sword_stone", 1, 1, 3, guard=1 }); +ADD_RCC({"default:sword_steel", 1, 1, 3, forge=1, guard=1 }); + +ADD_RCC({"default:stick", 20, 40, 2, church=1, library=1, chest_private=1, shelf=5, shed=1, lumberjack=1, hut=1 }); +ADD_RCC({"default:torch", 50, 10, 4, church=1, library=1, chest_private=1, shelf=1, shed=1, lumberjack=1, hut=1 }); + +ADD_RCC({"default:book", 60, 1, 2, church=1, library=1 }); +ADD_RCC({"default:paper", 60, 6, 4, church=1, library=1 }); +ADD_RCC({"default:apple", 50, 10, 2, chest_storage=4, chest_private=1, shelf=5}); +ADD_RCC({"default:ladder", 20, 1, 2, church=1, library=1, shed=1, lumberjack=1, hut=1 }); + +ADD_RCC({"default:coal_lump", 80, 30, 1, forge=1, shed=1, lumberjack=1, hut=1}); +ADD_RCC({"default:steel_ingot", 30, 4, 2, forge=1 }); +ADD_RCC({"default:mese_crystal_fragment", 10, 3, 1, forge=1, chest_storage=1 }); + +ADD_RCC({"bucket:bucket_empty", 10, 3, 2, chest_work=1, forge=1, shed=1, hut=1 }); +ADD_RCC({"bucket:bucket_water", 5, 3, 2, chest_work=1, forge=1 }); +ADD_RCC({"bucket:bucket_lava", 3, 3, 2, forge=1 }); + +ADD_RCC({"vessels:glass_bottle", 10, 10, 2, church=1, library=1, shelf=1 }); +ADD_RCC({"vessels:drinking_glass", 20, 2, 1, church=1, library=1, shelf=1 }); +ADD_RCC({"vessels:steel_bottle", 10, 1, 1, church=1, library=1, shelf=1 }); + +ADD_RCC({"wool:white", 60, 8, 2, church=1, library=1 }); + + +-- that someone will hide valuable ingots in chests that are not locked is fairly unrealistic; thus, those items are rare +ADD_RCC({"moreores:gold_ingot", 1, 2, 1 }); +ADD_RCC({"moreores:silver_ingot", 1, 2, 1 }); +ADD_RCC({"moreores:copper_ingot", 30, 10, 1 }); +ADD_RCC({"moreores:tin_ingot", 1, 5, 1 }); +ADD_RCC({"moreores:bronze_ingot", 1, 1, 1 }); +ADD_RCC({"moreores:mithril_ingot", 1, 1, 1 }); + +-- candles are a very likely content of chests +ADD_RCC({"candles:candle", 80, 12, 2, church=1, library=1, chest_private=1 }); +ADD_RCC({"candles:candelabra_steel", 1, 1, 1, church=1, library=1, chest_private=1 }); +ADD_RCC({"candles:candelabra_copper", 1, 1, 1, church=1, library=1, chest_private=1 }); +ADD_RCC({"candles:honey", 50, 2, 1 }); + +-- our NPC have to spend their free time somehow...also adds food variety +ADD_RCC({"fishing:pole", 60, 1, 1 }); + +-- ropes are always useful +if( minetest.get_modpath("ropes") ~= nil ) then + ADD_RCC({"ropes:rope", 60, 5, 2, chest_work=1, shelf=1, chest_storage=1 }); +elseif( minetest.get_modpath("farming") ~= nil ) then + ADD_RCC({"farming:string", 60, 5, 2, church=1, library=1, chest_work=1, shelf=1, chest_storage=1 }); +elseif( minetest.get_modpath("moreblocks") ~= nil ) then + ADD_RCC({"moreblocks:rope", 60, 5, 2, chest_work=1, shelf=1, chest_storage=1 }); +end + + +ADD_RCC({'bees:bottle_honey', 50, 4, 1, beekeeper=3, tavern=1, inn=1, chest_storage=1 }); +ADD_RCC({'bees:extractor', 80, 1, 2, beekeeper=1 }); +ADD_RCC({'bees:frame_empty', 50, 2, 5, beekeeper=1 }); +ADD_RCC({'bees:frame_full', 80, 1, 1, beekeeper=1 }); +ADD_RCC({'bees:grafting_tool', 50, 1, 3, beekeeper=1 }); +ADD_RCC({'bees:hive_industrial', 100, 1, 1, beekeeper=1 }); +ADD_RCC({'bees:honey_comb', 50, 2, 2, beekeeper=1 }); +ADD_RCC({'bees:queen_bee', 50, 2, 3, beekeeper=1 }); +ADD_RCC({'bees:smoker', 80, 1, 2, beekeeper=1 }); +ADD_RCC({'bees:wax', 80, 3, 3, beekeeper=1 }); + +ADD_RCC({'bushes:blackberry', 80, 20, 4, bakery=1 }); +ADD_RCC({'bushes:blackberry_pie_cooked', 80, 12, 4, bakery=1 }); +ADD_RCC({'bushes:blueberry', 80, 20, 4, bakery=1 }); +ADD_RCC({'bushes:blueberry_pie_cooked', 80, 12, 4, bakery=1 }); +ADD_RCC({'bushes:gooseberry', 80, 20, 4, bakery=1 }); +ADD_RCC({'bushes:gooseberry_pie_cooked', 80, 12, 4, bakery=1 }); +ADD_RCC({'bushes:raspberry', 80, 20, 4, bakery=1 }); +ADD_RCC({'bushes:raspberry_pie_cooked', 80, 12, 4, bakery=1 }); +ADD_RCC({'bushes:mixed_berry_pie_cooked', 80, 12, 4, bakery=1 }); +ADD_RCC({'bushes:sugar', 80, 99, 5, bakery=1, shelf=1 }); + +ADD_RCC({'carts:cart', 80, 1, 2, miner=1}); + +ADD_RCC({'castle:battleaxe', 50, 1, 1, guard=1, forge=1 }); +ADD_RCC({'castle:ropebox', 50, 2, 2, guard=1 }); +ADD_RCC({'castle:ropes', 50, 1, 1, guard=2, chest_private=1, chest_work=2 }); +ADD_RCC({'castle:shield', 50, 1, 1, guard=1 }); +ADD_RCC({'castle:shield_2', 50, 1, 1, guard=1 }); +ADD_RCC({'castle:shield_3', 50, 1, 1, guard=1 }); + +ADD_RCC({'cottages:anvil', 80, 1, 2, forge=1 }); + +ADD_RCC({'currency:minegeld', 80, 10, 2, chest_private=1, chest_work=1 }); -- TODO: could be in any chest with a certain chance + +ADD_RCC({'farming:hoe_stone', 80, 1, 2, farm_tiny=2, farm_full=2, chest_work=2 }); + +ADD_RCC({'homedecor:beer_mug', 50, 1, 2, tavern=5, inn=3}); +ADD_RCC({'homedecor:book_blue', 50, 1, 2, church=1, library=1, chest_private=1}); +ADD_RCC({'homedecor:book_red', 50, 1, 2, church=1, library=1, chest_private=1}); +ADD_RCC({'homedecor:book_green', 50, 1, 2, church=1, library=1, chest_private=1}); +ADD_RCC({'homedecor:bottle_brown', 50, 1, 2, tavern=3, inn=3, chest_private=1}); +ADD_RCC({'homedecor:bottle_green', 50, 1, 2, tavern=3, inn=3, chest_private=1}); +ADD_RCC({'homedecor:calendar', 50, 1, 1, church=1, library=1, chest_private=1, chest_work=1, chest_storage=1}); +ADD_RCC({"homedecor:candle", 50, 2, 1, church=2, library=1, chest_private=1, chest_work=1, chest_storage=1 }); +ADD_RCC({"homedecor:candle_thin", 50, 2, 1, church=1, library=1, chest_private=1, chest_work=1, chest_storage=1 }); +ADD_RCC({"homedecor:copper_pans", 80, 1, 1, chest_work=1 }); +ADD_RCC({"homedecor:dardboard", 50, 1, 1, tavern=1}); +ADD_RCC({"homedecor:oil_extract", 80, 1, 3, church=1, library=1, chest_private=1, chest_work=1, chest_storage=1 }); +ADD_RCC({"homedecor:oil_lamp", 50, 2, 1, church=1, library=1, chest_private=1, chest_work=1, chest_storage=1 }); +ADD_RCC({"homedecor:torch_wall", 50, 2, 1, church=1, library=1, chest_private=1, chest_work=1, chest_storage=1 }); + +ADD_RCC({"locks:key", 50, 2, 1, chest_private=1, chest_work=1, chest_storage=1, forge=1 }); +ADD_RCC({"locks:keychain", 50, 2, 1, chest_private=1, chest_work=1, chest_storage=1, forge=1 }); + +ADD_RCC({"moretrees:coconut_milk", 80, 5, 2, tavern=1, inn=1 }); +ADD_RCC({"moretrees:raw_coconut", 80, 5, 2, tavern=1, inn=1 }); +ADD_RCC({"moretrees:pine_nuts", 80, 99, 1, tavern=1, inn=1, chest_storage=3 }); +ADD_RCC({"moretrees:spruce_nuts", 80, 99, 1, tavern=1, inn=1, chest_storage=3 }); + +ADD_RCC({"quartz:quartz_crystal", 80, 1, 1, library=1 }); + +ADD_RCC({"screwdriver:screwdriver", 80, 1, 1, chest_work=1 }); + +ADD_RCC({"unified_inventory:bag_large", 80, 1, 1, chest_private=1, chest_storage=2 }); +ADD_RCC({"unified_inventory:bag_medium", 80, 1, 1, chest_private=1, chest_storage=2 }); +ADD_RCC({"unified_inventory:bag_small", 80, 1, 1, tavern=1, inn=1, chest_work=1, chest_private=1 }); + + +-- get some random content for a chest +mg_villages.fill_chest_random = function( pos, pr, building_nr, building_typ ) + + local building_data = mg_villages.BUILDINGS[ building_nr.btype ]; + + local meta = minetest.env:get_meta( pos ); + local inv = meta:get_inventory(); + + local count = 0; + + local typ = minetest.get_name_from_content_id( pos.typ ); + if( pos.typ_name ) then + typ = pos.typ_name; + end + if( not( typ ) or (typ ~= 'cottages:shelf' and typ ~= 'cottages:chest_work' and typ ~= 'cottages:chest_storage' and typ ~= 'cottages:chest_private' )) then + typ = building_data.typ; + else + typ = string.sub( typ, 10 ); + end + local typ2 = nil; + if( typ == 'cottages:chest_work' and building_data.typ ) then + typ2 = building_data.typ; + end +--print('FILLING chest of type '..tostring( typ )..' and '..tostring( typ2)); + if( not( typ ) or typ=='' ) then + return; + end + local inv_size = inv:get_size('main'); + for i,v in ipairs( mg_villages.random_chest_content ) do + + -- repeat this many times + for count=1, v[ 4 ] do + + -- to avoid too many things inside a chest, lower probability + if( count<30 -- make sure it does not get too much and there is still room for a new stack + and (v[ typ ] or (typ2 and v[ typ2 ])) + and inv_size and inv_size > 0 and v[ 2 ] > pr:next( 1, 200 )) then + + --inv:add_item('main', v[ 1 ].." "..tostring( math.random( 1, tonumber(v[ 3 ]) ))); + -- add itemstack at a random position in the chests inventory + inv:set_stack( 'main', pr:next( 1, inv:get_size( 'main' )), v[ 1 ].." "..tostring( pr:next( 1, tonumber(v[ 3 ]) )) ); + count = count+1; + end + end + end +end + +--[[ +--the old code used by Nores mg mapgen + for _, n in pairs(village.to_add_data.extranodes) do + +-- minetest.set_node(n.pos, n.node) + if n.meta ~= nil then + + + meta = minetest.get_meta(n.pos) + meta:from_table(n.meta) + if n.node.name == "default:chest" then + local inv = meta:get_inventory() + local items = inv:get_list("main") + for i=1, inv:get_size("main") do + inv:set_stack("main", i, ItemStack("")) + end + local numitems = pr:next(3, 20) + for i=1,numitems do + local ii = pr:next(1, #items) + local prob = items[ii]:get_count() % 2 ^ 8 + local stacksz = math.floor(items[ii]:get_count() / 2 ^ 8) + if pr:next(0, prob) == 0 and stacksz>0 then + stk = ItemStack({name=items[ii]:get_name(), count=pr:next(1, stacksz), wear=items[ii]:get_wear(), metadata=items[ii]:get_metadata()}) + local ind = pr:next(1, inv:get_size("main")) + while not inv:get_stack("main",ind):is_empty() do + ind = pr:next(1, inv:get_size("main")) + end + inv:set_stack("main", ind, stk) + end + end + end + end + end + +--]] diff --git a/mods/a_mapgen_mods/mg_villages/fill_chest.lua b/mods/a_mapgen_mods/mg_villages/fill_chest.lua new file mode 100644 index 00000000..b707297c --- /dev/null +++ b/mods/a_mapgen_mods/mg_villages/fill_chest.lua @@ -0,0 +1,283 @@ +--[[-- TODO: refill chest after some time? +-- TODO: alert NPC that something was taken + +mg_villages.random_chest_content = {}; + +-- add random chest content +local ADD_RCC = function( data ) + if( data and #data>3 and ( minetest.registered_nodes[ data[1] ] or minetest.registered_items[ data[1] ]) ) then + table.insert( mg_villages.random_chest_content, data ); + end +end + +-- things that can be found in private, not locked chests belonging to npc +-- contains tables of the following structure: { node_name, probability (in percent, 100=always, 0=never), max_amount, repeat (for more than one stack) } +mg_villages.random_chest_content = {}; + +ADD_RCC({"default:pick_stone", 10, 1, 3, farm_tiny=1, farm_full=1, shed=1, lumberjack=1, hut=1, chest_work=1, lumberjack=1 }); +ADD_RCC({"default:pick_steel", 5, 1, 2, forge=1 }); +ADD_RCC({"default:pick_mese", 2, 1, 2, forge=1, lumberjack=1 }); +ADD_RCC({"default:shovel_stone", 5, 1, 3, farm_tiny=1, farm_full=1, shed=1, lumberjack=1, hut=1, chest_work=1 }); +ADD_RCC({"default:shovel_steel", 5, 1, 2, forge=1 }); +ADD_RCC({"default:axe_stone", 5, 1, 3, farm_tiny=1, farm_full=1, chest_work=1, lumberjack=1 }); +ADD_RCC({"default:axe_steel", 5, 1, 2, forge=1, lumberjack=1 }); +ADD_RCC({"default:sword_wood", 1, 1, 3, guard=1 }); +ADD_RCC({"default:sword_stone", 1, 1, 3, guard=1 }); +ADD_RCC({"default:sword_steel", 1, 1, 3, forge=1, guard=1 }); + +ADD_RCC({"default:stick", 20, 40, 2, church=1, library=1, chest_private=1, shelf=5, shed=1, lumberjack=1, hut=1 }); +ADD_RCC({"default:torch", 50, 10, 4, church=1, library=1, chest_private=1, shelf=1, shed=1, lumberjack=1, hut=1 }); + +ADD_RCC({"default:book", 60, 1, 2, church=1, library=1 }); +ADD_RCC({"default:paper", 60, 6, 4, church=1, library=1 }); +ADD_RCC({"default:apple", 50, 10, 2, chest_storage=4, chest_private=1, shelf=5}); +ADD_RCC({"default:ladder", 20, 1, 2, church=1, library=1, shed=1, lumberjack=1, hut=1 }); + +ADD_RCC({"default:coal_lump", 80, 30, 1, forge=1, shed=1, lumberjack=1, hut=1}); +ADD_RCC({"default:steel_ingot", 30, 4, 2, forge=1 }); +ADD_RCC({"default:mese_crystal_fragment", 10, 3, 1, forge=1, chest_storage=1 }); + +ADD_RCC({"bucket:bucket_empty", 10, 3, 2, chest_work=1, forge=1, shed=1, hut=1 }); +ADD_RCC({"bucket:bucket_water", 5, 3, 2, chest_work=1, forge=1 }); +ADD_RCC({"bucket:bucket_lava", 3, 3, 2, forge=1 }); + +ADD_RCC({"vessels:glass_bottle", 10, 10, 2, church=1, library=1, shelf=1 }); +ADD_RCC({"vessels:drinking_glass", 20, 2, 1, church=1, library=1, shelf=1 }); +ADD_RCC({"vessels:steel_bottle", 10, 1, 1, church=1, library=1, shelf=1 }); + +ADD_RCC({"wool:white", 60, 8, 2, church=1, library=1 }); + + +-- that someone will hide valuable ingots in chests that are not locked is fairly unrealistic; thus, those items are rare +ADD_RCC({"moreores:gold_ingot", 1, 2, 1 }); +ADD_RCC({"moreores:silver_ingot", 1, 2, 1 }); +ADD_RCC({"moreores:copper_ingot", 30, 10, 1 }); +ADD_RCC({"moreores:tin_ingot", 1, 5, 1 }); +ADD_RCC({"moreores:bronze_ingot", 1, 1, 1 }); +ADD_RCC({"moreores:mithril_ingot", 1, 1, 1 }); + +-- candles are a very likely content of chests +ADD_RCC({"candles:candle", 80, 12, 2, church=1, library=1, chest_private=1 }); +ADD_RCC({"candles:candelabra_steel", 1, 1, 1, church=1, library=1, chest_private=1 }); +ADD_RCC({"candles:candelabra_copper", 1, 1, 1, church=1, library=1, chest_private=1 }); +ADD_RCC({"candles:honey", 50, 2, 1 }); + +-- our NPC have to spend their free time somehow...also adds food variety +ADD_RCC({"fishing:pole", 60, 1, 1 }); + +-- ropes are always useful +if( minetest.get_modpath("ropes") ~= nil ) then + ADD_RCC({"ropes:rope", 60, 5, 2, chest_work=1, shelf=1, chest_storage=1 }); +elseif( minetest.get_modpath("farming") ~= nil ) then + ADD_RCC({"farming:string", 60, 5, 2, church=1, library=1, chest_work=1, shelf=1, chest_storage=1 }); +elseif( minetest.get_modpath("moreblocks") ~= nil ) then + ADD_RCC({"moreblocks:rope", 60, 5, 2, chest_work=1, shelf=1, chest_storage=1 }); +end + + +ADD_RCC({'bees:bottle_honey', 50, 4, 1, beekeeper=3, tavern=1, inn=1, chest_storage=1 }); +ADD_RCC({'bees:extractor', 80, 1, 2, beekeeper=1 }); +ADD_RCC({'bees:frame_empty', 50, 2, 5, beekeeper=1 }); +ADD_RCC({'bees:frame_full', 80, 1, 1, beekeeper=1 }); +ADD_RCC({'bees:grafting_tool', 50, 1, 3, beekeeper=1 }); +ADD_RCC({'bees:hive_industrial', 100, 1, 1, beekeeper=1 }); +ADD_RCC({'bees:honey_comb', 50, 2, 2, beekeeper=1 }); +ADD_RCC({'bees:queen_bee', 50, 2, 3, beekeeper=1 }); +ADD_RCC({'bees:smoker', 80, 1, 2, beekeeper=1 }); +ADD_RCC({'bees:wax', 80, 3, 3, beekeeper=1 }); + +ADD_RCC({'bushes:blackberry', 80, 20, 4, bakery=1 }); +ADD_RCC({'bushes:blackberry_pie_cooked', 80, 12, 4, bakery=1 }); +ADD_RCC({'bushes:blueberry', 80, 20, 4, bakery=1 }); +ADD_RCC({'bushes:blueberry_pie_cooked', 80, 12, 4, bakery=1 }); +ADD_RCC({'bushes:gooseberry', 80, 20, 4, bakery=1 }); +ADD_RCC({'bushes:gooseberry_pie_cooked', 80, 12, 4, bakery=1 }); +ADD_RCC({'bushes:raspberry', 80, 20, 4, bakery=1 }); +ADD_RCC({'bushes:raspberry_pie_cooked', 80, 12, 4, bakery=1 }); +ADD_RCC({'bushes:mixed_berry_pie_cooked', 80, 12, 4, bakery=1 }); +ADD_RCC({'bushes:sugar', 80, 99, 5, bakery=1, shelf=1 }); + +ADD_RCC({'carts:cart', 80, 1, 2, miner=1}); + +ADD_RCC({'castle:battleaxe', 50, 1, 1, guard=1, forge=1 }); +ADD_RCC({'castle:ropebox', 50, 2, 2, guard=1 }); +ADD_RCC({'castle:ropes', 50, 1, 1, guard=2, chest_private=1, chest_work=2 }); +ADD_RCC({'castle:shield', 50, 1, 1, guard=1 }); +ADD_RCC({'castle:shield_2', 50, 1, 1, guard=1 }); +ADD_RCC({'castle:shield_3', 50, 1, 1, guard=1 }); + +ADD_RCC({'cottages:anvil', 80, 1, 2, forge=1 }); + +ADD_RCC({'currency:minegeld', 80, 10, 2, chest_private=1, chest_work=1 }); -- TODO: could be in any chest with a certain chance + +ADD_RCC({'farming:hoe_stone', 80, 1, 2, farm_tiny=2, farm_full=2, chest_work=2 }); + +ADD_RCC({'homedecor:beer_mug', 50, 1, 2, tavern=5, inn=3}); +ADD_RCC({'homedecor:book_blue', 50, 1, 2, church=1, library=1, chest_private=1}); +ADD_RCC({'homedecor:book_red', 50, 1, 2, church=1, library=1, chest_private=1}); +ADD_RCC({'homedecor:book_green', 50, 1, 2, church=1, library=1, chest_private=1}); +ADD_RCC({'homedecor:bottle_brown', 50, 1, 2, tavern=3, inn=3, chest_private=1}); +ADD_RCC({'homedecor:bottle_green', 50, 1, 2, tavern=3, inn=3, chest_private=1}); +ADD_RCC({'homedecor:calendar', 50, 1, 1, church=1, library=1, chest_private=1, chest_work=1, chest_storage=1}); +ADD_RCC({"homedecor:candle", 50, 2, 1, church=2, library=1, chest_private=1, chest_work=1, chest_storage=1 }); +ADD_RCC({"homedecor:candle_thin", 50, 2, 1, church=1, library=1, chest_private=1, chest_work=1, chest_storage=1 }); +ADD_RCC({"homedecor:copper_pans", 80, 1, 1, chest_work=1 }); +ADD_RCC({"homedecor:dardboard", 50, 1, 1, tavern=1}); +ADD_RCC({"homedecor:oil_extract", 80, 1, 3, church=1, library=1, chest_private=1, chest_work=1, chest_storage=1 }); +ADD_RCC({"homedecor:oil_lamp", 50, 2, 1, church=1, library=1, chest_private=1, chest_work=1, chest_storage=1 }); +ADD_RCC({"homedecor:torch_wall", 50, 2, 1, church=1, library=1, chest_private=1, chest_work=1, chest_storage=1 }); + +ADD_RCC({"locks:key", 50, 2, 1, chest_private=1, chest_work=1, chest_storage=1, forge=1 }); +ADD_RCC({"locks:keychain", 50, 2, 1, chest_private=1, chest_work=1, chest_storage=1, forge=1 }); + +ADD_RCC({"moretrees:coconut_milk", 80, 5, 2, tavern=1, inn=1 }); +ADD_RCC({"moretrees:raw_coconut", 80, 5, 2, tavern=1, inn=1 }); +ADD_RCC({"moretrees:pine_nuts", 80, 99, 1, tavern=1, inn=1, chest_storage=3 }); +ADD_RCC({"moretrees:spruce_nuts", 80, 99, 1, tavern=1, inn=1, chest_storage=3 }); + +ADD_RCC({"quartz:quartz_crystal", 80, 1, 1, library=1 }); + +ADD_RCC({"screwdriver:screwdriver", 80, 1, 1, chest_work=1 }); + +ADD_RCC({"unified_inventory:bag_large", 80, 1, 1, chest_private=1, chest_storage=2 }); +ADD_RCC({"unified_inventory:bag_medium", 80, 1, 1, chest_private=1, chest_storage=2 }); +ADD_RCC({"unified_inventory:bag_small", 80, 1, 1, tavern=1, inn=1, chest_work=1, chest_private=1 }); + + +-- get some random content for a chest +mg_villages.fill_chest_random = function( pos, pr, building_nr, building_typ ) + + local building_data = mg_villages.BUILDINGS[ building_nr.btype ]; + + local meta = minetest.env:get_meta( pos ); + local inv = meta:get_inventory(); + + local count = 0; + + local typ = minetest.get_name_from_content_id( pos.typ ); + if( pos.typ_name ) then + typ = pos.typ_name; + end + if( not( typ ) or (typ ~= 'cottages:shelf' and typ ~= 'cottages:chest_work' and typ ~= 'cottages:chest_storage' and typ ~= 'cottages:chest_private' )) then + typ = building_data.typ; + else + typ = string.sub( typ, 10 ); + end + local typ2 = nil; + if( typ == 'cottages:chest_work' and building_data.typ ) then + typ2 = building_data.typ; + end +--print('FILLING chest of type '..tostring( typ )..' and '..tostring( typ2)); + if( not( typ ) or typ=='' ) then + return; + end + local inv_size = inv:get_size('main'); + for i,v in ipairs( mg_villages.random_chest_content ) do + + -- repeat this many times + for count=1, v[ 4 ] do + + -- to avoid too many things inside a chest, lower probability + if( count<30 -- make sure it does not get too much and there is still room for a new stack + and (v[ typ ] or (typ2 and v[ typ2 ])) + and inv_size and inv_size > 0 and v[ 2 ] > pr:next( 1, 200 )) then + + --inv:add_item('main', v[ 1 ].." "..tostring( math.random( 1, tonumber(v[ 3 ]) ))); + -- add itemstack at a random position in the chests inventory + inv:set_stack( 'main', pr:next( 1, inv:get_size( 'main' )), v[ 1 ].." "..tostring( pr:next( 1, tonumber(v[ 3 ]) )) ); + count = count+1; + end + end + end +end]] + +--[[ +--the old code used by Nores mg mapgen + for _, n in pairs(village.to_add_data.extranodes) do + +-- minetest.set_node(n.pos, n.node) + if n.meta ~= nil then + + + meta = minetest.get_meta(n.pos) + meta:from_table(n.meta) + if n.node.name == "default:chest" then + local inv = meta:get_inventory() + local items = inv:get_list("main") + for i=1, inv:get_size("main") do + inv:set_stack("main", i, ItemStack("")) + end + local numitems = pr:next(3, 20) + for i=1,numitems do + local ii = pr:next(1, #items) + local prob = items[ii]:get_count() % 2 ^ 8 + local stacksz = math.floor(items[ii]:get_count() / 2 ^ 8) + if pr:next(0, prob) == 0 and stacksz>0 then + stk = ItemStack({name=items[ii]:get_name(), count=pr:next(1, stacksz), wear=items[ii]:get_wear(), metadata=items[ii]:get_metadata()}) + local ind = pr:next(1, inv:get_size("main")) + while not inv:get_stack("main",ind):is_empty() do + ind = pr:next(1, inv:get_size("main")) + end + inv:set_stack("main", ind, stk) + end + end + end + end + end + +--]] +--the code that works +-- adapted from the Mines mod + +local chest_stuff = { + {name="default:apple", max = 3}, + {name="farming:bread", max = 3}, + {name="default:steel_ingot", max = 2}, + {name="default:gold_ingot", max = 2}, + {name="default:axe_steel", max = 1}, + --{name="default:emerald", max = 5}, + {name="default:pick_steel", max = 1}, + {name="default:shovel_steel", max = 1}, + {name="default:book", max = 3}, + {name="default:torch", max = 13}, + {name="default:stick", max = 7}, + {name="default:coal_lump", max = 4}, + {name="bucket:bucket_empty", max = 1}, + {name="default:ladder", max = 10}, + {name="default:mese_crystal_fragment", max = 2}, + {name="vessels:glass_bottle", max = 1}, + {name="wool:white", max = 11}, + --{name="carpet:white", max = 11}, + --{name="quartz:quartz_crystal", max = 5}, + --{name="shears:shears", max = 1}, + --{name="crops:melon_seed", max = 18}, + --{name="mobs:saddle", max = 3}, + {name="farming:carrot", max = 3}, + {name="farming:corn", max = 3}, + {name="farming:melon_slice", max = 3}, + {name="farming:potato", max = 3}, + {name="farming:raspberries", max = 3}, + {name="farming:rhubarb", max = 3}, + {name="farming:sugar", max = 3}, + {name="farming:tomato", max = 3}, + {name="farming:seed_wheat", max = 3}, + {name="farming:cucumber", max = 3}, + {name="farming:grapes", max = 3}, +} + +-- get some random content for a chest +mg_villages.fill_chest_random = function( pos, pr, building_nr, building_typ ) + local meta = minetest.get_meta( pos ) + local inv = meta:get_inventory() + inv:set_size("main", 8*4) + for i=0,pr:next(1,6),1 do + local stuff = chest_stuff[pr:next(1,#chest_stuff)] + local stack = {name=stuff.name, count = pr:next(1,stuff.max)} + if not inv:contains_item("main", stack) then + inv:set_stack("main", pr:next(1,32), stack) + end + end +end + + + diff --git a/mods/a_mapgen_mods/mg_villages/highlandpools.lua b/mods/a_mapgen_mods/mg_villages/highlandpools.lua new file mode 100644 index 00000000..80e4b553 --- /dev/null +++ b/mods/a_mapgen_mods/mg_villages/highlandpools.lua @@ -0,0 +1,234 @@ +-- highlandpools 0.1.1 by paramat +-- For latest stable Minetest back to 0.4.8 +-- Depends default +-- Licenses: code WTFPL + +-- Parameters + +local YMAX = 33000 -- Maximum altitude for pools +local FLOW = 256 + +-- Stuff + +highlandpools = {} + +-- Functions + +function highlandpools_remtree(x, y, z, area, data) + local c_tree = minetest.get_content_id("default:tree") + local c_apple = minetest.get_content_id("default:apple") + local c_leaves = minetest.get_content_id("default:leaves") + local c_air = minetest.get_content_id("air") + for j = 1, 7 do + for i = -2, 2 do + for k = -2, 2 do + local vi = area:index(x+i, y+j, z+k) + if data[vi] == c_tree + or data[vi] == c_apple + or data[vi] == c_leaves then + data[vi] = c_air + end + end + end + end + for j = 1, 7 do + for i = -2, 2 do + for k = -2, 2 do + local vi = area:index(x+i, y-j, z+k) + if data[vi] == c_tree + or data[vi] == c_apple + or data[vi] == c_leaves then + data[vi] = c_air + end + end + end + end +end + +-- On generated function + +mg_villages.do_highlandpools = function(minp, maxp, seed, vm, area, data, village_area) + local y0 = minp.y + if y0 < -32 or y0 > YMAX then + return + end + + local x0 = minp.x + local z0 = minp.z + local x1 = maxp.x + local y1 = maxp.y + local z1 = maxp.z + local sidelen = x1 - x0 -- actually sidelen - 1 + + local c_air = minetest.get_content_id("air") + local c_ignore = minetest.get_content_id("ignore") + local c_watsour = minetest.get_content_id("default:river_water_source") + local c_grass = minetest.get_content_id("default:dirt_with_grass") + local c_tree = minetest.get_content_id("default:tree") + local c_apple = minetest.get_content_id("default:apple") + local c_leaves = minetest.get_content_id("default:leaves") + local c_dirt = minetest.get_content_id("default:dirt") + + for xcen = x0 + 8, x1 - 7, 8 do + for zcen = z0 + 8, z1 - 7, 8 do + -- TODO: village_area[ x ][ z ][ 2 ] == 0 means: not inside any village area or terrain blend area + local yasurf = false -- y of above surface node + for y = y1, 2, -1 do + local vi = area:index(xcen, y, zcen) + local c_node = data[vi] + if y == y1 and c_node ~= c_air then -- if top node solid + break + elseif c_node == c_watsour then + break + elseif c_node == c_grass then + yasurf = y + 1 + break + end + end + if yasurf then + local abort = false + for ser = 1, 80 do + local vi = area:index(xcen + ser, yasurf, zcen) + local c_node = data[vi] + if xcen + ser == x1 then + abort = true + elseif c_node ~= c_air + and c_node ~= c_tree + and c_node ~= c_leaves + and c_node ~= c_apple then + break + end + end + for ser = 1, 80 do + local vi = area:index(xcen - ser, yasurf, zcen) + local c_node = data[vi] + if xcen - ser == x0 then + abort = true + elseif c_node ~= c_air + and c_node ~= c_tree + and c_node ~= c_leaves + and c_node ~= c_apple then + break + end + end + for ser = 1, 80 do + local vi = area:index(xcen, yasurf, zcen + ser) + local c_node = data[vi] + if zcen + ser == z1 then + abort = true + elseif c_node ~= c_air + and c_node ~= c_tree + and c_node ~= c_leaves + and c_node ~= c_apple then + break + end + end + for ser = 1, 80 do + local vi = area:index(xcen, yasurf, zcen - ser) + local c_node = data[vi] + if zcen - ser == z0 then + abort = true + elseif c_node ~= c_air + and c_node ~= c_tree + and c_node ~= c_leaves + and c_node ~= c_apple then + break + end + end + if abort then + break + end + + local vi = area:index(xcen, yasurf, zcen) + data[vi] = c_watsour + local flab = false -- flow abort + for flow = 1, FLOW do + for z = z0, z1 do + for x = x0, x1 do + local vif = area:index(x, yasurf, z) + if data[vif] == c_watsour then + if x == x0 or x == x1 or z == z0 or z == z1 then + flab = true -- if water at chunk edge abort flow + break + else -- flow water + local vie = area:index(x + 1, yasurf, z) + local viw = area:index(x - 1, yasurf, z) + local vin = area:index(x, yasurf, z + 1) + local vis = area:index(x, yasurf, z - 1) + if data[vie] == c_tree then + highlandpools_remtree(x + 1, yasurf, z, area, data) + data[vie] = c_watsour + elseif data[vie] == c_air + or data[vie] == c_apple + or data[vie] == c_leaves then + data[vie] = c_watsour + end + if data[viw] == c_tree then + highlandpools_remtree(x - 1, yasurf, z, area, data) + data[viw] = c_watsour + elseif data[viw] == c_air + or data[viw] == c_apple + or data[viw] == c_leaves then + data[viw] = c_watsour + end + if data[vin] == c_tree then + highlandpools_remtree(x, yasurf, z + 1, area, data) + data[vin] = c_watsour + elseif data[vin] == c_air + or data[vin] == c_apple + or data[vin] == c_leaves then + data[vin] = c_watsour + end + if data[vis] == c_tree then + highlandpools_remtree(x, yasurf, z - 1, area, data) + data[vis] = c_watsour + elseif data[vis] == c_air + or data[vis] == c_apple + or data[vis] == c_leaves then + data[vis] = c_watsour + end + end + end + end + if flab then + break + end + end + if flab then + break + end + end + if flab then -- erase water from this y level + for z = z0, z1 do + for x = x0, x1 do + local vi = area:index(x, yasurf, z) + if data[vi] == c_watsour then + data[vi] = c_air + end + end + end + else -- flow downwards add dirt + for z = z0, z1 do + for x = x0, x1 do + local vi = area:index(x, yasurf, z) + if data[vi] == c_watsour then + for y = yasurf - 1, y0, -1 do + local viu = area:index(x, y, z) + if data[viu] == c_air then + data[viu] = c_watsour + elseif data[viu] == c_grass then + data[viu] = c_dirt + break + else + break + end + end + end + end + end + end + end + end + end + +end diff --git a/mods/a_mapgen_mods/mg_villages/init.lua b/mods/a_mapgen_mods/mg_villages/init.lua new file mode 100644 index 00000000..cd547631 --- /dev/null +++ b/mods/a_mapgen_mods/mg_villages/init.lua @@ -0,0 +1,75 @@ + +-- reserve namespace for the villages +mg_villages = {} + +mg_villages.all_villages = {} +mg_villages.mg_generated_map = {} +mg_villages.anz_villages = 0; + +mg_villages.modpath = minetest.get_modpath( "mg_villages"); + + +mg_villages.DEBUG_LEVEL_NONE = -1 -- -1: disable all printed messages +mg_villages.DEBUG_LEVEL_NORMAL = 0 -- 0: print information about which village spawned where plus important errors +mg_villages.DEBUG_LEVEL_WARNING = 1 -- 1: warnings/errors which may not be particulary helpful for non-developers +mg_villages.DEBUG_LEVEL_INFO = 2 -- 2: print even less important warnings +mg_villages.DEBUG_LEVEL_TIMING = 3 -- 3: detailled performance information + +mg_villages.print = function( level, msg ) + if( level <= mg_villages.DEBUG_LEVEL ) then + print( "[mg_villages] "..msg ); + end +end + + +-- save_restore is now part of handle_schematics +--dofile(mg_villages.modpath.."/save_restore.lua") +mg_villages.all_villages = save_restore.restore_data( 'mg_all_villages.data' ); -- read mg_villages.all_villages data saved for this world from previous runs +mg_villages.mg_generated_map = save_restore.restore_data( 'mg_generated_map.data' ); + +dofile(mg_villages.modpath.."/config.lua") + +-- adds a special gravel node which will neither fall nor be griefed by mapgen +dofile(mg_villages.modpath.."/nodes.lua") + +-- the default game no longer provides helpful tree growing code +dofile(mg_villages.modpath.."/trees.lua") + +dofile(mg_villages.modpath.."/replacements.lua") + +-- multiple diffrent village types with their own sets of houses are supported +-- The function mg_villages.add_village_type( village_type_name, village_type_data ) +-- allows other mods to add new village types. +dofile(mg_villages.modpath.."/village_types.lua") + +-- Note: the "buildings" talbe is not in the mg_villages.* namespace +-- The function mg_villages.add_building( building_data ) allows other mods to add buildings. +dofile(mg_villages.modpath.."/buildings.lua") + +-- mg_villages.init_weights() has to be called AFTER all village types and buildings have +-- been added using the functions above +dofile(mg_villages.modpath.."/init_weights.lua") + +-- generate village names +dofile(mg_villages.modpath.."/name_gen.lua"); + +dofile(mg_villages.modpath.."/villages.lua") + +-- adds a command that allows to teleport to a known village +dofile(mg_villages.modpath.."/chat_commands.lua") +-- protect villages from griefing +dofile(mg_villages.modpath.."/protection.lua") +-- create and show a map of the world +dofile(mg_villages.modpath.."/map_of_world.lua") + +dofile(mg_villages.modpath.."/fill_chest.lua") + +-- terrain blending for individual houses +dofile(mg_villages.modpath.."/terrain_blend.lua") +-- highlandpools +dofile(mg_villages.modpath.."/highlandpools.lua") +-- the interface for the mapgen; +-- also takes care of spawning the player +dofile(mg_villages.modpath.."/mapgen.lua") + +dofile(mg_villages.modpath.."/spawn_player.lua") diff --git a/mods/a_mapgen_mods/mg_villages/init_weights.lua b/mods/a_mapgen_mods/mg_villages/init_weights.lua new file mode 100644 index 00000000..3068ea2b --- /dev/null +++ b/mods/a_mapgen_mods/mg_villages/init_weights.lua @@ -0,0 +1,43 @@ +-- this functions needs to be called once after *all* village types and buildings have been added +mg_villages.init_weights = function() + + -- create a list of all used village types + mg_villages.village_types = {}; + for k,v in pairs( mg_villages.village_type_data ) do + if( not( v.only_single ) and v.supported and v.building_list ) then + table.insert( mg_villages.village_types, k ); + end + end + mg_villages.print(mg_villages.DEBUG_LEVEL_NORMAL,'Will create villages of the following types: '..minetest.serialize( mg_villages.village_types )); + + + + mg_villages.village_types[ #mg_villages.village_types+1 ] = 'single'; + mg_villages.village_types[ #mg_villages.village_types+1 ] = 'fields'; + mg_villages.village_types[ #mg_villages.village_types+1 ] = 'tower'; + for j,v in ipairs( mg_villages.village_types ) do + + local total_weight = 0 + for _, i in ipairs(mg_villages.BUILDINGS) do + if( not( i.max_weight )) then + i.max_weight = {}; + end + if( i.weight and i.weight[ v ] and i.weight[ v ]>0 ) then + total_weight = total_weight+i.weight[ v ] + i.max_weight[v] = total_weight + end + end + local multiplier = 3000/total_weight + for _,i in ipairs(mg_villages.BUILDINGS) do + if( i.weight and i.weight[ v ] and i.weight[ v ]>0 ) then + i.max_weight[v] = i.max_weight[ v ]*multiplier + end + end + end + -- the fields do not exist as an independent type + mg_villages.village_types[ #mg_villages.village_types ] = nil; + -- neither does the tower type + mg_villages.village_types[ #mg_villages.village_types ] = nil; + -- and neither does the "single" type (==lone houses outside villages) + mg_villages.village_types[ #mg_villages.village_types ] = nil; +end diff --git a/mods/a_mapgen_mods/mg_villages/map_of_world.lua b/mods/a_mapgen_mods/mg_villages/map_of_world.lua new file mode 100644 index 00000000..71cd64c4 --- /dev/null +++ b/mods/a_mapgen_mods/mg_villages/map_of_world.lua @@ -0,0 +1,193 @@ + + +-- villages up to this many nodes in each direction are shown on the map +mg_villages.MAP_RANGE = 1000; + + +mg_villages.draw_tile = function( content_id, image, x, z, dx, dz, tile_nr ) + if( not( image )) then + local node_name = minetest.get_name_from_content_id( content_id ); + if( not( node_name )) then + return ''; + end + local node_def = minetest.registered_nodes[ node_name ]; + if( not( node_def )) then + return ''; + end + local tiles = node_def.tiles; + local tile = nil; + if( tiles ~= nil ) then + if( not(tile_nr) or tile_nr > #tiles or tile_nr < 1 ) then + tile_nr = 1; + end + tile = tiles[tile_nr]; + end + if type(tile)=="table" then + tile=tile["name"] + end + image = tile; + if( not( image )) then + image = "unknown_object.png"; + end + end + return "image["..tostring(x)..",".. tostring(z) ..";"..dx..','..dz..";" .. image .."]"; +end + + +mg_villages.map_of_world = function( pname ) + + local player = minetest.get_player_by_name( pname ); + if( not( player )) then + return ''; + end + local ppos = player:getpos(); + + -- also usable: diamond_block, sand, water + local formspec = "size[14.4,10]".. + "background[0,0;10,10;"..mg_villages.MAP_BACKGROUND_IMAGE.."]".. + "label[10,10;x axis]".. + "label[0,0;z axis]".. + "label[0,10;|]".. + "label[0.2,10;->]"; + + + local r = mg_villages.MAP_RANGE; + local f1 = 10/(2*r); + + local map_tiles_shown = math.floor( mg_villages.MAP_RANGE/80 ); + local center_x = math.floor( ppos.x/80 ); + local center_z = math.floor( ppos.z/80 ); + for x = center_x - map_tiles_shown, center_x + map_tiles_shown do + for z = center_z - map_tiles_shown, center_z + map_tiles_shown do + if( mg_villages.mg_generated_map[ x ] and mg_villages.mg_generated_map[ x ][ z ] ) then + local surface_types = mg_villages.mg_generated_map[ x ][ z ]; + local content_id = 0; + if( type( surface_types )=='table' ) then + content_id = surface_types[ 26 ]; + else + content_id = surface_types; + end + + local x1 = f1 * ((x*80) - ppos.x +r); + local z1 = f1 * ( (2*r) - ((z*80) - ppos.z + r)); + local dx = f1 * 80; + local dz = f1 * 80; + + formspec = formspec..mg_villages.draw_tile( content_id, nil, x1+0.5, z1-0.5, dx*1.25, dz*1.25, 1 ); + + -- if more detailed information is available, draw those tiles that differ from the most common tile + if( type( surface_types )=='table' and false) then -- TODO: disabled for now + dx = dx/5; + dz = dz/5; + for i,v in ipairs( surface_types ) do + if( v ~= content_id ) then + local x2 = x1+( math.floor( (i-1)/5 )*dx); + local z2 = z1+( math.floor( (i-1)%5 )*dz); + formspec = formspec..mg_villages.draw_tile( v, nil, x2+0.5, z2-0.5, dx*1.3, dz*1.3, 1); + end + end + end + end + end + end + + local shown_villages = {}; + + r = mg_villages.MAP_RANGE; + f1 = 10/(2*r); + for name,v in pairs( mg_villages.all_villages ) do + + local data = v; --minetest.deserialize( v ); + local x = data.vx - ppos.x; + local z = data.vz - ppos.z; + + -- show only villages which are at max mg_villages.MAP_RANGE away from player + if( x and z + and mg_villages.village_type_data[ data.village_type ] + and mg_villages.village_type_data[ data.village_type ].texture + and math.abs( x ) < r + and math.abs( z ) < r ) then + + -- the village size determines the texture size + local dx = f1 * (data.vs*2) *1.25; + local dz = f1 * (data.vs*2) *1.0; + + -- center the village texture + x = x - (data.vs/2); + z = z + (data.vs/2); + + -- calculate the position for the village texture + x = f1 * (x+r); + z = f1 * ( (2*r) -(z+r)); + + formspec = formspec.. + "label["..x..",".. z ..";"..tostring( data.nr ).."]"..mg_villages.draw_tile( nil, mg_villages.village_type_data[ data.village_type ].texture, x, z, dx, dz, 1 ); + + shown_villages[ #shown_villages+1 ] = tostring( data.nr )..". "..tostring( v.name or 'unknown' ).."]"; + end + end + + -- code and arrows taken from mapp mod + local yaw = player:get_look_yaw() + local rotate = 0; + if yaw ~= nil then + -- Find rotation and texture based on yaw. + yaw = math.deg(yaw) + yaw = math.fmod (yaw, 360) + if yaw<0 then yaw = 360 + yaw end + if yaw>360 then yaw = yaw - 360 end + if yaw < 90 then + rotate = 90 + elseif yaw < 180 then + rotate = 180 + elseif yaw < 270 then + rotate = 270 + else + rotate = 0 + end + yaw = math.fmod(yaw, 90) + yaw = math.floor(yaw / 10) * 10 + + end + + -- show the players yaw + if rotate ~= 0 then + formspec = formspec.."image[".. 4.95 ..",".. 4.85 ..";0.4,0.4;d" .. yaw .. ".png^[transformFYR".. rotate .."]" + else + formspec = formspec.."image[".. 4.95 ..",".. 4.85 ..";0.4,0.4;d" .. yaw .. ".png^[transformFY]" + end + + local i = 0.05; + formspec = formspec.."label[10,-0.4;Village types:]"; + -- explain the meaning of the textures + if mg_villages.village_types ~= nil then + for _,typ in ipairs(mg_villages.village_types) do + formspec = formspec.."label[10.5,"..tostring(i)..";"..tostring( typ ).."]".. + "image[10.0,"..tostring(i+0.1)..";0.4,0.4;"..tostring( mg_villages.village_type_data[ typ ].texture ).."]"; + i = i+0.45; + end + end + + i = i+0.45; + formspec = formspec.."label[10.0,"..tostring(i)..";Villages shown on this map:]"; + i = i+0.45; + local j = 1; + while (i<10.5 and j<=#shown_villages) do + + formspec = formspec.."label[10.0,"..tostring(i)..";"..tostring( shown_villages[ j ] ).."]"; + i = i+0.45; + j = j+1; + end + + return formspec; +end + + +minetest.register_chatcommand( 'vmap', { + description = "Shows a map of all known villages withhin "..tostring( mg_villages.MAP_RANGE ).." blocks.", + privs = {}, + func = function(name, param) + minetest.show_formspec( name, 'mg:world_map', mg_villages.map_of_world( name )); + end +}); + diff --git a/mods/a_mapgen_mods/mg_villages/mapgen.lua b/mods/a_mapgen_mods/mg_villages/mapgen.lua new file mode 100644 index 00000000..a2f7dc42 --- /dev/null +++ b/mods/a_mapgen_mods/mg_villages/mapgen.lua @@ -0,0 +1,1215 @@ + +------------------------------------------------------------------------------ +-- Interface for other mdos + +-- this function gets executed only once per village - namely when the first +-- part of a village is generated; +-- relevant data about the vilalge can be found in the following data structure: +-- mg_villages.all_villages[ village_id ] +mg_villages.new_village_spawned = function( village_id ) + -- dummy function +end + + +-- use this function if you want to i.e. spawn mobs/traders/etc; +-- the village data structure contains information about the entire village; +-- minp, maxp indicates which part has actually been spawned; +-- the function may add information to the village data structure if needed; +-- the voxelmanip data (data, param2_data, a) is just for reading, i.e. finding +-- a good spawning position for the trader +mg_villages.part_of_village_spawned = function( village, minp, maxp, data, param2_data, a, cid ) + -- mobf needs a way to spawn its traders + if( minetest.get_modpath( 'mobf_trader' )) then + mob_village_traders.part_of_village_spawned( village, minp, maxp, data, param2_data, a, cid ); + end +end +------------------------------------------------------------------------------ + + +mg_villages.wseed = 0; + +minetest.register_on_mapgen_init(function(mgparams) + mg_villages.wseed = math.floor(mgparams.seed/10000000000) +end) + +function mg_villages.get_bseed(minp) + return mg_villages.wseed + math.floor(5*minp.x/47) + math.floor(873*minp.z/91) +end + +function mg_villages.get_bseed2(minp) + return mg_villages.wseed + math.floor(87*minp.x/47) + math.floor(73*minp.z/91) + math.floor(31*minp.y/12) +end + + +-- if you change any of the 3 constants below, also change them in the function +-- mg_villages.village_area_mark_inside_village_area +mg_villages.inside_village = function(x, z, village, vnoise) + return mg_villages.get_vn(x, z, vnoise:get2d({x = x, y = z}), village) <= 40 +end + +mg_villages.inside_village_area = function(x, z, village, vnoise) + return mg_villages.get_vn(x, z, vnoise:get2d({x = x, y = z}), village) <= 80 +end + +mg_villages.inside_village_terrain_blend_area = function(x, z, village, vnoise) + return mg_villages.get_vn(x, z, vnoise:get2d({x = x, y = z}), village) <= 160 +end + + +mg_villages.get_vnoise = function(x, z, village, vnoise) -- PM v + return mg_villages.get_vn(x, z, vnoise:get2d({x = x, y = z}), village) +end -- PM ^ + +mg_villages.get_vn = function(x, z, noise, village) + local vx, vz, vs = village.vx, village.vz, village.vs + return (noise - 2) * 20 + + (40 / (vs * vs)) * ((x - vx) * (x - vx) + (z - vz) * (z - vz)) +end + + +mg_villages.villages_in_mapchunk = function( minp, mapchunk_size ) + local noise1raw = minetest.get_perlin(12345, 6, 0.5, 256) + + local vcr = mg_villages.VILLAGE_CHECK_RADIUS + local villages = {} + for xi = -vcr, vcr do + for zi = -vcr, vcr do + for _, village in ipairs(mg_villages.villages_at_point({x = minp.x + xi * mapchunk_size, z = minp.z + zi * mapchunk_size}, noise1raw)) do + villages[#villages+1] = village + end + end + end + return villages; +end + + +-- TODO: determine water level from mapgens? +local MG_VILLAGES_WATER_LEVEL = -70; +if( minetest.get_modpath( 'mg' )) then + MG_VILLAGES_WATER_LEVEL = 0; +end + +--replacements_group.node_is_ground = {}; -- store nodes which have previously been identified as ground + +mg_villages.check_if_ground = function( ci ) + + -- pre-generate a list of no-ground-nodes for caching + if( replacements_group.node_is_ground[ minetest.get_content_id('air')]==nil) then + local no_ground_nodes = {'air','ignore','default:sandstonebrick','default:cactus','default:wood','default:junglewood', + 'default:pine_wood','default:pine_tree','default:acacia_wood','default:acacia_tree', + 'ethereal:mushroom_pore','ethereal:mushroom_trunk','ethereal:bamboo', 'ethereal:mushroom'}; + -- TODO: add all those other tree and leaf nodes that might be added by mapgen + for _,name in ipairs( no_ground_nodes ) do + replacements_group.node_is_ground[ minetest.get_content_id( name )] = false; + end + local ground_nodes = {'default:dry_dirt'}; + for _,name in ipairs( ground_nodes ) do + replacements_group.node_is_ground[ minetest.get_content_id( name )] = true; + end + end + + if( not( ci )) then + return false; + end + if( replacements_group.node_is_ground[ ci ] ~= nil) then + return replacements_group.node_is_ground[ ci ]; + end + -- analyze the node + -- only nodes on which walking is possible may be counted as ground + local node_name = minetest.get_name_from_content_id( ci ); + local def = minetest.registered_nodes[ node_name ]; + -- store information about this node type for later use + if( not( def )) then + replacements_group.node_is_ground[ ci ] = false; + elseif( not( def.walkable)) then + replacements_group.node_is_ground[ ci ] = false; + elseif( def.groups and def.groups.tree ) then + replacements_group.node_is_ground[ ci ] = false; + elseif( def.drop and def.drop == 'default:dirt') then + replacements_group.node_is_ground[ ci ] = true; + elseif( def.walkable == true and def.is_ground_content == true and not(def.node_box)) then + replacements_group.node_is_ground[ ci ] = true; + else + replacements_group.node_is_ground[ ci ] = false; + end + return replacements_group.node_is_ground[ ci ]; +end + + +-- sets evrything at x,z and above height target_height to air; +-- the area below gets filled up in a suitable way (i.e. dirt with grss - dirt - stone) +mg_villages.lower_or_raise_terrain_at_point = function( x, z, target_height, minp, maxp, vm, data, param2_data, a, cid, vh, treepos, has_artificial_snow, blend, force_ground, force_underground ) + local surface_node = nil; + local has_snow = has_artificial_snow; + local tree = false; + local jtree = false; + local ptree = false; + local atree = false; + local old_height = maxp.y; + local y = maxp.y; + + local look_for_snow = true; + if( cid.c_snow==cid.c_ignore or cid.c_snow==cid.c_air + or cid.c_ice ==cid.c_ignore or cid.c_ice ==cid.c_air ) then + look_for_snow = nil; + end + + -- if we are working on a mapchunk above, set all to air; + -- any terrain blending happens in the mapchunk below + if( minp.y > vh ) then + local air_counted = 0; + for y=minp.y, minp.y+16 do + if( data[a:index( x, y, z )] == cid.c_air ) then + air_counted = air_counted + 1; + end + end + if( air_counted > 3 or blend==0) then + for y=minp.y+15, maxp.y do + data[a:index( x, y, z)] = cid.c_air; + end + end + -- else do nothing + return; + end + + -- search for a surface and set everything above target_height to air + while( y > minp.y) do + local ci = data[a:index(x, y, z)]; + if( look_for_snow and (ci == cid.c_snow or ci == cid.c_ice or ci == cid.c_snowblock)) then + has_snow = true; + elseif( ci == cid.c_tree ) then + tree = true; + -- no jungletrees for branches + elseif( ci == cid.c_jtree and data[a:index( x, y-1, z)]==cid.c_jtree) then + jtree = true; + -- pinetrees + elseif( ci == cid.c_ptree and data[a:index( x, y-1, z)]==cid.c_ptree) then + ptree = true; + -- acacia + elseif( ci == cid.c_atree and data[a:index( x, y-1, z)]==cid.c_atree) then + atree = true; + elseif( not( surface_node) and ci ~= cid.c_air and ci ~= cid.c_ignore and mg_villages.check_if_ground( ci ) == true) then + -- we have found a surface of some kind + surface_node = ci; + old_height = y; + if( look_for_snow and surface_node == cid.c_dirt_with_snow and cid.c_dirt_with_snow~=cid.c_ignore) then + has_snow = true; + end + end + -- make sure there is air for the village + if( y > target_height ) then + data[a:index( x, y, z)] = cid.c_air; + -- abort search once we've reached village ground level and found a surface node + elseif( y <= target_height and surface_node ) then + y = minp.y - 1; + end + y = y-1; + end + + if( not( surface_node ) and old_height == maxp.y ) then + if( data[a:index( x, minp.y, z)]==cid.c_air) then + old_height = vh - 2; + elseif( minp.y < 0 ) then + old_height = minp.y; + end + end + if( not( surface_node ) or surface_node == cid.c_dirt) then + surface_node = cid.c_dirt_with_grass; + end + if( look_for_snow and has_snow and surface_node == cid.c_dirt_with_grass and target_height > 1) then + surface_node = cid.c_dirt_with_snow; + end + local below_1 = cid.c_dirt; + local below_2 = cid.c_stone; + if( force_ground and force_underground ) then + below_1 = force_ground; + below_2 = force_underground; + surface_node = below_1; + elseif( surface_node == cid.c_desert_sand ) then + below_1 = cid.c_desert_sand; + below_2 = cid.c_desert_stone; + elseif( surface_node == cid.c_sand ) then + below_1 = cid.c_sand; + below_2 = cid.c_stone; + elseif( cid.c_ethereal_clay_read + and (surface_node == cid.c_ethereal_clay_red + or surface_node == cid.c_ethereal_clay_orange)) then + below_1 = cid.c_ethereal_clay_orange; + below_2 = cid.c_ethereal_clay_orange; + elseif( surface_node == cid.c_sandstone ) then + below_1 = cid.c_sandstone; + below_2 = cid.c_sandstone; + else + below_1 = cid.c_dirt; + below_2 = cid.c_stone; + end + + -- do terrain blending; target_height has to be calculated based on old_height + if( target_height == maxp.y and old_height < maxp.y ) then + local yblend = old_height; + if blend > 0 then -- leave some cliffs unblended + yblend = math.floor(vh + blend * (old_height - vh)) + target_height = yblend+1; + else + target_height = old_height; + end + for y = math.max( minp.y, yblend), maxp.y do + if( y<=MG_VILLAGES_WATER_LEVEL ) then + -- keep ice + if( data[a:index( x, y, z )] ~= cid.c_ice ) then + data[a:index( x, y, z)] = cid.c_water; + end + else + data[a:index( x, y, z)] = cid.c_air; + end + end + end + + -- only place the surface node if it is actually contained in this node + if( target_height >= minp.y and target_height < maxp.y ) then + if( target_height < 1 ) then + -- no trees or snow below water level + elseif( tree and not( mg_villages.ethereal_trees ) and treepos) then + data[ a:index( x, target_height+1, z)] = cid.c_sapling + table.insert( treepos, {x=x, y=target_height+1, z=z, typ=0, snow=has_artificial_snow}); + elseif( jtree and not( mg_villages.ethereal_trees ) and treepos) then + data[ a:index( x, target_height+1, z)] = cid.c_jsapling + table.insert( treepos, {x=x, y=target_height+1, z=z, typ=1, snow=has_artificial_snow}); + elseif( ptree and not( mg_villages.ethereal_trees ) and treepos) then + data[ a:index( x, target_height+1, z)] = cid.c_psapling + table.insert( treepos, {x=x, y=target_height+1, z=z, typ=2, snow=has_artificial_snow}); + elseif( atree and not( mg_villages.ethereal_trees ) and treepos) then + data[ a:index( x, target_height+1, z)] = cid.c_asapling + table.insert( treepos, {x=x, y=target_height+1, z=z, typ=3, snow=has_artificial_snow}); + elseif( has_snow ) then + data[ a:index( x, target_height+1, z)] = cid.c_snow; + end + data[ a:index( x, target_height, z)] = surface_node; + if( target_height-1 >= minp.y ) then + data[ a:index( x, target_height-1, z)] = below_1; + end + end + + -- not every column will get a coal block; some may get two + local coal_height1 = math.random( minp.y, maxp.y ); + local coal_height2 = math.random( minp.y, maxp.y ); + y = target_height-2; + while( y > minp.y and y > target_height-40 and y <=maxp.y) do + local old_node = data[a:index( x, y, z)]; + -- abort as soon as we hit anything other than air + if( old_node == cid.c_air or old_node == cid.c_water ) then + -- the occasional coal makes large stone cliffs slightly less boring + if( y == coal_height1 or y == coal_height2 ) then + data[a:index( x, y, z )] = cid.c_stone_with_coal; + else + data[a:index( x, y, z)] = below_2; + end + y = y-1; + else + y = minp.y - 1; + end + end +end + + +-- adjust the terrain level to the respective height of the village +mg_villages.flatten_village_area = function( villages, minp, maxp, vm, data, param2_data, a, village_area, cid ) + local treepos = {}; + for z = minp.z, maxp.z do + for x = minp.x, maxp.x do + for village_nr, village in ipairs(villages) do + local force_ground = nil; + local force_underground = nil; + if( village.village_type + and mg_villages.village_type_data[ village.village_type ] + and mg_villages.village_type_data[ village.village_type ].force_ground + and mg_villages.village_type_data[ village.village_type ].force_underground ) then + force_ground = minetest.get_content_id(mg_villages.village_type_data[ village.village_type ].force_ground); + force_underground = minetest.get_content_id(mg_villages.village_type_data[ village.village_type ].force_underground); + if( not( force_ground ) or force_ground < 0 or force_ground == cid.c_ignore + or not( force_underground ) or force_underground < 0 or force_underground == cid.c_ignore ) then + force_ground = nil; + force_underground = nil; + end + end + -- is village_nr the village that is the one that is relevant for this spot? + if( village_area[ x ][ z ][ 1 ] > 0 + and village_area[ x ][ z ][ 1 ]==village_nr + and village_area[ x ][ z ][ 2 ]~= 0 + and data[a:index(x,village.vh,z)] ~= cid.c_ignore) then + + local has_artificial_snow = false; + if( village.artificial_snow and village.artificial_snow==1) then + has_artificial_snow = true; + end + + if( village_area[ x ][ z ][ 2 ] > 0 ) then -- inside a village + mg_villages.lower_or_raise_terrain_at_point( x, z, village.vh, minp, maxp, vm, data, param2_data, a, cid, village.vh, + nil, has_artificial_snow, 0, force_ground, force_underground ); + elseif( mg_villages.ENABLE_TERRAIN_BLEND and village_area[ x ][ z ][ 2 ] < 0) then + mg_villages.lower_or_raise_terrain_at_point( x, z, maxp.y, minp, maxp, vm, data, param2_data, a, cid, village.vh, + treepos, has_artificial_snow, -1* village_area[ x ][ z ][ 2 ], + force_ground, force_underground); + end + end -- PM ^ + end + end + end + + -- grow normal trees and jungletrees in those parts of the terrain where height blending occours + for _, tree in ipairs(treepos) do + local plant_id = cid.c_jsapling; + if( tree.typ == 0 ) then + plant_id = cid.c_sapling; + elseif( tree.typ == 2 ) then + plant_id = cid.c_psapling; + elseif( tree.typ == 3 ) then + plant_id = cid.c_asapling; + end + mg_villages.grow_a_tree( {x=tree.x, y=tree.y, z=tree.z}, plant_id, minp, maxp, data, a, cid, nil, tree.snow ) -- no pseudorandom present + end + +end + + +-- repair mapgen griefings +mg_villages.repair_outer_shell = function( villages, minp, maxp, vm, data, param2_data, a, village_area, cid, edge_min, edge_max ) + -- find out if this part of the shell has already been generated or not + if( data[a:index(minp.x,minp.y,minp.z)] == cid.c_ignore + + and data[a:index(maxp.x,minp.y,minp.z)] == cid.c_ignore + and data[a:index(minp.x,maxp.y,minp.z)] == cid.c_ignore + and data[a:index(minp.x,minp.y,maxp.z)] == cid.c_ignore + + and data[a:index(maxp.x,maxp.y,maxp.z)] == cid.c_ignore + + and data[a:index(maxp.x,maxp.y,minp.z)] == cid.c_ignore + and data[a:index(maxp.x,minp.y,maxp.z)] == cid.c_ignore + and data[a:index(minp.x,maxp.y,maxp.z)] == cid.c_ignore ) then + + -- no - none of the edges has been created yet; no point to place anything there + return; + end + + if( minp.x < edge_min.x ) then + edge_min.x = minp.x; + end + if( minp.y < edge_min.y ) then + edge_min.y = minp.y; + end + if( minp.z < edge_min.z ) then + edge_min.z = minp.z; + end + if( maxp.x > edge_max.x ) then + edge_max.x = maxp.x; + end + if( maxp.y > edge_max.y ) then + edge_max.y = maxp.y; + end + if( maxp.z > edge_max.z ) then + edge_max.z = maxp.z; + end + + + for z = minp.z, maxp.z do + for x = minp.x, maxp.x do + -- inside a village + if( village_area[ x ][ z ][ 2 ] > 0 ) then + local y; + local village = villages[ village_area[ x ][ z ][ 1 ]]; + -- the current node at the ground + local node = data[a:index(x,village.vh,z)]; + -- there ought to be something - but there is air + if( village and village.vh and (node==cid.c_air or node==cid.c_water)) then + y = village.vh-1; + -- search from village height downards for holes generated by cavegen and fill them up + while( y > minp.y ) do + local ci = data[a:index(x, y, z)]; + if( ci == cid.c_desert_stone or ci == cid.c_desert_sand ) then + data[a:index(x, village.vh, z)] = cid.c_desert_sand; + y = minp.y-1; + elseif( ci == cid.c_sand ) then + data[a:index(x, village.vh, z)] = cid.c_sand; + y = minp.y-1; + -- use dirt_with_grass as a fallback + elseif( ci ~= cid.c_air and ci ~= cid.c_ignore and ci ~= cid.c_water and mg_villages.check_if_ground( ci ) == true) then + data[a:index(x, village.vh, z)] = cid.c_dirt_with_grass; + y = minp.y-1; + -- abort the search - there is no data available yet + elseif( ci == cid.c_ignore ) then + y = minp.y-1; + end + y = y-1; + end + end + + -- remove mudflow + y = village.vh + 1; + while( y <= maxp.y ) do + local ci = data[a:index(x, y, z)]; + if( ci ~= cid.c_ignore and (ci==cid.c_dirt or ci==cid.c_dirt_with_grass or ci==cid.c_sand or ci==cid.c_desert_sand)) then + data[a:index(x,y,z)] = cid.c_air; + -- if there was a moresnow cover, add a snow on top of the new floor node + elseif( ci ~= cid.c_ignore + and (ci==cid.c_msnow_1 or ci==cid.c_msnow_2 or ci==cid.c_msnow_3 or ci==cid.c_msnow_4 or + ci==cid.c_msnow_5 or ci==cid.c_msnow_6 or ci==cid.c_msnow_7 or ci==cid.c_msnow_8 or + ci==cid.c_msnow_9 or ci==cid.c_msnow_10 or ci==cid.c_msnow_11)) then + data[a:index(x, village.vh+1, z)] = cid.c_snow; + data[a:index(x, village.vh, z)] = cid.c_dirt_with_snow; + elseif( ci == cid.c_ignore ) then + --data[a:index(x,y,z)] = cid.c_air; + end + y = y+1; + end + end + end + end +end + + + +-- helper functions for mg_villages.place_villages_via_voxelmanip +-- this one marks the positions of buildings plus a frame around them +mg_villages.village_area_mark_buildings = function( village_area, village_nr, bpos) + + -- mark the roads and buildings and the area between buildings in the village_area table + -- 2: road + -- 3: border around a road + -- 4: building + -- 5: border around a building + for _, pos in ipairs( bpos ) do + local reserved_for = 4; -- a building will be placed here + if( pos.btype and pos.btype == 'road' ) then + reserved_for = 2; -- the building will be a road + end + -- the building + a border of 1 around it + for x = -1, pos.bsizex do + for z = -1, pos.bsizez do + local p = {x=pos.x+x, z=pos.z+z}; + if( not( village_area[ p.x ] )) then + village_area[ p.x ] = {}; + end + if( x==-1 or z==-1 or x==pos.bsizex or z==pos.bsizez ) then + village_area[ p.x ][ p.z ] = { village_nr, reserved_for+1}; -- border around a building + else + village_area[ p.x ][ p.z ] = { village_nr, reserved_for }; -- the actual building + end + end + end + end +end + +mg_villages.village_area_mark_dirt_roads = function( village_area, village_nr, dirt_roads ) + -- mark the dirt roads + -- 8: dirt road + for _, pos in ipairs(dirt_roads) do + -- the building + a border of 1 around it + for x = 0, pos.bsizex-1 do + for z = 0, pos.bsizez-1 do + local p = {x=pos.x+x, z=pos.z+z}; + if( not( village_area[ p.x ] )) then + village_area[ p.x ] = {}; + end + village_area[ p.x ][ p.z ] = { village_nr, 8 }; -- the actual dirt road + end + end + end +end + +mg_villages.village_area_mark_inside_village_area = function( village_area, villages, village_noise, minp, maxp ) + -- mark the rest ( inside_village but not part of an actual building) as well + for x = minp.x, maxp.x do + if( not( village_area[ x ] )) then + village_area[ x ] = {}; + end + for z = minp.z, maxp.z do + if( not( village_area[ x ][ z ] )) then + village_area[ x ][ z ] = { 0, 0 }; + + local n_rawnoise = village_noise:get2d({x = x, y = z}) -- create new blended terrain + for village_nr, village in ipairs(villages) do + local vn = mg_villages.get_vn(x, z, n_rawnoise, village); + if( village.is_single_house ) then + -- do nothing here; the village area will be specificly marked later on + + -- the village core; this is where the houses stand (but there's no house or road at this particular spot) + elseif( vn <= 40 ) then -- see mg_villages.inside_village + village_area[ x ][ z ] = { village_nr, 6}; + + -- the flattened land around the village where wheat, cotton, trees or grass may be grown (depending on village type) + elseif( vn <= 80 ) then -- see mg_villages.inside_village_area + village_area[ x ][ z ] = { village_nr, 1}; + + -- terrain blending for the flattened land + elseif( vn <= 160 and mg_villages.ENABLE_TERRAIN_BLEND) then -- see mg_villages.inside_village_terrain_blend_area + if n_rawnoise > -0.5 then -- leave some cliffs unblended + local blend = (( vn - 80) / 80) ^ 2 -- 0 at village edge, 1 at normal terrain + -- assign a negative value to terrain that needs to be adjusted in height + village_area[ x ][ z ] = { village_nr, -1 * blend}; + else + -- no height adjustments for this terrain; the terrain is not considered to be part of the village + village_area[ x ][ z ] = { village_nr, 0}; + end + end + end + end + end + end + + -- single houses get their own form of terrain blend + local pr = PseudoRandom(mg_villages.get_bseed(minp)); + for village_nr, village in ipairs( villages ) do + if( village and village.is_single_house and village.to_add_data and village.to_add_data.bpos and #village.to_add_data.bpos>=1) then + mg_villages.village_area_mark_single_house_area( village_area, minp, maxp, village.to_add_data.bpos[1], pr, village_nr, village ); + end + end +end + + +-- analyzes optimal height for villages which have their center inside this mapchunk +mg_villages.village_area_get_height = function( village_area, villages, minp, maxp, data, param2_data, a, cid ) +-- figuring out the height this way hardly works - because only a tiny part of the village may be contained in this chunk + local height_sum = {}; + local height_count = {}; + local height_statistic = {}; + -- initialize the variables for counting + for village_nr, village in ipairs( villages ) do + height_sum[ village_nr ] = 0; + height_count[ village_nr ] = 0; + height_statistic[ village_nr ] = {}; + end + -- try to find the optimal village height by looking at the borders defined by inside_village + for x = minp.x+1, maxp.x-1 do + for z = minp.z+1, maxp.z-1 do + if( village_area[ x ][ z ][ 1 ] ~= 0 + and village_area[ x ][ z ][ 2 ] ~= 0 + and ( village_area[ x+1 ][ z ][ 2 ] <= 0 + or village_area[ x-1 ][ z ][ 2 ] <= 0 + or village_area[ x ][ z+1 ][ 2 ] <= 0 + or village_area[ x ][ z-1 ][ 2 ] <= 0 ) + -- if the corners of the mapblock are inside the village area, they may count as borders here as well + or ( x==minp.x+1 and village_area[ x-1 ][ z ][ 1 ] >= 0 ) + or ( x==maxp.x-1 and village_area[ x+1 ][ z ][ 1 ] >= 0 ) + or ( z==minp.z-1 and village_area[ x ][ z-1 ][ 1 ] >= 0 ) + or ( z==maxp.z+1 and village_area[ x ][ z+1 ][ 1 ] >= 0 )) then + + local y = maxp.y; + while( y > minp.y and y >= 0) do + local ci = data[a:index(x, y, z)]; + if(( ci ~= cid.c_air and ci ~= cid.c_ignore and mg_villages.check_if_ground( ci ) == true) or (y==0)) then + local village_nr = village_area[ x ][ z ][ 1 ]; + if( village_nr > 0 and height_sum[ village_nr ] ) then + height_sum[ village_nr ] = height_sum[ village_nr ] + y; + height_count[ village_nr ] = height_count[ village_nr ] + 1; + + if( not( height_statistic[ village_nr ][ y ] )) then + height_statistic[ village_nr ][ y ] = 1; + else + height_statistic[ village_nr ][ y ] = height_statistic[ village_nr ][ y ] + 1; + end + end + y = minp.y - 1; + end + y = y-1; + end + end + end + end + for village_nr, village in ipairs( villages ) do + + local tmin = maxp.y; + local tmax = minp.y; + local topt = 2; + for k,v in pairs( height_statistic[ village_nr ] ) do + if( k >= 2 and k < tmin and k >= minp.y) then + tmin = k; + end + if( k <= maxp.y and k > tmax ) then + tmax = k; + end + if( height_statistic[ village_nr ][ topt ] + and height_statistic[ village_nr ][ topt ] < height_statistic[ village_nr ][ k ]) then + topt = k; + end + end + --print('HEIGHT for village '..tostring( village.name )..' min:'..tostring( tmin )..' max:'..tostring(tmax)..' opt:'..tostring(topt)..' count:'..tostring( height_count[ village_nr ])); + + -- the very first village gets a height of 1 + if( village.nr and village.nr == 1 ) then + village.optimal_height = 1; + end + + if( village.optimal_height ) then + -- villages above a size of 40 are *always* place at a convenient height of 1 + elseif( village.vs >= 40 and not(village.is_single_house)) then + village.optimal_height = 2; + elseif( village.vs >= 30 and not(village.is_single_house)) then + village.optimal_height = 41 - village.vs; + elseif( village.vs >= 25 and not(village.is_single_house)) then + village.optimal_height = 36 - village.vs; + + -- in some cases, choose that height which was counted most often + elseif( topt and (tmax - tmin ) > 8 and height_count[ village_nr ] > 0) then + + local qmw; + if( ( tmax - topt ) > ( topt - tmin )) then + qmw = tmax; + else + qmw = tmin; + end + village.optimal_height = qmw; + + -- if no border height was found, there'd be no point in calculating anything; + -- also, this is done only if the village has its center inside this mapchunk + elseif( height_count[ village_nr ] > 0 ) then + + local max = 0; + local target = village.vh; + local qmw = 0; + for k, v in pairs( height_statistic[ village_nr ] ) do + qmw = qmw + v * (k*k ); + if( v > max ) then + target = k; + max = v; + end + end + if( height_count[ village_nr ] > 5 ) then + qmw = math.floor( math.sqrt( qmw / height_count[ village_nr ]) +1.5); -- round the value + -- a height of 0 would be one below water level; so let's choose something higher; + -- as this may be an island created withhin deep ocean, it might look better if it extends a bit from said ocean + if( qmw < 1 ) then + qmw = 2; + end + else + qmw = 0; -- if in doubt, a height of 0 usually works well + end + + village.optimal_height = qmw; + end + end +end + + + +mg_villages.change_village_height = function( village, new_height ) + mg_villages.print( mg_villages.DEBUG_LEVEL_TIMING, 'CHANGING HEIGHT from '..tostring( village.vh )..' to '..tostring( new_height )); + for _, pos in ipairs(village.to_add_data.bpos) do + pos.y = new_height; + end + for _, pos in ipairs(village.to_add_data.dirt_roads) do + pos.y = new_height; + end + village.vh = new_height; +end + + +-- those functions from the mg mod do not have their own namespace +if( minetest.get_modpath( 'mg' )) then + mg_villages.add_savannatree = add_savannatree; + mg_villages.add_pinetree = add_pinetree; +end + +mg_villages.grow_a_tree = function( pos, plant_id, minp, maxp, data, a, cid, pr, snow ) + -- a normal tree; sometimes comes with apples + if( plant_id == cid.c_sapling and minetest.registered_nodes[ 'default:tree']) then + mg_villages.grow_tree( data, a, pos, math.random(1, 4) == 1, math.random(1,100000), snow) + return true; + -- a normal jungletree + elseif( plant_id == cid.c_jsapling and minetest.registered_nodes[ 'default:jungletree']) then + mg_villages.grow_jungletree( data, a, pos, math.random(1,100000), snow) + return true; + -- a pine tree + elseif( plant_id == cid.c_psapling and minetest.registered_nodes[ 'default:pine_tree']) then + mg_villages.grow_pinetree( data, a, pos, snow); + return true; + -- an acacia tree; it does not have its own grow function + elseif( plant_id == cid.c_asapling and minetest.registered_nodes[ 'default:acacia_tree']) then + data[ a:index( pos.x, pos.y, pos.z )] = cid.c_asapling; + return true; + -- a savannatree from the mg mod + elseif( plant_id == cid.c_savannasapling and mg_villages.add_savannatree) then + mg_villages.add_savannatree( data, a, pos.x, pos.y, pos.z, minp, maxp, pr) -- TODO: snow + return true; + -- a pine tree from the mg mod + elseif( plant_id == cid.c_pinesapling and mg_villages.add_pinetree ) then + mg_villages.add_pinetree( data, a, pos.x, pos.y, pos.z, minp, maxp, pr) -- TODO: snow + return true; + end + return false; +end + +-- +-- places trees and plants at empty spaces +mg_villages.village_area_fill_with_plants = function( village_area, villages, minp, maxp, data, param2_data, a, cid ) + -- do not place any plants if we are working on the mapchunk above + if( minp.y > 0 ) then + return; + end + -- trees which require grow functions to be called + cid.c_savannasapling = minetest.get_content_id( 'mg:savannasapling'); + cid.c_pinesapling = minetest.get_content_id( 'mg:pinesapling'); + -- add farmland + cid.c_wheat = minetest.get_content_id( 'farming:wheat_8' ); + cid.c_cotton = minetest.get_content_id( 'farming:cotton_8' ); + cid.c_shrub = minetest.get_content_id( 'default:dry_shrub'); + -- these extra nodes are used in order to avoid abms on the huge fields around the villages + cid.c_soil_wet = minetest.get_content_id( 'mg_villages:soil' ); --'farming:soil_wet' ); + cid.c_soil_sand = minetest.get_content_id( 'mg_villages:desert_sand_soil'); --'farming:desert_sand_soil_wet' ); + -- desert sand soil is only available in minetest_next + if( not( cid.c_soil_sand )) then + cid.c_soil_sand = cid.c_soil_wet; + end + local c_feldweg = minetest.get_content_id( 'cottages:feldweg'); + if( not( c_feldweg )) then + c_feldweg = cid.c_dirt_with_grass; + end + + if( mg_villages.realtest_trees ) then + cid.c_soil_wet = minetest.get_content_id( 'farming:soil' ); -- TODO: the one from mg_villages would be better...but that one lacks textures + cid.c_soil_sand = minetest.get_content_id( 'farming:soil' ); -- TODO: the one from mg_villages would be better...but that one lacks textures + cid.c_wheat = minetest.get_content_id( 'farming:spelt_4' ); + cid.c_cotton = minetest.get_content_id( 'farming:flax_4' ); +-- cid.c_shrub = minetest.get_content_id( 'default:dry_shrub'); + end + + local pr = PseudoRandom(mg_villages.get_bseed(minp)); + for x = minp.x, maxp.x do + for z = minp.z, maxp.z do + -- turn unused land (which is either dirt or desert sand) into a field that grows wheat + if( village_area[ x ][ z ][ 2 ]==1 + or village_area[ x ][ z ][ 2 ]==6) then + + local village_nr = village_area[ x ][ z ][ 1 ]; + local village = villages[ village_nr ]; + local h = village.vh; + local g = data[a:index( x, h, z )]; + + -- choose a plant/tree with a certain chance + -- Note: There are no checks weather the tree/plant will actually grow there or not; + -- Tree type is derived from wood type used in the village + local plant_id = data[a:index( x, h+1, z)]; + local on_soil = false; + local plant_selected = false; + local has_snow_cover = false; + + ------ + for _,v in ipairs( village.to_add_data.plantlist ) do + if( plant_id == cid.c_snow or g==cid.c_dirt_with_snow or g==cid.c_snowblock) then + has_snow_cover = true; + end + -- select the first plant that fits; if the node is not air, keep what is currently inside + if( (plant_id==cid.c_air or plant_id==cid.c_snow) and (( v.p == 1 or pr:next( 1, v.p )==1 ))) then + -- TODO: check if the plant grows on that soil + plant_id = v.id; + plant_selected = true; + end + -- wheat and cotton require soil + if( plant_id == cid.c_wheat or plant_id == cid.c_shrub ) then + on_soil = true; + end + end +--------- + local pos = {x=x, y=h+1, z=z}; + if( not( plant_selected )) then -- in case there is something there already (usually a tree trunk) + has_snow_cover = nil; + + elseif( mg_villages.grow_a_tree( pos, plant_id, minp, maxp, data, a, cid, pr, has_snow_cover )) then + param2_data[a:index( x, h+1, z)] = 0; -- make sure the tree trunk is not rotated + has_snow_cover = nil; -- else the sapling might not grow + -- nothing to do; the function has grown the tree already + + -- grow wheat and cotton on normal wet soil (and re-plant if it had been removed by mudslide) + elseif( on_soil and (g==cid.c_dirt_with_grass or g==cid.c_soil_wet or g==cid.c_dirt_with_snow)) then + param2_data[a:index( x, h+1, z)] = math.random( 1, 179 ); + data[a:index( x, h, z)] = cid.c_soil_wet; + -- no plants in winter + if( has_snow_cover and mg_villages.use_soil_snow) then + data[a:index( x, h+1, z)] = cid.c_msnow_soil; + has_snow_cover = nil; + else + data[a:index( x, h+1, z)] = plant_id; + end + + -- grow wheat and cotton on desert sand soil - or on soil previously placed (before mudslide overflew it; same as above) + elseif( on_soil and (g==cid.c_desert_sand or g==cid.c_soil_sand) and cid.c_soil_sand and cid.c_soil_sand > 0) then + param2_data[a:index( x, h+1, z)] = math.random( 1, 179 ); + data[a:index( x, h, z)] = cid.c_soil_sand; + -- no plants in winter + if( has_snow_cover and mg_villages.use_soil_snow) then + data[a:index( x, h+1, z)] = cid.c_msnow_soil; + has_snow_cover = nil; + else + data[a:index( x, h+1, z)] = plant_id; + end + + elseif( on_soil ) then + if( math.random(1,5)==1 ) then + data[a:index( pos.x, pos.y, pos.z)] = cid.c_shrub; + end + + elseif( plant_id ) then -- place the sapling or plant (moretrees uses spawn_tree) + data[a:index( pos.x, pos.y, pos.z)] = plant_id; + end + + -- put a snow cover on plants where needed +-- if( has_snow_cover and cid.c_msnow_1 ~= cid.c_ignore) then +-- data[a:index( x, h+2, z)] = cid.c_msnow_1; +-- end + end + end + end +end + +-- + + +time_elapsed = function( t_last, msg ) + mg_villages.t_now = minetest.get_us_time(); + mg_villages.print( mg_villages.DEBUG_LEVEL_TIMING, 'TIME ELAPSED: '..tostring( mg_villages.t_now - t_last )..' '..msg ); + return mg_villages.t_now; +end + + +mg_villages.save_data = function() + save_restore.save_data( 'mg_all_villages.data', mg_villages.all_villages ); +end + + +mg_villages.place_villages_via_voxelmanip = function( villages, minp, maxp, vm, data, param2_data, a, top, seed ) + local t1 = minetest.get_us_time(); + + local cid = {} + cid.c_air = minetest.get_content_id( 'air' ); + cid.c_ignore = minetest.get_content_id( 'ignore' ); + cid.c_stone = minetest.get_content_id( 'default:stone'); + cid.c_dirt = minetest.get_content_id( 'default:dry_dirt'); + cid.c_snow = minetest.get_content_id( 'default:inv'); + cid.c_snowblock = minetest.get_content_id( 'default:snowblock'); + cid.c_dirt_with_snow = minetest.get_content_id( 'default:dry_dirt' ); + cid.c_dirt_with_grass = minetest.get_content_id( 'default:dirt_with_dry_grass' ); + cid.c_desert_sand = minetest.get_content_id( 'default:desert_sand' ); -- PM v + cid.c_desert_stone = minetest.get_content_id( 'default:desert_stone'); + cid.c_sand = minetest.get_content_id( 'default:sand' ); + cid.c_tree = minetest.get_content_id( 'default:tree'); + cid.c_sapling = minetest.get_content_id( 'default:sapling'); + cid.c_jtree = minetest.get_content_id( 'default:jungletree'); + cid.c_jsapling = minetest.get_content_id( 'default:junglesapling'); + cid.c_ptree = minetest.get_content_id( 'default:pine_tree'); + cid.c_psapling = minetest.get_content_id( 'default:pine_sapling'); + cid.c_atree = minetest.get_content_id( 'default:acacia_tree'); + cid.c_asapling = minetest.get_content_id( 'default:acacia_sapling'); + cid.c_water = minetest.get_content_id( 'default:mud'); -- PM ^ + cid.c_stone_with_coal = minetest.get_content_id( 'default:stone_with_coal'); + cid.c_sandstone = minetest.get_content_id( 'default:sandstone'); + + cid.c_msnow_1 = minetest.get_content_id( 'moresnow:snow_top' ); + cid.c_msnow_2 = minetest.get_content_id( 'moresnow:snow_fence_top'); + cid.c_msnow_3 = minetest.get_content_id( 'moresnow:snow_stair_top'); + cid.c_msnow_4 = minetest.get_content_id( 'moresnow:snow_slab_top'); + cid.c_msnow_5 = minetest.get_content_id( 'moresnow:snow_panel_top'); + cid.c_msnow_6 = minetest.get_content_id( 'moresnow:snow_micro_top'); + cid.c_msnow_7 = minetest.get_content_id( 'moresnow:snow_outer_stair_top'); + cid.c_msnow_8 = minetest.get_content_id( 'moresnow:snow_inner_stair_top'); + cid.c_msnow_9 = minetest.get_content_id( 'moresnow:snow_ramp_top'); + cid.c_msnow_10 = minetest.get_content_id( 'moresnow:snow_ramp_outer_top'); + cid.c_msnow_11 = minetest.get_content_id( 'moresnow:snow_ramp_inner_top'); + cid.c_msnow_soil=minetest.get_content_id( 'moresnow:snow_soil' ); + + cid.c_ice = minetest.get_content_id( 'default:ice' ); + + cid.c_plotmarker = minetest.get_content_id( 'mg_villages:plotmarker'); + + if( minetest.get_modpath('ethereal')) then + cid.c_ethereal_clay_red = minetest.get_content_id( 'bakedclay:red' ); + cid.c_ethereal_clay_orange = minetest.get_content_id( 'bakedclay:orange' ); + end + + + t1 = time_elapsed( t1, 'defines' ); + + local village_noise = minetest.get_perlin(7635, 3, 0.5, 16); + + -- determine which coordinates are inside the village and which are not + local village_area = {}; + + for village_nr, village in ipairs(villages) do + -- generate the village structure: determine positions of buildings and roads + mg_villages.generate_village( village, village_noise); + + if( not( village.is_single_house )) then + -- only add artificial snow if the village has at least a size of 15 (else it might look too artificial) + if( not( village.artificial_snow ) and village.vs > 1500) then + if( mg_villages.artificial_snow_probability and math.random( 1, mg_villages.artificial_snow_probability )==1 + -- forbid artificial snow for some village types + and not( mg_villages.village_type_data[ village.village_type ].no_snow ) + and minetest.registered_nodes['default:snow']) then + village.artificial_snow = 1; + else + village.artificial_snow = 0; + end + end + + -- will set village_area to N where .. is: + -- 2: a building + -- 3: border around a building + -- 4: a road + -- 5: border around a road + mg_villages.village_area_mark_buildings( village_area, village_nr, village.to_add_data.bpos ); + -- will set village_area to N where .. is: + -- 8: a dirt road + mg_villages.village_area_mark_dirt_roads( village_area, village_nr, village.to_add_data.dirt_roads ); + else -- mark the terrain below single houses + mg_villages.village_area_mark_buildings( village_area, village_nr, village.to_add_data.bpos ); + end + end + t1 = time_elapsed( t1, 'generate_village, mark_buildings and mark_dirt_roads' ); + + local emin; + local emax; + -- if no voxelmanip data was passed on, read the data here + if( not( vm ) or not( a) or not( data ) or not( param2_data ) ) then + vm, emin, emax = minetest.get_mapgen_object("voxelmanip") + if( not( vm )) then + return; + end + + a = VoxelArea:new{ + MinEdge={x=emin.x, y=emin.y, z=emin.z}, + MaxEdge={x=emax.x, y=emax.y, z=emax.z}, + } + + data = vm:get_data() + param2_data = vm:get_param2_data() + end + t1 = time_elapsed( t1, 'get_vmap_data' ); + + -- all vm manipulation functions write their content to the *entire* volume/area - including those 16 nodes that + -- extend into neighbouring mapchunks; thus, cavegen griefing and mudflow can be repaired by placing everythiing again + local tmin = emin; + local tmax = emax; + -- if set to true, cavegen eating through houses and mudflow on roofs will NOT be repaired + if( not( mg_villages.UNDO_CAVEGEN_AND_MUDFLOW )) then + tmin = minp; + tmax = maxp; + end + -- will set village_area to N where .. is: + -- 0: not part of any village + -- 1: flattened area around the village; plants (wheat, cotton, trees, grass, ...) may be planted here + -- 6: free/unused spot in the core area of the village where the buildings are + -- negative value: do terrain blending + mg_villages.village_area_mark_inside_village_area( village_area, villages, village_noise, tmin, tmax ); + t1 = time_elapsed( t1, 'mark_inside_village_area' ); + + -- determine optimal height for all villages that have their center in this mapchunk; sets village.optimal_height + t1 = time_elapsed( t1, 'get_height' ); + + mg_villages.village_area_get_height( village_area, villages, tmin, tmax, data, param2_data, a, cid ); + -- the villages in the first mapchunk are set to a fixed height of 1 so that players will not end up embedded in stone + if( not( mg_villages.all_villages ) or mg_villages.anz_villages < 1 ) then + villages[1].optimal_height = 1; + end + + + -- change height of those villages where an optimal_height could be determined + local village_data_updated = false; + for _,village in ipairs(villages) do + if( village.optimal_height and village.optimal_height > 0 and village.optimal_height ~= village.vh ) then + -- towers are usually found on elevated places + if( village.village_type == 'tower' ) then + village.optimal_height = village.optimal_height + math.max( math.floor(village.vs/2), 2 ); + end + mg_villages.change_village_height( village, village.optimal_height ); + village_data_updated = true; + end + end + t1 = time_elapsed( t1, 'change_height' ); + + --mg_villages.flatten_village_area( villages, minp, maxp, vm, data, param2_data, a, village_area, cid ); + mg_villages.flatten_village_area( villages, tmin, tmax, vm, data, param2_data, a, village_area, cid ); + t1 = time_elapsed( t1, 'flatten_village_area' ); + -- repair cavegen griefings and mudflow which may have happened in the outer shell (which is part of other mapnodes) + local e1 = {x=minp.x,y=minp.y,z=minp.z}; + local e2 = {x=maxp.x,y=maxp.y,z=maxp.z}; + mg_villages.repair_outer_shell( villages, {x=tmin.x, y=tmin.y,z=tmin.z}, {x=tmin.x+16, y=tmax.y, z=tmax.z}, vm, data, param2_data, a, village_area, cid, e1, e2 ); + mg_villages.repair_outer_shell( villages, {x=tmax.x-16,y=tmin.y,z=tmin.z}, {x=tmax.x, y=tmax.y, z=tmax.z}, vm, data, param2_data, a, village_area, cid, e1, e2 ); + mg_villages.repair_outer_shell( villages, {x=tmin.x+16,y=tmin.y,z=tmin.z}, {x=tmax.x-16, y=tmax.y, z=tmin.z+16}, vm, data, param2_data, a, village_area, cid, e1, e2 ); + mg_villages.repair_outer_shell( villages, {x=tmin.x+16,y=tmin.y,z=tmax.z-16}, {x=tmax.x-16, y=tmax.y, z=tmax.z}, vm, data, param2_data, a, village_area, cid, e1, e2 ); +-- mg_villages.repair_outer_shell( villages, tmin, tmax, vm, data, param2_data, a, village_area, cid ); + + t1 = time_elapsed( t1, 'repair_outer_shell' ); + + local c_feldweg = minetest.get_content_id('cottages:feldweg'); + if( not( c_feldweg )) then + c_feldweg = minetest.get_content_id('default:cobble'); + end + + for _, village in ipairs(villages) do + + -- the village_id will be stored in the plot markers + local village_id = tostring( village.vx )..':'..tostring( village.vz ); + village.anz_buildings = mg_villages.count_inhabitated_buildings(village); + village.to_add_data = handle_schematics.place_buildings( village, tmin, tmax, data, param2_data, a, cid, village_id); + + handle_schematics.place_dirt_roads( village, tmin, tmax, data, param2_data, a, c_feldweg); + + -- grow trees which are part of buildings into saplings + for _,v in ipairs( village.to_add_data.extra_calls.trees ) do + mg_villages.grow_a_tree( v, v.typ, minp, maxp, data, a, cid, nil, v.snow ); -- TODO: supply pseudorandom value? + end + end + t1 = time_elapsed( t1, 'place_buildings and place_dirt_roads' ); +----------------------------------------- + + + + + + +------------------------------------- + mg_villages.village_area_fill_with_plants( village_area, villages, tmin, tmax, data, param2_data, a, cid ); + t1 = time_elapsed( t1, 'fill_with_plants' ); +----------------------------------------------- +------------------------------------------------ + if( mg_villages.CREATE_HIGHLANDPOOLS ) then + mg_villages.do_highlandpools(minp, maxp, seed, vm, a, data, village_area); + end + t1 = time_elapsed( t1, 'create highlandpools' ); + + vm:set_data(data) + vm:set_param2_data(param2_data) + t1 = time_elapsed( t1, 'vm data set' ); + + -- only update lighting where we actually placed the nodes + vm:calc_lighting( e1, e2 ); --minp, maxp ); --tmin, tmax) + t1 = time_elapsed( t1, 'vm calc lighting' ); + + vm:write_to_map(data) + t1 = time_elapsed( t1, 'vm data written' ); + + vm:update_liquids() + t1 = time_elapsed( t1, 'vm update liquids' ); + + -- do on_construct calls AFTER the map data has been written - else i.e. realtest fences can not update themshevles + for _, village in ipairs(villages) do + for k, v in pairs( village.to_add_data.extra_calls.on_constr ) do + local node_name = minetest.get_name_from_content_id( k ); + if( minetest.registered_nodes[ node_name ].on_construct ) then + for _, pos in ipairs(v) do + minetest.registered_nodes[ node_name ].on_construct( pos ); + end + end + end + end + + local pr = PseudoRandom(mg_villages.get_bseed(minp)); + for _, village in ipairs(villages) do + for _,v in ipairs( village.to_add_data.extra_calls.chests ) do + local building_nr = village.to_add_data.bpos[ v.bpos_i ]; + local building_typ = mg_villages.BUILDINGS[ building_nr.btype ].scm; + mg_villages.fill_chest_random( v, pr, building_nr, building_typ ); + end + end + -- TODO: extra_calls.signs + + + -- useful for spawning mobs etc. + for _, village in ipairs(villages) do + mg_villages.part_of_village_spawned( village, minp, maxp, data, param2_data, a, cid ); + end + + -- initialize the pseudo random generator so that the chests will be filled in a reproducable pattern + local meta + for _, village in ipairs(villages) do + -- now add those buildings which are .mts files and need to be placed by minetest.place_schematic(...) + -- place_schematics is no longer needed + --mg_villages.place_schematics( village.to_add_data.bpos, village.to_add_data.replacements, a, pr ); + --t1 = time_elapsed( t1, 'place_schematics' ); + + if( not( mg_villages.all_villages )) then + mg_villages.all_villages = {}; + end + -- unique id - there can only be one village at a given pair of x,z coordinates + local village_id = tostring( village.vx )..':'..tostring( village.vz ); + -- the village data is saved only once per village - and not whenever part of the village is generated + if( not( mg_villages.all_villages[ village_id ])) then + + -- count how many villages we already have and assign each village a uniq number + local count = 1; + for _,v in pairs( mg_villages.all_villages ) do + count = count + 1; + end + village.extra_calls = {}; -- do not save these values + village.nr = count; + mg_villages.anz_villages = count; + mg_villages.all_villages[ village_id ] = minetest.deserialize( minetest.serialize( village )); + + mg_villages.print( mg_villages.DEBUG_LEVEL_NORMAL, "Village No. "..tostring( count ).." of type \'".. + tostring( village.village_type ).."\' of size "..tostring( village.vs ).. + " spawned at: x = "..village.vx..", z = "..village.vz) + village_data_updated = true; + + -- hook for doing stuff that needs to be done exactly once per village + mg_villages.new_village_spawned( village_id ); + end + end + -- always save the changed village data + t1 = time_elapsed( t1, 'update village data' ); + mg_villages.save_data(); + t1 = time_elapsed( t1, 'save village data' ); + +end + + +--minetest.set_gen_notify('dungeon, temple, cave_begin, cave_end, large_cave_begin, large_cave_end',{}); + + +-- the actual mapgen +-- It only does changes if there is at least one village in the area that is to be generated. +minetest.register_on_generated(function(minp, maxp, seed) +-- this is just for learning more about dungeons and caves; it is not used anywhere here +-- local structures = minetest.get_mapgen_object('gennotify'); +-- print('STRUCTURES BY MAPGEN: '..minetest.serialize( structures )); + + -- only generate village on the surface chunks + if( minp.y < -32 or minp.y > mg_villages.MAX_HEIGHT_TREATED) then --64 + return; + end + + -- this function has to be called ONCE and AFTER all village types and buildings have been added + -- (which might have been done by other mods so we can't do this earlier) + if( not( mg_villages.village_types )) then + mg_villages.init_weights(); + end + + + local villages = {}; + -- create normal villages + if( mg_villages.ENABLE_VILLAGES == true ) then + villages = mg_villages.villages_in_mapchunk( minp, maxp.x-minp.x+1 ); + end + + -- if this mapchunk contains no part of a village, probably a lone building may be found in it + if( mg_villages.INVERSE_HOUSE_DENSITY > 0 ) then + villages = mg_villages.houses_in_mapchunk( minp, maxp.x-minp.x+1, villages ); + end + + -- check if the village exists already + local v_nr = 1; + for v_nr, village in ipairs(villages) do + local village_id = tostring( village.vx )..':'..tostring( village.vz ); + + if( not( village.name ) or village.name == '') then + village.name = 'unknown'; + end + + if( mg_villages.all_villages and mg_villages.all_villages[ village_id ]) then + villages[ v_nr ] = mg_villages.all_villages[ village_id ]; + end + end + + if( villages and #villages > 0 ) then + mg_villages.place_villages_via_voxelmanip( villages, minp, maxp, nil, nil, nil, nil, nil, seed ); + end +end) + + diff --git a/mods/a_mapgen_mods/mg_villages/name_gen.lua b/mods/a_mapgen_mods/mg_villages/name_gen.lua new file mode 100644 index 00000000..9833d20d --- /dev/null +++ b/mods/a_mapgen_mods/mg_villages/name_gen.lua @@ -0,0 +1,90 @@ + +namegen = {}; + +namegen.prefixes = {'ac','ast','lang','pen','shep','ship'} +namegen.suffixes = {'beck','ey','ay','bury','burgh','brough','by','by','caster', + 'cester','cum','den','don','field','firth','ford','ham','ham','ham', + 'hope','ing','kirk','hill','law','leigh','mouth','ness','pool','shaw', + 'stead','ster','tun','ton','ton','ton','ton','wold','worth','worthy', + 'ville','river','forrest','lake'} + +-- people/environmental features + + + + + +namegen.silben = { 'a', 'an', 'ab', 'ac', 'am', + 'be', 'ba', 'bi', 'bl', 'bm', 'bn', 'bo', 'br', 'bst', 'bu', + 'ca', 'ce', 'ch', 'ci', 'ck', 'cl', 'cm', 'cn', 'co', 'cv', + 'da', 'de', 'df', 'di', 'dl', 'dm', 'dn', 'do', 'dr', 'ds', 'dt', 'du', 'dv', + 'do','ren','nav','ben','ada','min','org','san','pa','re','ne','en','er','ich', + 'the','and','tha','ent','ing','ion','tio','for','nde', + 'has','nce','edt','tis','oft','sth','mem', + 'ich','ein','und','der','nde','sch','die','den','end','cht', + 'the','and','tha','ent','ing','ion','for','de', + 'has','ce','ed','is','ft','sth','mem', + 'ch','ei','un','der','ie','den','end', + 'do','ren','nav','ben','ada','min','org','san','pa','re','ne','en','er','ich', + 'ta','bek','nik','le','lan','nem', + 'bal','cir','da','en','fan','fir','fern','fa','oak','nut','gen','ga','hu','hi','hal', + 'in','ig','ir','im','ja','je','jo','kla','kon','ker','log','lag','leg','lil', + 'lon','las','leve','lere','mes','mir','mon','mm','mer','mig', + 'na','nn','nerv','neu','oto','on','opt','oll','ome','ott', + 'pen','par','pi','pa','po','pel','pig','qu','ren','rig','raf','res','ring', + 'rib','rast','rost','ru','rum','rem','sem','sim','su','spring', + 'cotton','cot','wood','palm', + 'do','na','ik','ke','gen','bra','bn','lla','lle','st','aa','kir', + 'nn','en','fo','fn','gi','ja','jn','ke','kr','kon','lis','on','ok','or','op', + 'pp','p','qu','re','ra','rn','ri','so','sn','se','ti','tu', + 'a','e','i','o','u', + 're','ro','pe','pn','ci','co','cl', + 'no','en','wi','we','er','en','ba','ki','nn','va','wu','x','tel','or', + 'so','me','mi','em','en','eg','ge','kn'}; + + +namegen.generate_village_name = function( pr ) + local anz_silben = pr:next(2,5); + local name = ''; + local prefix = ''; + local postfix = ''; + if( pr:next(1,8)==1) then + prefix = namegen.prefixes[ #namegen.prefixes ]; + anz_silben = anz_silben -1; + end + if( pr:next(1,4)==1) then + postfix = name..namegen.suffixes[ #namegen.suffixes ]; + anz_silben = anz_silben -2; + end + if( anz_silben < 2 ) then + anz_silben = 2; + end + for i = 1, anz_silben do + name = name..namegen.silben[ pr:next( 1, #namegen.silben )]; + end + name = prefix..name..postfix; + name = string.upper( string.sub( name, 1, 1 ) )..string.sub( name, 2 ); + return name; +end + + +namegen.generate_village_name_with_prefix = function( pr, village ) + + local name = namegen.generate_village_name( pr ); + + -- if a village consists of a single house, it gets a prefix depending on the house type + if( village.is_single_house and village.to_add_data and village.to_add_data.bpos ) then + -- the building got removed from mg_villages.BUILDINGS in the meantime + if( not( mg_villages.BUILDINGS[ village.to_add_data.bpos[1].btype] )) then + return 'Abandomed building'; + end + local btyp = mg_villages.BUILDINGS[ village.to_add_data.bpos[1].btype].typ; + local bdata = mg_villages.village_type_data[ btyp ]; + if( bdata and (bdata.name_prefix or bdata.name_postfix )) then + name = (bdata.name_prefix or '')..name..(bdata.name_postfix or ''); + else + name = 'House '..name; + end + end + return name; +end diff --git a/mods/a_mapgen_mods/mg_villages/nodes.lua b/mods/a_mapgen_mods/mg_villages/nodes.lua new file mode 100644 index 00000000..de9e3ba3 --- /dev/null +++ b/mods/a_mapgen_mods/mg_villages/nodes.lua @@ -0,0 +1,142 @@ + +minetest.register_node("mg_villages:road", { + description = "village road", + tiles = {"default_gravel.png", "default_dirt.png"}, + is_ground_content = true, -- will be removed by the cave generator + groups = {crumbly=2, falling_node = 1}, -- does fall + sounds = default.node_sound_dirt_defaults({ + footstep = {name="default_gravel_footstep", gain=0.5}, + dug = {name="default_gravel_footstep", gain=1.0}, + }), + paramtype = "light", + paramtype2 = "facedir", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { { -0.5, -0.5, -0.5, 0.5, 0.5-2/16, 0.5}, }, + }, +}) + +mg_villages.road_node = minetest.get_content_id( 'mg_villages:road' ); +-- do not drop snow on roads +if( moresnow ) then + moresnow.snow_cover[ mg_villages.road_node ] = moresnow.c_air; +end + + +minetest.register_node("mg_villages:soil", { + description = "Soil found on a field", + tiles = {"es_mud.png^farming_soil_wet.png", "es_mud.png"}, + drop = "es:mud", + is_ground_content = true, + groups = {crumbly=3, not_in_creative_inventory=1, grassland = 1}, + sounds = default.node_sound_dirt_defaults(), +}) + +minetest.register_node("mg_villages:desert_sand_soil", { + description = "Desert Sand", + tiles = {"default_desert_sand.png^farming_soil_wet.png", "default_desert_sand.png"}, + is_ground_content = true, + drop = "default:desert_sand", + groups = {crumbly=3, not_in_creative_inventory = 1, sand=1, desert = 1}, + sounds = default.node_sound_sand_defaults(), +}) + + +-- This torch is not hot. It will not melt snow and cause no floodings in villages. +minetest.register_node("mg_villages:torch", { + description = "Torch-air", + drawtype = "torchlike", + --tiles = {"default_torch_on_floor.png", "default_torch_on_ceiling.png", "default_torch.png"}, + tiles = {"default_invis.png"}, + inventory_image = "default_torch_on_floor.png", + wield_image = "default_torch_on_floor.png", + paramtype = "light", + paramtype2 = "wallmounted", + sunlight_propagates = true, + is_ground_content = false, + walkable = false, + --light_source = LIGHT_MAX-1, + selection_box = { + type = "wallmounted", + wall_top = {-0.1, 0.5-0.6, -0.1, 0.1, 0.5, 0.1}, + wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1}, + wall_side = {-0.5, -0.3, -0.1, -0.5+0.3, 0.3, 0.1}, + }, + groups = {choppy=2,dig_immediate=3,flammable=1,attached_node=1}, + legacy_wallmounted = true, + sounds = default.node_sound_defaults(), + drop = "default:torch", +}) + + +minetest.register_node("mg_villages:plotmarker", { + description = "Plot marker", + drawtype = "nodebox", + tiles = {"default_stone_brick.png"}, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5+2/16, -0.5, -0.5+2/16, 0.5-2/16, -0.5+3/16, 0.5-2/16}, + }, + }, + groups = {cracky=3,stone=2}, + + on_rightclick = function( pos, node, clicker, itemstack, pointed_thing) + return mg_villages.plotmarker_formspec( pos, nil, {}, clicker ) + end, + + on_receive_fields = function(pos, formname, fields, sender) + return mg_villages.plotmarker_formspec( pos, formname, fields, sender ); + end, + + -- protect against digging + can_dig = function( pos, player ) + local meta = minetest.get_meta( pos ); + if( meta and meta:get_string( 'village_id' )~='' and meta:get_int( 'plot_nr' ) and meta:get_int( 'plot_nr' )>0) then + return false; + end + return true; + end +}) + + +-- default to safe lava +if( not( mg_villages.use_normal_unsafe_lava )) then + local lava = minetest.registered_nodes[ "default:lava_source"]; + if( lava ) then + -- a deep copy for the table would be more helpful...but, well, ... + local new_def = minetest.deserialize( minetest.serialize( lava )); + -- this lava does not cause fire to spread + new_def.name = nil; + new_def.groups.lava = nil; + new_def.groups.hot = nil; + new_def.groups.igniter = nil; + new_def.groups.lava_tamed = 3; + new_def.description = "Lava Source (tame)"; + new_def.liquid_alternative_flowing = "mg_villages:lava_flowing_tamed"; + new_def.liquid_alternative_source = "mg_villages:lava_source_tamed"; + -- we create a NEW type of lava for this + minetest.register_node( "mg_villages:lava_source_tamed", new_def ); + end + + -- take care of the flowing variant as well + lava = minetest.registered_nodes[ "default:lava_flowing"]; + if( lava ) then + -- a deep copy for the table would be more helpful...but, well, ... + local new_def = minetest.deserialize( minetest.serialize( lava )); + -- this lava does not cause fire to spread + new_def.name = nil; + new_def.groups.lava = nil; + new_def.groups.hot = nil; + new_def.groups.igniter = nil; + new_def.groups.lava_tamed = 3; + new_def.description = "Flowing Lava (tame)"; + new_def.liquid_alternative_flowing = "mg_villages:lava_flowing_tamed"; + new_def.liquid_alternative_source = "mg_villages:lava_source_tamed"; + -- and a NEW type of flowing lava... + minetest.register_node( "mg_villages:lava_flowing_tamed", new_def ); + end +end diff --git a/mods/a_mapgen_mods/mg_villages/protection.lua b/mods/a_mapgen_mods/mg_villages/protection.lua new file mode 100644 index 00000000..3feab501 --- /dev/null +++ b/mods/a_mapgen_mods/mg_villages/protection.lua @@ -0,0 +1,307 @@ +-- get the id of the village pos lies in (or nil if outside of villages) +mg_villages.get_town_id_at_pos = function( pos ) + for id, v in pairs( mg_villages.all_villages ) do + local size = v.vs * 3; + if( ( math.abs( pos.x - v.vx ) < size ) + and ( math.abs( pos.z - v.vz ) < size ) + and ( pos.y - v.vh < 40 and v.vh - pos.y < 10 )) then + local village_noise = minetest.get_perlin(7635, 3, 0.5, 16); + if( mg_villages.inside_village_area( pos.x, pos.z, v, village_noise)) then + + local node = minetest.get_node( pos ); + -- leaves can be digged in villages + if( node and node.name ) then + if( minetest.registered_nodes[ node.name ] + and minetest.registered_nodes[ node.name ].groups + and minetest.registered_nodes[ node.name ].groups.leaves ) then + return nil; + elseif( node.name=='default:snow' ) then + return nil; + -- bones can be digged in villages + elseif( node.name == 'bones:bones' ) then + return nil; + else + return id; + end + else + return id; + end + end + end + end + return nil; +end + +local old_is_protected = minetest.is_protected +minetest.is_protected = function(pos, name) + + if( not( mg_villages.ENABLE_PROTECTION )) then + return old_is_protected( pos, name ); + end + + local village_id = mg_villages.get_town_id_at_pos( pos ); + if( village_id ) then + local is_houseowner = false; + for nr, p in ipairs( mg_villages.all_villages[ village_id ].to_add_data.bpos ) do + + trustedusers = p.can_edit + trustedUser = false + if trustedusers ~= nil then + for _,trusted in ipairs(trustedusers) do + if trusted == name then + trustedUser = true + end + end + end + + -- we have located the right plot; the player can build here if he owns this particular plot + if( p.x <= pos.x and (p.x + p.bsizex) >= pos.x + and p.z <= pos.z and (p.z + p.bsizez) >= pos.z) then + + -- If player has been trusted by owner, can build + if (trustedUser) then + return false; + -- If player is owner, can build + elseif( p.owner and p.owner == name ) then + return false; + -- the allmende can be used by all + elseif( mg_villages.BUILDINGS[p.btype] and mg_villages.BUILDINGS[p.btype].typ=="allmende" ) then + return false; + -- the player cannot modify other plots, even though he may be house owner of another house and be allowed to modify common ground + else + return true; + end + -- if the player just owns another plot in the village, check if it's one where villagers may live + elseif( p.owner and p.owner == name or trustedUser) then + local btype = mg_villages.all_villages[ village_id ].to_add_data.bpos[ nr ].btype; + if( btype ~= 'road' + and mg_villages.BUILDINGS[btype] + and mg_villages.BUILDINGS[btype].inh + and mg_villages.BUILDINGS[btype].inh > 0 ) then + is_houseowner = true; + end + end + end + -- players who own a house in town where villagers may live (not only work!) + -- are allowed to modify common ground + if( is_houseowner ) then + return false; + end + return true; + end + return old_is_protected(pos, name); +end + + +minetest.register_on_protection_violation( function(pos, name) + + if( not( mg_villages.ENABLE_PROTECTION )) then + return; + end + + local found = mg_villages.get_town_id_at_pos( pos ); + if( not( found ) or not( mg_villages.all_villages[ found ])) then + minetest.chat_send_player( name, 'Error: This area does not belong to a village.'); + return; + end + + minetest.chat_send_player( name, "You are inside of the area of the village ".. + tostring( mg_villages.all_villages[ found ].name ).. + ". The inhabitants do not allow you any modifications."); +end ); + + + +mg_villages.plotmarker_formspec = function( pos, formname, fields, player ) + +-- if( not( mg_villages.ENABLE_PROTECTION )) then +-- return; +-- end + local meta = minetest.get_meta( pos ); + if( not( meta )) then + return; + end + local village_id = meta:get_string('village_id'); + local plot_nr = meta:get_int( 'plot_nr'); + local pname = player:get_player_name(); + + if( not( village_id ) + or not( mg_villages.all_villages ) + or not( mg_villages.all_villages[ village_id ] ) + or not( plot_nr ) + or not( mg_villages.all_villages[ village_id ].to_add_data.bpos[ plot_nr ] )) then + minetest.chat_send_player( pname, 'Error. This plot marker is not configured correctly.'..minetest.serialize({village_id,plot_nr })); + return; + end + + local owner = mg_villages.all_villages[ village_id ].to_add_data.bpos[ plot_nr ].owner; + local btype = mg_villages.all_villages[ village_id ].to_add_data.bpos[ plot_nr ].btype; + + --minetest.chat_send_player( player:get_player_name(),'DATA FOR '..tostring(plot_nr)..': '..minetest.serialize( mg_villages.all_villages[ village_id ].to_add_data.bpos[ plot_nr ] )); + local original_formspec = "size[8,3]".. + "label[1.0,0.5;Plot No.: "..tostring( plot_nr ).."]".. + "label[2.5,0.5;Building:]".. + "label[3.5,0.5;"..tostring( mg_villages.BUILDINGS[btype].scm ).."]".. + "field[20,20;0.1,0.1;pos2str;Pos;"..minetest.pos_to_string( pos ).."]"; + local formspec = ""; + local ifinhabit = ""; + + -- Get Price + local price = "default:gold_ingot 2"; + + if (btype ~= 'road' and mg_villages.BUILDINGS[btype]) then + local plot_descr = 'Plot No. '..tostring( plot_nr ).. ' with '..tostring( mg_villages.BUILDINGS[btype].scm) + + if (mg_villages.BUILDINGS[btype].price) then + price = mg_villages.BUILDINGS[btype].price; + elseif (mg_villages.BUILDINGS[btype].typ and mg_villages.prices[ mg_villages.BUILDINGS[btype].typ ]) then + price = mg_villages.prices[ mg_villages.BUILDINGS[btype].typ ]; + end + -- Get if is inhabitant house + if (mg_villages.BUILDINGS[btype].inh and mg_villages.BUILDINGS[btype].inh > 0 ) then + ifinhabit = "label[1,1.5;Owners of this plot count as village inhabitants.]"; + end + end + -- Determine price depending on building type + local price_stack= ItemStack( price ); + + + -- If nobody owns the plot + if (not(owner) or owner=='') then + + formspec = original_formspec .. + "label[1,1;You can buy this plot for]".. + "label[3.8,1;"..tostring( price_stack:get_count() ).." x ]".. + "item_image[4.3,0.8;1,1;"..( price_stack:get_name() ).."]".. + ifinhabit.. + "button[2,2.5;1.5,0.5;buy;Buy plot]".. + "button_exit[4,2.5;1.5,0.5;abort;Exit]"; + + -- On Press buy button + if (fields['buy']) then + local inv = player:get_inventory(); + + if not mg_villages.all_villages[village_id].ownerlist then + mg_villages.all_villages[village_id].ownerlist = {} + end + + -- Check if player already has a house in the village + if mg_villages.all_villages[village_id].ownerlist[pname] then + formspec = formspec.."label[1,1.9;Sorry. You already have a plot in this village.]"; + + -- Check if the price can be paid + elseif( inv and inv:contains_item( 'main', price_stack )) then + formspec = original_formspec.. + "label[1,1;Congratulations! You have bought this plot.]".. + "button_exit[5.75,2.5;1.5,0.5;abort;Exit]"; + mg_villages.all_villages[ village_id ].to_add_data.bpos[ plot_nr ].owner = pname; + if mg_villages.all_villages[village_id].ownerlist then + mg_villages.all_villages[village_id].ownerlist[pname] = true; + else + mg_villages.all_villages[village_id].ownerlist[pname] = true; + end + meta:set_string('infotext', 'Plot No. '..tostring( plot_nr ).. ' with '..tostring( mg_villages.BUILDINGS[btype].scm)..' (owned by '..tostring( pname )..')'); + -- save the data so that it survives server restart + mg_villages.save_data(); + -- substract the price from the players inventory + inv:remove_item( 'main', price_stack ); + else + formspec = formspec.."label[1,1.9;Sorry. You are not able to pay the price.]"; + end + end + + -- If player is the owner of the plot + elseif (owner==pname) then + + -- Check if inhabitant house + if(btype ~= 'road' + and mg_villages.BUILDINGS[btype] + and mg_villages.BUILDINGS[btype].inh + and mg_villages.BUILDINGS[btype].inh > 0 ) then + + ifinhabit = "label[1,1.5;You are allowed to modify the common village area.]"; + end + + formspec = original_formspec.."size[8,3]".. + "label[1,1;This is your plot. You have bought it.]".. + "button[0.75,2.5;3,0.5;add_remove;Add/Remove Players]".. + ifinhabit.. + "button_exit[3.75,2.5;2.0,0.5;abandon;Abandon plot]".. + "button_exit[5.75,2.5;1.5,0.5;abort;Exit]"; + + -- If Player wants to abandon plot + if(fields['abandon'] ) then + formspec = original_formspec.. + "label[1,1;You have abandoned this plot.]".. + "button_exit[5.75,2.5;1.5,0.5;abort;Exit]"; + mg_villages.all_villages[village_id].ownerlist[pname] = nil; + mg_villages.all_villages[ village_id ].to_add_data.bpos[ plot_nr ].can_edit = {} + mg_villages.all_villages[ village_id ].to_add_data.bpos[ plot_nr ].owner = nil; + -- Return price to player + local inv = player:get_inventory(); + inv:add_item( 'main', price_stack ); + meta:set_string('infotext', 'Plot No. '..tostring( plot_nr ).. ' with '..tostring( mg_villages.BUILDINGS[btype].scm) ); + mg_villages.save_data(); + end + + -- If Player wants to add/remove trusted players + if (fields['add_remove']) then + local previousTrustees = mg_villages.all_villages[ village_id ].to_add_data.bpos[ plot_nr ].can_edit + local output = ""; + if previousTrustees == nil then + previousTrustees = {} + else + for _, player in ipairs(previousTrustees) do + output = output..player.."\n" + end + end + formspec = "size[8,3]".. + "field[20,20;0.1,0.1;pos2str;Pos;"..minetest.pos_to_string( pos ).."]".. + "textarea[0.3,0.2;8,2.5;ownerplayers;Trusted Players;"..output.."]".. + "button[3.25,2.5;1.5,0.5;savetrustees;Save]"; + + mg_villages.save_data() + end + + -- Save trusted players + if (fields["savetrustees"] == "Save") then + + if not mg_villages.all_villages[ village_id ].to_add_data.bpos[ plot_nr ].can_edit then + mg_villages.all_villages[ village_id ].to_add_data.bpos[ plot_nr ].can_edit = {} + end + + local x = 1; + for _, player in ipairs(fields.ownerplayers:split("\n")) do + mg_villages.all_villages[ village_id ].to_add_data.bpos[ plot_nr ].can_edit[x] = player + x = x + 1 + end + + mg_villages.save_data(); + end + + -- If A different Player owns plot + else + formspec = original_formspec.."label[1,1;"..tostring( owner ).." owns this plot.]".. + "button_exit[3,2.5;1.5,0.5;abort;Exit]"; + end + + minetest.show_formspec( pname, "mg_villages:plotmarker", formspec ); +end + + + +mg_villages.form_input_handler = function( player, formname, fields) +-- mg_villages.print(mg_villages.DEBUG_LEVEL_NORMAL,minetest.serialize(fields)); + if( not( mg_villages.ENABLE_PROTECTION )) then + return false; + end + if( (formname == "mg_villages:plotmarker") and fields.pos2str and not( fields.abort )) then + local pos = minetest.string_to_pos( fields.pos2str ); + mg_villages.plotmarker_formspec( pos, formname, fields, player ); + return true; + end + return false; +end + + +minetest.register_on_player_receive_fields( mg_villages.form_input_handler ) diff --git a/mods/a_mapgen_mods/mg_villages/replacements.lua b/mods/a_mapgen_mods/mg_villages/replacements.lua new file mode 100644 index 00000000..6f5903c1 --- /dev/null +++ b/mods/a_mapgen_mods/mg_villages/replacements.lua @@ -0,0 +1,964 @@ + +-- ethereal comes with some intresting trees +if( minetest.get_modpath( 'ethereal' )) then + mg_villages.ethereal_trees = {'acacia','willow','redwood','frost','mushroom','yellow','palm','banana'}; +end + +if( minetest.get_modpath( 'forest' )) then + mg_villages.forest_trees = {'beech','birch','cherry','fir','ginkgo','lavender','mirabelle','oak','plum','willow'}; +end + +-- we are dealing with the TinyTrees mod from Bas080 +if( minetest.get_modpath( 'trees' ) + and minetest.registered_nodes[ 'trees:wood_mangrove' ] ) then + mg_villages.tinytrees_trees = {'mangrove','palm','conifer'}; +end + +-- The trees modname is not unique; there are other mods which bear that name. +-- If all the other mods are present as well, it's a strong indication for realtest beeing the game. +if( minetest.get_modpath( 'trees' ) + and minetest.get_modpath( 'anvil') + and minetest.get_modpath( 'joiner_table') + and minetest.get_modpath( 'scribing_table' )) then + mg_villages.realtest_trees = {'ash','aspen','birch','maple','chestnut','pine','spruce'}; + --print('REALTEST trees will be used.'); else print( 'NO REALTEST trees'); + + -- realtest is very special as far as stairs are concerned + mg_villages.realtest_stairs = {'default:stone','default:stone_flat','default:stone_bricks', + 'default:desert_stone_flat','default:desert_stone_bricks'}; + for i,v in ipairs(metals.list) do + table.insert( mg_villages.realtest_stairs, 'metals:'..v..'_block' ); + end + -- the list of minteral names is local; so we can't add "decorations:"..mineral[1].."_block" +end + + +-- only the function mg_villages.get_replacement_table(..) is called from outside this file + +mg_villages.replace_materials = function( replacements, pr, original_materials, prefixes, materials, old_material ) + + local postfixes = {}; + local use_realtest_stairs = false; + -- handle realtest stairs/slabs + if( mg_villages.realtest_trees + and #prefixes==3 + and prefixes[1]=='stairs:stair_' and prefixes[2]=='stairs:slab_' and prefixes[3]=='default:' ) then + + prefixes = {''}; + materials = mg_villages.realtest_stairs; + postfixes = {''}; + use_realtest_stairs = true; + + elseif( mg_villages.realtest_trees + and #prefixes==1 + and prefixes[1]=='stairs:stair_') then + + return; + else + for i,v in ipairs( prefixes ) do + postfixes[i] = ''; + end + end + + local known_materials = {}; + local wood_found = false; + -- for all alternate materials + for i,m in ipairs( materials ) do + -- check if that material exists for each supplied prefix + for j,p in ipairs( prefixes ) do + -- if wood is present, later on try moretrees wood as well + if( 'default:wood' == m ) then + wood_found = true; + end + if( minetest.registered_nodes[ p..m..postfixes[j] ] ) then + table.insert( known_materials, m..postfixes[j] ); + end + end + end + + -- support wooden planks from moretrees + if( wood_found and mg_villages.moretrees_treelist ) then + for _,v in ipairs( mg_villages.moretrees_treelist ) do + if( minetest.registered_nodes[ "moretrees:"..v[1].."_planks"] ) then + table.insert( known_materials, "moretrees:"..v[1].."_planks" ); + end + end + end + +--[[ + -- deco is used by BigFreakingDig; as that one lacks default nodes, it doesn't work out here + if( wood_found and minetest.get_modpath('deco')) then + local bfd_treelist = {'birch', 'cherry', 'evergreen', 'oak' }; + for _,v in ipairs( bfd_treelist ) do + if( minetest.registered_nodes[ "deco:"..v.."_plank"] ) then + table.insert( known_materials, "deco:"..v.."_plank" ); + end + end + end +--]] + + if( wood_found and mg_villages.ethereal_trees ) then + for _,v in ipairs( mg_villages.ethereal_trees ) do + -- mushroom in ethereal is a pretty decorative material; increase its probability + if( v == 'mushroom' ) then + table.insert( known_materials, "ethereal:mushroom_pore" ); + table.insert( known_materials, "ethereal:mushroom_pore" ); + table.insert( known_materials, "ethereal:mushroom_pore" ); + -- also increase probability for the decorative blueish wood + table.insert( known_materials, "ethereal:frost_wood" ); + table.insert( known_materials, "ethereal:frost_wood" ); + elseif( minetest.registered_nodes[ "ethereal:"..v.."_wood"] ) then + table.insert( known_materials, "ethereal:"..v.."_wood" ); + end + end + end + + if( wood_found and mg_villages.forest_trees ) then + for _,v in ipairs( mg_villages.forest_trees ) do + if( minetest.registered_nodes[ 'forest:'..v..'_wood'] ) then + table.insert( known_materials, 'forest:'..v..'_wood' ); + end + end + end + + if( wood_found and mg_villages.tinytrees_trees ) then + for _,v in ipairs( mg_villages.tinytrees_trees ) do + if( minetest.registered_nodes[ 'trees:wood_'..v] ) then + table.insert( known_materials, 'trees:wood_'..v ); + end + end + end + + if( wood_found and mg_villages.realtest_trees ) then + for _,v in ipairs( mg_villages.realtest_trees ) do + if( minetest.registered_nodes[ 'trees:'..v..'_planks'] ) then + table.insert( known_materials, 'trees:'..v..'_planks' ); + end + end + end + + + -- nothing found which could be used + if( #known_materials < 1 ) then + return; + end + local new_material = known_materials[ pr:next( 1, #known_materials )]; + + if( use_realtest_stairs == true ) then + table.insert( replacements, { original_materials[ 1 ], new_material..'_stair' } ); + table.insert( replacements, { original_materials[ 2 ], new_material..'_slab' } ); + table.insert( replacements, { original_materials[ 3 ], new_material } ); + table.insert( replacements, { original_materials[ 1 ]..'upside_down', new_material..'_stair_upside_down' } ); + table.insert( replacements, { original_materials[ 2 ]..'upside_down', new_material..'_slab_upside_down' } ); + return new_material; + end + + -- no replacement necessary if we did choose the same material as before + if( new_material == old_material or old_material == (prefixes[1]..new_material)) then + return old_material; + end + + for i,v in ipairs( prefixes ) do + table.insert( replacements, { original_materials[ i ], v..new_material } ); + end + return new_material; +end + +-- replace the tree trunk as well so that it fits to the wood type +mg_villages.replace_tree_trunk = function( replacements, wood_type ) + if( wood_type == 'default:junglewood' ) then + table.insert( replacements, {'default:tree', 'default:jungletree'}); + elseif( wood_type == 'default:pine_wood' ) then + table.insert( replacements, {'default:tree', 'default:pine_tree'}); + elseif( wood_type == 'default:acacia_wood' ) then + table.insert( replacements, {'default:tree', 'default:acacia_tree'}); + elseif( wood_type == 'mg:savannawood' ) then + table.insert( replacements, {'default:tree', 'mg:savannatree'}); + elseif( wood_type == 'mg:pinewood' ) then + table.insert( replacements, {'default:tree', 'mg:pinetree'}); + + elseif( mg_villages.moretrees_treelist ) then + for _,v in ipairs( mg_villages.moretrees_treelist ) do + if( wood_type == "moretrees:"..v[1].."_planks" ) then + table.insert( replacements, {'default:tree', "moretrees:"..v[1].."_trunk"}); + table.insert( replacements, {'default:leaves', "moretrees:"..v[1].."_leaves"}); + end + end + + elseif( wood_type == 'deco:birch_plank' ) then + table.insert( replacements, {'default:tree', "mapgen:birch_log"}); + elseif( wood_type == 'deco:cherry_plank' ) then + table.insert( replacements, {'default:tree', "mapgen:cherry_log"}); + elseif( wood_type == 'deco:evergreen_plank' ) then + table.insert( replacements, {'default:tree', "mapgen:evergreen_log"}); + elseif( wood_type == 'deco:oak_plank' ) then + table.insert( replacements, {'default:tree', "mapgen:oak_log"}); + + elseif( wood_type == 'ethereal:frost_wood' ) then + table.insert( replacements, {'default:tree', "ethereal:frost_tree"}); + + elseif( wood_type == "ethereal:mushroom_pore" ) then + table.insert( replacements, {'default:tree', "ethereal:mushroom_trunk"}); + + elseif( mg_villages.ethereal_trees ) then + for _,v in ipairs( mg_villages.ethereal_trees ) do + if( wood_type == "ethereal:"..v.."_wood" ) then + table.insert( replacements, {'default:tree', "ethereal:"..v.."_trunk"}); + end + end + + elseif( mg_villages.forest_trees ) then + for _,v in ipairs( mg_villages.forest_trees ) do + if( wood_type == "forest:"..v.."_wood" ) then + table.insert( replacements, {'default:tree', "forest:"..v.."_tree"}); + end + end + + elseif( mg_villages.tinytrees_trees ) then + for _,v in ipairs( mg_villages.tinytrees_trees ) do + if( wood_type == "trees:wood_"..v ) then + table.insert( replacements, {'default:tree', "trees:tree_"..v}); + end + end + + elseif( mg_villages.realtest_trees ) then + for _,v in ipairs( mg_villages.realtest_trees ) do + if( wood_type == 'trees:'..v..'_planks' ) then + table.insert( replacements, {'default:tree', "trees:"..v..'_log'}); + -- realtest does not have most of the nodes from default, so we need to replace them as well + table.insert( replacements, {'default:wood', 'trees:'..v..'_planks'}); + table.insert( replacements, {'default:leaves', 'trees:'..v..'_leaves'}); + table.insert( replacements, {'default:ladder', 'trees:'..v..'_ladder'}); + table.insert( replacements, {'default:chest', 'trees:'..v..'_chest'}); + table.insert( replacements, {'default:chest_locked', 'trees:'..v..'_chest_locked'}); + table.insert( replacements, {'default:fence_wood', 'fences:'..v..'_fence'}); + table.insert( replacements, {'default:bookshelf', 'decorations:bookshelf_'..v}); + table.insert( replacements, {'doors:door_wood_t_1', 'doors:door_'..v..'_t_1'}); + table.insert( replacements, {'doors:door_wood_b_1', 'doors:door_'..v..'_b_1'}); + table.insert( replacements, {'doors:door_wood_t_2', 'doors:door_'..v..'_t_2'}); + table.insert( replacements, {'doors:door_wood_b_2', 'doors:door_'..v..'_b_2'}); + -- not really wood-realted, but needs to be replaced as well + table.insert( replacements, {'default:furnace', 'oven:oven'}); + -- farming is also handled diffrently + table.insert( replacements, {'farming:soil_wet', 'farming:soil'}); + table.insert( replacements, {'farming:cotton_1', 'farming:flax_1'}); + table.insert( replacements, {'farming:cotton_2', 'farming:flax_1'}); + table.insert( replacements, {'farming:cotton_3', 'farming:flax_2'}); + table.insert( replacements, {'farming:cotton_4', 'farming:flax_2'}); + table.insert( replacements, {'farming:cotton_5', 'farming:flax_3'}); + table.insert( replacements, {'farming:cotton_6', 'farming:flax_3'}); + table.insert( replacements, {'farming:cotton_7', 'farming:flax_4'}); + table.insert( replacements, {'farming:cotton_8', 'farming:flax_4'}); + -- stairs and slabs made out of default wood + table.insert( replacements, {'stairs:stair_wood', 'trees:'..v..'_planks_stair'}); + table.insert( replacements, {'stairs:slab_wood', 'trees:'..v..'_planks_slab'}); + table.insert( replacements, {'stairs:stair_woodupside_down','trees:'..v..'_planks_stair_upside_down' } ); + table.insert( replacements, {'stairs:slab_woodupside_down', 'trees:'..v..'_planks_slab_upside_down' } ); + end + end + else + return nil; + end + return wood_type; +-- TODO if minetest.get_modpath("moreblocks") and moretrees.enable_stairsplus the +end + + +-- if buildings are made out of a certain wood type, people might expect trees of that type nearby +mg_villages.replace_saplings = function( replacements, wood_type ) + if( wood_type == 'default:junglewood' ) then + table.insert( replacements, {'default:sapling', 'default:junglesapling'}); + elseif( wood_type == 'default:pine_wood' ) then + table.insert( replacements, {'default:sapling', 'default:pine_sapling'}); + elseif( wood_type == 'default:acacia_wood' ) then + table.insert( replacements, {'default:sapling', 'default:acacia_sapling'}); + elseif( wood_type == 'mg:savannawood' ) then + table.insert( replacements, {'default:sapling', 'mg:savannasapling'}); + elseif( wood_type == 'mg:pinewood' ) then + table.insert( replacements, {'default:sapling', 'mg:pinesapling'}); + elseif( mg_villages.moretrees_treelist ) then + for _,v in ipairs( mg_villages.moretrees_treelist ) do + if( wood_type == "moretrees:"..v[1].."_planks" ) then + table.insert( replacements, {'default:sapling', "moretrees:"..v[1].."_sapling_ongen"}); + end + end + elseif( mg_villages.ethereal_trees ) then + for _,v in ipairs( mg_villages.ethereal_trees ) do + if( wood_type == "ethereal:"..v.."_wood" ) then + table.insert( replacements, {'default:sapling', "ethereal:"..v.."_sapling"}); + end + end + + elseif( mg_villages.forest_trees ) then + for _,v in ipairs( mg_villages.forest_trees ) do + if( wood_type == "forest:"..v.."_wood" ) then + table.insert( replacements, {'default:sapling', "forest:"..v.."_sapling"}); + end + end + + elseif( mg_villages.tinytrees_trees ) then + for _,v in ipairs( mg_villages.tinytrees_trees ) do + if( wood_type == "trees:wood_"..v ) then + table.insert( replacements, {'default:sapling', "trees:sapling_"..v}); + end + + end + elseif( mg_villages.realtest_trees ) then + for _,v in ipairs( mg_villages.realtest_trees ) do + if( wood_type == 'trees:'..v..'_planks' ) then + table.insert( replacements, {'default:sapling', "trees:"..v.."_sapling"}); + table.insert( replacements, {'default:junglesapling', "trees:"..v.."_sapling"}); + table.insert( replacements, {'default:pine_sapling', "trees:"..v.."_sapling"}); + end + end + + elseif( wood_type == 'deco:birch_plank' ) then + table.insert( replacements, {'default:sapling', "mapgen:birch_sapling"}); + elseif( wood_type == 'deco:cherry_plank' ) then + table.insert( replacements, {'default:sapling', "mapgen:cherry_sapling"}); + elseif( wood_type == 'deco:evergreen_plank' ) then + table.insert( replacements, {'default:sapling', "mapgen:evergreen_sapling"}); + elseif( wood_type == 'deco:oak_plank' ) then + table.insert( replacements, {'default:sapling', "mapgen:oak_sapling"}); + end +end + + +-- Note: This function is taken from the villages mod (by Sokomine) +-- at least the cottages may come in a variety of building materials +-- IMPORTANT: don't add any nodes which have on_construct here UNLESS they where in the original file already +-- on_construct will only be called for known nodes that need that treatment (see villages.analyze_mts_file and on_constr) +mg_villages.get_replacement_list = function( housetype, pr ) + + local replacements = {}; + + -- else some grass would never (re)grow (if it's below a roof) +-- table.insert( replacements, {'default:dirt', dirt_with_grass_replacement }); +-- table.insert( replacements, {'default:dirt_with_grass', dirt_with_grass_replacement }); + table.insert( replacements, {'default:dirt', 'default:dirt_with_grass' }); + + -- realtest lacks quite a lot from default + if( mg_villages.realtest_trees ) then + for i=1,8 do + table.insert( replacements, {'farming:wheat_'..i, 'farming:spelt_'..tostring( (i+(i%2))/2) }); + table.insert( replacements, {'farming:cotton_'..i, 'farming:flax_' ..tostring( (i+(i%2))/2) }); + end + for i=1,5 do + table.insert( replacements, {'default:grass_'..i, 'air' }); + end + table.insert( replacements, {'default:apple', 'air' }); + table.insert( replacements, {'default:cobble', 'default:stone_macadam' }); + table.insert( replacements, {'default:obsidian_glass', 'default:glass' }); + end + + if( housetype and mg_villages.village_type_data[ housetype ] and mg_villages.village_type_data[ housetype ].replacement_function ) then + return mg_villages.village_type_data[ housetype ].replacement_function( housetype, pr, replacements ); + end + return replacements; +end + + + +-- Taokis houses from structure i/o +mg_villages.replacements_taoki = function( housetype, pr, replacements ) + local wood_type = 'default:wood'; + + if( mg_villages.realtest_trees ) then + wood_type = mg_villages.replace_materials( replacements, pr, + {'default:wood'}, + {''}, + {'default:wood'}, + 'default:wood'); + table.insert( replacements, {'stairs:stair_cobble', 'default:stone_bricks_stair' }); + table.insert( replacements, {'stairs:slab_cobble', 'default:stone_bricks_slab' }); + table.insert( replacements, {'stairs:stair_stone', 'default:stone_flat_stair' }); + table.insert( replacements, {'stairs:slab_stone', 'default:stone_flat_slab' }); + else + -- the main body of the houses in the .mts files is made out of wood + wood_type = mg_villages.replace_materials( replacements, pr, + {'default:wood'}, + {''}, + {'default:wood', 'default:junglewood', 'default:pine_wood', 'default:acacia_wood', 'mg:pinewood', 'mg:savannawood', + 'default:clay', 'default:brick', 'default:sandstone', + 'default:stonebrick', 'default:desert_stonebrick','default:sandstonebrick', 'default:sandstone','default:stone','default:desert_stone', + 'default:coalblock','default:steelblock','default:goldblock', 'default:bronzeblock', 'default:copperblock', 'wool:white', + 'default:stone_flat', 'default:desert_stone_flat', -- realtest + 'darkage:adobe', 'darkage:basalt', 'darkage:basalt_cobble', 'darkage:chalk', + 'darkage:gneiss', 'darkage:gneiss_cobble', 'darkage:marble', 'darkage:marble_tile', + 'darkage:mud', 'darkage:ors', 'darkage:ors_cobble', + 'darkage:schist', 'darkage:serpentine', 'darkage:shale', 'darkage:silt', 'darkage:slate', + 'mapgen:mese_stone', 'mapgen:soap_stone'}, + 'default:wood'); + end + -- tree trunks are seldom used in these houses; let's change them anyway + mg_villages.replace_tree_trunk( replacements, wood_type ); + + -- all this comes in variants for stairs and slabs as well + mg_villages.replace_materials( replacements, pr, + {'stairs:stair_stonebrick', 'stairs:slab_stonebrick', 'default:stonebrick'}, + {'stairs:stair_', 'stairs:slab_', 'default:' }, + { 'stonebrick', 'stone', 'sandstone', 'cobble'}, + 'stonebrick'); + + -- decorative slabs above doors etc. + mg_villages.replace_materials( replacements, pr, + {'stairs:stair_wood'}, + {'stairs:stair_'}, + {'stonebrick', 'stone', 'sandstone', 'cobble', 'wood', 'junglewood', 'pine_wood', 'acaica_wood' }, + 'wood'); + + -- brick roofs are a bit odd; but then... + -- all three shapes of roof parts have to fit together + mg_villages.replace_materials( replacements, pr, + {'stairs:stair_brick', 'stairs:slab_brick', 'default:brick'}, + {'stairs:stair_', 'stairs:slab_', 'default:' }, + { 'brick', 'stone', 'cobble', 'stonebrick', 'wood', 'junglewood', 'pine_wood', 'acacia_wood', 'sandstone' }, + 'brick' ); + + return replacements; + end + + +mg_villages.replacements_nore = function( housetype, pr, replacements ) + + mg_villages.replace_materials( replacements, pr, +-- {'default:stonebrick'}, +-- {'default:'}, + {'stairs:stair_stonebrick', 'stairs:slab_stonebrick', 'default:stonebrick'}, + {'stairs:stair_', 'stairs:slab_', 'default:' }, + {'stonebrick', 'desert_stonebrick','sandstonebrick', 'sandstone','stone','desert_stone','stone_flat','desert_stone_flat','stone_bricks','desert_strone_bricks'}, + 'stonebrick'); + + -- replace the wood as well + local wood_type = mg_villages.replace_materials( replacements, pr, + {'default:wood'}, + {''}, + { 'default:wood', 'default:junglewood', 'default:pine_wood', 'default:acacia_wood', 'mg:savannawood', 'mg:pinewood' }, + 'default:wood'); + mg_villages.replace_tree_trunk( replacements, wood_type ); + mg_villages.replace_saplings( replacements, wood_type ); + + if( pr:next(1,3)==1 and not( mg_villages.realtest_trees)) then + table.insert( replacements, {'default:glass', 'default:obsidian_glass'}); + end + + if( mg_villages.realtest_trees ) then + table.insert( replacements, {'stairs:stair_cobble', 'default:stone_bricks_stair' }); + table.insert( replacements, {'stairs:slab_cobble', 'default:stone_bricks_slab' }); + end + return replacements; +end + + +mg_villages.replacements_lumberjack = function( housetype, pr, replacements ) + -- replace the wood - those are lumberjacks after all + local wood_type = mg_villages.replace_materials( replacements, pr, + {'default:wood'}, + {''}, + { 'default:wood', 'default:junglewood', 'default:pine_wood', 'default:acacia_wood', 'mg:savannawood', 'mg:pinewood' }, + 'default:wood'); + mg_villages.replace_tree_trunk( replacements, wood_type ); + mg_villages.replace_saplings( replacements, wood_type ); + + if( not( minetest.get_modpath('bell' ))) then + table.insert( replacements, {'bell:bell', 'default:goldblock' }); + end + if( mg_villages.realtest_trees ) then + table.insert( replacements, {'stairs:stair_cobble', 'default:stone_bricks_stair' }); + table.insert( replacements, {'stairs:slab_cobble', 'default:stone_bricks_slab' }); + end + return replacements; +end + + +mg_villages.replacements_logcabin = function( housetype, pr, replacements ) + + -- for logcabins, wood is the most likely type of roof material + local roof_type = mg_villages.replace_materials( replacements, pr, + {'stairs:stair_cobble', 'stairs:slab_cobble' }, + {'cottages:roof_connector_', 'cottages:roof_flat_' }, + {'straw', 'wood', 'wood', 'wood', 'reet', 'slate', 'red', 'brown', 'black'}, + '' ); + -- some houses have junglewood roofs + if( roof_type ) then + table.insert( replacements, {'stairs:stair_junglewood', 'cottages:roof_connector_'..roof_type }); + table.insert( replacements, {'stairs:slab_junglewood', 'cottages:roof_flat_'..roof_type }); + table.insert( replacements, {'cottages:roof_connector_wood', 'cottages:roof_connector_'..roof_type }); + table.insert( replacements, {'cottages:roof_flat_wood', 'cottages:roof_flat_'..roof_type }); + -- realtest does not have normal stairs + elseif( mg_villages.realtest_trees ) then + table.insert( replacements, {'stairs:stair_junglewood', 'trees:aspen_planks_stair' }); + table.insert( replacements, {'stairs:slab_junglewood', 'trees:aspen_planks_slab' }); + end + + if( mg_villages.realtest_trees ) then + local wood_type = mg_villages.replace_materials( replacements, pr, + {'default:wood'}, + {''}, + { 'default:wood' }, + 'default:wood'); + mg_villages.replace_tree_trunk( replacements, wood_type ); + mg_villages.replace_saplings( replacements, wood_type ); + table.insert( replacements, {'default:stonebrick', 'default:stone_bricks' }); -- used for chimneys + table.insert( replacements, {'stairs:stair_stonebrick', 'default:stone_bricks_stair' }); + -- table.insert( replacements, {'default:junglewood', wood_type }); -- replace the floor + -- replace the floor with another type of wood (looks better than the same type as above) + mg_villages.replace_materials( replacements, pr, + {'default:junglewood'}, + {''}, + { 'default:wood' }, + 'default:junglewood'); + end + return replacements; +end + + +mg_villages.replacements_chateau = function( housetype, pr, replacements ) + + if( minetest.get_modpath( 'cottages' )) then + -- straw is the most likely building material for roofs for historical buildings + mg_villages.replace_materials( replacements, pr, + -- all three shapes of roof parts have to fit together + { 'cottages:roof_straw', 'cottages:roof_connector_straw', 'cottages:roof_flat_straw' }, + { 'cottages:roof_', 'cottages:roof_connector_', 'cottages:roof_flat_'}, + {'straw', 'straw', 'straw', 'straw', 'straw', + 'reet', 'reet', 'reet', + 'slate', 'slate', + 'wood', 'wood', + 'red', + 'brown', + 'black'}, + 'straw'); + else + mg_villages.replace_materials( replacements, pr, + -- all three shapes of roof parts have to fit together + { 'cottages:roof_straw', 'cottages:roof_connector_straw', 'cottages:roof_flat_straw' }, + { 'stairs:stair_', 'stairs:stair_', 'stairs:slab_'}, + {'cobble', 'stonebrick', 'desert_cobble', 'desert_stonebrick', 'stone'}, + 'stonebrick'); + table.insert( replacements, { 'cottages:glass_pane', 'default:glass' }); + end + + + local wood_type = mg_villages.replace_materials( replacements, pr, + {'default:wood'}, + {''}, + { 'default:wood', 'default:junglewood', 'default:pine_wood', 'default:acacia_wood', 'mg:savannawood', 'mg:pinewood'}, --, 'default:brick', 'default:sandstone', 'default:desert_cobble' }, + 'default:wood'); + mg_villages.replace_tree_trunk( replacements, wood_type ); + mg_villages.replace_saplings( replacements, wood_type ); + + + if( mg_villages.realtest_trees ) then + -- replace the floor with another type of wood (looks better than the same type as above) + mg_villages.replace_materials( replacements, pr, + {'stairs:stair_junglewood', 'stairs:slab_junglewood', 'default:junglewood'}, + {'stairs:stair_', 'stairs:slab_', 'default:' }, + { 'default:wood' }, + 'wood' ); + end + + + local mfs2 = mg_villages.replace_materials( replacements, pr, + {'stairs:stair_cobble', 'stairs:slab_cobble', 'default:cobble'}, + {'stairs:stair_', 'stairs:slab_', 'default:' }, + { 'cobble', 'brick', 'clay', 'desert_cobble', 'desert_stone', 'desert_stonebrick', 'loam', 'sandstone', 'sandstonebrick', 'stonebrick' }, + 'cobble'); + + return replacements; +end + + +mg_villages.replacements_tent = function( housetype, pr, replacements ) + table.insert( replacements, { "glasspanes:wool_pane", "cottages:wool_tent" }); + table.insert( replacements, { "default:gravel", "default:sand" }); + -- realtest needs diffrent fence posts and doors + if( mg_villages.realtest_trees ) then + local wood_type = mg_villages.replace_materials( replacements, pr, + {'default:wood'}, + {''}, + { 'default:wood' }, + 'default:wood'); + mg_villages.replace_tree_trunk( replacements, wood_type ); + mg_villages.replace_saplings( replacements, wood_type ); + end + return replacements; +end + + +mg_villages.replacements_grasshut = function( housetype, pr, replacements ) + table.insert( replacements, {'moreblocks:fence_jungle_wood', 'default:fence' }); + if( pr:next( 1, 4) == 1 ) then + table.insert( replacements, {'dryplants:reed_roof', 'cottages:roof_straw'}); + table.insert( replacements, {'dryplants:reed_slab', 'cottages:roof_flat_straw' }); + table.insert( replacements, {'dryplants:wetreed_roof', 'cottages:roof_reet' }); + table.insert( replacements, {'dryplants:wetreed_slab', 'cottages:roof_flat_reet' }); + else -- replace the straw and cobble one of the huts uses + table.insert( replacements, {'cottages:straw', 'dryplants:wetreed' }); + table.insert( replacements, {'stairs:slab_cobble', 'dryplants:reed_slab' }); + end + if( pr:next( 1, 4) == 1 ) then + table.insert( replacements, {'dryplants:wetreed_roof_corner', 'default:wood' }); + table.insert( replacements, {'dryplants:wetreed_roof_corner_2', 'default:junglewood' }); + end + if( not( minetest.get_modpath( 'cavestuff' ))) then + table.insert( replacements, {'cavestuff:desert_pebble_2', 'default:slab_cobble' }); + end + + table.insert( replacements, {'default:desert_sand', 'default:dirt_with_grass' }); + return replacements; +end + + +mg_villages.replacements_claytrader = function( housetype, pr, replacements ) + -- the walls of the clay trader houses are made out of brick + mg_villages.replace_materials( replacements, pr, + { 'stairs:stair_brick', 'stairs:slab_brick', 'default:brick' }, -- default_materials + { 'stairs:stair_', 'stairs:slab_', 'default:' }, -- prefixes (for new materials) + { 'brick', 'stone', 'sandstone', 'sandstonebrick', 'desert_stone', 'desert_cobble', 'desert_stonebrick' }, -- new materials + 'brick' ); -- original material + + -- material for the floor + mg_villages.replace_materials( replacements, pr, + {'default:stone'}, + {'default:'}, + { 'brick', 'stone', 'sandstone', 'sandstonebrick', 'clay', 'desert_stone', 'desert_cobble', 'desert_stonebrick', + 'default:stone_flat', 'default:desert_stone_flat', -- realtest + }, + 'stone'); + + -- the clay trader homes come with stone stair roofs; slabs are used in other places as well (but those replacements here are ok) + mg_villages.replace_materials( replacements, pr, + {'stairs:stair_stone', 'stairs:slab_stone' }, + {'cottages:roof_connector_', 'cottages:roof_flat_' }, + {'straw', 'straw', 'straw', 'straw', 'straw', + 'reet', 'reet', 'reet', + 'slate', 'slate', + 'wood', 'wood', + 'red', + 'brown', + 'black'}, + ''); + + -- hills and pits that contain the materials clay traders dig for + mg_villages.replace_materials( replacements, pr, + {'default:stone_with_coal'}, + {'default:'}, + {'sand', 'sandstone', 'clay'}, + ''); + + if( mg_villages.realtest_trees ) then + local wood_type = mg_villages.replace_materials( replacements, pr, + {'default:wood'}, + {''}, + { 'default:wood' }, + 'default:wood'); + mg_villages.replace_tree_trunk( replacements, wood_type ); + mg_villages.replace_saplings( replacements, wood_type ); + table.insert( replacements, {'default:clay', 'default:dirt_with_clay'}); + local mfs2 = mg_villages.replace_materials( replacements, pr, + {'stairs:stair_cobble', 'stairs:slab_cobble', 'default:cobble'}, + {'stairs:stair_', 'stairs:slab_', 'default:' }, + { 'stone' }, -- will be replaced by mg_villages.realtest_stairs + 'sandstone'); + end + return replacements; +end + + +mg_villages.replacements_charachoal = function( housetype, pr, replacements ) + if( mg_villages.realtest_trees ) then + local wood_type = mg_villages.replace_materials( replacements, pr, + {'default:wood'}, + {''}, + { 'default:wood' }, + 'default:wood'); + mg_villages.replace_tree_trunk( replacements, wood_type ); + mg_villages.replace_saplings( replacements, wood_type ); + + table.insert( replacements, {'stairs:slab_loam', 'cottages:loam'}); + table.insert( replacements, {'stairs:stair_loam', 'cottages:loam'}); + end + return replacements; +end + + +-- wells can get the same replacements as the sourrounding village; they'll get a fitting roof that way +mg_villages.replacements_medieval = function( housetype, pr, replacements ) + + if( not( minetest.get_modpath('bell' ))) then + table.insert( replacements, {'bell:bell', 'default:goldblock' }); + end + + -- glass that served as a marker got copied accidently; there's usually no glass in cottages + table.insert( replacements, {'default:glass', 'air'}); + -- some plants started growing while the buildings where saved - eliminate them + table.insert( replacements, {'junglegrass:medium', 'air'}); + table.insert( replacements, {'junglegrass:short', 'air'}); + table.insert( replacements, {'poisonivy:seedling', 'air'}); + +-- TODO: sometimes, half_door/half_door_inverted gets rotated wrong +-- table.insert( replacements, {'cottages:half_door', 'cottages:half_door_inverted'}); +-- table.insert( replacements, {'cottages:half_door_inverted', 'cottages:half_door'}); + + -- some poor cottage owners cannot afford glass + if( pr:next( 1, 2 ) == 2 ) then +-- table.insert( replacements, {'cottages:glass_pane', 'default:fence_wood'}); + local gp = mg_villages.replace_materials( replacements, pr, + {'cottages:glass_pane'}, + {''}, + {'xpanes:pane', 'default:glass', 'default:obsidian_glass', 'default:fence_wood', + 'darkage:medieval_glass', 'darkage:iron_bars', 'darkage:iron_grille', 'darkage:wood_bars', + 'darkage:wood_frame', 'darkage:wood_grille'}, + 'cottages:glass_pane'); + end + + -- 'glass' is admittedly debatable; yet it may represent modernized old houses where only the tree-part was left standing + -- loam and clay are mentioned multiple times because those are the most likely building materials in reality + local materials = {'cottages:loam', 'cottages:loam', 'cottages:loam', 'cottages:loam', 'cottages:loam', + 'default:clay', 'default:clay', 'default:clay', 'default:clay', 'default:clay', + 'default:wood','default:junglewood', 'default:pine_wood', 'default:acacia_wood', 'default:sandstone', + 'default:desert_stone','default:brick','default:cobble','default:stonebrick', + 'default:desert_stonebrick','default:sandstonebrick','default:stone', + 'mg:savannawood', 'mg:savannawood', 'mg:savannawood', 'mg:savannawood', + 'mg:pinewood', 'mg:pinewood', 'mg:pinewood', 'mg:pinewood', + 'default:stone_flat', 'default:desert_stone_flat', -- realtest + 'darkage:adobe', 'darkage:basalt', 'darkage:basalt_cobble', 'darkage:chalk', + 'darkage:gneiss', 'darkage:gneiss_cobble', 'darkage:marble', 'darkage:marble_tile', + 'darkage:mud', 'darkage:ors', 'darkage:ors_cobble', 'darkage:reinforced_chalk', + 'darkage:reinforced_wood', 'darkage:reinforced_wood_left', 'darkage:reinforced_wood_right', + 'darkage:schist', 'darkage:serpentine', 'darkage:shale', 'darkage:silt', 'darkage:slate', + 'darkage:slate_cobble', 'darkage:slate_tile', 'darkage:stone_brick', + 'mapgen:mese_stone', 'mapgen:soap_stone'}; + + -- what is sandstone (the floor) may be turned into something else + local mfs = mg_villages.replace_materials( replacements, pr, + {'default:sandstone'}, + {''}, + materials, + 'default:sandstone'); + if( mg_villages.realtest_trees ) then + table.insert( replacements, {'stairs:slab_sandstone', 'default:stone_slab'}); + local mfs2 = mg_villages.replace_materials( replacements, pr, + {'stairs:stair_sandstone', 'stairs:slab_sandstone', 'default:sandstone'}, + {'stairs:stair_', 'stairs:slab_', 'default:' }, + { 'stone' }, -- will be replaced by mg_villages.realtest_stairs + 'sandstone'); + elseif( mfs and mfs ~= 'default:sandstone' ) then + + if( mfs == 'cottages:loam' or mfs == 'default:clay' or mfs == 'mg:savannawood' or mfs == 'mg:pinewood') then + mfs = 'default:wood'; + elseif( mfs =='default:sandstonebrick' or mfs == 'default:desert_stone' or mfs == 'default:desert_stonebrick' + or not( minetest.registered_nodes[ 'stairs:slab_'..string.sub( mfs, 9 )] )) then + mfs = ''; + end + + if( mfs and mfs ~= '' ) then + -- realtest needs special treatment + table.insert( replacements, {'stairs:slab_sandstone', 'stairs:slab_'..string.sub( mfs, 9 )}); + end + end + -- except for the floor, everything else may be glass + table.insert( materials, 'default:glass' ); + + local uses_wood = false; + -- bottom part of the house (usually ground floor from outside) + local replace_clay = mg_villages.replace_materials( replacements, pr, + {'default:clay'}, + {''}, + materials, + 'default:clay'); + if( replace_clay and replace_clay ~= 'default:clay' ) then + uses_wood = mg_villages.replace_tree_trunk( replacements, replace_clay ); + mg_villages.replace_saplings( replacements, replace_clay ); + end + + -- upper part of the house (may be the same as the material for the lower part) + local replace_loam = mg_villages.replace_materials( replacements, pr, + {'cottages:loam'}, + {''}, + materials, + 'cottages:loam'); + -- if the bottom was not replaced by wood, perhaps the top is + if( not( uses_wood ) and replace_loam ) then + mg_villages.replace_tree_trunk( replacements, replace_loam ); + mg_villages.replace_saplings( replacements, replace_loam ); + elseif( mg_villages.realtest_trees ) then + local wood_type = mg_villages.replace_materials( replacements, pr, + {'default:wood'}, + {''}, + { 'default:wood' }, + 'default:wood'); + mg_villages.replace_tree_trunk( replacements, wood_type ); + mg_villages.replace_saplings( replacements, wood_type ); + end + + + -- replace cobble; for these nodes, a stony material is needed (used in wells as well) + -- mossycobble is fine here as well + local mcs = mg_villages.replace_materials( replacements, pr, + {'default:cobble'}, + {'default:'}, + {'sandstone', 'desert_stone', 'desert_cobble', + 'cobble', 'cobble', + 'stonebrick', 'stonebrick', 'stonebrick', -- more common than other materials + 'mossycobble', 'mossycobble','mossycobble', + 'stone', 'stone', + 'desert_stonebrick','sandstonebrick'}, + 'cobble'); + -- set a fitting material for the slabs; mossycobble uses the default cobble slabs + if( mg_villages.realtest_trees ) then + local mcs2 = mg_villages.replace_materials( replacements, pr, + {'stairs:stair_cobble', 'stairs:slab_cobble', 'default:cobble'}, + {'stairs:stair_', 'stairs:slab_', 'default:' }, + { 'stone' }, -- will be replaced by mg_villages.realtest_stairs + 'cobble'); + table.insert( replacements, {'moreblocks:slab_cobble', 'default:'..mcs..'_slab'}); + elseif( mcs ~= 'mossycobble' and mcs ~= 'cobble') then + + -- if no slab exists, use sandstone slabs + if( not( mcs ) or not( minetest.registered_nodes[ 'stairs:slab_'..mcs ])) then + mcs = 'sandstone'; + end + table.insert( replacements, {'stairs:slab_cobble', 'stairs:slab_'..mcs}); + table.insert( replacements, {'moreblocks:slab_cobble', 'stairs:slab_'..mcs}); + else + table.insert( replacements, {'moreblocks:slab_cobble', 'stairs:slab_'..mcs}); + end + + + -- straw is the most likely building material for roofs for historical buildings + mg_villages.replace_materials( replacements, pr, + -- all three shapes of roof parts have to fit together + { 'cottages:roof_straw', 'cottages:roof_connector_straw', 'cottages:roof_flat_straw' }, + { 'cottages:roof_', 'cottages:roof_connector_', 'cottages:roof_flat_'}, + {'straw', 'straw', 'straw', 'straw', 'straw', + 'reet', 'reet', 'reet', + 'slate', 'slate', + 'wood', 'wood', + 'red', + 'brown', + 'black'}, + 'straw'); + +--print('REPLACEMENTS used: '..minetest.serialize( replacements )); + return replacements; +end + + +mg_villages.replacements_tower = function( housetype, pr, replacements ) + -- replace the wood - this is needed in particular for the fences + local wood_type = mg_villages.replace_materials( replacements, pr, + {'default:wood'}, + {''}, + { 'default:wood', 'default:junglewood', 'mg:savannawood', 'mg:pinewood' }, + 'default:wood'); + mg_villages.replace_tree_trunk( replacements, wood_type ); + mg_villages.replace_saplings( replacements, wood_type ); + + mg_villages.replace_materials( replacements, pr, + {'stairs:stair_cobble', 'stairs:slab_cobble', 'default:cobble'}, + {'stairs:stair_', 'stairs:slab_', 'default:' }, + {'stonebrick', 'desert_stonebrick','sandstonebrick', 'sandstone','stone','desert_stone','stone_flat','desert_stone_flat','stone_bricks','desert_strone_bricks'}, + 'stonebrick'); + + return replacements; +end + + + +-- Translate replacement function from above (which aims at place_schematic) for the villages in Nores mapgen +mg_villages.get_replacement_ids = function( housetype, pr ) + + local replace = {}; + local replacements = mg_villages.get_replacement_list( housetype, pr ); + for i,v in ipairs( replacements ) do + if( v and #v == 2 ) then + replace[ minetest.get_content_id( v[1] )] = minetest.get_content_id( v[2] ); + end + end + return replace; +end + + + +-- mapgen based replacements work best using a table, while minetest.place_schematic(..) based spawning needs a list +mg_villages.get_replacement_table = function( housetype, pr, replacements ) + + local rtable = {}; + local ids = {}; + if( not( replacements )) then + replacements = mg_villages.get_replacement_list( housetype, pr ); + end + -- it is very problematic if the torches on houses melt snow and cause flooding; thus, we use a torch that is not hot + table.insert( replacements, {'default:torch', 'mg_villages:torch'}); + + -- make charachoal villages safe from spreading fire + if( not( mg_villages.use_normal_unsafe_lava )) then + table.insert( replacements, {'default:lava_source', 'mg_villages:lava_source_tamed'}); + table.insert( replacements, {'default:lava_flowing', 'mg_villages:lava_flowing_tamed'}); + end + + for i,v in ipairs( replacements ) do + if( v and #v == 2 ) then + rtable[ v[1] ] = v[2]; + ids[ minetest.get_content_id( v[1] )] = minetest.get_content_id( v[2] ); + end + end + return { table = rtable, list = replacements, ids = ids }; +end + +mg_villages.get_content_id_replaced = function( node_name, replacements ) + if( not( node_name ) or not( replacements ) or not(replacements.table )) then + return minetest.get_content_id( 'ignore' ); + end + if( replacements.table[ node_name ]) then + return minetest.get_content_id( replacements.table[ node_name ] ); + else + return minetest.get_content_id( node_name ); + end +end + + +-- they don't all grow cotton; farming_plus fruits are far more intresting! +-- Note: This function modifies replacements.ids and replacements.table for each building +-- as far as fruits are concerned. It needs to be called before placing a building +-- which contains fruits. +-- The function might as well be a local one. +mg_villages.get_fruit_replacements = function( replacements, fruit) + + if( not( fruit )) then + return; + end + + for i=1,8 do + local old_name = ''; + local new_name = ''; + -- farming_plus plants sometimes come in 3 or 4 variants, but not in 8 as cotton does + if( minetest.registered_nodes[ 'farming_plus:'..fruit..'_'..i ]) then + old_name = "farming:cotton_"..i; + new_name = 'farming_plus:'..fruit..'_'..i; + + -- "surplus" cotton variants will be replaced with the full grown fruit + elseif( minetest.registered_nodes[ 'farming_plus:'..fruit ]) then + old_name = "farming:cotton_"..i; + new_name = 'farming_plus:'..fruit; + + -- and plants from farming: are supported as well + elseif( minetest.registered_nodes[ 'farming:'..fruit..'_'..i ]) then + old_name = "farming:cotton_"..i; + new_name = 'farming:'..fruit..'_'..i; + + elseif( minetest.registered_nodes[ 'farming:'..fruit ]) then + old_name = "farming:cotton_"..i; + new_name = 'farming:'..fruit; + end + + if( old_name ~= '' and new_name ~= '' ) then + -- this is mostly used by the voxelmanip based spawning of .we files + replacements.ids[ minetest.get_content_id( old_name )] = minetest.get_content_id( new_name ); + -- this is used by the place_schematic based spawning + replacements.table[ old_name ] = new_name; + end + end +end diff --git a/mods/a_mapgen_mods/mg_villages/schems/allmende_3_90.mts b/mods/a_mapgen_mods/mg_villages/schems/allmende_3_90.mts new file mode 100644 index 0000000000000000000000000000000000000000..27cf78d0d1d743a2fce04a33367bb21ad2a82d51 GIT binary patch literal 207 zcmeYb3HD`RVGso2dLUq6W8g_iO-n4zDX~h)EGl8(gYlB{lag{$8JH6@ix@;;g5`-N zsYUU{`K3k4sSM&UQIN*?^30Nq`1GR0;$j9Nm_%A?UUF)Dd47IM#hka-Jh=`i2(SiP zzuH+`T6jZc!CMxkE5ExNR!2$p-gLNP`>N{3v!wRyK0d1#3!3??u33MY|F)!kO7P0E gANRlS<2(D}_u=KW=i(SFGET>GFid9R=W(+G0P`4A#{d8T literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/baking_house_1.mts b/mods/a_mapgen_mods/mg_villages/schems/baking_house_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..fa459c6cce73df948121f583c2f85fcb6880f787 GIT binary patch literal 1095 zcmeYb3HD`RVc=xoX5gtu00wym@s!lG#L}D+tCY;5lKAq>l8pHDqQv522Ij=fA_l(X z{F0Ky^weUjq}06R35g^;*$KlR0ckn{^b0mq?}X+;gtORqGBr$8DE~C zpAw%GZ^*y{Q&duv3RD6&KRpNNmH2{0pgC|Q$vKIYn5L8fO%W3BoX8RUbtKHi-18YfNUwq zLr8&MoRON7#vlT>BMle{sqw|Rpg=^3W+av*X8_%knwo>~B`7+9zJx|@PGVVNd~tqh zQ8F-eU>1Tr3-hK3Ol5f@C_14^5fN3AQIuMok(rkspOym*c?N!%`n1xbyhNa>0&qu` zCxR7L%y}FBI;`1%$4_5llU84;)$-4wwWX84h$VcU!}<6_^2uGxGADn@_Tpwx4w`9N zG^zK3_J)n?TyD>Mx&30%jr8h!A~rm?t{WXl?&owp`$r^O>goYD8JpxnjmtVxQ{s{` zE5dY7_m$>;xtG+f6D_z=c1wQyBhhVhy7d+nL~PS}8?o)j`@qLDV_i17^FGa=pPsom z)LwjdYthA{dqV==Y&y#J-NWIbyT&1o&PDO+m7XH1;=LO@tXD0_VCl*$)dE^*tpoHf^=aA7(hj`y=p~!Q5#z5D-gjFS zN4}r+Rqy<%jpvTuY5Ak#w>jq3lC|tSk^dD91mu$?U!9Wbf4Vf!w)27Uq8~|rIZv18 zA6qWiHNErV^GDu0Ef)Q`erkPJ{kxLo)^{_Hn*6&We7~k)yYPp#tTF6!JNLTv?4DLq z0Wh_WtXA~JG2(B_$Pem$itk~JZ&E|S+o;A zIbH1X5cewNFwWJ`cz$DWGe1-LvwanLRI&3 fry1D~Q+^dIUJ5w#d|BWAgpMzB^6D8?MHAZr0Yk|g literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/baking_house_2.mts b/mods/a_mapgen_mods/mg_villages/schems/baking_house_2.mts new file mode 100644 index 0000000000000000000000000000000000000000..cf9fde8a75fb3ce67b3d5a7698544a48994b2183 GIT binary patch literal 1179 zcmeYb3HD`RVc=xoW#Fkt1`J9JJSnMZiKRIuR^|EmDGYotUUGg?Qcfy^IE`I+pI($$T+G0nm|4Uin4Diyl9--aY?YCimy(;Alf%FV7fMRaOU_{6NAMGiic)hJ zWZ(kjnRzMs#0()<~eL zOUp?t!B7lzQgKOsUMhodN`8J(u@#7n2l+BSDc%s_?~ad@FbKhvg8~hrx?;}TY23w!6nGk#Bi`=1>X&=>vTfbV zf4@F8T?(_cjb2;s%h%{2Y}drjkPxv}tHF8h$NVO%=hK>97yE7fzMxd<=A(}x`!o8F z)?Qk3Ro;nFPTFh9p?^zE&z?%;WVK0-Oqv}wE4g~9>hr1VcgAkWU3>53ww_-}+ERaS zPs&?xrBEsML00Sr5g#ub)oG%iIbX`?N?)l|@cg;jS9|%@j-p*hi(gmty1iWW;i%Bb z){?7=QzZ>EH-CG(aiUtp@5|Bk5B>9fXR%+J?&tTu`HJSsIdK=Y=G?p0e*R_lg=(dx z8?BcA_RF8XWn0huD<&SXufObTHJclEKCbn$by*Pi`>Od8KQ8>f!t(b@Wzqc~(d}VT zFM5>L>`RDVXepMo(WLxfNuK28$nfi%cF&mNa!u!va&4mLqM7%jVopE%df{~9{TsPO zw^aW!&cCYma-H+9>Q+%cPpufX)7uQUpREl4Wqwj+vX9ZptE_z7cdd+TWlz0j{uMPP zQ2gxfm^E=_Z1I9W`VK6RlrrL*b#u-21$u(=U*ZJPQ-h|dPFB0dmB|#=toE0s^i{)N z$#zF?`75)l@5kLbeq*Jf%oSeQDKZjeX^K_*B)pA$0tA9SK8q2#($6n+#ro_K$-jwd thx7Ei*Unx(Nv^c0Ym4kHjXwfQO0D{XzUXF0WNa}0{ygR<`+Tiy4*^CU@*DsF literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/baking_house_3.mts b/mods/a_mapgen_mods/mg_villages/schems/baking_house_3.mts new file mode 100644 index 0000000000000000000000000000000000000000..1ccfc0be11fd30db2959ef22dfa07e19c1f33411 GIT binary patch literal 1206 zcmeYb3HD`RVc=xoX5gzw00tEX@s!lG#L}D+tCY;5lKAq>l8pHDqQv5220@raabjLd zaY=q&Dg$$3W)Xu3OuRg?B(*5MIKQ+gIhBDgIlrVNF+H`|Dk(KDIRlAbl9-f}${+xj zFHbDa$jnP;kU@xK=B4D9#}{XmmVivmFG$T}5QfVZ<>#lx7nc+zmLoYSGd(Z9JTWJS zL7=z<=%`|=;+({!_~e|#N(K?Q&UByyfnxc^sVNK+a8a;%X*r1{P(yiO{wXO+O=S>H z$7oVO9ZL5B=@&fQXEof#%!5aROG zv9|QG$zSO%nG)f5(_*fh_|C4$49jD1m}tqtsCyZLVrDQJVwG8IQWwXjL>>_KB?t{BdQTcGs#t6Vvx`pJ!Qpir9WE zcHsq+%||9jY+SQO9=>f#>#p6y2J5_E`9p(uEfUxr)V-&(ud0u35B>*HxxCDsX$#qNenD zwI4-O1NJ!0>w5L*E!&MMwtsss*zlE4zR0mYaLGlJYj*n|E-MY(b$k2o*=7$I`VSrX z?N-QsuaMhv>tl=ig~huhOX36H9}#PvD%!Hm|k#T<~0d8&SE?H?-u^WMNRkLuh7oW@np{t&gs7VUA*aS zq(;T_E3G>Yu)fvZlQHd@#uc{KBj;x>YE3F>5g^ z;*$KlR0ih6%pwL6n0R?&NorAiaeir0aw-E~a(+okVtQ(^RZ?nRat4DSoSy;Io|~DI z!yo_`Do-rV$jnP;;Ds4gl3xVU1LGEFrsu_%Cj#{d!}S#9=cmONmlP$IGswUN%QN#* z^2_6kGfGQ9Zpkl5&12w!nNm`enu_2h=Ok7#2&d%d7ZqE9$oTU7{FL~lcq43rhM0mS z*i@Fp8zO7~8OR_DcN^Hj$@zJCsmVa^L7k59PkIh8kmCyyfx#*S*8_G_T25jKgJ5w9 zFtCfQz!cc6NI_hZn3R*sAOKU6lbD3AqBtWpCk^2=P~0*|z^ws04P*_}ReZ1@OU_RM znT$|bl2Mcjj;r{z9AKa^h``OrNGwUt0P0Uo1;!Fge@L1m1u2H{M{v)PTV;!ma|J=|8t>j z%hH?oTQ>1BoZ(koSM+>rc(MN5;%|GW^~Y8FRQYDUT=DSk zv2CRm-H+EaN!>dvJT26uX$^aY-x|?J5&^8$kE_3}xNzv3lwAe))ZTlGFV6FQlxUoo z{QJf>v2+#Pnj@RrCciIs>V0)>{?=oWYs(ea#W8t^Yfqgo5c4_x&hL*hlXp9oZ2bD~ z5l_vWtN&z*j`^IrG4Evd9L}n9$9iHey=&flUNC)Xky_-5u+Gh1GndqeoU<^GzCU?h zr@G6-^|K7L>V%B?;|0E-o_Qpa^RdP2O7E@HJ1vyY%@aD;GXFWJ+q>?~n~%>h{(XMV z)*baeg=IHn(kIQ1KdAP5QSTQM^P6U8eD9fWpE>*b<2Nz}J)846tT*SMn%%JHX>LBh zg?6=O`h7v?b5`-?^(ST~RKJ%xB9e5zrc!mrhD z>&j<6exsgrMl$lb#cjQH#n&ot&zPHc=v$eAZgzF)FKg3hpgZF zc5#+I>|Y@6DQt0d?yb3eaP1|n^jDG=bL%9}C!E{dzSYKfPTR$-Uz(Msn)=NbOr z-yf^WoODq$=zNM>@P*IYIp!_grI4<)XIY|Y_4$a{shf{1`KPm!{Y>??We@7M2;YtS ORrq%8>3r2aKe_-~Tt!g; literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/bench_1.mts b/mods/a_mapgen_mods/mg_villages/schems/bench_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..0923ff09e4249c43a85fdf47972328cd77fe1993 GIT binary patch literal 127 zcmeYb3HD`RW?*4pVqpINA4rR*q^2d7=9E~aWEPdgmuHq_#HSY}78f&!<>nWqCgtQO zXBS%)=OiY@C+8<6<)kw3CFhrvB&MepTP3CDC1)@&CuSB^%t=mYU`o?yVRU0tQ%Fg1 dIAP4B__iC>bKl#|N9oS0cuF()~pfjP~>MJzcbfhp-wQoxV-9tRrOBqV1VMkp{a JG~Lt?1pq6LCE)-7 literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/bench_3.mts b/mods/a_mapgen_mods/mg_villages/schems/bench_3.mts new file mode 100644 index 0000000000000000000000000000000000000000..7451c693a88b8f4d3301b786e6f07f0ebbc5c82c GIT binary patch literal 165 zcmeYb3HD`RW?*ArVqp9KA4rR*q^2d7=9E~aWEPdgmuHq_#HSY}78f({AWJat!Fb8} zNl7`W41&caiJ3*kR$wZ=JU>5$fgh%%II$onGcTQi8K|OSPI7_+(;ANnjg5kyb2xR5 qF^Rc{o$qnBU1p(tMJ7!l<&Xh8-~V7vg9q$qEN)0JFnrSRNCg1H8#wX+ literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/bench_4.mts b/mods/a_mapgen_mods/mg_villages/schems/bench_4.mts new file mode 100644 index 0000000000000000000000000000000000000000..58173317908adab75a967ac5d4f41070acbbbcd5 GIT binary patch literal 152 zcmeYb3HD`RW?*MvVqpINpMi}*JS8e7qN%1-PiMb3s$VwS_lk-bT64O(Qt-zAPFv*<6vc&k}{L-T2R0ctq86cw|hVa4F zr6!i879$KTDN0Rc5Q533rRF84#+T>kr!X)B^;XPzJLM!_vjLAw@7pN~Ul08MpEKLy zoSU=swzyl8iYz^Urz9{0EG)jDB6sAn;(f8}6Pr7qy%*XrqiczveB$&a4%|xu=VYc| zh>vWZ5K*aPoyoP!bBTj~=KJ!xxv5|0L~eVPYZAQq4d1mH*Cs~R{MxmyCjS1M!%M5m zlBdhp|7|!Gxapc1+Z(Bc(${-ueVt!e&Mvr9pL+>s?TSyG5v)0L8?fTmS$7 literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/charachoal_hut.mts b/mods/a_mapgen_mods/mg_villages/schems/charachoal_hut.mts new file mode 100644 index 0000000000000000000000000000000000000000..834d8bd4970b987062060137d1b6777fc63bb787 GIT binary patch literal 470 zcmeYb3HD`RX5e68XJG#i0StT$;whoHQhUQfgju1_Lk59-xzeT!d@OGxJjN%j1hPN=r&o zi{kSOQu7#uQ}XkRimgCoe0hF;N_?w>v#4Uu+u+-LhZQ(nFPzQG`1Rj@ zx8g06O=+>y%WgXJ8)oc~;b2Obz&9<`E`3iyxE+)Ja*wCn1yh>^X8Sid-Vg4XTpfS$ z`B%{&YFq8u#V4|q3!hfIedZyLvRAF`<3CaF^k@CMwC?ZP^Y6DAP0juM`{DnZIX}4f zocUXQB=?=9X9%ICImjGSl<&i&7cHic1nRi;As^a}tx{i%atJQj>}@ zld~CwQc}|rOLI!Bki>XlV(B@F#l;L9<@xzJRz;~P4B{|DKxSbzB`q~CIW-=rA%y{M zN=bfEat4DE4!xxX#hEFo@hSP`c?>)-i@^qPgYB(M&B@6xXApr)C6=TD?anVPN={`E zL@^YsOA#i7>QQ8CWME3b-T>)BmgR%ll$@WGl#|N94D@TooVPPO%bFDgTqEx!WzYWq z|I{BxY0;Dkj)lsLK0lkYVs96Z|A{LG$Bwvc;d;1<`(W0z#>Ix`t>UUH*Pi=Oc(Jhl zck%b@d&_n*h{&CNeqP=3ebj;TFK3FS|8ywoo~eE7%`d@>$K@~L&+WT6ar1Jn+BH8f z3wu{G+8M?*omYJuuCeyOkKO4ZefGQ@cjmWuS^S&vPqM!5p5Zt5s^jiz2c7?9-)&rz zxXzwmpzv?z`rP#w_g+4J{e$|E{l^k}Kl%6nO%|#CHMvqL=kJd%KWe8HACZ21G49_L zEu-xDe>{)Q&lmO2{xA1$PGaru(|&N8R?7L=DR_puuxQ+4k+4kvD|CKFj|1UYSvd-GvzTLj!&f)nY z*S2e)pZ|G({q1jc>QiQ)TH&yB<(gBWZ-4&`y%*2@w2O20>^;Z#{I@+?@aFsUw|k`A z&VB#wXByDsoi6`OeeHoy+h@M+Ki|yz@6SXJ6`@WSB@m_Qxlwz?@An~954{h)JtbWr zKlxhb2mX8BOnK%L&#!i`s@^i^&$MhKd9{|ky=z2&`aYjLPh)%Pg}wTm&K_tdIQ7@(vWmakHtoG|Zpn_g(}mBUyxP~s@#Hgq<$5bg E03+z3)&Kwi literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/church_1.mts b/mods/a_mapgen_mods/mg_villages/schems/church_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..fda227f3e6c68a41d123bf26b36bfcbddd81a499 GIT binary patch literal 1557 zcmZ`$do)ye9KQ`t4^dH@)-u+vQA(v!u`#Liz$C9sM$O(k4>MzCE_1K-JSwG{N?SyX zLEcK`In1oQNy4$@k($*>n?e#3gM)UcQD@uz{_#EM`#GP-_xt-1TwMr&D)2q923UIX z{|e9rR#Rzo(2tE;QkguI?9W6QWG^0wAb<+Ud7wYA^lJ&A zshlV<1hHv=#=L|LgPgA%yx0m`vJc3m0ebVCIa>-%uVyVbBmXKsZR!pu`(2w>2$74n=Vr%4XiqOzsQA z@O-?q;%nq52!t2nGgpn>U2mynB?|mbC+T4qg%wjT;~ENaWz@K_?1D6oM~}EDVnb0U zCOOSue60i1P=hqKy|oCuJ`_RqSS6Z_HOIDlGIyA@&T()=$Rf;)Sv9d5rb6A%cfIKEt9Wp?Wvr`=QMHWI za=g}&^dWVj+lT2wTfF5F+j6|8-m9@p!30x%n$MB4Jo_`Zajge#;-%4Yu4lHrYg^ZQ z(~8%i7?alCvMGL>SGh*7zfbq63dRLH*FW2d z*K(8cqdO0zYnEF_X2%Rb03gwG3haN3E7m-jqINnW6A_{b#-IwPqJl*7* zYf}4qy-?qDWU}|J3IuTN25;2b&ymD|opFQMZfL=3%1^*As`Rl7fb7G>Ob<+HFMIb*C;(f*3U> zSXgivsdc;TBY$abcDAmPPEd4C6RWet86AV-`i>A|o5KSS1`7@Rt(%~XV+%v6f&k|c z>BL!SU~1#X)x&vm;-g@!%qnK2yDqX+IH7MJ=x8XaYrU6W=d54+!2bXDojshA9B=_O>H?)isb)^;$#xqBDd-00Ve987FK=oL zI@nnAv}`dxJZOsnDaGl0`a8}Zi%UtK(j%4H}r+5?d`ecRPI~>?sj7H*OD=48zEr$5`@Zu6_WG;wjOnYqt*qjar3TX{9@f!letHi2t!`TaEt06;`1sapwL`pk?KX@en15;(w4*&oF literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/clay_pit_1.mts b/mods/a_mapgen_mods/mg_villages/schems/clay_pit_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..1e01d601c9393c748e4e99470d316733b6b3c09f GIT binary patch literal 220 zcmeYb3HD`RW?*MvVc_@=1V9#VN@`kSX-}_+aXC5>rxAix`-J@)dLL243W9P!O1X z`Q88jHy&)sn7-hvNbUkZGk<@F31S}d?=8!gEzsz(^y)JZ3A|RW5UJ$d`Ybs0a#e}{ s=eT0CGpUtx6N}?R7VpdWuJQV@-uZtIZ5IEN`C-)Mvwj1!qU3|w08ran(f|Me literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/clay_pit_2.mts b/mods/a_mapgen_mods/mg_villages/schems/clay_pit_2.mts new file mode 100644 index 0000000000000000000000000000000000000000..2a6e4b170b7140fd3ae40de648bc6c9ab04d824b GIT binary patch literal 86 zcmeYb3HD`RW?*ArVqp9KAIRcKNli;E%_*@ePRvU|@RD;9D;by*Gm9$bBqu0H87OX) hoai!hg3H9Ck{egJnX+>K@K<%%v;6}zL&;9}698Ii9Y+8F literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/clay_pit_3.mts b/mods/a_mapgen_mods/mg_villages/schems/clay_pit_3.mts new file mode 100644 index 0000000000000000000000000000000000000000..1ef3897511b37dc958d8508d0690cc64cddd8bd4 GIT binary patch literal 191 zcmeYb3HD`RX5eOEXW;q|0Sqh*JSnMZiKRIuR>?Vul?(#KC5f3u#a6{RiAnM0`S~df zA~5;##FEsa_~QK1qU2NtW}vEyId3Ol`wg$ne%{(7 m`(~AAc${Q>=l9o3Yx;NXo?dKqZvDo8jeW`9Os+o}7XbhS@>s(F literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/clay_pit_4.mts b/mods/a_mapgen_mods/mg_villages/schems/clay_pit_4.mts new file mode 100644 index 0000000000000000000000000000000000000000..8c68fef5cc5e1499eedc1f2088a7f43466f9c361 GIT binary patch literal 355 zcmeYb3HD`RX5eJtVBq-=1q>_r}%owMy2-$5Veq<(cSHij1_ zK35O5Pf~KIn|-=Ha)Q?BKYu1%{P}ZX^hd?zlh#iw{hhjd+vlGbUfE3T`C7K+tj4RH z(;qaBFRoEJ6g2hW`X6z%B~2H4^Z%wlJN$ary^YtZ?XQ`tAA8Pz;G6SH`^{EcH$!$|_@*-Y)OD|f;PtHi%Xz}vc!5-&tuX*Rxp0tQPZg6hn-&+S?%5*x; m$>6;r7$W{^&gpBdPkY4q*U2ut#_;~m>4zJhvwJK|SqT92La*rn literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/clay_pit_5.mts b/mods/a_mapgen_mods/mg_villages/schems/clay_pit_5.mts new file mode 100644 index 0000000000000000000000000000000000000000..83eb9e3a8810c2639faacb67a5c8ce5ae920a3c0 GIT binary patch literal 207 zcmeYb3HD`RX5e68W#Ik~0t_q+;whdXxd8zT`nI#$V$@z&n2#J);q7sOB zdQoC=F#``w2S|c}IWe=SV$R#i54jo?1e(oj|EI5W3Chn%cMN#&Et|cL&qna$vWF>t zMTZ{h%(cxd-K3@OtJ8n^F9*l^YAjL{pC~D qca6<2*)p%GRaZ^PG~zwIX)o`-oeytc(trAA@zVY*_BBg(-Ua}fU|hxk literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/cotton_field.mts b/mods/a_mapgen_mods/mg_villages/schems/cotton_field.mts new file mode 100644 index 0000000000000000000000000000000000000000..ac32a0a54ce193b1e317b704babafd8b300ef580 GIT binary patch literal 112 zcmeYb3HD`RX5eICV&MG$pMixzAT6;dH#0BYsyIJ0C%!zj1R;`~Us95v7jMBJl9HO1 zSejE}Ri0RqS`=TLUs{x$%D|kMSyVA6IUyk-iGh*jcEk2Wf`*5~?LC=$DnG|t#s!zE=udC1p1=S5j)mPH{1Vxmgdf~BKK1d@ z>z`437Jk1TQ(^n~=c>)Wj`wbUqJ84_$vTxi>d%jUU;O#Qy|*?R&uiy@zwlA8(?w~b zhl)_D=3fkeN^M%pwM{;u0WLY*n0-m=s@JlAo8FRFs*V%^(gF2T3DK@TR1u zC6?xtSe4`#C1)@Q!MI3z`Cwwn`AJDRsSF}8etBX^D$ua}(xT+liaBq?8-)%F@Tivj z{I7q{YyD(}Epy|nzs_0R6{Ij`zKCdh|NMmt$&^E(eT<4QgxO(0RDL<;rICjFw?HvnqqD%CI47=ZZo-eFj z$Z+U{+uPJ@(|)LK2|l~+#L7M1{a({|oJ`KDw|n(o##Z;*U;V}ZirV&l+SQ;}^#1z+ z5NPPRb2Tyat?WgvPiy7gh5w($aad|OVPEb9v^V7O7mM#mw3R=I=PAYw% z&yb(IHR;;E43D?w0xX5$I~!lIlE2`N&o!GkbHe{!pC{(l+CsAE=#m%cgSv+Bj+Z!*<=Hm2M;`ZSTe%#6{>tFZ4gWpIAI({vto?r8Rn^m-3*(-hT)iuG zUqJrT;Q8$Za?gMK;rqh#mYpeTwcPo#$O`*ge{G}N?gU!Uc)=kNafvXQ^Lt?Tm> z`OAjiY@XM-`)-_a{e!XP^RM&nt}Wzmv~P4!5a3|heSG(Q^*HXTkFzB5A<5DB(9J}KT1o1hVmv;u&sR&i6>?0S_&foYL z(R{C)n}5FWj;hAO!!oLK_&la_ojBgh{^oGPlbdsGe^^AlF}=|F=42e>a<|~KZfU*; z96ul3AtisK#yQAbd zx#YhgUswORC-?1cw9o@10xH@W8 zZ9vO|BkA9M8e47U&zc+f!%DbxSB<>Y_VSM>AJ*>Ixp1)V?p4|E55p4k<@4g6O7O>bO@IFVd+n2#Cytlh*N=H_YIo|}=PRFkPCNK}WtV(>Jda79snJ0}fTNv# z+x71``!*NtT# z6z3!+#Ut#knDchpNxlXJ9v9Y_fB(DhT5j;j?&_JfZ)b<5&lIQIr3O6C($g05x?Am9 zlfVCz@f+p$-j41^?px1u`rYNI||CRmYPh6#a z_loit)Y$r8XAO~EQnDs$`#a|uqOO5Qmb)8B2DoUjYD){ftWh literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/default_town_house_large_1.mts b/mods/a_mapgen_mods/mg_villages/schems/default_town_house_large_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..4c2b3b3b1a3b2843102e28331a0097cdf5c8eb5e GIT binary patch literal 3074 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 ZYklur6scdpTl24jQ&|fuuHHPV{9ho40#yJ2 literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/default_town_house_large_2.mts b/mods/a_mapgen_mods/mg_villages/schems/default_town_house_large_2.mts new file mode 100644 index 0000000000000000000000000000000000000000..6e19db4249d4927d06a7c4aaab125bb9b85c8959 GIT binary patch literal 2486 zcma)4d0dit9%kE5P1~uJ*^a5xY>p|ZV`-+FGC4bIm*Z$ll*daPuL^P)hYAL@rnVi@ zVPNBdnVDDmW@2ihHf7?-rlW|IdDN(oB3dHh1uf-jZT+*q&*we9&-eKr&-3~D|Kp%P zY!S=`w$Aj}!B*hGa14{g@WK;l44CD|5jvK@h(t%wFmyWXj~D_Cwq`y{XHY31mPWuu z!7S+vQ;P2O{)7G~u|N(7DL4=vOQqsrE9V<9s5D$8%xu1vgu%`c%s)ov1}rT2za1h- z@77vq_z9Om1HlhTTqH}zlIQ* zln4?yC;zirhN*V-Jo7yV?fzlldmCWuKNjDiO^@CNI=x7ocm#NA66RvCLy2Ql|B0M2B z^=`&vz`x!2w!Uh46R%V+bpGy1IyHTfpz)grLLb|zeayxp->9Vt=|vusZbAJ4djWDs z&x`z#wHq3OFw9VOn;qUqDb%dTm>lz8nHS*#$D0I0Xs_~(<^@&7Zxl+Dy_)hOm zKY&w?x0h9Z#|1Q5Wqs#Dj6Mz?RjsBQZyW?CG&T^D1WN2=MKZUFK11W=iad${l@p>H}FxOHkn$3R}W^P_k~%Rlu&5~x#ft{FZx$*(RIeFG(5TPcB*XmsAct~*0MtlaE= z9imzrFC9ON;99i8wL<4qR9-LHxAU<#6wQ5gk0n>mKEIye%8w5zAB&g*iJuh z)1k*g$GI1!#aFbaDp-#={k*8a&S2q;;TL2_4X!pyl3^b&mGWQzK69$fd|A@iYNd*w zwTL|d^}E-f(YWh@t4s5rkiBfXYh0`J5gRfcirXZ8*}Ly)6NL7ot+x-nFs?|ucpwb0 zz7QP>ha#z0{oy;x4xR2h7;!lZWi;TIP>W*5`>k5xOA~_Z4yK{*t#{T6;p*AY@i7({ z5UVBTbpm6!XVG3~D-Lmc9u?lA70IM~75dT)Rt~UP<_tOWnH`+zn}u8;P_N!TrM(5L zb-W=QFAD42UAre-$g*SQ&78K;4qs(*g>5YU^;#K1QPc8fm~0$;UQuZf^@oT&{8KH@ zEDk%gjmfgh%8%*~GgtY1|5}c$YeAwPsc`LIBixTuc{PnzEvj9)i=B|1OQ|TXlVE$% z%^jvYGo9Wp5<3>A_)-age9T|qnZxZ^+g^9{fGqCk?l_!eqKysIAzl*q6aXVJHLAN0 z_Sd$&Zp7>Tu)AHImK%wSE0Mi@x$FS)sp(C;{80l@hfvt-E?@Mbw61gE`%k#BJ(aEo zLtF2J*zxr%`bp&tyG@{l{8V!;^0yFA?_?RBovmq0@6$Rc-uw+X*0<@rUN%E=U|Eb> z(f|((u)!q_g{Zx;FW_V$wXS@tZMEk>e2yS^RoSg&@l%8!9{~@r_6?~Z63e@F;!>yqx-G=U&hF-93(|M zCC9|rss4L({TJ#Mzq&G~AZ5ed;NF??0xy~>`1dza<+GR4l|jnHu0oG?Ua5@NAGb2_ z>5rrFRhh(gBEa_4_@}EtU;s%SP7!xCGaDM)v-ckv?iiG-XY@&5MY4udMAK)z8u_W4 zI30V;7@*+`*#CWwn!D9nTENN&D6@ZnofO>KKZfz#x!Nebxnk7zGKAvzJ?~xzRa!1l z%S-5o={rjLPNmd;Eu*edBjYLVbmDzBbLFzmjb2MyL`#~>&s0z{QKB>eA_|rVU2OdA zNFD=oeDtB&=-b0Dpog@mHDQB%n;aHtz2)O#QPQyz3h=8A*_%lZ-hE-~R!C5Fw(oEq z_Jo-zw^&z%;qYti8LC~AE*UhHanlg7cG1z8E0X8eC<6_)@8sQ2$T3Dmn|`iYz8d@L Q9rFI%&z!W~=&7gv2T6O`ZU6uP literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/default_town_house_medium.mts b/mods/a_mapgen_mods/mg_villages/schems/default_town_house_medium.mts new file mode 100644 index 0000000000000000000000000000000000000000..5e13d65312d2e5601c64e3d3ffedd4481c68e43e GIT binary patch literal 1673 zcmZuudpJ~i7(R(736o1yXibT*o1JxeozpGjy2>swE~Qbf zPa=^nn@eJ}Te-~2h~%Ea)L3M!dxKh(%d^}050 zAutd@82>FI0csdN+l-lGFqH;kIN}G5W2LDdF%5w z7k5TO5Fd;M!OW#dm;tCCl@0-F3w#I-V>8%PKXBe@P|Ew{6(PymYa?Xv$o`Js3n|>9 zsZTpGm32Z+Pk2r}BXr_mg^OkEVQoplHnRjk*Bz@d@O(SO^$lq^A}5+Yx-|P^Og>n4 zC53lHSFb&w2tl>=X3~r@Zb@aC@>Vh2i@VHcjVOZg--34 zh0#7XoYu@O#{HQdaO`7v2(H!9mEx_@=)6ZbW`fgg`fdvmj+dAwbS%H7To`Sn(ZtDJTRptSK!a~b-( zYrhzztt>JlH;_QTlb1*2n%3}x{b3z@BhZ)W>hD*l;l7J(KQ^v5)YN;VEFw!E6+Dq; zN-}Lqy~+k#YaWU7Q{T2m>V^)QkbOq&NW%5s)JELYuQdcT?1krirTMFi#jWij1|1<4 zmZqyakDx=E4jNht<=e%+4u~bWX2PyLUS$xoRadv?u(0vJ3Xm5&?guDq)Wr9si4tsz zt?DZCs~yELwCWE#S`vh+-;(1Duck1QUOyL_ygEjF8gcLHn1CpHoPZI%H)WQz$ z<6c;^M{u546~xu?Qq*8JW>0BKjvW{sNl|}1#FB|Q_0V6Vq+`D?u0XD}<`BiFnI%}! z?Q~+*DEVejOPesfY{pX0i8CzO*kSjsW1{J2g0x8f!Kz`N0&9!FVmBwfi*VVo*<#!z zps}Qeb12r1v*Av!Sp#TYbz;UAW+8R1)%`_|JujVtMR7K@XXreVaGG7~VS|oJT5s!H zHJtRXxQJ0(9mXCCJ&klk%Gx5hc={vl*+_3iPkgq4lOQCcl3oghj!6kE#}Pwppj?td z^St5Jqf$7M{Hl*v*esW%*&9Q&r^Jnr*1tkn`;rtollKbD#8@wAJyNDG#(u==hmwzv zFk8ahL!}<21&OBvtNjn8w&dImJSC1Rj`Q^8O@-M`y)Ji$(80EkOz3N$44xOOFyN)w zXW;|y@Gd26E4`Q=75=RA{E(JzLAmqf8~Z&1&ES%tN#UiZRwUW?<^4ig$xhV|pWJNw z28(MiIG;p&&xxJ0JXrcsYjr~Igt=7;|H$p$db*(wba6&2^1Pk$j!Lg__c34R%Ak1U z8B@UXxx)!h=(t6-s%CaOrAwj5-&Be8q&M+W6fD1!jLQUx+V}^)CvP3VBxj?~*~`wf zI9%z>c)?%cD7x6Q@BVFWc=N8^VfQ9){G`|XKBM$nYvU=X>qJYF;eb*_Qc6RNP4Bg2 z%{P>_G21abQ0s5CmqV<=n%qWyWbXdcu4gw_|0CDz!FEin*AiUEqw;`oi+zfNAGjN3 zt-Z6HP0qaF$D41CBoJiuxrW1IHt4jn`-Y8^W&Y0xs${yyQ^^eqeB#ROhHbTpzvW81 kU!M@O)9$Yd=Eomu>?)h6FA%*xl)Oi3YpR40ZJfmV7i6;${r~^~ literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/default_town_house_small.mts b/mods/a_mapgen_mods/mg_villages/schems/default_town_house_small.mts new file mode 100644 index 0000000000000000000000000000000000000000..4f0321e836501687626fedd6371668a512b41bd9 GIT binary patch literal 979 zcmeYb3HD`RV&G@s17dLoo|M$I#L}D+tCY;55(aT(UVM3GNk)8nQDSj119M_#5rbfH z36LtbD$Yqvicc!aOwMKyf@vr&$7R5jMU;1gqzY*^O95J!LAU58CIN` zo)=%9n3KaG05cBc8?Yiin4;wTq@fKu^qf?1NLS2xJF~N_SwX;6P^C9_*OIk= z|J&y_E1fV9+QwFFl;6kssfRBna8ZwGkT_3WyW*Y|Tc4NpJlJ)5MLAQN?%WS|n>$O) zw>%FBYqGWc$kEfMX5dy)*>~8@^4Qdz3riPTExsdo&Fgon$gN_{#e0CvBOKg!GM7g6 z%)40awPL<^Owy4rO~$WocE1!q>DO>^b=;r2y4`mo)5~45{{&m86kFsk&=Z6<>NL8Em&g*#Wp>pR)N4I}7e%ZTylR0$9asI>|yZ_#P z-P4z$)AMIq&8(_3f1`Gm$=rOe_#rwvzB};N{uM!PJM->XcqOL1UcZz1(Ncq7`&e`$ znX;@SHuWrsZoinZY4yvp$S>^tv--2SM5^sy+wu@e~wV3!U@9oZ>z`QM&lx@DR`@-{Q zx{K084;7(KAhqer8+rN6Ni(ikb$hI|xoxZLaXD??D@JbTs+ePM!{78p%#F#rx8&v2 ziVh+DoSVMUOZr&jKW&b)&AZb5qSpSof_Gv3^MqZ03PrA}1eUQry1n|6&cyJhyIwo) zPcIa?pUTh}6}zhC-tBLU+G~;~z3#2xs(UAs@T%=)^Wk18j~o7W^RI2}TobjVD^gcW z#@(v(T;$ctue+G4{Ukr!ers3@FJjO3q*qfa%RiOoAxjfhhnh7f#8~2O13`!P4=f8<&k0R fgdh3q55{&KZqhHjT)xzPmFmv_$JuWzirWPMBdYDj literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/default_town_house_tiny_2.mts b/mods/a_mapgen_mods/mg_villages/schems/default_town_house_tiny_2.mts new file mode 100644 index 0000000000000000000000000000000000000000..a59324ab89c9fdce0590c99d3fed0a8c4890a1df GIT binary patch literal 611 zcmeYb3HD`RV&G?BW8h*CWnfOsEMgEVE&)=-R>e7qN%6%c`FW{HMVZOj3_>ZXX^Evd zC00mc;xM%!Em#$&rRF84#+T>kr!ers3@FJjO3q*qfawL<16CjoQ;?EbR1#mFS&|W- zUX)l|%)kSa04ozt$`FBOXPy5e=rr;u;ef6EQb#Et8eF@@X(9uaoTQ|FZoe!i7vCSRPE-1 z<9(aT_p0a4nZq2HGtK+JzQsaZ>rbpndzSKYO39U^obOww^s2uKr16;BJuS^YE>+&#v&u2XT_*IQmFbFv z2WCHP+>d%G#C5tP1^XCYdV6pFhnXHPc_bs>i!8a|;}N)uZ%@qaGN&2*JEuMNWBho6 adH;vqCuSTfX`U#aa*gv{zxje)Jt+V}mG;d5 literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/default_town_house_tiny_3.mts b/mods/a_mapgen_mods/mg_villages/schems/default_town_house_tiny_3.mts new file mode 100644 index 0000000000000000000000000000000000000000..54ffd358f0099f398d06d3020a1be01ed01ce786 GIT binary patch literal 587 zcmeYb3HD`RV&Gz617cAI=ETe*2C?E2AXRKtoRgRoUtE%(mzq?RnViiao|2lDSejE} zm6BOh5?`KKk`bR?lvrHMAOw>@QVbVMOU+A8jW5s7PhsGNsVm7ZO3q*qK(+_0fFGs+ zY;L>}0}o69EG?XppAU2why)uLp9EBbAy@(wgxdshxgfGl5Fsw0i8)r~8JQ)i2-V3M zsl_FjCMLxjVhWZ31>x4D=YYZi?)27TFE?e~J`yK%evgk?i|`bUz(tGBC)cbo4?na|E6gg@ZA)L}*-XWQ(ZRx- z8>iab*4k|MCO6qio~?Srw|lWYzRz`%d@l3)7_OoAbpVmafv>o_9d|Y{mLb=F9!=O?Y;2TJ!GL_deCN xn#UG}rq!RxO-y8awqx}z{%o$rTb94rzhP=d`~g3G$p>?nfBk)jQG_i<6#)ND?mhqj literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/default_town_park.mts b/mods/a_mapgen_mods/mg_villages/schems/default_town_park.mts new file mode 100644 index 0000000000000000000000000000000000000000..3af734c88b7573954e0c59d3b0c070c520abf5a4 GIT binary patch literal 420 zcmeYb3HD`RV&G?B1!7JH=ETe*2Hup^w8YY!604H@qT~z)AsDx~BtI`TsVFl!n?by| z1gNsu3QWZ#Nr=HDauSn}#o>merRF84#+T>kr!WY@)Pl@{2=T$}O3qJ8%1LDqf++zR z2NA27^LARaShE6;izmbFzxg}X>N8DpT+@G;-CSN{V#*N(iD1s$Te}}7lo{>x-+Ozx z`<+YOQR|;fwtLHa-LB27daq=iT2Hy%3Z18454>Ke_EP@yek0+~W}_mGRqqz%hQ3c& z)Rj;+FYOki{;T!JnL@vnJX!Zj^46Nw+pZ^6ue$YT`}Xbp*FL_O`S9|~607n>e=Fwf zOj>Top&2fCrm#8bLfIanY}?SnS33E}TxMxmE?63uE3GA@y4+Ofu=^*$u0=i}yapj& zzJ(!ew>TI1R9gwEpFi<}`=7LymP57c1qL1ewYPTe@lmkOF3@{(_-O7K@k^Y4`Zxr4pkN#_+Ih zg~#uE8V43cqzi1(w)pPyd{)sdapuF%y(Cwv-~SlEUAr;k{m)B%Z?!*bzZR66JyCF8 zOWWP7mHUn?sI3%y{B6<0HEUxzOuuX?+V^GSGnwAq@s}#atA*$PdVbpUVSWEPuWxn| ztd0UL%S7z{|L1&sRo!`M*tb0O%o}NszDn$w#c#Uu3Xk=z^Cr2bixaNR*jZyaIWB4S Xo%&!Q7nzrbEmj@PJL8jCUz!8}L-?kz literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/default_town_well.mts b/mods/a_mapgen_mods/mg_villages/schems/default_town_well.mts new file mode 100644 index 0000000000000000000000000000000000000000..28e6c64b28f6bdc36679c3d2971e1c2797b3a0e3 GIT binary patch literal 408 zcmeYb3HD`RV&G!n24Y?Yo|M$I#L}D+tCY;55(aT(UVM3GNk)8nQDSj119M_#5d%L= z7AzKTiY{QpAOurUT#}!cnpBjToXx-o6HCrdO3Fz^s7XuBOHPe1&(BX`5GXDIT2O3N zoRgRY5fOpuDo-p)Es8JBFD*(=MYtBM3vO~wVoFLXhWiXF=DeNK&DU(e;ktWQ;MRZt z-|za>HD%%F#+7Dwq@|0MIgbnVcrFo7)_!BXN%Yy@if#Nwzp9%PqBc)qjP|{`D<@6+ z(BofcTw|?D)}=muF=H*)vR`N0X6?vM_$Q=OXP(M@d&o z**9&HvfZ@wPi^zPv&Qq>lD#Qv+dYat-^rhTVpE{`U!P~E(o|nYP4!wT6tKy5XW{j@*A*jC>z!N9Q9e*Yl=m{}pb literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/empty_2.mts b/mods/a_mapgen_mods/mg_villages/schems/empty_2.mts new file mode 100644 index 0000000000000000000000000000000000000000..7d310a18f2504422c8eb1b66b0477be9faa2d039 GIT binary patch literal 111 zcmeYb3HD`RX5awf|Ns93De;ulw8YY!604NVqLTRX%#w`w^rFP#Vg@0YL|STIa%y~e zetrrAb7E#u#hl~>2j(7!6D+MKawLv~^y_#>*zWpsAh|IRWAKgv588MYrj GU=9FLd@6PT literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/empty_3.mts b/mods/a_mapgen_mods/mg_villages/schems/empty_3.mts new file mode 100644 index 0000000000000000000000000000000000000000..2a4fff1029984328508b8ce3febbe0f0e6175ecc GIT binary patch literal 141 zcmeYb3HD`RX5au~uK)l4Gq5m-r=+GOmgbaLrDPVB#FuB5WW=WzB^DPm2*D)MQuC5i zNGm9AbVG_lO1v!~{=@oO56C9X(98R#bp2(3n64I~Z9bvo6#_-il&k+Ar hKbNdN{#MEBth%WU=aK9G1=$P^rO#kyke>0u9RQpYHC_M! literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/empty_4.mts b/mods/a_mapgen_mods/mg_villages/schems/empty_4.mts new file mode 100644 index 0000000000000000000000000000000000000000..381cbefa5cb1988cc7e9d6a29349856bb71c133b GIT binary patch literal 115 zcmeYb3HD`RX5au~p8x;<11a&8)U?FXoD!>)%%YO`^30Nq`1GR0;$j9Nm_%A?UUF)D zd47Hh19M_#QN^6(1PA6GhZ8KVCvqf?g!JopN7(NAv!d$PDs|I+9822&FJ{m`z;QmX Lfr(+6xIzj5|FNGm9AbVG_lO1v!~{=@oO56Amy*G)~~;T=Y3nV0THUh?otM2mZz&l0{*z}dVT^d3Arc_Vz`(UIqX_`yaW{Mb literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/farm_full_1.mts b/mods/a_mapgen_mods/mg_villages/schems/farm_full_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..37f5434651ddf9b302927ad32d04f53c18dfc43a GIT binary patch literal 1218 zcmeYb3HD`RX5eFBXW;!00Sw9v;wh;z7bRyfNWc{p<>#lxr{yG;#21$oC6*&B06C6<53Vi=XhQ~rFq{w8 z2hqX{7tF~|%te@xoRe6|APtwyNX$u#Psz_OiqFg|OD!r%O<@qilw=SFDJixBD+GBc zJ}KT1Q?LXmC=1sOc1&`9US4W4(0@>$@WZ8(5{rtE!yq{$wYUV~PH?cn!#*c5B_*|p zfgcuNX{AMZiOH!9GH~O{GxJjN%j1hPN=r&oi{kSOQuB}kCOrojmGK3Mz{nDWYe`B? ziO)z)M2?;G#FEtb zvRJR;uYIn5Mw7iJp0nZ84XWQa?MlIZHlOpg?7P&smt^P9aeK{?bWvhaV7JD?w#L3M zd|tflX>S&9*(!N>&gyMqhh@He*S*=?R=VP(;>=ve2tV1JXX1f;TThxy|5kcp_dc^v zhxhK>D;(&Dl^~ zdZX{k!+-_LHCH+W|23Fi=6vbzg$W<)0(dUT@F~kY^5|hUlv%NO7Bf5FtCgF3>}E=R z206>$%+@#I#KKjz2|I-J5?Y`#==NQWv%v8PMEwc8~x-9{+IV`TO ee|g(yZ{+CtyX&#WltrhW2HaITWL{O2;{gD^yZkKx literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/farm_full_2.mts b/mods/a_mapgen_mods/mg_villages/schems/farm_full_2.mts new file mode 100644 index 0000000000000000000000000000000000000000..a464a4cb741760cef5f3f35998525cd32477e04c GIT binary patch literal 1692 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 literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/farm_full_6.mts b/mods/a_mapgen_mods/mg_villages/schems/farm_full_6.mts new file mode 100644 index 0000000000000000000000000000000000000000..f6d6f9502ad0dc885e6b1ae2c04343af503302ea GIT binary patch literal 1604 zcmZWnYfuws6kSWLS`ifRQ3(`OOnnsr5r`zTqC5rx6-NzKx0_`1uuB$pH{>O#_^L#L zpluWx>R?eRMhZS41++y0!C<7RjtHa{D2R-WCJ_XJG=UOmyFb2}d+xd4IeYFGy)7;p zumkJ?2f%*hUmxHF%xA%DNPrL&77rspA&=mK91Oy7z+t?>L>UYO1{|0uK|mZBr!ZhX zlM6VF_t};b28Aff0%nb41d3TGB-@CP$7i8J5a$XA0>(fz5#|F6Y+VdR*&rK%2oNVQ zNH|G~fUMF^HYNum;IV0Yn-m7afUO#{VdEnxlmIx}N)BTAGcXb2!+@I&993tcd_K&y z*#5_Yqpi(=Fbqb3ITHZP0=Y26nso2z6=U9AY`jsgOa#SY)`UMM0*L`<7K&mx#d?nB z1~NdO|AT}DoCqD~!U+36F4!naOk~dF!Z)Tkej0a*h~M0q&M=Ov3NI1IB89-jlu z#tDdLae*TcV{ChK#t~~{400S#nJvKh5OY${*5@+uMi7X_f-%5loG!HN$r2?hz$`Pf zZIK8eoNLvdSSS}l*q}8CV6KfdmNoaelm;^mRRj9Mn$TWxL{K@08W2W;rSFhjqZN^s5h52`H~Tj#4bE_bDd#D;EoSo+>>zZ)s2-Y=ssIxxSjw1qubCZ?6HH4N#VH3vB@RW(F< z9Le6$cFR*LyHsU#8l1MdvL);p^{R7mZIgN!v5S=^%qQ0QF}<^SoddHNPp0jja(_j; zDy=_!C{VMfl|udcLa(^UbI8Y3=|&~df0u4)mzOIKCg{5a9e?e)R^s|&JiB*OR@*#> zk29%gv#Uo>W?WeM8M1G^hDr+WZ>3h$9o989Gv!x%5;Cv6obfI~LSB@_NIvzdbD_Q> zc`|S8l$8 zoqBTYMS-2V&g*j8_IU4_rwJPe2J|lqwi+6S{X5P+HMZ5(Ru=7y@?R5>WiUzHyO%sr zb1rvp+}WF2bty-GJS*qoo4gm|;O;Hvl)0R)kB4<;)xAZsm8F)$EUb?5S|+$g8ZKY3 zxu2}$?+^8e38F2}TqHa1GSsr_ExD!gGd0)V^JIEtp*csMw0G5A){;i@jy%2EBPajh z(hP0VbjnGBJ}>Eq=RCymvvltC_>7{p za)*&){9Wfn$=dcSA9!pe&YOEqoIpFnla$qQj9dvLH?95fl#4k51)0@~?M-g-!diOw zar(Mw;s&oK%kmEadiSdSb*}q2F*8Pd)9bg9Zvz+ZDa3yR#X96V literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/farm_tiny_1.mts b/mods/a_mapgen_mods/mg_villages/schems/farm_tiny_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..bdb76a5b7e00868a5f0587daf750060e41eab6d6 GIT binary patch literal 1217 zcmeYb3HD`RX5eGsVBq-=1q`YT;wh5$K^CqS?7rmuyu8$8 zpt(?&^1`Ka@)L8Be3PC7^j&;GVjhx#$vKIY48ke-`9;N6ATl0gLwr)aA%h6qnDoSw z)cE9_{NmIU1|gU~(tyrP1*^u?UINrE2G^dPky=~=bX$HAFiep`E-^0!C3~1mVI-sVVUpsfp-9Y5Dmj7-3aVlvxIJ4udpYcSd4PT0A&@GV{t(i%Nho z!JL>`R59mmcxPFYfj|tCrbdu%)Yf^nKmNz(m_JvO*s#dvwYKr3mYlx1IUF1pnob$5 zeX3ZrT*gwSy8P_l-wPR&A-m&AQIdGES$?JAEfZ-urB}`|ec> z3$N?SZNGVs>6gT&2FoJt;Dd)=t={mb>u=eH3qM`Epmj=iKfJdi7%UgQMDo+1=+~6x(Xd-Nh3A;)+_>+ST7a z|Khr`#Zhj__xT5ZOgwATy5#)@A^W6t?q~KspYbYh{d>l-UikTFmE`xbZB1bs z8(LXEWvq1+rpekxR8D7PyRK@Kk+1&(|{cv}2NkO8+ zSnbe4)lw{kI-?a@i>UPxK}$qrNUb&oswj2@Emp-^BA6k>kaPniVe0 zB>EZTO%UKwcXtYcJdpy*AZYAEp#X#)Ulw(Q+hmidrq{2`o2xeGR%@4wmsC@Kx z#2&<*7==V0r}12xLdT!VShXk+=B=hsVGN7p(CW?ne#codigS?80unEIWL%s?*|AA| zhs&ri5(fglhdkY*^oO5TE($2iR-M}XMScAVQr20UrE$&uv!}RV$MTBT<3D?{Ju=GJ zy1MnNiRU`?#^?4j4|K~!=NmhXPk+*s7=E^0KFt!hPH)il9dH;nb}Vw?j<}|I8@_u* z++8X@-aTMxSf}#q_^|p?Q`S~Pn+=8#M*TFTc~VtL4a6o+lH4fjhP8}#P5zq-~) z%d|%wtu}RmVEvZ|^|lY9Bl3<8&Fp9kwG6)C6rBBJb8+9i!j|*R+b#36mo~$tGX+%z zSC5_B^-foV?c;kZ9LaARzL!f1?*m<~^n&8aukzG#;c)YK-wdd4} zHTd_J3_7E>PFpwZFaPGFWl`qR6MnlxtfuS>{`T-2hyH#*M>7*8(!EOcZHkSTsHKo`ThZ6 zZ#8+cW!LV)3Q>P@(kgpuhHZNv*COp0d|B~tP(rHFuyg->`@WX2_2jV@rz|4BAmh>- z>FXw@39Y7tsh1-ilf}CG+v;;_^QhU@p_DBfe<(84OVVZ=<0skQ-kT@V#{SayYgB~{ zNvkzw4Ex!1_ROX=voagrBP9NofvsBY0-@{MavR>XL>PE;{;j)2m`kJU2xqU%wkn6O z`yD!V!XO#^t>3ybT^m$*#WksO&jQi&jy=7i+cjZ1a}2NbM&GHaSQ{UuzhHL$-cF<( bUG?L&dq=cQH!CZ@p7X?9@0_4duTK3BPGXxT literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/farm_tiny_3.mts b/mods/a_mapgen_mods/mg_villages/schems/farm_tiny_3.mts new file mode 100644 index 0000000000000000000000000000000000000000..c639cdf04f3130da514ad1dbde3330cb50a42023 GIT binary patch literal 1809 zcmZWn3p7*-7`|K417)y^M)X|Dqfjxj$|H{&k5VJ0>(0!bhpxH0_fF%nv|HLDW{$_U zyVYc^w!%gV({S`qA@rCEOQsj0L0Vx@vO{awZO%P&&;On8|NifO|4$9vP6eg|^MJX4 z?&yDhfCVt039}$RLQt4oi~t2(f&;QK2*-iB43r=sHjGo~Fpt5RQWFpzfdRcRK97yS z<77%W%;fUJ0lf(^mZ}8?1t`h{NK<(@2gL|LXM#qcm`a&6QQ}-S4-`NM0_dxUV<^f3 zaRP$`fG!Kd!nr&)1xL9ED1Zq-d!lp9JYX`3>cU@fih6~m~XYp*a(yd z+JAxA0S4;vY?TzqKu{cJ0=jBc0O1^!ktsX@#8znuI53O=PZX^j1yo4#yy~l10bn!I?M!FC`$Yf;=mB| zi*A)BraC8pgcA@~Zb$}?Jr^tEcL+g-9k$I+HjOn&{REXfkdm{~3|+4n8xNy92;W~g04j=`1?;b!MpuI3KPQrezqi)2}3<4UQFol=-pJYV0JHBeP(O7(KFm3p7Au%RwdmK1VMXL;Lr zrkS_pC)QK_jjKuQ4o}nJuwkbj3;W>0fvjsmm9Ia&*WXMVI)6VdzGdCsGtWeHvNTeu z*C;w!)tF2#J+9nuP&rT+(oX4r>m$C`Jgd!}<`x@!8y8zNfJ9#IZ}*~3cLwz|#z^P9;?6CNN?Y&zE_pPI;!ee)JQ+>s8Q< zl~O{=(f{;I(lLqDfBI9ykPAk)T78mQ8tBJTJJ%e^z5Y#%ExmD;_1VF?o6c2-FvAzS z9zMHY0bL&SiS#$Nv)l>v#V4$`7RV`DI}Hvhd~c>KTJ=7| z?51Wie})Ss*~2LKc3FVC!=fHyHF;NhtGT&JsO&z!lGJX$Q3O;EM{`_^H@&NIb-8?n sZ)L0@>rVHRLs+q2$QCSfTI!sD(s;L^!zYFynbZ6XNr!3O!wSoP0Q=f6vH$=8 literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/farm_tiny_4.mts b/mods/a_mapgen_mods/mg_villages/schems/farm_tiny_4.mts new file mode 100644 index 0000000000000000000000000000000000000000..bc7131fc74ff191f0cc3ee3700010bf3506314e0 GIT binary patch literal 1662 zcmZvac~BE~6vwxX)e-?AA*3EquUNETOb~S^M`?LDW)e;yk%3!;QSL@ag7p} z0u4+mR1}30Fi1r4VfAJY(Vz$v9kL`CvJGNO0iaO~-i{x`VpssNT@Bj7nhzibx@j%jKAp-W8z2rI3%axQ5n=9ulYsy2E%^vI4!2&tgg1@d)yURO#alxlhmh_zXT z%Q4ik&Y}cVs#GOFEa#^O_x8;$4^u@93;$0lA;h3bX|p=l?MeE5miy`n^2=yx#%?vL z^Luc`9^N!9qH;_o=di)NEZ46#tuy>0?`uX=>Qnt+B{y@oj2d0c)t*&>&=fU*m5*M& zz}u63@2}}i+;MIHjL#PGtYd7PdU4GvL&jP>e$O~-KG5~2C6)hnvN7-bGg~{LTjQ*i zzg+4UeO_^5(*p8|S@K-axc+%-MaDX0Q(SXf!Z5Is@&$R&h(j7 zS@1)q$={##P0QlCkir+%FDh)k=X-=%Ci`UmPbvDgnx4~De*Hxa(HF*9BK|qfvxjQE zW0U=rZN-PCj4#XZm}97jA~lba3)4(w3(vrcdVMp-+uVab$x&~kROt}v932p*4Axb)`dP! z>0@-%mobyWqh5u@8N1FtT$*{LU&>*wEAWCG($1QzGDvyE}wZUn)USO7*hjx%JlHRw-sfUEh+Qax%v?I1MA5y^I5k( zVNOZ_e|{`@uZPeT2i#t;uAx%h6LT|e;9|ifzGaC;FFZBY*q(GCi*LHT#1auG;0s0Y zyrNjD@_5#UkqbjMsoU*+S+{eluC``a+RNSNc=oUcu6L(rbhVv3go46@M{473Q5AQ! zf7bO`r|w@Nta*L$Gk4|+f{h!dmR1dXWh{-Io1Y)~*rPXzajiapnPT61wDWF9f$qd| zv(20r>dQf*p8)eg&PK)vW@%{5K>Uh}r`3xCODaox){1QD%{*;Vn^jPB_)dQ*FEAgm zu;c&8W_}Whe#kGp^nT7ngKo!&xhpx%x~A=c*92>0(+l<}lzmh8v3HqAMCEoF_nLR@ z6W8Ql*>-%wG#&LLFEyx6f2!U1Wp!(GxBI;4mY`3w6|)YAs`V4U>zw|k_(HD-b(1Z abN%^VfIVt@GaJza&&&({_914(bN&Sox7<|# literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/farm_tiny_5.mts b/mods/a_mapgen_mods/mg_villages/schems/farm_tiny_5.mts new file mode 100644 index 0000000000000000000000000000000000000000..3b9d858e08bfe6645d2f75d1d931eccc742a59e3 GIT binary patch literal 1389 zcmZWnYcO1A82(b7DnVVAbX=;)rK;+d)o~eZ6N0vGAtX9_oIQJX_tbGdJ?E?=Aw&}? zxYB3Q#E7{$4d_Ufq@0sWQp67kuFC;25 z1n2-mpa;x0)d%bbyTrHzm6NQun4npNBUl+CrBQ|f<``sIREjg+3`?UNk3u;m28J4# zglHl#RkurU3d0c&LNPEfO#=;~1lf8_OJQjo2LcU6in2I@k&wZ~z(|9#sEEXY zspc+2NeLo`kOqcoDHhV03>ZsLI+38H-V7v2gu_{_kZL?2P}4bHhejAEr!idHr4oP? z;;{{J|Bo3FKd20tGAv5ad^RL1LNF*&88p@y+0fs$1D3BE$`76PJ?wCXpnR!nZS7o@t}; zx3wD#QWTEyQ9j#})*woW89o{uSZF#h8P2ds5=|uYSppLcF2co#3`fPlL>-YTsi!~V z|11fFEO<#hpF~bmD8CJ@`=<&Vq!WM+|3pgpLQHOQnX7@&Gt|3P@on6J(KkaJH#gzN z=_BdaR`t;R=jUD({@U93Wqti+BfDVYos#N=4MA~t!cLFU`q$U$TJ;Dxv;D#WpYLNkk!ezYkhJWhkq-6tKV_d+$rC_ef~D~ zlVBvZZ*OJLy`q>!7e(|~key*n<3~}xip4`y_DB9C18Ne!=h(z5q(EQrVd|v0mu#S` zDQQVGn^Ce~_mi3wMt03Yu_64Cn~09Tb1t^ENQnIWHE7tgT-1{hKr3Qf|F*o|nFL&K-)|xhJsVwzIOwIc$2Eaj~cD#KWWXUd~3oUdKGXoTi^6b{Fln?86~j(IAi!oufRQ9soQI2fA7{v z^vJOCO5OW;GJNeu;rM`$li##$bmw!m3S**jPQVGuJ2E{da(eYDJJHTZMxkE*OZurc zcxsLrVLjs9yQ04^{O+v_&235HoI|HFBQ}dI^k1L3V@=jHmFY|t-yF;gJGHODpRv?$ z4t+7^_=st{-q4)qDl7=FI40gI)23JQGsCAO>n`cA{qS0LNNASJth8G>ZCofFaQ^Cx z6E}i;4+dt%zx=`DC!b#Y*x`3kQ{Q!_|Fx=;#LrVj_8ptqJ31?c@`yg=TKx-NEVI|c zzi>Fb=zvAYTzr>uW&Z3NXTFO#KQ<&18o7@?oVdRltXsNNXfX9a96Fs=>zcD>JzqOo kmv+DZhrihJi$?Ay5A1HSMo3X3-yR&U;qFB literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/farm_tiny_6.mts b/mods/a_mapgen_mods/mg_villages/schems/farm_tiny_6.mts new file mode 100644 index 0000000000000000000000000000000000000000..3b7d92d1b306bbd9c2cc380b46a021539be83bb1 GIT binary patch literal 1434 zcmZWnYfuwc7`;f*!3RPxYKmCFahw`OA>q*=_!v7tTgSFG4VL@lC41#1}}blPMr21n7-fl_E9GCry()pUbqq2vCzGxyB7XU{p` zxBQcp%RwNR2*!dCFaLpAV2TdvaSOr7bS8?ySQBH!3=~e&AY6+W1~))jMj@ofXokXB zFn%N(gzyv%B(=s7cLvuG5C~`nH&L{VCU6a=MH(MA!LPs|ihDARmtak#4zU<*v@i^$ zFq8#J5auV-CIgAFI6;6AKlDnEcf?Q-4*Sy*cs2;vA;kUOcVa9;I!uGb0)byZ&v}MJ zIGDt{FyIWtv;?A|ZbSnHf@=iJ!b$kLCc|k?;NKGnH-kw2I#it&ktEb|d0&+{oC+s( zG=n(RP(4nWO{76aBNKtKkO32Un-+@1wIe7#aYSO0;jq4JAk1I3uk)9&!gwDVsKbm9 z=UD%P^awE{Vrq?$=5_#4nP4i<8;YPOaORc!Nq%E2R}~itSty@7p3ma6kxK$5^TOVj(wPiW?RP+YQDyX^IT** z*|Gk%)a_`oI_E_cJsNeoH{ss-^Q?Yz{0M(lpt6j<6RSJz zH63Fj6Q4;duDFGbZJ8^!%FQZkKuw2ia(Z3c(eI?T0a0aP^b^mqUMQEEv99q;e|3v) z7g(jXj}^+@1@fTGe~&$_nL+MfXnwchB>cyG!fs@$ob1)Y>pOZIQ`WZLIIdKtsUytl zFtPmoF#}tlROe=m?n`m!#U{>Klz%<-(5>9jEl)z*77xCajnv(dtJf%Ft*Sn!PPipR zAbv4-Fc14(R5|;PBOi4+FXogum%RAgnw-1S5Em~I&n`LMm{N5{?0Pn*Ul}!Tuk|dJ z5?_%lKbLU7;eO#)<5E2G{*E0g*DhCS^UrNA$>B>4ACx;(iYx0BM*|eL||eMbbo;FchA%3n1(KefK$!7=QB zR2iIhxT)PE5y?vqC4OT~?0;bUVo`B==u)^pujuW|=?Vb`FZCFNs%@p))#~mY2P@}` ze^{R1b;j2T>gVyXA2K{$xQacBQsV`%{Kfvu3MCx6ekYTPMP^^(cH2>YwMEM XG}H!fk~F4;pDMcH=$~I=7-RVlH&SvW literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/farm_tiny_7.mts b/mods/a_mapgen_mods/mg_villages/schems/farm_tiny_7.mts new file mode 100644 index 0000000000000000000000000000000000000000..7c3a0b77f86a69473de912e3e517284f50fdcffc GIT binary patch literal 1645 zcmZWn3s4hR6kP_eT0RX4AO(>sh@e#i!CIpZ(kOyJ#!oB?fn~GVd}P^2b~kK=(b3Y8 zaT(})tI zgi3_QU=#-wCWlKu;r>RC=Y*lf9q|M;3#93|NbcDblUmIqMAqofrLs<#l&~&xZd_%(a9Eu}* zAf6lmmZfE#k`|W1A#Vq1HaOiNrNVFpC8<;^T zm6}jO90fwAu^S-;)Huvw^mN36WgQVf?^$apv?PJBWu|B5b)O6%Q{T!9g*eupEPhXU z$F;q$LU09akr?uMI|i$X42-1N`Q<2Zz+kK!N{mDZwKfg1XZ884aA=p4=pLWbmMz>^ z?pe+|Jcqb8F&Tb!(YKE?_f#30wr8D=JCS@u+E6P^kl$)?I^f~T+47a$U$J%p^ON;l zch{1E%h?r)hM2|@gL1HE&C#C(d+U_XH9?bk&lY}3396Usm&!-(gcu+2!teLI<5T^@ z@9)BEZ;8;lPBnMo>EHywv2owIY7K z<4|D2`MVOoD-Fr^A0x=D{x5W4;tqc4;jJ6JR(c;QGaq@N^NuSsS4K@xOD?k3e#6ha zG`!CKQcT)Pth+oYLWCNdRLyoty~U%t<=oudt_J|33y6(dQYOHLrL_+N9+0!5Yv@)KQUia_XHP@ zi~$Fa@pAT30AqxN=`K-BtS*Ur-u#?dBCe36Dgt2zt)BXbPr z4z=%SJlArDG8LmE!6}l6Su2Heyu;h}Z|Gmk(^D6EqUWDn@qFx6jA8fF>hD1+FkS5fb#T1x_!%N z!SS1C8y0QqSP^Jnu)4wd)o54Diu%_}WlnjN!%^;}hAEH@3Yr{ENu?E$^3;B=V}X0; zP`+$|qp~YA`&s+0k-D`nM;H18Oq^=2n-g03zTfYKVQSuY{VBZJ&K?R0$Sx1eKhSli zUtN2lD3>{#_40#*q3u8T)#%~5oW4g92Uj--R67;s{-)*}w8PRN9MUz*3ao!#Z>m=xX-HMg|_zv;E$-I1Cd i4nG&1y#5iVB{X^PUWr)MyZG?Hs*20aux`nQC;tI+cF!3A literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/field_1.mts b/mods/a_mapgen_mods/mg_villages/schems/field_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..e0fc520dc4116063ba5bf3c6464b793a17439f8f GIT binary patch literal 289 zcmeYb3HD`RX5eOEV-WZc1`M1GJSnMZiKRIuRw5HymYJL{LGyA^3)OrewavkMrvY7ykW(hw^QG8H7M}7ny-EHcm5Xh7tBJ2 z?-VpOzs&oc-yw4(S7}j`L+JM7@kS>&j1I1vD#XV=b%LtZnaCFb#})tf?7QE{SMp;v zbMD E0P75O2><{9 literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/field_2.mts b/mods/a_mapgen_mods/mg_villages/schems/field_2.mts new file mode 100644 index 0000000000000000000000000000000000000000..bd78dacf29abe863e1597c9ee35d9247412c41f2 GIT binary patch literal 264 zcmeYb3HD`RX5e99Wf1re0t}oCJSnMZiKRIuRw8Zt5X{k9W<*Dfm z%!!#r2t_4Dsi_PCX^BO-nR)3}#rc^z@#U!{416#{a#9n^Qi~b*VJgZqQWHz!4H-mW z3d$2pQj6k?^Gl18QyIizq9D8D%QH(d;?s)~i;FAfyq$89>wp4>t8w<*|MeA~0z3z2 z0^4;zAqk831f9LFf(__QV f<%R0)5@$$=Uh~z#e9!8qXJZ)-6k8oRazqFKvW;k> literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/field_3.mts b/mods/a_mapgen_mods/mg_villages/schems/field_3.mts new file mode 100644 index 0000000000000000000000000000000000000000..a3cfed416320050a36ca1cb5215df626bdbce3e6 GIT binary patch literal 172 zcmeYb3HD`RX5e68W#Ib{0t{>nJSnMZiKRIuRw!k-mqd$a)JVb z#6<;RMh^}H;|&UqX$$zmR4lUYt*Bi5j92;dzy78`2PTCX|J)90I507=Y&B8`0AA!h AKL7v# literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/field_4.mts b/mods/a_mapgen_mods/mg_villages/schems/field_4.mts new file mode 100644 index 0000000000000000000000000000000000000000..45f3d1709b72cb37a14387720bce8eb5017d3613 GIT binary patch literal 132 zcmeYb3HD`RW?*MvWnljg0zd{&N@`kSX-a$0W=?#0Y6$~B zOr$&`HL)b#kbyZdvxq?irmH-$B(*5MIKQ+gIkjR=a>4;-i9iKmt`xV%=DQ-(9G^^M UGdXxd8tW7naSAf;dbZB#kV=nVW8vnVy$ll*+&lvpKD_C@(QN zm4O!~kercPT!P@1;XzlmVfBg4; z`QljblyjlGe`tQ-7$mD-7-alUbi$6>{ltDGGxVir4zu({P|Np1{*LczWKU)e7{(rZ(Kl;*A v;i|BCaN_()UYGs^1U~ztdHa4?)%^Q6{Ily8)_+&>{wuyvlv`fx@0J$;llP)T literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/forge_1.mts b/mods/a_mapgen_mods/mg_villages/schems/forge_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..5b8b1cce096d6ed3a60c34b00c7c693e5e5df517 GIT binary patch literal 1021 zcmZWnYe*DP7`>zf`CherM+Mn~62Y=sO%bA`Py~Bv(Rg>}&LgL}Iy1YYp{`_Psf9-L z6c@34C9XXdrBX}7@Q0Npr9o|3Q6yT1N?Bs-V^*d6?>pb)ob!D*Zf{~7a0D*E6)Z8% ze_#dhp%4xAysV`-Q6>~lW(h`wk^~$eCxSo{%Q9q;q*XY9!U`d=dRayyfzyxxyzE&K zW15g;5h_5V4wRrkNir4?a8n@?>vTKwmi8N^A2wJFx#DaiG8H=;3=A@D=l59q?maFd$Jz6ws*UQ(ZIlUJD>~ zYyS@c?&@Y}y(mBu0WTHcp#c&S){8c9&LF$l$-*U3c%Pp3! zboX<)qB*5$S*&^6G2r+iOBJi zx=QWh<9?ZJvbF5=_Ba9-m^9JH}i};59Zh8IFF8%C0V0Ro9-6ui`lsD z&C(2gd#o~Wt+3COdc>O3Xu93<9^yt8of%!g0y#suPbmP15cC;JbC60mvz literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/fountain.mts b/mods/a_mapgen_mods/mg_villages/schems/fountain.mts new file mode 100644 index 0000000000000000000000000000000000000000..43bdaab4f3cfe6c61a414943b1a42fda9eb1644b GIT binary patch literal 291 zcmeYb3HD`RW?*OFW?=u106+nrl+?7u(wq{jl+2HK`~wIh%nOCRUPP zl$?R!f|W3c!eq-6OHzyC({l35GxO3JL{No`^Gl18QyG{OGm9$bybX@#I-i^}u+LFz_C!21t>y|Jbo0w=6!M&him72oJum5H-6$GiyoPNml;naUTX4B4S&o6B2 zs+@Y(FITmA(wY@>Rved1Ydf@0_|28X#Php0@7}X{_P^Ql#r1P??!U>u+vwo4Fem7- vtnNS4({VnbGZw6O?K{@e^~U8+Ur=~A&sAT43&ooY%dc(toPBO>g8ESaS6zcl literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/grasshut1.mts b/mods/a_mapgen_mods/mg_villages/schems/grasshut1.mts new file mode 100644 index 0000000000000000000000000000000000000000..00cacbdecebb6815f8b90a95df5d68b264fcc1b2 GIT binary patch literal 253 zcmeYb3HD`RW?*ArWnlXc0zjs4N@`kSX-ne%*uB+ z%;WxC{d#!C>b46KUvF4gCo_3ibQ*5v(h<${Z(SjJ>ho!ad)nE_i?r@-%-C)S0CHVv AsQ>@~ literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/grasshut2.mts b/mods/a_mapgen_mods/mg_villages/schems/grasshut2.mts new file mode 100644 index 0000000000000000000000000000000000000000..0b8c006041a9d42c7479e99534a2c229a2a143c6 GIT binary patch literal 423 zcmeYb3HD`RX5eJtVBq`@1q|#A!YQd~iKRIuRw=2)sYNC6#ff<-K*6HQf}F&>l47f( z)YO#t;+(`J23dq)d1?t*yeL0EEj~HFC@-~$K@7VzgHUpQNl9XQYOz&uNl{{Xd~RY1 zHnm_Ym=iOLD(1YMa+|N&fTQhUer(mlR`GrRSLb>7-#Yy4*`^&X9&hwn|1^ayI+b_O za%CAy%9X&UvLDU(yQBA}iTPdkc&t40g>;MVyw;0@tC4X=G@|vxwvrG?O^WAv=`O43yW9%>fpLzc0zWJNyuD5Al`~SiJ z;{9(n3Ez0;vcsw1@s&Mh>4|g2mozCdy*Hb~z~m-aWi2$Db5&7SKm z)53YxJNl)?@^7+pG?G+O@_x5W{qo;c^PeSuz?Jj`Np^~X$5`g}UwoBUYxG(n--~r+ W!=8Hg>eJWfa(#6B$t=S)`4#{t*26mh literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/grasshut3.mts b/mods/a_mapgen_mods/mg_villages/schems/grasshut3.mts new file mode 100644 index 0000000000000000000000000000000000000000..ad3cbfc3236c606a2a50b09f27a19916ea1cd904 GIT binary patch literal 433 zcmeYb3HD`RW?%=w{}8~y#UPxLnwD6aQ(~2pTAW%`5?`E{m%<>MQdC)xlbBahY*n6G zQk0sS5?_>`pBA5-UzC?x#2|)U8fX?=8(a^DU~x`j5`#QKB^C?fjTmH-^Giw+(^G*C z$jnR0FOM(IC@m>TEsD=CNX^6M0I;z_a9tURIcf1J`T0c*%!!#r6?5JOzvVlm!1IQE zg-Z9#>i^|eofx?%Z;8#`T8V`C-DP1kFME95n8YBIoL^Fsn4Vf}Ra{b(SRS97Sc1&} zuv+HC%%X}pZzo^mYgXWKt&WbU_;~Qh|NmFlURjvhq0_x@EpLoQZaNS5CX6N+0ub9tLIQRA3_dK%~pDR3(&3SNcSM=t`8{c}@gqQvN*fQbo zzVeLsj(Ypri~m22uKM?uZ*j7-`a7N06sJgqM)uOpeJeR!T(vh`xU_oq9);67(=@^q l#GZFCl47f( z)YO#t;+(`J23dq)d1?t*yeL0EEj~HFC@-~$K@7VzhFKsz3_{8IB_)aJsl`^sB}Iwl z@wtg53^H)B^31%H{POtXjM9>l)S~$Og48^0#)DmjFexK3CoMiDKfj29IWe=SV$Rus z(|ipE9L*1ty=_+f|Gz%!nOx4SijN7Lyo^?t1Vvd`+_z0tc5FMo;g(|R+L$Y;@8VY` zND1z{bH(e@v>8`s*zdXhYwo?ja{FD19vd6p-FT@;aP`i-RN=&1TUOUHcFVpOa0^m= TvTo+16r7R{9W|3qU97{*GewB$hGY-Z)`}@9U(<>v?Y0cxv2UtdZ{5OEkM8EC1@0|> o{Vuy${M+6-&ikx^%F8Tt`!dZ-SyWA*v+J9@+EB+lv0%m=020k-l>h($ literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/grasshutcenter.mts b/mods/a_mapgen_mods/mg_villages/schems/grasshutcenter.mts new file mode 100644 index 0000000000000000000000000000000000000000..46c931d6404be589e25f2b499dfa18bb64dad54b GIT binary patch literal 150 zcmeYb3HD`RW?*MvVqpLOpMixzI3+bLu{5W|DkZfzwWuV%I597UK{7e9EVa0#G%XD# zT#%ZSl#?27#2}QMUs95oo?2{GTvC)+9-o_7!oZxESyVA6Il+PPOu`9{r5B${OnkEO zW%99A{ENCdS52;{ZF$>#>i=>}hln#r8cwAp9pIYbc<90VPSOPc+EhKi literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/hochsitz_1.mts b/mods/a_mapgen_mods/mg_villages/schems/hochsitz_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..b6acc4ff735b3a19654c34857fc8842908b3da6e GIT binary patch literal 407 zcmeYb3HD`RW?*IDWMKUd0}Q+j;whyq2&CMlEn1XVyp7}{FL~#oWv3a8H8A7UP^v>d~rr;Nl9u^e11V{9)l3f zgtXMWcaS4M2+<>C|{4}tk@x?%sQyKW+GD$$)84SWH`T0e~Rv;2= zQhZXpA;Pqh{32{>N`Pv3U^as6ub6Xp;zO>(3Op_6=bhW>soC`Y|BC2oX-fmPIQ=(m zSM&N|qqLzl*mqjBsO#&S-7(J9MH{ZJS|R!|z^qm3O>ail#NUf5Rp)ukvW=_YpXhFz zp7{K1@s2k?U+lAfe*W%bd-M7mL6i3ASoCsyq2&CMlEn1XVyp7}{FL~#oWv3aUYMGa{G#Lx1_`*5qWt_cu#)&c#sJdbFKzl8Zt5<@xz3@o71UB@99^9cig~$*J)m2?idR7?>xLn_rZgl#`#FU2IjHlb8fi zBLO$7C_g_9Y*su_wj`B-52iaOF(oCnh(Q>xG9$4hIRm1d7pABrzbH9_K@{DN;*$Kl z)QUMz15ficDDX(T&Xw>#a{Pb&%D#3t9zngTjc2DVyQ#slNO+Y)#j;g>*Lh^Mmpkxo z4SM(Gf#S^9Hm4=Ketdb)HR(XmL)N|JbMhaBxI2d)Gk;(4)PCFjrXqu5N5VL}Sr>~M j+VMQR^`9N@`kSX-e0gR`MtpivVsSA8b7E!@gHUpQ zNl9XQYOz&$ett@PT25jKgD_kyBe5hoBOWBfzy~uXCov@@6{r!$PfN{9PKBruPRY+N zDz*ZVV1f9gctZvZ!4jaL1l)?E{QNYqweiJ3yHgo>Vdj?P7bRy@%sJbCkgLIf$N6&D zbzU3ZKmYx&YLzM!UukClEU_?_L!{th_6>`eo`2sjwcK2A;quMn0q<2(7Qa_M?|!aV s=u2(U`)|dGOM)8a%ndy1?MM&C{Gg6C75T=#n7bRyf z2&d%d0}TU_V4d+v@rIa!B|t%Dpy3sB-cIi1I-tPOc6O8O-v6K9`4z3b#b}+de?!T_ z`4bsAG#_d^Y^za8ZMea6qi5~Y8wo3{*M0qRRJCaKL=n#WMdpR-mb=7QYCGO#_mn*P zZ+y8xJ+n%=;;rj0?iWY??LHT0Tk+ofe9iaQv%A{9Ez;O(*gwrK`ug(KDT2DwoOW4V b^K{{#uNiK%w8SB1|NB^{9^q=0{QW@yRj-xW literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/house_with_garden.mts b/mods/a_mapgen_mods/mg_villages/schems/house_with_garden.mts new file mode 100644 index 0000000000000000000000000000000000000000..bee33d13a42dd08fa3550e32e2328be8de71fd14 GIT binary patch literal 522 zcmeYb3HD`RW?*CBWZ?M^0}R3pd?~4EiKRIuR>}EENja$uoVn>%ndy1?MX3xtFsYKF zR3u(`etrsr5KJyDH7_|e9xTQS6D!FtO3q*qC@x9NEGo7t&PhyyC=i5+fFz(oFg;26 z`Ps!8sX1v3{4k;PqQv6jcoPQUl>B_4IUo|ODLyIQkU=6XC%-%uB%GL+lA4p5pBG=5 zngbNWR9*s94tHC64$x2rUYPE(%>0~0gluv~YHZ^?9R-tA5Z~Ar}uJ~=i!7!Pv19OC4KDhegjMSVo20=JK zDK#ZNBQ-GvVMR`2N=j-GgFtZ!&^N_a#W{&d@#XpXDGb6X`T0Nr5D6BDPl`80Gbt@U zzXVfV2~Zs(7?Lwmi-Dn*UzE)t19wJwW?o8ud3;Mrry^pqV)oxGHLlxl+G4lP zOG{cT$1D5vWr9CXbNhAYB&EtV>5C6V*l*s^mTG&vpvtT2oTk(HZ`_9eHiZ`)y!>;s z-DcCTk`LV8+ljn-{Nh>e>)?0tbHDbV{&hU%@8)Z9=cjwT>Hb{$|FQbVJ58%DOxtQO zu_H87MpdDLDXfR{_pc>>N>O~1jrwH&ANo_WkVUPb|?Ij(>goDoMiu4&g+Q?e6U S@@$D-O;=jw59X@Jf1?2BVjso; literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/hut_2.mts b/mods/a_mapgen_mods/mg_villages/schems/hut_2.mts new file mode 100644 index 0000000000000000000000000000000000000000..de1d17464d75ef1ab9eadb3a3f4dbaebbb2ac122 GIT binary patch literal 771 zcmeYb3HD`RX5a)uj{h*gAi*G>lA4xSnp0wxl37#|U!GZ#5uaX^SX|7&oS0d}zzdTt z$uCOIU=U8uFDXe(Pc618%Fj=WFD@xcEN9?>sVUFTPeJfXic(V<1YvT;iFql-CHZ-& z47_kNa`F>%8D!yHu#w66d3mYHK--{(^TDNyGg5QX7!drD#H5^527Z_YX{AMZiOH!9 zd@zCJ{3MV9gp-pqQj38;%rDAj5Q3Wua&vrIPGSjzAY3ddH6=bHH8F)jI3+*7sMrcb z0`&nECdC_K3YLHb;hNKPfPoiZkO=gt3|z20GcP5-Jia)iw4@}pC_cX+H4n|cwEX-M zB+n(K<^h8n?w6dzl$6vW1~IsS5Wf@@WtJtDq*ly%JN53QLkc{t!bz^#Yu}Y!uKllm zm4#{B(#KckzkAbaDW1Z>FE8oI*mXcBU0L*y{S~*6gV#bN6It(t+}!uEC+Hnp)Z|Fc z?aZ!D{M9Q`Z5)z++sG{B&04c>*K?Iy?K4lz$+{zQ#<%d(L)AmYao^4AB;&d7UwArI zeq!3M`WGpz#($^${AqPwaMPR%-n_3Ts9w6qQM>Gg`t}`XU+7*_S#x-%jEMjBUt5%& zo+kbf{TQun=5JA}x#z>uH3x%V#clVLDxXza$rWq&v9n&_vHPZ(l@|PL&yH{R?yT-l zRQLOp%E4*Op056Ji=v{OsiM=zWR;))UP#{J%CP(~VS<8ym%C@nlx>+!Pl9v|d*<>S h=C_nu7V*f~pd{@{kdXd!xz9U=^?$`M>NZVC0RZ=8J6He! literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/inn.mts b/mods/a_mapgen_mods/mg_villages/schems/inn.mts new file mode 100644 index 0000000000000000000000000000000000000000..e37f8966d35a445d4b438581988977a0b83610dc GIT binary patch literal 580 zcmeYb3HD`RX5eSwVPOA{1Q_@jcv4c+5=(PRtjhEAQxLq8qSRCdA(&ioNq$~xQc-4d zHUlqAEIlW&xR^n(xFj*NsMrcj#e>b@%uTn-OwY?NN@Wm$$>t;`K_ubYlQU9_OAw}& z%nSE3yL#SQsYzd%kvndVX`oLktLad zIx6P84Q~``Qs9wozGU+6e=)bnl$$bYH|HL`9lGhcVZ~!JCV_i zhsIX_uT`GgyfN;~{!FnScQ5R^Xb~UPUmVKn>1yX*d#_Bp^7w>(U>1_Y@ca; Q<;33sn@*^^#4;oR02!10tpET3 literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/lamp.mts b/mods/a_mapgen_mods/mg_villages/schems/lamp.mts new file mode 100644 index 0000000000000000000000000000000000000000..14cd338e39f5fc9a4eaa6c8d4ae64b840117dcb1 GIT binary patch literal 118 zcmeYb3HD`R20|7F=Knyzz{kr!a5=$sDWnqSQ(T=ETgRiaE&%2bd%dst8M+JaK?$>cK_->;)MXHnJW}VVcFo MzJ`ZkWvKEG03zQhs{jB1 literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/library.mts b/mods/a_mapgen_mods/mg_villages/schems/library.mts new file mode 100644 index 0000000000000000000000000000000000000000..76381ddaea636e034fc2c22c2ca1d8d35465f6a9 GIT binary patch literal 391 zcmeYb3HD`RX5eOEW8nD@1`J#bJSnMZiKRIuR^|EmDGUO|C5f3u#a6{RiAnKb5kZ&; zNCG0nnVW8vnVy$ll*%9o)18!`pIw}hnv=#LoRXgpGyz0{mB%N=8)6EU00ntrnv*k9 zi%SsP^qj=vVg_cQeHC-wPVMAtRuFJW-=1~)e|ZOt?m&89@*?B2+*Mj>V(@TvkU8=VlYeZMS(|%ZVBv$f9)f+>PMN(~+ zr#93~eK`Gd!Zpd;tGvG7;a`|7A#jtwDE^6LR?N0_^?E-NIJJ*I*sZqxjZ|B~o`VJQ zhec8+ta};wup;EHelX8hy@ku|t-s1iNeOlR*U{^`S*!Hi<@-tB1-leJ2WV}4L1JENd~s$c0y;Z`K@jH0r2PEs;*8XsG=xw}QDuB_Mp0=J120Tf zNq!NsrsBlBl;V>7JfJV(_9UgI#Al=?rl1L><>!|$@WaeWD=o@POio1@oSczbT!M&| zoWzur)FK9P6fc2oN-D}s&SnsTTL%ih__UnF5=4X`)K$!R8*-7a$$-b^+Dix5K!Lme z>sL%G(`lACaK^n_^6kM}(pwk>w4Y=-@JNf*CRj73Cal}u?tIdFewd6bleOB3i`qMry1HTGI2=6!@F#mO6(B`f+URN@U#Cpp(x4np!TvhJe%~#&{>wwhCo9wOZ z^A275{(ApA`K13chmT)g?vwrdr1+P~QFWocarM7fDqi;r=9?S7{btmolPfDF6#I_k rp1jN=xm#&jvT5wsj=8cj7iP}tkWzW?%(%wvcuT`<%t`@ literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/logcabin10.mts b/mods/a_mapgen_mods/mg_villages/schems/logcabin10.mts new file mode 100644 index 0000000000000000000000000000000000000000..ab25bc3febf8dc4df57d6c31f781f47b5f4128b8 GIT binary patch literal 596 zcmeYb3HD`RW?%=w{}8|+!XTcKnwD6aQ(~2pSyU2Vo>`I+pI($$T+F}+lK^tdQgaxX z6Elk#1d2<5RIycYPGVAgd47Hh13yezT4_;UVsa{j5KN%BBtI`TsVFl!n?VR!TXKF< zQcfy^FiZ?&Vmwq3t~skTFFhv}Yy)3%eo0AUdTOy%Qfgju1_Od$oRON7hQu#P1Q{#= zSD&5(^hkU`VqR)|ab`*?124>J$r-7|B@DtT`T0Pcc%JtwiaIKCh;FEze6GbNQl2w81%eo|5nPz+{hR%u>(PAb?0 zLAVJ?sVVUpsfj5Jd`Loh$r(ue;*8XsGzJ;Ce0gSGN`85KaYkuLNorAienDy;1FC^( z`S~Rb!Z5dhoF5N$jBrYRKF}{966}}wqrxAix_xe-bl_!EiPdY zLO2H)B=KoEi6so8aIxZ?)YO8^y!7~7pfJK`C5fN_;fI-&R$7#on2Z!c#U=T9sYykd z$=MZi-Uh!FYBJz?Z8kxXC*aw~fBvgpniV*oWB&7FaqlJWh{@CXG&miLnmBw|r>P3$ zGX~lh0v@}43+q^pT>1WEwUF=%rMIt~U&)nzVN;peQrV*yH~UD;UIwW< z`E%XaO@36BF-etAb=>Z$w(;)Kn7=$f)J>PgTK(laW1;`g^Lg3Eo_nY6&5d{!oACVI z-g3|PZ?9DM{GD8HQ&?N{C?_HAxLTFj&-Lj!g4gT+r1ZRAW@+K+7rl78%(Cas&6{^F zmI>E8ey{srQH}|P=mV9Ls4mi*GZ0%WHA&Dr-8EcIm#!L?2TITuXPN#|2&aklQ eo2^bo&Rw8ayQXk{>K{(eU7t)#&EHouE&~Ac_a2o1 literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/logcabin2.mts b/mods/a_mapgen_mods/mg_villages/schems/logcabin2.mts new file mode 100644 index 0000000000000000000000000000000000000000..3247a26539e4de30cb1a7336c9101bed17b88953 GIT binary patch literal 485 zcmeYb3HD`RW?*ArXJGjc0SrP6d?~4EiKRIuR_R5FWvMv~LNI<-XI{(8PnWyP`ETzeMp*igRpceGgg-p}vPFe+CsE@WGlG$(VpkK*&mH%-cS-~V=3 zIBR?U+k0XA4d>S@-H#2OqNk+0TItdyJGV@}?-fF3hySmz340~yRQzm0^#bwu8LPtp D@@K}k literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/logcabin3.mts b/mods/a_mapgen_mods/mg_villages/schems/logcabin3.mts new file mode 100644 index 0000000000000000000000000000000000000000..72a99144d1989615b9b050768f8c73d7a014d748 GIT binary patch literal 616 zcmeYb3HD`RW?*CBU|{q5GI?HpPyZvk(!f+5K1Ykj4#e8DosLiG(-tM+%-vwMMbGO6?5JO zT@-3E;CUT2fm7+lm;d&mo7eGFBrMo>>rUB2u}kY@C$=6=5^`ld7Q*bLzM*Z;!i$sr z1?CEKtB)4THcb(W15TZO7! z)A@gg57k>l)VrJSO78ra@U{F)K+Wa(mh;TwPuhC@Y5%$JUm(xxJ>TUPCwzO|nB$rt z_Dc1VogL4lSlcOyE6bP8Z+dWsHPoWhKfzyq?q$2HhnKDn>Bvmi^SICdTxAOYhspfV literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/logcabin4.mts b/mods/a_mapgen_mods/mg_villages/schems/logcabin4.mts new file mode 100644 index 0000000000000000000000000000000000000000..dbd4f4a41c3dec272b67f1e8c341af1978b7f2c9 GIT binary patch literal 662 zcmeYb3HD`RW?*IDWMKaf0}K)jd?~4EiKRIuR_R5FWvMv~LNI<-XOEeaYj*T5|Xo$ zfWeZ%AcJsLW?o8uIZ#oGXHHtgmbL0h z$bA3#C$86T6^lE~%EjZ}Bl)!B$_s;}cVF!Vs<}kcXMXM8e3CQe)R~?Y&S$?l`5rxy TVtjf^q^yz8W5c}p><;q*tw{`$ literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/logcabin5.mts b/mods/a_mapgen_mods/mg_villages/schems/logcabin5.mts new file mode 100644 index 0000000000000000000000000000000000000000..4fdc80ca3166cc241645612f87146d66dff9137e GIT binary patch literal 470 zcmeYb3HD`RW?*GtXJGvg0Stl+d?~4EiKRIuR_R5FWvMv~LNI<-XzM?XQbw&G4R1nO-jv6&Oj(hDXNSw&L}EP zV&H}8O3p|vE%N1mvA6DcbVtcNy>eyF=Ryuqr(4k}JkA2*zl6K~EzW=EAYJx; GlPLg6f4mC- literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/logcabin6.mts b/mods/a_mapgen_mods/mg_villages/schems/logcabin6.mts new file mode 100644 index 0000000000000000000000000000000000000000..d3a71b77c1299a6e1c3890665946c35bab872050 GIT binary patch literal 633 zcmeYb3HD`RW?*GtXJG#i0SpohLMf?fiKRIuR#~Na={c$8`S~dbv9#2@Ag z&o4;LV~~K$rspIU7snSQ=B36LXQregnNysRnv;gaPXdN%2EvIY`9(l356s0WnMEZG z{4icxX;EHcaw;N1ic9kIQj>}@ld~)4JPm%!cSwQ9W}nE#pBo=m{8zua*m0Uf!MXk4 z4vA*$H1TCzrRl_-zCJadBQ`=jFL7g7$?mS!!+qK3quI|-y)Vm>t>q}v_k~Y=9(z^$ z<|B8mZ*2)W>HRb)blr}>ON>6*be`(iv2j|%?t(f~Z}U%jSNAQsHT_C(<)6i#pL-t` zNYDJ>u_nU&Xm-5Dv9PW~DGS(y+}ABvx;W?h`lU;5@N4~%-*&-g&rRW_CO_W*0K7Q> A$N&HU literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/logcabin7.mts b/mods/a_mapgen_mods/mg_villages/schems/logcabin7.mts new file mode 100644 index 0000000000000000000000000000000000000000..91242fe6b9d2f64b221cd099de6f1bb085c6a566 GIT binary patch literal 764 zcmeYb3HD`RW?%=w{}8|+!yuHBnwD6aQ(~1>nwOrFTArVuf)Gnf%}Y*=2a7Q$W)?9B z6_)_1Vyohu#H9G-{G_CuR0jU!{F0Ky^weUjq{O14)Eou@WJO@Tf-n(~ZisQhDf#(8 zgFqx$AU-MHkU;`&RC-QgadCV>VqR)|ab`*?1BUVvpmIK#)6W zD1zeCauQ1_=DZDg%hzPU^Tz4|=Q(~hrCJxp>C^%c>=HtvgNMCi>K^Dw(jx(&`eY&EvhE zugoJ`8&2t#PCmpMUp3)nm)2qJ?4G=U9nDob>k%CYq5fXi+W|*$D9Kz3a@zVTXf98t$PK@Z>dsPGlQCt(Kaptj+o~!7T@tQQBG-h9eYspzcKdF7{7_u++_ek< D+iKp3 literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/logcabin9.mts b/mods/a_mapgen_mods/mg_villages/schems/logcabin9.mts new file mode 100644 index 0000000000000000000000000000000000000000..4a8f84c7c5385b4839fa3af9d7e625be71ffda88 GIT binary patch literal 745 zcmeYb3HD`RX5eAqU|{u8tkS&n zoYeCC{1gTrm>8JHoS0dJP?naOmz)|8mf(Xa1DaHpn!_NFmROXVnU`)=oS&H!U!GdR zAd;M4Qj(aST5Oe+SX7jn6Q5s@n#UkeTmm$**s3@uF$rRla7unYPyj@N1>%$94H3qH z49U*}ieM-!0SXEso0goPl$4XoAPf@&SriWy7zAO`N%{HN z#TltNX$*o$N>bv}^7D~(l_Y{}5=5~H94s<$UFDg1Df#8`#Tlg~C86_!reV!hA8SWHs|M1ke zV|6R$7v%pxbbUtD?tOJhb`}3Sa~8~xx@*}r@t5ukec8YIJ-_|8y+8bK{mT7|xrO$n z{);vHnN?K9^L+X9{j)4<_5K^%TbKP|{BhxH_Og&yOD0`(_jVNYJ!bh-@l?9hsV|1R rX6T<5`09IXt>&B?`+hOLo^8js*1qp2(`CP$a<6AbHH_zFJ--70a7H)J literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/logcabinpub1.mts b/mods/a_mapgen_mods/mg_villages/schems/logcabinpub1.mts new file mode 100644 index 0000000000000000000000000000000000000000..8aede5a8a175af60b3ff1f95188026a0f26a8f61 GIT binary patch literal 954 zcmeYb3HD`RX5ePvWZ?M^0}L_@LMf?fiKRIuR#~Na={c$8`S~df%!!#r3^K|2B_)aJ zsl`_1nRzMsJDn2#M0lb8h2CWI^kRfRCBBoU-b6mE2JPHJjFW?p)HZej@oKU_E|v8X6Dhk*y? zo0QC=5(KZLC^eNq5M~d^RS>I%Q}XkH4g`^4f%v3&Lk0}N5}+X5V6ablVb&yPq!yPj z@WHt0MTuoVR|vwLm64d2lAD>6!vNP&l3xT28h)6Lw9=xy#N<>&covuB=cOhUWhQ4c z2qPI&lAM7a$i*3{IcW&Ha}rZhQi~YGVJ3q@Aig}aBqJW^s^Ve>fwY|b@>HO2(^HEQ z^D;|wE9SfnPpocI5NKnTPSpvXp8fm({$gtvK8_gQwa5AIshtjccoBk;lZ*et_AKB59;U%o%wM)NlT?SZlV3O%$TEcw`<*4>o;+^F8;pN z!sYL!s~gxvQx_~;5+zgUBDKDJPv4d29WxHRKC+5I_rvVZ5l1C&e?FZZIJrwU?7+1} z2XB16D6*AtS6kE(tvg+pRygun-KkK#b@z2>AludgExQ}7zd|CI#j8z13OObIbnS9E zL`Wu5xWZ_q%NG)(_fQ$L%hzua$n+Et3@*vsr7MzV+g)Pd|E! ze&zS6T|b}xoG)8-IjFP?(4j)L)#rsL???q z2=X$#bJp>W+KengRs*jyH$}J_sznafs0A@B6JHg&ph~Lozihz~vrzss%MGs0m=iO5 zgOTq-VbNmsRl-cwnX^wt^d;SMF>On#`26v%?oomBb651WoohWL?lg7Pj96e^yzqQ& nZHLGtjSr%E*IW!U&(wWS+_Fewwx40%ViEqg@8Wy+Z!QD?n%I>D literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/logcabinpub2.mts b/mods/a_mapgen_mods/mg_villages/schems/logcabinpub2.mts new file mode 100644 index 0000000000000000000000000000000000000000..668f93e5a0b093e5579fc9c0013557f935e65331 GIT binary patch literal 1238 zcmeYb3HD`RX5eGsX5jgc01R>rLMf?fiKRIuR#~Na={c$8`S~df%!!#r3^K|2B_)aJ zsl`_1nRzMsJDn2#M0lb8h2CI}M&sYW-cBoU-Z6mD{HPHJjFW?p)HZej@oFU;-98L7o341#b~ zNvSFEY5Do+LK&%vDGWkzRUk*lr{w?*5>Cm_2Ral)f*lZ_6mN(rSOOH}fmxZ7SyY1H zl@z6>BAio_Uj+0%Tq!tk_~F(jB^DK><{3p^gT3K*GP+xtIx-K5_9 zgv(#1n57=}OZ%9u;E`pvzl>Ewg!P+W`-Cj= zS60(1@j0WkFIOvR(asZ(XNvY+WxSimU;h2C+-9lk?lEx>rX(D5*txgz{LT}bXI460 zw&|YhzfC^*TXN&g%FAbFwc6}{A+_qm%QI#<^%uV?e|&jnTkn?mx!!yGW(w*ry}5#A z^JfWfWACj$v(mh`M((s#y5@RiN!<3Ti3QzBX6Jo+&(6I1f~)S)zqhxqE^~=X^H*$~ zz}>%(aq2U(^swHamgkL6nM_M8yE1iV^0)m@W;Vrb=iC_+YdUL5S29Vh#qWKjK_B%p0zhBnLo2>KouFRe5o9DQ;yBu+8?R#2xnXl9AT03jn zVXiZAlkY9q|LVtm|1Y-TacPT-)5_j$+4=t2{<~$jbGHMDw|UWje0LiPbGxsRK07DP zRq^zq4c86yPA_2mELba1zIBuD)R!wK?^bON{-L2$w@!3Qp&$2t_n8a_l~ex&p7NMr zQNrHWZK*7^C)U~E*zAj;-=_I+a0XeWmWXIfE{aVHpL9Iqk>53jzh$Y91r2vIMi^;) zQL&ln-k+u)5V>~8wL@nXX#IOMrBt>gY^G#MJflre*!9XOYn_{{tyu-NA`-gpB8> uPc-_Wm1>pGwRWk5zpH!S8V>%wMiDC*ewb`lt#+5(%Mrf%ta-+~08Id4hadp} literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/logcabinpub3.mts b/mods/a_mapgen_mods/mg_villages/schems/logcabinpub3.mts new file mode 100644 index 0000000000000000000000000000000000000000..0427a866eca2263eedff59a094e200bda2d4545f GIT binary patch literal 1650 zcmZ`%eNYoe96gHGLis49DntyG2n8xASRBB>IDk@Xk&%xfMa+3gE+iq`LGD6AuzrA` z!689Kpa!&xVrwQaU`2$&$e0iYfuItqh+v^06C0K26j9LzB*D??{;@mz_WgeE?c0q> zh>roR0RmtL*u8yk0A#?K39}#p4-e%EkW?NlL{TPS4RQDY0mDrT7CN_p43tji!GOJ) zjiY=98z3=I9EVb2EL6xrn5YoM*a94f`5=RbVlWeM`@eHE14b64SunzY!8vIMO9kBo zvVkwmE_e|A9mCFSVUF))KA$!FVGA6Z^}N*5663*e1_wz6(;$>RFfz{m}_T`5UrBAQA zEAmizZG9ujEgnK8%cjcI)3NzehRTx8H6nVUyq~C1GDw@R7|YZ4_}eB35+@WX_Xv(l z8wimHysZ~wU}5Jvbt6$nAAFTHh((MkCFc};u{*2p`8@OTnHcC_Q_@r($pkQ0E#=k?GIrz*d8c;D} zU29YUV{vz@C-1~(DKdY!TG8$xi-&)&e&!}Cj9kj`(>u#5wnPftrtdBJ36jrNHk>bH$zXw)FRC!mv(w1sVtjvMCL*$JQMM-cbV(% z0v_$e2%$Y{T#0=@a?5>XzjphUL{uF|+0gfrD6?;9?YWsF)tu_}EOpCKHWqIVV2;*Z zaPkdG_R&N??miZ#F1s}#U%89acC$(vt%lccY|ytn=(?BwAhVUUd}Gy(RKqjczZ7Pt?7S_#JS;!0&nq@0sa zh-)~1@m0*m$uAL+p6f9h}e&ril{^_lLwk(^C@o0RI;k_ZpYaJ$!aWqvRHQFBog z@kseG+UNJJb60bcnH*ou@WDI}`HSz$uVux%Uy(c^@4e!)VrFNaSnlfP=3X3a^@{`b z)5YQSF}606;d@bTtC)s2;hptstsMC!VJH0lO-Pr9{B(A`s3qpyny4Kw!hPc>7*5HE zVRUPD>90keb^Eit7xzxrAIQr)w>CjLV-&hKd!Qo9Ctq$3vQZuxa9g!mRhB8KnzuvZWj)E ze(iH!e{sCdwcxKJXlt9-qD>xQ?lRw_pM-nAuE-llIvGN(Q1E<*!L~WvfxA66`uJn% zXqBtiBXV)q3z2r(sk8n|pO6y$A9}gVc}HiOHE`!{`>u!k)l|t?#huVm=}5@m>Z-c^ THjRtA#M%ynQIDSP=_&sYO~&h} literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/lumberjack_1.mts b/mods/a_mapgen_mods/mg_villages/schems/lumberjack_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..a16723bbc0fbb62ec1482f35d1dbb95223fbcd58 GIT binary patch literal 682 zcmeYb3HD`RX5e7pV&M7@2MmG?%!!#r3 zL97ylYe`B?iBHSVFJa(=IX@>cB_*|p0aZyxYGMk)hshbK#U%{7MR|$IsTFhH zhIN-UEAX6czOnY!@&EtdxG{Z-5`BAZ?pqn>i7b!4PU_%gNVxcKkwQSu|MvM=dn(#D z>n-EIdMe?r>w3krUXLwJzOOyG@}gg7{Rc*iO{@Ingu@bNS?*V?t2?iI`OOx_y-&YX_ZKrZoi6og`n+`h-ve%Y#V;=W*LzD# z+Tau0gP!Tf?kJvBPtdmCT_HJruU?&sh=|iQPeU6;!NbWnJJV-B>oUJ>#%%xY{q{TN zzgujMaW~%Xbq`DW^&^{0%jWuV?(;{*BHWc~X7ERyKE8=#!hsm3Y`Z@p2cjQ;=gg~D GJ_P_1Upiy} literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/lumberjack_10.mts b/mods/a_mapgen_mods/mg_villages/schems/lumberjack_10.mts new file mode 100644 index 0000000000000000000000000000000000000000..8afba27eab94e4e5e2a705cda60aaaf83cd3176f GIT binary patch literal 664 zcmeYb3HD`RX5aw9|4_gn%D|kMS;QbvTmqzut%`FJlj6(s^HUgjQ&Q6sOLI!BO7e@6 zGZ7 zGQfFY8-!Ex^MO`^NU-AgqFv zA6!duMruwPgCNX05Ur>};mROR?fG{p8H4hjZf^c<7 zsVVVk`S~Rbd@!%(B&MXK79nXVNleN~MbnaznwY}C57UxXT9lWVoLVvGZRl;jW(6MG zEr*^xdzbeA|8i;FR>`v^dcU^JRom-uD_DS~A-Ix1=)91HD8}gS;^Pr*(dbv8S9d%ldBHhdr`4i*5No`;J)`u&)4_-3bFFsxS%iI@kjBT zpZv1CuQUA2YyTPR?I`=9+II91e|P+!>8?NXCw$%B`hQv3+P~jz&rh%W^pjhA{{F%> zRsZGc|Cq3`FVf0VJFz9okDu%F8X?V-r}q}Wj^o81}g{Lnk|;Ipx1fubO82hnLe?ednvyG2ML1Tn7N16B!Bs literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/lumberjack_11.mts b/mods/a_mapgen_mods/mg_villages/schems/lumberjack_11.mts new file mode 100644 index 0000000000000000000000000000000000000000..3da623d801fd0251d611e3edfdd1531f181f542e GIT binary patch literal 473 zcmeYb3HD`RW?*ArXJGpe0Sp2RJSnMZiKRIuR^|EmDGbbsnMDkI$@wKEiRr1uR!OOO z$r(uelEkE(R0dv{mXiD;ptLw#c~O3TT6|hgVo5yMFu1znlKi|>giR$ysi_RYDf#(D z#a18^tU5j^-Vjr;1SlwjYJPHlUS4W4&}xV!d@#r4B&MXK79puF&&*57FOM(IC@m>T zEsD=CNX=sqhMSe1lUQ6FUyulNm>^s*DK#ZNBQ-GvO(-otzocT$(}}nFm=t+jmQRl@ z-TUT${aQb6!#8e%!uN9$Gfq5lV9an@up#8+mt9=TW*JR6FlUeDO!ik3rS`1w5AnZs zNM>o?d&$ppst$gQWWN}xKlNwl-t>DL(ym@R*fY2A*}ig>3H5I`F z8!nuZpAWPRM1qZqPl`8W5QZCV^qDJPWy!B0xf1A2uI=CGW^l$6vW264E0uxV*Ii6sz&1mO}%sVVUpsfj5Js6uJ^ z`6Ucua8=0}sl_Gn1x1-&@d~|ZNf%VCm+)4l%NmCv|^r-Z}4Xpv<9@H>Ta={QQTfS>uMq&WbF3K2_1l z+n(?icyc!Svp*}DvwPnC-C{A*%@6Uu`*v1!``?-njiq09X8&wHUGe^W=k5m|kNYd! xclX%JxNkyK!bOjiyZ=me-(A|dCsNpD`Hwl@wc-NzKNscpSXFmWSnY9F4FGs7-njq( literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/lumberjack_13.mts b/mods/a_mapgen_mods/mg_villages/schems/lumberjack_13.mts new file mode 100644 index 0000000000000000000000000000000000000000..b82e198d24ad2214f5643290ba1d4c474db55ce7 GIT binary patch literal 626 zcmeYb3HD`RX5eJtVBq=>1q{Lr%!!#r3_K~RX^EvdB~~Rxsi_Qn$@wKEiRr1uR!OOO z$r%j1aM}DKAXlKc1gNLjsyHVxDZV^EKZQXCuAw|LFD1V`zBr?_q$IT{KEEI}k3k$R zTa=%l7N3@rSOU=ow-s!Na7unY&{Pl!mX1$~H)Ifo>rKx|EG~{ONX$!Rz))ENR4D{k z3AP2zU0|`~{Jgx>>z1jf_fIsO*<+|tkQq7AqFUZ5?f(8pY}@ zy~5z~8QqnSY!&h%dlzj>&02Eh@s)~2OVn2+u1MdoPbzjr$M)}RVRxmKE8gDt=>EVr zRw(R;nbWLUnm&6E?5M95-S^?y=T7IH#V4}*CmP&U+Ls=5_-}=k%G3#EzcMTDh&HqZ b>772gtj+wDV92I3XO(A&|6^M!ad{yC3@`>t literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/lumberjack_14.mts b/mods/a_mapgen_mods/mg_villages/schems/lumberjack_14.mts new file mode 100644 index 0000000000000000000000000000000000000000..5c2b7f051880b15e3d5089dcb9f0828066e6e669 GIT binary patch literal 526 zcmeYb3HD`RW?*GtXW;w~0SrP6%!!#r3_{8IB_)aJsl`@B`T1$_<@xz34C1I_X*r1{ z5D9_e5}=-9tKyu*B#4L%Txoe`UP^v>d~rr;Nl9u^e11V{9s_SmYFc7xPKi}Xeo=A; z0}q^Al$wg*f$bDd$TUQ7wf_5B|4Y1{jcpMGAydTaT+4Y9T_T|S0# iaklPTvBNiYMbMgnoY~Xozu{^<7rG*+oORO$o89oEl%8o0yZsAXr=ilq|La zQ}N~b`6&!SaD_$r`DqX_-jvj|#L}D+tCIYpwUL39ekjZDu;EG~{ONX$!R z;DZa6BqrsgGVsHUPb)3TOH58>5KhU@2l@>}f{lq!iZ?{kRh*HUlZL6N1gJ<1Zgg@+ zYH>+?K~ZK|VhOU9Nx(qNVBmvUnUk23l3K(d2-laCni8LpnwWwnl$M`gQZeUk$W5U` z3Osj&v;yA0`u~5`qzM|q+0pCG%iEsK$eT8S(c!{@r>Pkwf_u_xzFFp}DxID5j90ry z`Gol@-c{mDoKF1Ih+H@2g6EVeGmECI@;Wcl))6&TRO#A{gxR_;@0H&Ox0Mn5YOuDz zMc*>`Mc{m)eG3W>S-!s_Vo_Djx8hmCwPynP#R>a=SMZfzIG|tnJBok0eI4V6)+vY6 zFMnA2eTlxqxk{$e_r=Ca5^bkhI6bFxTDipqxfSfmy6Shv~BFKovRDDMcG=u MH5Rb8q(o){0HR|64FCWD literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/lumberjack_16.mts b/mods/a_mapgen_mods/mg_villages/schems/lumberjack_16.mts new file mode 100644 index 0000000000000000000000000000000000000000..887c8758dad84986226b8cbdfe6dc793eec152e7 GIT binary patch literal 494 zcmeYb3HD`RW?*MvV_^Lc1`I+BJSnMZiKRIuR^|EmDGbbsnMDkI$@wKEiRr1uR!OOO z$r(uelEkE(R0bKie0gSGN`85KaYkuLNorAienDy;124?LlKdi|W^uUUqWt`{__UnF zl6bIHaCOBc`FW`bca#*RrZNbpiDF1Lk3~EQRz8}#l`Uji9mfADocPW z`Cx9yNlZyeEkbfJ*b&M3d3mYHK=(mhA_O-VEDLs>AY3ddH6=bHH8F(&RVXb#zl1>y zt|~brwYVg{peVB}u_U!(&fQ6oe1{cyT;`v=mX=-o|M0SHnJYb(Xgo1CHu}aOmBV>L zfklhgb4}*H(Aj}}9CL;FA3nV2fA-O;aMK-HpL;syWlUe3{(9r}(kp%!GiJ`18@%y( zw|Vz<-({z4cANaqFT3=nzO?Gw*Rq7}s_n(HQ)hPmvdjJ;heVIf+T}<@xz33^H&P<(YXY`Q`D&8Kos9sYUVm1*v%q;&9ob z{QR`|w4B5ebZuaXVqPkPAY3phH6=bHH8F)j2rdM+9c&99%;!0YDJiK%h>%FmNG&cwGbJrQzXU08 ziZfDk(ir$*CZv@X#Al2p0?r%V%HyU`@R2~E+>2At1WhU z@7$9Q3VeBedr1dF630P<>M6==FFHTbe=~8z+?$s-eEP4g=>7W58H3Q9A+h0CW_HOv zU^xEBBFC%a=)^^GRhf2fCzSFp`CYAFwC8ok_4#YR8*yEkUa>}9PW{WYv#Y<{JLY%d zgp$I%(`Vw8eran6-Fu)nF>*Ir5S$>#@&XQrLE^!d8aTh05> zHD$}T!Ug|kR&;$ZejcFwGTz*`Ld>iq{IA`@u$im1mYW8K-!u=s#Ud z`kBp())cvZs!Tg|<;2vy_T^`*p647@3+X^EvdB~~T* zML@0)T)HSfKP|pIKR<;*230IMKQAve8K@j0%L6x{C^eM<&I9Y@hsmXt7Ud--r!q*u zjY`i+EG~{ONX$!(FV0L!We_MX0XnbPsyHVx31ToGOmj|RN=j-GgK$cIK2QOO1S^P7 ziZ{d*ECC9N!)*b3A}uGe1Y)EhTp}qoB|alHF@*tDC@nv~1Q8_38L7o36?5K(Mhi77 z@TfTEzPrdCoWc zV}&R7S|xw{mS< z~4IVna^b^+slEH=PhG<*D0L58l61Afm|PutCP6p>t>aN8u+6lob{o+tW6; zKDyYrc?{O88?cj}+9o6jz0 VIinvh`s}^s|LT+Z`)4dl005i{3lRVS literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/lumberjack_4.mts b/mods/a_mapgen_mods/mg_villages/schems/lumberjack_4.mts new file mode 100644 index 0000000000000000000000000000000000000000..74e673081fe1f7464aa762a616e2b8d138b8a4a8 GIT binary patch literal 594 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 literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/lumberjack_9.mts b/mods/a_mapgen_mods/mg_villages/schems/lumberjack_9.mts new file mode 100644 index 0000000000000000000000000000000000000000..c1b9633b7dbc872d0c223d640b3cedbeeb1ff728 GIT binary patch literal 911 zcmeYb3HD`RX5a=w-v0=|AjQC(m|4WYlaiX2SejE}RZ^6i%D@ZfvdjJ;heVIf+T}<@xz3NGeJalX6lK#(`z|5&9F0ic)hJWZ(kjnRzMs zs$JUKrvFEzOYYAXXjEMU?~i}DhaQ;|GgoRON7#=r+tkdv5_ zl3Il1m*SHAvebgif>b0iQ0T;`Rl$sKsk(!u-CX|++U&0^;SCyQRT3ixe zP?TAgSdz*h4i^VI8e}3Q*m&R)C8bFfbKXWY7Bw00_y%`vvYeUs=-Yq!T}v~)Z$-UZ z#%?iDT=8kF{>f~O3WkQJ=S@k)i>K%_s;^J4>PSj_vd2Y3V|DblBwx0GuiI)Qj8^YR zt7bd8@ObLc*>9?>CD@hki@dFO_>}Dvh{s*az*5~&foEPcy%&Pxi=Zt9P+-+=c zW3Mgr(<#{Y`F%md;{DS;x2JDRpBSm~ZSoqwMOyQ!U)>ZgDNvidV-w$7pVtOUZhSE| z`5gT!zf1Q1^A2Nwv5xUtj0OKdQ-G8Hl zVkXDE{5W%WPHn>TcN?{So!%>XV?%%WyxJqRHL}}girXC7{44!vm#B8w8i_-9<3fFv zXD*gn_Fv9mLPgb)dhRs8KQ#yJYt+{KF;pwDd*YO$k@|9R!V{$l35Vh~IhTB0U>N)S zc@ER+z}ZDJUN4N)cp9pe$T3MmE1vJK)~p40rW>8sI>>wTw+Mryp=yWF?-kqBtX+Tt cdW{z!3Vg44lhb;H=kW0rH|rRUcj#6F0LB`GX#fBK literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/lumberjack_church_1.mts b/mods/a_mapgen_mods/mg_villages/schems/lumberjack_church_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..32cae555c1a75ef6e699b08500c629a6283cff30 GIT binary patch literal 967 zcmeYb3HD`RX5eHHVBq_Y1{eexm=iOL7zBz-fK;(naZX}Ve0hF;3Ik6{YFc7xPKgzm z#|z_?#lxC+Fwor6vQVAXuhcLNM)VK+{se4yu^*HllmlVg(*vh1Azpzh7A1 z{{R2--4+&(1;KYO&O9fhzqO6qX@{E&gMiv{;bMb?SCb@zh|a{O)iS-;yp|2*?{ zOX}ON(~sxvS7urz95S!yzS8QM*~f33sYrB7tT@x^`B=V1azVm@qPgle{dSIvj;Hl9 z)f_iD$i3`{K-MwWwxmXh`L7E!Um6}so@Ctox>c?2PW=&o>GR?_&6ob25~~fW3rc-0 zA!Tl8uOzHe=Qa0J&DUQn4O&&dE7&@BF{%3mp5R^_z3N1U*5kL8Hy=%|%?YjUd-*kT*8KB7Dr4p6 z_1^pU@7IZ+>Artd?%z4~W99jibJF~NXU4JdV z_)Qe=wdFR2nSX<4l+FEH`9+h9^{B*BKI5-DQ)>=?n86)TAY zi@CeoK3?j(_PBGu{=az^g^!MO3ajsvv8$@x$mP7(%Io$MKb@!osWp$6Y`Ld$UvQc6 zw7-p8b{5RApEkkwRc9HOPIcqYjJt2={@r;f^v}oce;ISlt=~QpRg*OPB`j@ph3Sg+;w-ExDK~jhuunT^BGrC zlV_Mr(ls~#J$c=mzZX9WE2z{i`ChRxEoaZ|i>ZblE6@JZdA<1W&clBnPS{&>b%xN) z*M^JvBg+oTTm1TYYX$$4=z=Nsmwui4(b)Xu-*6SpZ~skW|%vpbbJ$uEyD&L}M@NiB-cFG$T};DxCz z$uCOIU=W0Hi!;;n;>#0rav0#Il@z6>G6<*S=L1~^BEgo$C&e3K6EtKHhTEH-lUQ6F zUyzuGMSBT0?IrPs3v_A> zYOCM3fBm~u1?>3Pm#)oAx8Grzw8Qk_q@*YY_Ql^gBIYK3wF*;W=vd3k%pC1~TH>$a zWut@Aw?i^!a;43kHq*X&*8Gzio69YBygwj&^M8YIzxz{;bB5pMtSt#kTRm;bk<}m1 zu!=p`&1rr%Kk10b^_}JY->xoQm)f}c^SV{3Pof;2G^8&+JuiFV8U3rai=PVTty44q z<`ml^%yIqoB@nze>H35BuZ)^|y>i}coc8v>-0Nv`V(bf_Z`~;FeShnRqiOM1${nxX zX!1_Jk^SJ(Jj0^(miiBW8jHtB)&85~9hDY7edh(GZR_>Emb2}2SA8P4b>r(db>$@` zC4Yq8mDuI_z6wgXzU6Gzw8n*zO_!OH9!jonHOrXjF~#6CC` cXSZU#%(3bx(>c1AT%C8YS@ti3?d~jV0Ed%jod5s; literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/lumberjack_pub_1.mts b/mods/a_mapgen_mods/mg_villages/schems/lumberjack_pub_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..e9ba42dd65e0ce6ff9b6436cbaa34a165c229e36 GIT binary patch literal 787 zcmeYb3HD`RX5ePvVBq-=1q`AL%!!#r3U8U{gflCMSWdj?byg%u7e|OGaWzat6dqct|E^q!yP{%y}FBwyar! z$Cu+=>Du3~?)?wlK0!brt^eq%zmI(xg-?H-*Wt*>GUJWlj`p)kpdC^tu zfi>&z8SRf;KliqG{xyT`a>xGH9;>>rCu>d3y?smf+dZv({qxnqsvj%0rdM5mF+FhY z!BX4HKJNlsnUDSant4SkXM^Z+(;dg+s@oQ&x_@K1`fnR|9lwl4!2`B;tCe1h>dEKo z9`ToY#Jv65_udN%LX)MGFRCVM>Z`?Vnai!Y&*D%0%FGA6My=*=-Bj$Kr<91qX68IGypl^iYG_?jQREm8^s~7xK^C;vBbMZB1yBp>E1XX+s^A P*{E7Of%*jX(ujlwh%9tr%0@RS5<#32gQ@NE09X&)swHcYf!)-;Igg z7y~&&vmiIf6TI<3??P{hQ3;YFCsz_Ara+-t_EIdvNr+{yM3_)0MGIeg;f|PerbioaFG;p zw^QYa&<=Ijd(q%7!blQHM2VF+hDjzNoY(gxa>O=#fys2rMYAM_&q$-6p)iMEG=MRJTl#n8*RCPcQ^ zL&%*4PmgCQi-X+u6MEs3(CA8~N(Y?M_9m=R@z!h>LKZZ z;#}W>q55quwbA|EtlHn_F9WbZ0=9W?`rXn3Bc~Mrt2p>H{AJgObdznPq87%z2CEAr0@R zbY}`51f1MBN=GF(?M*BnOiwKVsqN!CjEsuYW}RW>_ED*g{SnN2!8@l!&ew7y8LMYb zO2~9((-7_9XCAHxPW0L~@cinKW!Rru_1npz!d~^Q70H(ES8Il-c~rHhvExnzlebH+ znL`yk(z4NfP3_Xlz4S$MgT)p_rjdGhQ_T+@)~ask{L&WD-0QHKRx&d*RMjcH$?!d3 z@oWo-{=xsV;>b+*g^nK|uXa~ulAw^YD>g%@8QdvIkJ@@?(3CC++r*Fh`7(VOxCB)0 zT6b~HXxzQLnfosA#+o9h`lJb6l1itu8s=uPFC3z#(z)^G*gX{=RVf3Hef9Tzw?mD_ zc={4`u#+2n#7Zi>r;RKL>#XNjGE4FYm4IE^VW8HRd5!JAdxKM=ZDKe+HFF2zy)TuQ z{n^n2cQzHudW{$EReD&Z)2&W~(QrxySa zLS7k&-_pSx-O@e#mh^=0>GkRZIXU32IlpeHv0{&`UHGlGjgQa$l>58T7MzpFx83JI DQ2ViG literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/lumberjack_school.mts b/mods/a_mapgen_mods/mg_villages/schems/lumberjack_school.mts new file mode 100644 index 0000000000000000000000000000000000000000..f218c5613f195a0ae4d5243b4c0716947f8be279 GIT binary patch literal 1294 zcmeYb3HD`RX5eDrW)S#~01UDW%!!#r3 zEj2GWHNH4EF(-$CCnYs4u{5W|3amyDrVFGQqD=^{ttdY~4I;)1(^QgQl$^mJ2;&xK zrsu_%gNzkN)s>c$SOU>11D7bz%uC5Hk1x(BEh$MYiq9`d%|p1Rq$o9&K{zEpALs=T z3Dz8+6mN(rSOOG8mfZl`4 zBxj@+gTkjMn?Vdsu%IZjEU^SxaYkZEat6d>f^fx2sX*)U^Gg^+U@-`a_xvQFMVX0t z4E#X%I@6F3gd0T!r-2Bv7d@!p0E1z&)_4P~FH{a>wEaM65V|KaloGEge zv`TX4iB6#dl6s6^B@C_^nIBZi{FL51`%DOPc*VkLJE!Mxvd8RVy?J#R*36X8EV?k$o|5-EyIWmi>LN{&3fI-{IM>ed5vD;(WE| ziCs|vD~tEnsNP$2|J6q^_diT!xnAynd+#6Xd$)4U`CQrkdqe+(tyA?bT76vFLTy9B z9$B{Ev)@ct?S6c!`hfPH=BLx&tK8S_6>NF-WbNHl zz0GQs3r}(gWglSAu=HP@@m8*Q`x?uzlJOlIv#Y q__nW_^;_B3^6Wl?^}TB+PY!=7-E{8vt@FX>d7u4!Yu@qioi+e}CrK0l literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/lumberjack_shop_1.mts b/mods/a_mapgen_mods/mg_villages/schems/lumberjack_shop_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..7dba0430f7fd6d7b55bbcaa2130e600af360dbbe GIT binary patch literal 1168 zcmeYb3HD`RX5ePvXW;vf3K(P_({1TFzFusAm{ zCx<~0W-rKkh(bQN!X%*084NOTetBkIN`85KaYkuLNorAienDy;gCNZM;>`5C_;Qe$ z+(7r|SXHLxCmU%CC}*~!xto^EkhlTVQ}kW`oMVPN1g(Bxu~3VPvqEoF`8qORAg3XclQ zO5ZY1{GGpeb}ZNVkUUniQzc)lZ`K|Sx7f+^`^=lQaY}zYymJ1kPu=qEL*+LiiH|R* zdfB|{)>&o|d9cmv>(e(vetDU0$2Xn55&vP@hGQG8Z(RO2x9`Y8=WB-)x756Npfm5q zj}P)zoHO|+S|8H1++=XZ>sf8U+BuWeE=I1kP%l>ZZ?taHD8Hm!`pG!)`s74yGTtma(ANJb#r5k^(FN7%bM8*`O)pP*zNSfzar^o+v;E>SHYY1ZYAh~(WNda% zJ?E_7yqnXtHWa6Q|L%6#({a{h@o#4iZMl)=7x!TI^CvPnKYw3e_eA@1&ECAIH(#gz zw9bDV_Uv`z%fz;S<@-NuYnt;XH~<1Rc*Vr4@7!*$wa#6}u3iVr3C82ISQ7^=h zXZr$y?XHjV7N@rzRuVP(q4!qarTKMyn{@NNIQ8eu?6-@Q-nxW+(u;1L&=!4Las4{p z@0SXc6#W#Rs&`*Wt}C3z_H_wok@53AlW(q7Jd@Yhv24zc<`aG`=BISkHx@T;H2BB# I%unNGm996U_xoBdC95qU-C^pPZ9l40I1d zv^+6AKQF#KBQ-ULK^WwbVk-~{HZeXa-Vjr;1Skl1TylO=63`YQWXC|oL|`5$2U=Vd zUz}fBl$=^I=WS$n*=z$I(Yh@gwq+*7?JE8Mf9~wupNf)`k6Uu8SWXk#P}{rn&Iu-& z2IXsl;wjO;41Jn5>8-wD{HwAmE9lZu4*d_WzOUalC3@=LZ{Mtc+!Dy@S`d>RD)U?D z*fWkrd+&cYR_PCRp7VdhzP5S!2P-YJ8o%+$FMJY}a;S{+HtU&>VGk|#^%iQS@0aaO zkUVxMSMv6zDjxUg&kk2r)m4?ZE!{3MKX3o`&6O;3E?3_+YUMa!xA*w33r4KAjCE1+ zHfBGJCj2m|dvEY~Z;$_xT}+)XJbq1mu|r_z_a*A*CoY{=vnS|$o}>TdKEr@><%hG1 zZC`uj?XI`2pZK=)%bXK|!3&=s$y%Cpeu6!_#RQ|X^KZO&*f7U_aL~RpH}n#%o375ce_U$!`*Zr;B>B7d`q!;m{`uR#x_Rf{_J0rZ z|C0Ycx_Dpu`qiCX$Ly4j+%y04^`1!VH?jHQU+d4#GR?lWCUSGy*;#8d-0$C)Kh^W! zg1bAqIo`bBYJ$;%B}uEf9GuTjXvH9HLibr0?t&Y6^Jv!Lp_?`F}@71gCHfk>2w(P)L`*o$$)d8z# BRX_j$ literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/mill_1.mts b/mods/a_mapgen_mods/mg_villages/schems/mill_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..a04110b701d56c979654f63c41fdab795113cac9 GIT binary patch literal 811 zcmeYb3HD`RVc=&FW#F&J1{eex#8Xn!5=(PRtWq+IO5)2iOETiqixP{A8JH6@ix`Ap zvT3P#$*J+>`S~dfd@!-({G_CuR0fIU{F0Ky^weUjl8mC%;*89^^!T)#{QM#YUYN>~ z{G#Lx1|Ap}WEFx}Qk0sCFf=DIB_*{8Aq%!r7H&mRetuefa(-T3YBJE!_~MeH#Bv6K z;u4@^i>-=t5|bcq6oiR@B%nfYGcpqMQgSnMau`J5Lg|Smsqx7<`NgRzNd5s^mX?!P z0<}jNu0A;W zlpf}*)-y5WLa>b@*UP5YhghyZz0xy-<@!z_BV@(vS9jBQt$(m<&MvR@lcmGkUKgD@ z)>|@H;k7Aa^09dbr`;7l>ZU5WHZ1UV%!@nQT?=C8oZ9tHu(vq&wAG_G+gE=t%fE1O zW14wy!uf^8ON*wgviHA~{=h!#%MIVcJGooeU*FX*!$w`~x#!c4w4%_(mh0oIJdL09 z8eX>i`(&Pb==F)O`K$e%Zx$0)G|uitwvhCD5bU9~==^EG8^ z8(!qDGx{}eV{`G-&z09tZI^n-ROQ0+!_8XkSk%vF`dijczbz?WX<8}1=z7;GQOi#^ YuXWX?uT?X*mSA8waO@9L!8u120Bj?0?EnA( literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/pub.mts b/mods/a_mapgen_mods/mg_villages/schems/pub.mts new file mode 100644 index 0000000000000000000000000000000000000000..ce1d0b7f8070c007f4b8a570987ad0cf1be9dc17 GIT binary patch literal 906 zcmeYb3HD`RW)NdwXAt}k0Sv+noVn>%ndy1?MX3xz#U+WEMa5RdIf+T}$@xi1IjIc7 zFfou6OprGvH7&6;r^KqbBtH+R4~3gll$o5(09OLx^1+lqjpc#y%k%S75Q>vCQj1Fv z+>-pFusqrcK<#`O!Fjq(trkwn&j)%L zM1qyaC&e2vU5HhCWMrL&BktCElf+E7Ujd z`u{Z`_W#4z*RC%u=e_jG`HSvS_58=BW{bs-@%&rmo_68=WBnN(KRCr#&x}3#`juOr z;hCt5-kRGwXa2mqq4DO~7uuhH-wLi4H$L_5&Y5ZZUafh5e3@PJ3lpx-R`#2Bo;TQR zxqg16ab+pX{VR`e+SP75zW1m3uQkRvZ;bB$d!`X|uVyEuB zw&8lrtP0<>E2n!i{L@UD&z$i;sM6^AchcpfJgd##onCn6BaioDKcnNu+po)<*I?cE zKI_}BimczpuTMx#PrqjMD`#)`uJHf*#=EX9xL)d(W^SbX#O|}DP^2$ofud9>#? RKfT*Ijw)S|y>+^OCIHLYbjkn# literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/shed_10.mts b/mods/a_mapgen_mods/mg_villages/schems/shed_10.mts new file mode 100644 index 0000000000000000000000000000000000000000..e203f11bb35ca23f4435ea577a2e713c9179e10e GIT binary patch literal 506 zcmeYb3HD`RW?*OFWMKOb0}T8O;whe7qN%7_R`6&#-$@wKEiRr1uRz>;wY4OD+MTzAMd@xNwGs;qP7=&Q_wA8%h zRES1CxW?j))SNU1L734X8z4$V;7ZC9)ARG<%QI4ehRGmAGxJjN%j1hPN=r&oi{kSO zQu7#O;j&=&B@x&P~opEiOU0J0~$ECAElw8R(RXId6k5 z@*Ps(dBdfZwf)0}AOGuDT_`)Cmf2zW@#yZ7SmSlqCo;X+FyqLfxX{A~*It+@tNx)i zc$L5J8|@ZvVUBbK-kA?pZ9F?!^3v|dl5^5-*FHJly6~scKJSnF&EI`}@>}PA;qk*e zKP>zmX=(nKDg0{rwb}RmZcQ!ye0=R@^XxTJ_jWy(w`VF5G|EbvRiLTn$?$QbTF?=m zu01@OstPxAUG}8~JV{%!cBj)N6TS541$$*!*Pc3kx%*D{yBStiVyZJ%uC8Vju&=O*UlFu-ldNlZyeEn<*{tI9~s zNsCX(&o7G4%qvSRDoIUY5W)H21T_KZ6;-W236TAz1{DPo7WLdD^ohb32huzK+?`M#x=(T-yW zJ^fA2_a0L;<8wSW>BrvH=lPVkw+L_l@>u`xpKJ#M?f64iL$+*8P}Ny7@#C4M(s*mn neXlYWsXg^6T@Vr%Wd6YSl;sD8{~r|-uZq7<{}s>PW>^dW%dWdb literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/shed_12.mts b/mods/a_mapgen_mods/mg_villages/schems/shed_12.mts new file mode 100644 index 0000000000000000000000000000000000000000..6cf9da9f29c3771d285108dd96f8056d0c372345 GIT binary patch literal 559 zcmeYb3HD`RX5e68V_^Re1`GlW;whe7qN%7_R`6&#-$@wKEiRr1uRz>;wY4OD+MTzAM5~zY{If*4u8Bw?lSS8Td{L;J> z1{t_;d1hWpetCRxMrlb&YEgWCL24d@2wXNTH7_|ezBo5ACkM%9h*3$2IjIb?aHU}9 zB}zoA_id)S!@L&!5)lHiZ{d*ECC8iW9p92 z%qvSRDoIUY;DcF|lbDi{TExH%47Q3nZ-Y+@H7f{2A3U^e>rvI$0m_<)1|+~Pp>o_kBz z|9W!$*3s=>zkgafZ>d>$z#ewzf14K;JbYao{;whe7qN%7_R`6&#-$@wKEiRr1uRz>;wY4OD+MTzAMvZ#W|`FVM%$tC$kP-#Ax znaTM{Nja$uyl~|?`H8s)fnVFZ)Ae@q)4|E%d z1iLLhDc%rMummV50XG2b=(L=~5_G5KB&MXK7BTR`otlwaT!Q3Vut(#Q5`oTV1_nvR zoV$TxkIN$M8PYdzU{#ihSEb*7w_7&^VE|z zpS6FomUI~xlr@}FEy~~eZ}mPu`NwbmoI1BL{_c}wk&pkpyD9Zs?zC5m{JgnNZ|6qJ zbj)72*X#G*s(-N$9U?dRC8f=rW1jYOiN)5wOGn#hcU=yj?jLxoxhH0w4zu{GTb>>z MrgvC5HE&G=0A$b67ytkO literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/shed_3.mts b/mods/a_mapgen_mods/mg_villages/schems/shed_3.mts new file mode 100644 index 0000000000000000000000000000000000000000..501b8c2322a7a44fb34e9dbc078f2978d09f6f4a GIT binary patch literal 539 zcmeYb3HD`RW?*OFU|{e7qN%7_R`6&#-$@wKEiRr1uRz>;wY4OD+MTzAMd@xNwGs;qP7=&Q_wA8%h zRES2nnw-Rxl++>yez-wNiA6;~O)_wS^31%H{POtXjM9>l)S~$Og48?)5rk}FdVXGf zc}6Nw4Z8^Rhhz8%cfL3eDSVi8jr8oDLw|Sj7#C$ zLIbv>S#(V8d-X8;MxU$;#;=Aho zt97Ql^1Ji<<;<|u-@TvevTvTf`mJv9C+U|i;+GR)l-Hmr S-b8BKzMg$0(sq2Map3?{uIJkT literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/shed_5.mts b/mods/a_mapgen_mods/mg_villages/schems/shed_5.mts new file mode 100644 index 0000000000000000000000000000000000000000..dd3bf0890f161cdfc62d3402b55c31802e80587f GIT binary patch literal 402 zcmeYb3HD`RW?*4pWnljg0t~ziJSnMZiKRIuRwJzzz0`ToRON7hN-9os7MB`s5~<-CBHnrIHR>nusfsyg104Ad8SoSfGv9rY`2WAo=NQAa2Uy&bmafw=@8W)- zB(g>Sh24v?qd7|-tuq#MdgZn-Gw6G(?MCCXU%LN1$evO6$#(AZeX|9uFP}MFx3_Qi x(Fun?%hiWitmY_RX&QLx(xQ}T?Pm*eXU1)Ho&RxNuib=qPEpZ}x@#x60RXv2rC0y} literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/shed_6.mts b/mods/a_mapgen_mods/mg_villages/schems/shed_6.mts new file mode 100644 index 0000000000000000000000000000000000000000..1139a139622dec1db8268770c0d75c74f43154e8 GIT binary patch literal 370 zcmeYb3HD`RW?*4pWnlXc0t`G1;whe7qN%7_R`6&#-$@wKEiRr1uRz>;wY4OD+MTzAMvZ#W|`FVM%$tC$kP-(cC z5ED}J^MOW!NU)LdN%2Mu!svn}KtUO}vE`Y0Df#8`#Tlg~C8e7qN%7_R`6&#-$@wKEiRr1uRz>;wY4OD+MTzAMvZ#W|`FVM%$tC$kP-#Ax znaTM{Nja$uyl~|?`H8swd{a7*QZooypW(A%-PUfqd zkF@{&zdrAJSGV!G2d}F#EiL$FG0k5wU2zBNo!JJ4*&Ez9oOyNP$*IuUt6f;%F$PHP zkbjhy>mz-+BK>6Y`lJ1;x99zP`8}*>`kqa%E8o0|Wcu;Se5=jetFPZP$tIqhrj#}< u^0V8V%7Ce7qN%7_R`6&#-$@wKEiRr1uRz>;wY4OD+MTzAMvZ#W|`FVM%$tC$kP-#Ax znaTM{Nja$uyl~|?`H8s0k<0LyR@9d5~v@rSY(LJ zU_%CGV2D-BxjX4D-ysE&=IXkTkPwfa_y3ngohvx^!f5XYw^>uuo;J7g9MEF9vR+j< zY~x|gds;?Z>B(6}Y0uxxwQ6I2EpQ{pYPrV^_o8J|F}(NEZn`Z=*lzKma?WS#upOKF z?$`KxuW7lUDO(x4YxV2X4rJzsksroR4?nbi@Nszugyq`*Y0e YoQq|7-}+j2^Q)O`yLVgKz2deN0O7gXIsgCw literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/shed_9.mts b/mods/a_mapgen_mods/mg_villages/schems/shed_9.mts new file mode 100644 index 0000000000000000000000000000000000000000..a48df9c7e140ec1502989f0e9cf8e58e9c46d5c5 GIT binary patch literal 620 zcmeYb3HD`RW?*OFU|{n#;whe7qN%7_R`6&#-$@wKEiRr1uRz>;wY4OD+MTzAMd@xNwGs;qP7=&Q_wA8%h zRES2nnw-Rxl++>yL734X8z4&f;btc#78L=_k%0@8XXd5km&X@pl$MmF7RBcmq~LX7v>0{P;v%?2wZh}VtRgFe0fGH&;~xZXcEw=8A#p(`z$^w zF((yCE5tv=xrsSBNJ=vjOOi7nUVvMgoRL~wf@FMgMruwP12fRC6?5K(Bnmev@W?Ws zy~K6&)&KvOr1B;xToSkccJJ*x>zni5lrgCkgeIlT%iIx=aWRUYRV^s+-WsK|0)DF< zUOd=VAmac3%>BUP^M7S{gc{3}s^s6*$JzYgP4^R77=Ko!^!~3{)j28Cc6>dYbMANK z-Sty{`<~7`cj)h}BkPxT_Lby$$^4T4eCB&EGqsnYv!sEV{BlQ-r&r_S}(! zztU3{)@mPqpWZOnmhGL9hyUvCr}`BYfl}EENja$uJTQJqQ7RIzJU>5$ffpv1 zo|9Ny%pg!)l9*XkY*n0-m=q6IAP5ryNkD`+bJMLd)ARC+QW=C(^7DbpK_pl%J}KT1 zQ?LXm2)C#tzbH9_ff;C8#hkPKx!es3JT3XlUmyMdzy5T}nHWcw+82B`7gnn=$1s_l z*1R}(;aSPaySp{c?(xks-ePn!&82LuspLea=$_Ek_y1JqnE&2)`t!cq`mNU|Rb47L We0p_D-+{6QX8))=j7OeLe+~fR^><_d literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/taverne_1.mts b/mods/a_mapgen_mods/mg_villages/schems/taverne_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..08776301fb75490df11cccb50dae28eba918bc90 GIT binary patch literal 2041 zcmZWnX;c$g8Z8^N7Xz~BkO2ueZMqSHc2okghzpwm`Zx+9!aztWMS@AEAgLrmQ1lFf zN(59uXb|Z}mR1;yYzIV80*T5tEXIHgG`lQ-sDWIbHIGfDQFv4iorl02 z2tcjp1KKOQHG(DxBM6lN@vLbO2V?@et9vdC2T*tjmnsAd{}%*d4hI4enEU7Png&9p zu_0jlDqR@Jp~FH7kI6?6h)aQkAkLa4gbS@RD1>1;ps`|5C9X1~u`0xdsXwjr#$c;@ zrUX${9j+DUF(G!qIugi)c&dzGE(`d}s?Z-`5I0ajMb=dZ+0+m~mkz_K2tTf>YcQQc zqu~D^L{y;msvZrZQvzTZ`3z!0R64L_rJDdgmqP_1Kzn6KA7}Nc1fa9ZQN<7afqm{) zHA=2(M1bZB7ldgab2eCY!KAVSD4%=>as&_;f#`tNO0AC%;#0U=SFQ_Ht*d4S^SLTd zTB{;LDvue+VE}3>b7xZD_-qDKtWX3(?lG6<{X^h?1oGwO1Yu%VBIQuoA$?crh8?)L zgRU|pLY&@hz_T1?d*3@cZ%|Z;H?JU!nkhtHt@kIB5{{cK-wCR?gTHCC0W`=is=OW^ zXFhoA_q>*|h=r((BE52c`=g80RXVuwpPzZzAtqhC## z98wpAiMCCI_rAdlJ#{(SL507M$^8*ML7ujW`R>w(hyHPeeV5@zZLtPX&Gl^bxTCo3 zTsunEd933~ZRHjH^pi4We%0*THf%UncBhL{{Z;(JjmPBh!vxXpq537G%-+EV9<9EH zm*aJBrnOq+JDG+^C!+c3c1c$bXn=&+Onkr;*>;X{OWs2|k|(MMmmTo$tJ}OkSUygQ zDW^Xsk30BIlErPd1e5LEwpsHdx4MQxMw9K^PLYAxQ+6=fY>(4mkK>uAWL*6$F9erm z^s>xLTr;Uu(C;5EY;5xWt&u3!c;-FCwKB4?VKm;YvDR}Q{I&f<7_Kk?A30$j`-7}7 zCVH?GZ4(^nme>epN2SJ=o*J>-Anrd65%*S*XfgHj!flH-cCpXSyb@VCy=^)mn7M@CYXCCd%|B`Ccg0caI-QLrO%lnR3vKlEG+w>v1gXEXK;2m~i!RP=h>d3hSp65PJN={;iYN)I(`<*ny<<&8iFoEno_HizLORXb zJ14O%-ls4gyZN(RefjDPF=@j7>qwk#h1VQ!DTA4xGF39HZ_ejWx7YY11FghG!q?;f zVzl_UR(bF0GTZaK*{g1rH?nZ{urzJn4_(003l_JvdF^SK@yhoF6n)QYSll;9-kbKf zyxjd`b%k`;l5A`6a=x7uMmUH8AKY$a=Ph_x$6l1|V%;Aj;uJ{_Hi=F&!Lx}Cpmj=p z$`ni7=6PL578ck}yGt5gTnNK)u&v&6BCOMkyb5e7B|gmWRmn~tv##<4Wl%%@OMju) zIoIozaoI5&#WkkfoFa~R(Xh6pcYM)(L94?#H^0B~@}QPr8C@HEZdBlC{tq*Fxx_A| zhlfj*FWvL_?L;Oq!PN8a+RxC1U6SF@eWw?WMmnNc_^=)Ovh{Jt|K?@vP;ox`zJL8R z8N=#V__a7!fma0y6X=b{oXb+>)i17&OE~TrgTsa0jSVKh3}kHXZG3EPh1CQxpc^}) zNfzoBUL0)eWOqSOFfNIV(EPbql9hA8EvR>`AR5pp?A=EeGZV|oO);?697iqK39ws&C+WCH82Td4JJBe7j2#R@)j0W<21J7QA$YNPR{|N%gzEq zveZf4&>`=(JT-X(8BgoS^R=tc`n+bnuRw93D;2d#2YQl&!rm~kG*uH9Ar2THd6?S( z{_kZ$1B|<`u{lo?;>{Ivz9?$O4lfO6T5Z%T4!RKPV|>!iX)HjXogGtU-|qg9=#Goe;AJ%T rWLyg$(X6M(7MV>dZB0d}&3!16?*WUc77OaA+3O|S_x7d*<=y`Upj^v; literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/taverne_2.mts b/mods/a_mapgen_mods/mg_villages/schems/taverne_2.mts new file mode 100644 index 0000000000000000000000000000000000000000..dae4458aab6cdb900f0abec369af1ed744379ea8 GIT binary patch literal 1247 zcmeYb3HD`RX5ePvW#Ijf3>cId#8Xn!5=(PRtWq+IO5)2iOETiqixP{A8HAJbOG*;c zQ;V&N^7GT;i%W_U%NbOFE2H@B)<}mQW zbN~%W&Oov>IU}_g7+m>9*$jLLO{sZ6MPhJ1L=n)UB49WosVmM%%}HYrf~(6&%t?z+ z$I<;cX+wktPW(A(3;aj&|-MRMm zu6Hm0|9|WzVCe9{bnQEt;{Jy1ifz_PeTJ7#34RE?eSG`JFCIN76SEpvrLszsc(>Lc z@sla-z8SLBbop<$Nxl{bv_+NAsI6c>%hwjyK07-tEBIyb%HkCNKTIaC=GhATn#!z(Yl zZxgK~u6A+Xi&OPl>b&k*d?=5XY{L6W?(56<%=h2C@YS2ED;%bZF7BB4C~3>4U7Nn$ zy1ZXi+B#y5@AUkhs<@iKg<#JFa^#JKak3oY3Vb8`xyqRy|&&ld*bkv-WD0V`jVKfC87dmGAm^zocNb z^WXWRQ4v;`SwC#PnKnCj8<6NVJkEaX*4gD6O>^G<+$X^!Mn z&G_!k9-rfFa}68?Z@vBz`&)V&5A$T%sr~JjCD-(sUjELsf8)cK4>GQOc~(BJ#G~@c vqrUTul51=KzYKno;A&#j6(Qp2z3cqMX63nj+iw=V$c*OmzM+4A<*QBrKT{to literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/taverne_3.mts b/mods/a_mapgen_mods/mg_villages/schems/taverne_3.mts new file mode 100644 index 0000000000000000000000000000000000000000..9c2a0cb4ee592a531e29fe8df1e8c3e1383feabe GIT binary patch literal 1161 zcmeYb3HD`RX5eSwVc`Fd1Q-+;cv4c+5=(PRtWq+IN*KhEdGY0$B^mMQMTy153e7qN%7_R`6&#-$@wKEiRr1uRz>;wY4OD+MTzAMf-wEXiFql-CHZ-&4192P zNvV0s8A$w+#H5^5240w!lKdi|v%@ZpCWk(5|el$ygJ1{X-qNG&djFDS|^1NwqN z5H6mSni8LpnwWwnl$M`g!T`52Cov@@wFoH~i!)Ml(inu`req}Mq{XM?=NBRTot%?c z$si08E4BiWU>C+G#T#M@mH-7s;buXc9-mVQ3RHf$FH4K^5`p24NCFTamFE{_GcW_w zNyVJE5#43Y3OueCZ~Fd@*#33n+SmW<-^_!JGe?ivPWmh9V9yEw8>2<%}9G+17 z`1J&*=WDktU1;xg^`D;4$*Qac0RgvfeZGF-y7q=CQtz$fc1zt@UHbj{!*8Yc6kflI z@v=R#r~iP|SN$z(mc+8|2}{3v?YsWNDrPO!{VB1huU)yjt$uH1TYD;C z^#nb8`6aerU+L7D3(l4P@ax~w>C^oK^RGV6z4dY9ch{ip+wM&`H+#jo3O~E8a@Sw{ zkvJ>u-~5dCD0@hF<>B++Yb%+*o1Wj3IKRf(hJE`4-EYh8zbg)?xV!6W(Y*5q>*l_l zedovf((EOVZTDYanJ*kD_1OC9w5fa66u+ry-naYmhe_v-n5fKke`wz5pdi4(!qjLW z*z}yGrE@~}<;I(dZHmz%$2J`BDPlOhJoDkg^VDa9rEd8rISFrl>6yyVpQ^8EZ1 z2EOF{l9I&q)MBe7pkM}r1e{-#pPv?=mXlZ#UtCg@SdOH!Brz!`m4P3wGAXgBC^d(H z7iN4(ei6_l8Mu6TW?o8ud3s2=)oY6S8oXV8P`4yu8$8pnIWy zgu5ywv#5kY5Uw~WH6=bHH4!@2c{@O12{+?K~ZK|Vo53kA1t795>rxAix`AK!BK1lBEcHtlj03A z1xtW}{4kwqrA2v($w)>e=O=+;kQwNNiaBpXURO0M@bDgaeQVd*yQ|;-pB24Bg=te) zZ2jBpA4ig(6r2!b{P0m?OXcRRO#*&R{$I8{xc1HPy^5r`>}lboyL?smtsWM>)39uD zJjUDj&LP=H?V7C0X1?Xo!ml~w9?F_1KC`^SQS`O%gWL5PSF)eoSXI6@`^vn(GdAxx zpOS4ePbhY=jq0vt^Nn^rSDJ5cY*+7Uw?D!}%})Q-!t>Ez&wWT(Z}s8IQ>h;wHRs;1 zp7UEO3_>u4X{mY1sqsLG6b9jx{QRO~D-a15h);?)#3pEjDOiF{Wl6jd124>; zIFr*|gDJQjJ&eed6 zd`$*Cd)8|CWc9SP{Qn=c=cAa(H6>%)fP6mJ5g8j!BDON?Tpu zTUqU$UwkXa==|KQ4>zOsWGCHDpI^IS(#|WF51(9PF#XiIo5f|%zp33XS^1RzVg0OE y{Tb&B(t^?-Mv6GCxvTSKs{h${Hk`X1?($AMR6Hf~UTM9boBNiW3g%Al?KuGIdaQN; literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/tent_big_2.mts b/mods/a_mapgen_mods/mg_villages/schems/tent_big_2.mts new file mode 100644 index 0000000000000000000000000000000000000000..9683fd93de7264fd83f07581429bff4c395a0dec GIT binary patch literal 379 zcmeYb3HD`RW?*ArWnlXc0t`G1d?~4EiKRIuR_R5FWvMv~%!!#r3_{8IB_)aJsl`_1 z`T05VC8>EO3_>u4X{mY1sqsLG6b9jx{QRO~D-a15h);?)#3pEjDOiF{Wl6jd124>; z=cm6+_B)gI zIi+mxdAYLp(=5LIJil(~x`UVho?R1BbUV_vyu8nR=d16(>;(QT-}$Gbpv^P0L~LGa li-6YF=_`e0hF;3WHE` zeo0AUdTOy1ked@COn(n aI7RkGj$?X;&)Esh9Y->DG3@3^-3|ZYF=_`e0hF;3WHE` zeo0AUdTOy1ked@%cCjkw~VBmrCOG=X% zcwsh_H`40?1x literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/tent_medium_3.mts b/mods/a_mapgen_mods/mg_villages/schems/tent_medium_3.mts new file mode 100644 index 0000000000000000000000000000000000000000..75d72b5ed87f40adb4a457f0243293a1b7d2d9e5 GIT binary patch literal 277 zcmeYb3HD`RW?*GtVPO3a1Pq)Ed?~4EiKRIuR_R5FWvMv~LNI<>YF=_`e0hF;3WHE` zeo0AUdTOy1ked@%cCjkw~VBm$BS(0A_ zwp4Bi|Oq<3KA^U|K0DtndEij{oRQ(Ymc~^ z9GT*gQ}}}AS?5ig!<->(nigAai)I&Fzbn}=(fYxblKA%<&s&ttd;inX_E_e-)D>RO hg5Iufb+IYh8oKIEiQ)sJ?9`$qtKw$Go#ap51^`mPbH)Gw literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/tent_medium_4.mts b/mods/a_mapgen_mods/mg_villages/schems/tent_medium_4.mts new file mode 100644 index 0000000000000000000000000000000000000000..9e3938faa1f8c746f2624fcafedf01bec56713df GIT binary patch literal 277 zcmeYb3HD`RW?*GtVPO3a1Pq)Ed?~4EiKRIuR_R5FWvMv~LNI<>YF=_`e0hF;3WHE` zeo0AUdTOy1ked@15QX!Kb5c_aGV{{oa}!G#_~61xKqE64 zcwsh_cDL literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/tent_open_1.mts b/mods/a_mapgen_mods/mg_villages/schems/tent_open_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..03a2c57e1f1ba30d0a1e2d1304fc274eb1ba760d GIT binary patch literal 181 zcmeYb3HD`RW?*GtVPO3a1Pp8pd?~4EiKRIuR_R5FWvMv~LNI<>YF=_`e0hF;3IlUu zW)Xu>a(+okVtQ(^6;LcEz9coTgn{)JFJa(uVMt3$6WPb%(bFi|Z>6S|;?Kko It(;O006616_5c6? literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/tent_open_2.mts b/mods/a_mapgen_mods/mg_villages/schems/tent_open_2.mts new file mode 100644 index 0000000000000000000000000000000000000000..54e23d033a90ae2a7bd08138216873f9b6e73fe0 GIT binary patch literal 174 zcmeYb3HD`RW?*GtVPO3a1Pp8pd?~4EiKRIuR_R5FWvMv~LNI<>YF=_`e0hF;3IlUu zW)Xu>a(+okVtQ(^6;LcEz9coTgn+rFnE_We8f;)P^pSI1yjuC3&7OC^{n-yVuq33VwONZF5n}8#GYF=_`e0hF;3IlUu zW)Xu>a(+okVtQ(^6-X>TEhn)ARV*jIBsH&uK^U$sBe5ho17ZRnT(CGJH7AV$!7oWn z%1LG5h1r^%ky>0*F=y|DSiS}Wj%M$f(&7g9{x9)5@z2C~-_7?+o7)T;^ca~VcPW0| z&Njz`akz?Ym~ zQj(aST5OdB6wF{?PRuMq5-dqf%1LDqf-3^*$%!vX%`2&xlbqnd)WhQwaDt=dOhCu% zUY;3}5ep_r@~5;qrJ3wCsNVRxVPk^I*DsUarwJW?^+J-P#HON+C!_ literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/tent_open_big_2.mts b/mods/a_mapgen_mods/mg_villages/schems/tent_open_big_2.mts new file mode 100644 index 0000000000000000000000000000000000000000..509a6f99b646a5b3d8e736bec861a45e46aae3d6 GIT binary patch literal 193 zcmeYb3HD`RW?*ArWnlXc0zf8TN@`kSX-z?Ym~ zQj(aST5OdB6wF{?PRuM~5P}N=)#SvNq~?_%DJ)4$%1N!5lbqnd)WhQwaDt=dOhCu% zUY;2bt7d+55YtFei_&*7ZDCao{Q78n?}oUrJ!ub$j13<)ANgm`!pL0NAjz@8tE0R5 T@SH}O$Ukbz3=E%VY)u9LUL#5a literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/tent_open_big_3.mts b/mods/a_mapgen_mods/mg_villages/schems/tent_open_big_3.mts new file mode 100644 index 0000000000000000000000000000000000000000..2e752be15dee26b67fd107b6759aa3e810afc07f GIT binary patch literal 182 zcmeYb3HD`RW?*ArWnlXc0zd{|N@`kSX-z?Ym~ zQj(aST5OdB6wF{?PRuM~5P}N=)#SvNq~?`W%t=mgVCv!V;W^`Qf+fYUDN>XkOu!=~;;(!YgPfN_3$uaqAtqN2jt!@}x}952 QOmsDu6lY-gd1q@e0L2|a1ONa4 literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/tent_tiny_1.mts b/mods/a_mapgen_mods/mg_villages/schems/tent_tiny_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..e3b5782c9628b69c1ad747d1ea269a59fe5a9c5f GIT binary patch literal 221 zcmeYb3HD`R20~T__WvNjz|J6^lA4xSnp0wxl37#|U!GZ#5uaX^SX|7&oS0d}zz>rx zPAtgD%u8qBg9!i?m8Iq|h$iQklq9C77F!kPq^1@CmBi;JmM{pxh0F8vbK*-<^N_`g zONtW9LFy{zBquO1yRoS$9BVm~(BaD#IgRy9@s^GBdpIYoakySxqkNl l%iIP6EHVi!%uYTwPCPaa`HnkzG-BAw3=Xj|%&p1%2>=$YPFMf{ literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/tent_tiny_2.mts b/mods/a_mapgen_mods/mg_villages/schems/tent_tiny_2.mts new file mode 100644 index 0000000000000000000000000000000000000000..f2c97c81232ddc896eb6870e647cb6461d30c627 GIT binary patch literal 164 zcmeYb3HD`R20|7Fmj6J&z{-Fc`Hk_Z)EOXk_nDIHtT=^2WiAMn;CSVg@Gx5Ft8> literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/tower.mts b/mods/a_mapgen_mods/mg_villages/schems/tower.mts new file mode 100644 index 0000000000000000000000000000000000000000..4363248ee22870df3cd64688c1734696d0fc6555 GIT binary patch literal 361 zcmeYb3HD`RW?*FyU|{`^1{k;)gi=z|5=(PRtcpwW^HP(FGLy3zgj4eKi;As4WPEvk zeoA~&ydkDw2~dzTH{B{TJukl~m4O##P)UAKat4D~aYG8Mgj>^6^O94+PGevO8dEXnZSZZr1_h3#Jd^+bf1q@Xr+Zem z&5sL-uLS#e@)?{JGoyFd=VUJ8ko1t)n3!6U_|a-gMo_%bn_V3$uJgoF$qz TRz3JTBQ9R&$)B?5uaivxRA``= literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/trader_clay_1.mts b/mods/a_mapgen_mods/mg_villages/schems/trader_clay_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..82eaf61b968368d34326ce1d5f5e3feebdca6af6 GIT binary patch literal 559 zcmeYb3HD`RX5eCAW8nG^1`L7>yeX+^iKRIuRwemG$r%hnFm76EUUF)Dd47HhLP>E+ zeqJhqn^csUoXx-o(~+E?l$4XoAXHqEm|0Y8Rh*NU6b}^>L>7aXA`H`(l3JWvR1#mD zn3ux90~1WnNvvexhw;)%i}Dhak&Fh}5DzmaKObmY3XlZ5Ha;od5Md73RAG=LvXT;@ z61cz9a}tY-5!~dA)Z!8bW}pQXbKXvUE!CvJ)21%0YxMYE{x%C984a$m|974rPRQLO z^GVPoL&9U1*MTVgsTB!}KX{85i+7z!NzM?ddGTFA(@a`%wtwKXqAPtTx|GaTcRx{n z_u@~pTbY{YPyg%ZPS)kJ{Ylxc{BwHt*2ir(HXMBVeD5>8RZsbPR^Rm7xa0o&9p)$A zn@{-h_tc4_6|-wh(|63XkyQM!^+(1j-~ZPWr_6WI{r+x+@Z3k&qEceIdryj{`Y-+7 zv07yE%%~k-n|kkg?$zJ@hM!IK^xq3{{Bg>wsQDdNxLFtVX&2?Zp0)W_ i)Vr!_*EVZiJ+(MW#8bC8w=IQN)yS;+8{=E%LMH&$%JFdk literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/trader_clay_2.mts b/mods/a_mapgen_mods/mg_villages/schems/trader_clay_2.mts new file mode 100644 index 0000000000000000000000000000000000000000..f53c569d61ee9ed7e45b9b601fc24603944d2ae7 GIT binary patch literal 549 zcmeYb3HD`RX5e99W#IY`0t`Y7yeX+^iKRIuRwemG$r%iS#U+WEMa5RdIf+T}#U=T9 zsR$Kl+@zw+JTL>mYK2qs z^MTfb$as)Id{Vp-1BPG;P!O&!IVZ7_K?vE_a%#i#YL|KP5>D|NA6P?PJZSUMZ|7VXv#k8(#{D1LKC(sLo~?BM zQq@jBulqW`GVg_ayeqMiU;W2DantUZUmBy%^KX&6@$3Hksk!n??AS|fZ`QFL`~Nz- ze4Sw8-UDB@-;UfJ_tWo5wdCCjmH6}0kCy81*e?2?{hH_`_G_mu3L1T_Tess;OM}9$ z2a|iBCDfURyNcM|DSP?Lv$ie&;V!d-vd>nPKHuo{)YiE0=&e)xeAVKAZ@&0bIqLJi I6VLJ$0139~SpWb4 literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/trader_clay_3.mts b/mods/a_mapgen_mods/mg_villages/schems/trader_clay_3.mts new file mode 100644 index 0000000000000000000000000000000000000000..b52fd0a27977075d2d922b6edb88d0d9a107fe00 GIT binary patch literal 597 zcmeYb3HD`RX5eLDW8nM`1`NUsJSnMZiKRIuR>?Vul?YyOVqOXZKTIyIv?wnzIh8>e zCXkX^oLW>84_3ts6HL!ZEG}k%bCWYti%S>;i%SwSi;As^a}tx{lZrBvvl;kc8gdd- zQc{Z;MACBd%Ts}B$`eaci*hn^D&tK|5$2TS7bRyPxDYdhQ}XkHIzVK6d47IMd{Vq2 z(0OQrB|t&J9!V6f~i<{QMFIJ|tCn$kr8?hpRQyPVu6nNU6AIX}Mw(tLLF&?3#3+Ggo-TnE$y+itOv&oBu)taxq zZwbx3A-zY&&_uErcm&0N7-t-EG%MYx%AoagK=@pZet z-O*`$w0p+cd6^N*4X>wd;;U2>;@GyC)&FMG`Gs! z$@jIbSAJhpyLn5cUu5Qgsrrv|+3s&LUixeI|NVRY=l+U5IB80LrINBnhqby4|ADBE z4O}aw0`A{*@35HB?C{k5=5|Z77pr%MI2~vRZaY}C)#1i+$v;kVYgVS2ZWV( b_L#$i`Oa(e)Tx)8m!I0MQ_J8m`&B#uZ0h}T literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/trader_clay_4.mts b/mods/a_mapgen_mods/mg_villages/schems/trader_clay_4.mts new file mode 100644 index 0000000000000000000000000000000000000000..f4c79668f7d840994dd411315617863622fd1354 GIT binary patch literal 777 zcmeYb3HD`RX5eGsWZ?V{0}P@JyeX+^iKRIuRwemG$r%W4aY=q&DuSC-l$o5(AXr?I zm|0Y8Rh*NU6b})C>rc)|EiPf;OU^GTNlZ^Iwn|FP1DeMJGrl}OKZQXMNj4=uBQ-IF zfe)r2Cov@@wFqHjdQM_-F@q4yMv%qv5J#b!l9r!e!XOAUB`H5YyEr2?Cyjw0CX`lM zl$V&CicphMR2g5KQB<0Q>K};V!YTRrKp%q0c#xaplj02-Fa%40f^e@T=Ok7lc*Ti% zDGba&*H+AV8`@pgtiZ#&VD>KG-LL-te|2oO08{qX>bc497$>t$iU|@lyTPw;-nLp^ z@^c->1VN|U#xbT9@^{UD9sC*fTTVXs74);6hm{p~DAL4!(d`~@I`7iE%cyB;D zf4+g>x|P?3ul%wzOn>s`VD_Egb~m0M+V|dh@q6Y=`Oo9-&0o!4zrC&a;kzeWrHt>k z)W4j^Kf^e?*XGra=l8$&2m4t*ogy!o;q~18ZuRX`t9ty-2uJRGzo0ekLi_@g$8W9$ z)h*rlB*QNJL7LQ2yQSODoU(hfOgsPKyP#WtmC`u28W_4S{ooZeQ{d6QH=6PDVn6lF zc=Ji|rekVP(dxkGitqmYC^fs{%NqM=T}IiSP0qFFvpSz{-_%}jw@x)OaxPPs@$H}U Z-REtzSbdK_u4>Ws@M}+mU8Zf>006qlVOjtH literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/trader_clay_5.mts b/mods/a_mapgen_mods/mg_villages/schems/trader_clay_5.mts new file mode 100644 index 0000000000000000000000000000000000000000..242af26d3afb7d3ebb01dc173477b57f7e77e345 GIT binary patch literal 724 zcmeYb3HD`RX5a)u?*A~rAi}_#lA4xSnp0v`l3$dZ!5~;%l9*XkY*n0-m=s@JlAo8# zAOus9mYSEG8eg8DpMubpRFs*Vjo_x|Bo-Gl@W6BwC+4Lv@WFUFi76?mMGX8fep+c! zUSe`8s+|x6;U<7>6NKqV%FoX(&PdHkV-QTvFDXe(Pc61eN==E+NKHg?6U5oVDf#(8 zkAO(9o8yz>4bilv<>!|$V5lnrs^dd4J`Wfy@K8$5NG&cwcrZC9v66uq7-AK3-iF>R zI;_AW(tdk_nfu}Y_1WAW4I2)W%KG1C&sKMflU%GTlIKV}on8kUTt zqBTa5#sbMw3X8dWD$d=nPh(!ruufp=ec><9_El@!Ogy*h0(U+Co(q0+CR%>9y;`0c z6l#4q;_A5#*O%`N=RNlMf%Vhh-o?k1@|p~dpD~#=l=k@C9y+Lo34JSy< zNla0Ax}zzkbeZHl@6f;XPqp^xYt`uAShwN)8PTX~m-%MwbK3Kq>vrWk^TXyl+J2a> z*~wL%Aad&J^cTA%`_4W5)AM)E#JSt&9xiRTd26@yRo&Fu)$c!VIL!B(yE%)i%y9a8 zS@vE_tJW{V)q#gExMY7{^R4e$Xxh@`i{)n8TXrt=dH3SLq8(22B7RN#DCy*PXiAjn zi|MN#sry-8IOk)anLf+?npBd#Hb6uUEZD>!GoFXL3F6B2V)z13R7 dBmL~mL`!btH#c1N@A@!fLDX-ihsA5p0syb4H)Q|- literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/tree_place_1.mts b/mods/a_mapgen_mods/mg_villages/schems/tree_place_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..e07768a995e8d5920cfd8b6490fd15d883f2f6f6 GIT binary patch literal 171 zcmeYb3HD`RWZ+<624YqQ=ETe*2EOF{l9I&q)MBfo)V$;j2ELTkw8YY!6079=q@;E`ep^H>1R0 KUWUV87%~Cv+B!A> literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/tree_place_10.mts b/mods/a_mapgen_mods/mg_villages/schems/tree_place_10.mts new file mode 100644 index 0000000000000000000000000000000000000000..476e960c9cd7eaca4d76c663ffdecb9f9073f183 GIT binary patch literal 209 zcmeYb3HD`RWZ-6C1!LyK%pwM%l+?7u(wq{jwA8%h)cErJ{1gW9w4D6%)S_aml*GK0 z)SS%xy!i5r%#u_FQJCVa(!BJX)Z)Z~oXos*27Z`udQoC=alCQGoa6)sW;eDFsr?!} zLCgjZr?%cW#F2hc=s-?_%fpF_dyr literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/tree_place_4.mts b/mods/a_mapgen_mods/mg_villages/schems/tree_place_4.mts new file mode 100644 index 0000000000000000000000000000000000000000..fe77ece0e2bee7fb26829442c48526513f744b00 GIT binary patch literal 120 zcmeYb3HD`RWME@p24WTl=ETe*2ELTkw8YY!6079=q@fCHWz!^i3RgF;Ol@1O?xxCpQETID&pp$B(h5L(sNRa6AN-O^U@i_VFsoo z=B1?OWaj6^muF;_q*lyHPGDemGf-hQaQr%98UK=5l02Q)*)JYuYCH1!@Y?RFugWGq l*Pmg>k;3d0^tG317gIokad2=~V`pb)QTjnfhVlf4NdS!1O}qdA literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/tree_place_7.mts b/mods/a_mapgen_mods/mg_villages/schems/tree_place_7.mts new file mode 100644 index 0000000000000000000000000000000000000000..0c6f59091be184a93882941c3a5159412f8214b1 GIT binary patch literal 237 zcmeYb3HD`RWZ+_8W8eg0=ETe*2BDPHw8YY!605Y-yyVpQ^8EZ12A;H>{PNVIVymM3 z;#3BK;u4_3Vyohu#3YEkG`dJ>L2+hEYJ5t5c^-o(%)qSDy!4#Z;>3cS%)Io9Id3Q5 zQ9V6_*W3DX`1^y88r$QelGw6L`d0fz zzw`7>J`teYd2H61=o71|_OfSR`d&59{Og?3Cl9S_-~8^c_G_L~7k=sW-TF(~zh_;y P=W0?gFl6>EX7~dD0ghsZ literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/tree_place_8.mts b/mods/a_mapgen_mods/mg_villages/schems/tree_place_8.mts new file mode 100644 index 0000000000000000000000000000000000000000..25b6d550b12f281f0f0ef49b79fb8ded41a68e8c GIT binary patch literal 99 zcmeYb3HD`RWME}r24m*L%pwN9?J*3?otzTE2$>tztBz!tGAt}k}5hH_u4}&5Am!BVf literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/tree_place_9.mts b/mods/a_mapgen_mods/mg_villages/schems/tree_place_9.mts new file mode 100644 index 0000000000000000000000000000000000000000..6fca2c6514d26185fea85561bda0c8b559c751d3 GIT binary patch literal 301 zcmeYb3HD`RWZ(iq4hD7xp_J6L#L}D+tF+X-{PNVIVymM3 z;#3BK;u4@>u~l(SViH7=G`dJ>L2+hEYJ5t5c^(5_a(+okVtQ(^RT9wH3iTs|YQBsn9#JU>4LNwB!2D6u>~ zDG{iWIWe=SVoq{G1GCv4fk;_pk!A&Mfk#2dS&ruLoZ(sHz!AupI5AmH?#Fz-21a!T i%UO+$-Q1Bra~!8MI~mfg i7(8IoNoe6Y;_B)uDIp;_b7rE_nuHc+28N4;(IEg2wn_>B literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/wagon_12.mts b/mods/a_mapgen_mods/mg_villages/schems/wagon_12.mts new file mode 100644 index 0000000000000000000000000000000000000000..b01f0805a8a8f45806b8d7720c40e2304091b04b GIT binary patch literal 232 zcmeYb3HD`RW?%zi*8l(iGjK47r=+GOmgbaLrDPVB#FuB5WW=WzB^DPmh$QEilq9C7 z7F(4krswCymuIA=<}mQVMUztVk~0{D;rxumlH`o|^8EZ127b6;QesgNP?sp0KzvSR zW?ni2FU;=bjMU;12Ij=fqKY}m2@XteEEHBrxhbTvPTq0Vz|eqMQ8=Qlvys(fQ=)16 q+y={thxM}<*5$fjKd=sA5iXf&=rS_scrbyr)l$H~P%u?kgn@y{aK>!_#U)oV literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/wagon_3.mts b/mods/a_mapgen_mods/mg_villages/schems/wagon_3.mts new file mode 100644 index 0000000000000000000000000000000000000000..4baaa2d99ed829d993da7ac52816d017723a064b GIT binary patch literal 189 zcmeYb3HD`RW?%*3|Ns9purY|Iq^2d7=9E~aWEPdgmuHq_#HSY}78f&!BSBz{q3{M8Zt5 z<%#L}dGX~Lsi`>(d~ngE)V$;j24OfqBe5hoBfdO8KZSugF|(**PI5v6vzU%R{zivgIU?w Ucv7>3#EcmiN*NjUW_f=D05l~;dH?_b literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/wagon_6.mts b/mods/a_mapgen_mods/mg_villages/schems/wagon_6.mts new file mode 100644 index 0000000000000000000000000000000000000000..1ce04096d0a4353d5aa7c7c6aa3af6055c37a868 GIT binary patch literal 160 zcmeYb3HD`RW?%*3|Ns938R99aX^EvdB~~e!MJ4g&nI#$V=|zdf#S9|J`6VTZ>8Zt5 z<%#L}dGX~Lsi`>(d~ngE)V$;j24OfqBe5hoBfdO8KZSugF|(**PI5v6vzU%R#!oPxe29r%BRndb(>DrSizk}j^25;JEmj0saX!p5*@rS~BKQ+heV literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/wagon_7.mts b/mods/a_mapgen_mods/mg_villages/schems/wagon_7.mts new file mode 100644 index 0000000000000000000000000000000000000000..379d40f267ae234b150c86896e6e7bf74ed1f29d GIT binary patch literal 170 zcmeYb3HD`RW?%*3|Ns938R99aX^EvdB~~e!MJ4g&nI#$V=|zdf#S9|J`6VTZ>8Zt5 z<%#L}dGX~Lsi`>(d~ngE)V$;j22nV_I43o=ATuvLJ~y$1fjKd=sA5iXLIbmyjzHuz z!7j%MoE(9vGaoGS;W^{r(G|z@V}4ZwqqM_Usb-7j6&lRS#yzLGT6lPTd|vEgn0?=S FHvopuJv0CS literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/wagon_8.mts b/mods/a_mapgen_mods/mg_villages/schems/wagon_8.mts new file mode 100644 index 0000000000000000000000000000000000000000..95f8eab6e93d23579a36b1db6fc54490929fbb56 GIT binary patch literal 218 zcmeYb3HD`RW?%)u{~*A?#vq=OnwD6aQ(~2pSyU2Vo>`I+pI($$T+ASnoL^Fsn4Vf} zRi2ohpBG=Ak(!#rzy}viO3h2oU=W4#i*r&_3o`T4<8u>B7=+=%8Hpvy8S&-$`6&#{ ziJ3(ebCMGpn8TD5H}Sb?usNnFxTGh(N?=OnILXvRsum5nDgZ(w9N IzTf*V08NlU*8l(j literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/watermill_1.mts b/mods/a_mapgen_mods/mg_villages/schems/watermill_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..53d1b58da7edfce38d935ef4754f9b62c933b556 GIT binary patch literal 2945 zcmZ`&c|25Y8$R0cW{YZ+v?)tjddo6}QX(=fgX%@cnVB~d%l2z8MT2Z9)ufCuX|WB_caY($?|uF_=l9(A^<4LI-M5P?(FK?cr~{h7>>vN< z02Y7>1*SqA28t&mBoYG#{usMc=qwbN#YQ1Ii;W-ofj=P{V-PCLB*P#VK`7(TMs9La z9~Kk@Gk`f`FNR4$E*+(Tn1{^>_(wRPhDlLSVa=c}uNG`(i1I9BQ#$XCTD4->${287RGOXJ8`;l&g zBnTTZ)nBl{tl?tW_~GwJSdav+`rU|PM%6K0s2mm(!h}*8=fZ}OHsOv!BjYUhqa4zN zbZ8Jtrj6D(R}LA`Ww;!W#DK_t6W}ABQRBbLIO-lxh)shT)Csz9As>VZa%nKO5bE-n zG;HSm>6j?;k;Bx$rbWIoBiGTLAtMmu_r8!ovk8187*hm6u+{ywspxMw8Vpe;Br4 zK$7qRXSW@-*-nY9ox+yX(L=m>d$)edq!F70Xx8=sB7SA=rRwI{5f(+qdjv|^Mrg;4 zyO){0nT?isEzV5X)XVUhVe6^n4XaaddYyeFzzRw8@@(67*~C@2ehzvk9j}ozK0Y;G7}IDp?!0 zplp&b{P2m}9K#0Pzla06MY5y>X>roJV}t@X*7=(+n7jyIPD6H$uI%gbbhAVub3Lfi z4Ye26C@G7RTAxPnY#wDNMOIIiHJ5(>lG}4CS$gZBFsDYfnJIgneUW%y?PW+sa23XQ z^?{`gM{!Ui^Sv3T=|$(jwfHMFCdoT4f)1HmI__=h$`euG&YxQ$s=Pr!gLOHQJ{Ue5MOCwH>;<2e^*> z=l{+0=~fSN(ZIhPXVcY3n)~?;Spa+R$Gvqc7|A z{|F)-=Y2BSK$}G?sOfcZ!*^K$Ttlcv> zaRcFLO45i(`af+YTer=S^tsgU$1Piyvfz1rN>;EoHR)@pW#Za~5(AGRf)h?TJR$n7 zYWG0zdcIf5t>*^RFfp7;EJJc-TT7qRe{;mUC43Qyb){dcDuesyfCCSA98izr4~oLq zq)3kS2Bu#Lo$DJ^0r#Qp$4)SXxFS)8N2XhgPg;$olCNt+{Yn(?`B-h}yJkMqF`_@) zOvc?GB9T~BuSktxPZd61|S{ikO9%Au25?>(4x;89SyUgO%vjoDRp^gXN>9o~8rTcANNKudV->hRX zX|{s2jYkaU`!3=v@Zh_ya?RDmm(-Z&rCo6G+lXeVxxWpVR!3j_Eozefo?K^f?bCjv zsj88C4VxqaI-1;hj@XkVv5tK5!X`FySuZJfqemIxcIlp1d-+!T;&dflI`v|&wQ*&V zS_4X-6l4+y%$tJEV+e^nj_=d;xqi=1o7(1y#7$On5^?u@-hnAIh2ljkt`e{ABAYj_ z%gc$O`S|^?-}LXNIIs}B!fz9(-x<i$k|SNlboE=@sCfA$Wl;tz1jSN%|d+bxGHsz+D9D&kbGwO9E3ynl0{ z{eJh8P;P0u-j9og7d};_&XOUKT3o`TFk3j`=!%N|Eyj~hFScJ*k+|C7q3M}zijd73 zl`VjYLZ{=TT|-O5lRsJ+pQ)0zyc$>-<|KVx(R}N>&{`Hs6CKw=kBW$arY`@PENzQ8 zSSfLUcoF5ya zEJ)UB%S@kdJPDcNYi4ulgZ|o2U&QXc5#@Vo6!UD$&7)s5THJKvekg7&Uf;PT(lO^u zleJCunf%Ni+n&-7}uVZ%WWM~4=Kdx3GfLFFxI;#YA&eb z>_;PwPd-X|zuL2H;aqQN$07VwKO^-ETH7r-VfYO0rh|XJam2Ix NY!?nqFZ#3~{=XQJP!IqB literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/weide_1.mts b/mods/a_mapgen_mods/mg_villages/schems/weide_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..e1e559b838b5f1a060769f1b3ce25ec5fb1ca5dc GIT binary patch literal 542 zcmeYb3HD`RX5eICXW;n{0Sp2R;whu8wA8%h z)cErJ{1gU}IrFkg~2umQsNr^eB416#*=Om`2q!uyo!1b1t zCNapsdF7dTDf#8`#Tlg~Aiw1oq~=x3c{{C9s7ZmR&HUM^saJp7=RRcdJL0!;!mc~- zQp~^I-+s4|Yl1|S`L8e9qMt3RVglRmg)E%CenzdfmHHRwtvCB$9nM?)r7-P7n6c1P zziY)W)4$HRckt-jIN7;Q$1eZ&iEfb#pP}O1x0_XV_2vB57w7%%{_ws1UHH4oe9O}B zcgubobARvgus7&1E-z@knDW=NQdW4PXM@r@)u_C+pY1sn9UjQ+6#jYOlwv&J`;#wC VEsdq4-Hs%d#m)Q6Sg!oL7XSrb<=FrL literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/weide_2.mts b/mods/a_mapgen_mods/mg_villages/schems/weide_2.mts new file mode 100644 index 0000000000000000000000000000000000000000..51c8221a0ed391638cbfacc9ed9eef1a614a5c0c GIT binary patch literal 626 zcmeYb3HD`RX5eCAW#IY`0t{jd;whu8wA8%h z)cErJ{1gTrm>5Vg13!#coLG>PnU~HWlAK>sl9--aY?Yo^k{X|!lV6;g!XN@uRt^*_ ziZ9MDElN&h5P+*KPb|&==@uw1Nz5!Nwkpm^OoCV^3s+N=pPv?=oS&DMnp~0(G^3;_ zv7A8yRXQyvu>>k33YP(^1o|kyG%tmL4=$Vp^iu`{51e08nuPEi*sBP?K>S~vo0yZs zAPm<5F*qqPClyH$>`aK`_+Y+H&QD4LDuVNK5>rxAix`Ac^7Db71(9IS#wW!aVhWZ3 z1(|`NQZeW4rj#Y?YcZF}`se(RmH_cdEooUT}Ih+QXVe}%WBM3K42=F;bT z2U6Rl-=2IBzm;D=F?Guh@q`0mI@YuOC3k)jJ+9Ux%Xh7D^NOyP-4nK&A}9g?f1CXK literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/weide_3.mts b/mods/a_mapgen_mods/mg_villages/schems/weide_3.mts new file mode 100644 index 0000000000000000000000000000000000000000..fea05068979f67344de87362ab23320d1f7ad8bc GIT binary patch literal 517 zcmeYb3HD`RW?*MvWf1re0u1~N;whu8wA8%h z)cErJ{1gU}3cS%)E34f#Q1Pp=<;whu8wA8%h z)cErJ{1gU}^QCcb#=f@3Zk!!70!8 zJ)bLKaMIHF(XHq?N47nFEpquw^1RycV~-|=+5U8y!=LMA*SGM`F7BDBUo_+I{z^Re j>RHEiWm$pC`h|_zlb;Li2%7lhp0!_q&>`;5NUg;HL$KAs literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/weide_5.mts b/mods/a_mapgen_mods/mg_villages/schems/weide_5.mts new file mode 100644 index 0000000000000000000000000000000000000000..6877d3e732a6661945b1e00ed83496130beaa465 GIT binary patch literal 362 zcmeYb3HD`RX5eOEVc`A`1VEN}N@`kSX-e0gR`MtpivVsSBp5KJO1H7_|e zzC1rag+U}azoaBFJ+;^>J+UM;J~=19I5mZVAEvT6u^=ZiFP%XICQuGkRTN*GUs{x$ z%D@NLoCGv6gFyh!FHbDa0O{j{=>xi;EH#Hg0bV$R#iy<80nJS}&x+3)-R`r4LBmpWawm3Hx`^n5l6PIlqt-kQEn zv!q{vTjGmyPFC-oD?iuW=_<^!&2~GyX64=uldim-QL_K{9o@{PJGxJg{g2l+|Mx8W z`G-5T3RmxRzfbz}wKDacUtr6VBab^hEBeKAZ-}-EIhaK+4EY*#b9F5rhu@6oJf^jC H-fsW^llz*{ literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/weide_6.mts b/mods/a_mapgen_mods/mg_villages/schems/weide_6.mts new file mode 100644 index 0000000000000000000000000000000000000000..37445d1f0b2b15b8845f8eae4d714c8a3f565baf GIT binary patch literal 239 zcmeYb3HD`RW?*MvVqpLOpMjG>JS85$K?EjN zo>-Dv6knWQT9lm1z?_&_R52$xK|$ES$beZ*I8~^|S literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/well_1.mts b/mods/a_mapgen_mods/mg_villages/schems/well_1.mts new file mode 100644 index 0000000000000000000000000000000000000000..330457538b332c72d132bb5b11e01da19a2aac04 GIT binary patch literal 301 zcmeYb3HD`RW?*GtV_^Lc1`J#b;wh8Zt5Mfv$@@o71UCGo{2MTzAM!l*J3K^|no7=(&TfMyh173U--#V6+{CFP_t z@WE6-`9d&$T54W$YJ7QqehPyKOsqVyB(*5MIKQ+gIh8>G*))*4iaE&%4a{yb6FM6u zI|NObni#kRn!ao@+Q4Y&GDns}P$x~{EYDKKXO3Ss9r(J*uzG`XA*eW7(Seu_8$Nj1adV1 literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/well_2.mts b/mods/a_mapgen_mods/mg_villages/schems/well_2.mts new file mode 100644 index 0000000000000000000000000000000000000000..4966620152c6a0dadcc80963b112d92553ee4fae GIT binary patch literal 276 zcmeYb3HD`RW?*GtXJGpe0SufB;whoGIC00D|4*B>4=gL{ zT0TeXt-odH>2{U(VN1L3W@P*|Ref$=_D%1m?CkLCet}M9M|O9dc;>mGOJm0KiQC`L z+CRm-Y~JVhr;mIu_)sSm!|o7aJ#UWJQ3u5Cb>bvV(nFlvd^(cN=n7 literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/well_5.mts b/mods/a_mapgen_mods/mg_villages/schems/well_5.mts new file mode 100644 index 0000000000000000000000000000000000000000..e0a9a61e0febc8945fe19caf4b65fd4e6cf81f7f GIT binary patch literal 224 zcmeYb3HD`R20~T_=KmnTz`-D%lA4xSnp0wxl37#|U!GZ#5uaX^SX|7&gDk}gp>12N)ppki>-?C^V8ysONtW986;2z({d6^ zpfVybBgzv?Qj6k?^Gl18Q!C~qCnO}K0C7?RTap@^m_i!sq%{t+csnEyPMFy!tJSa7 Z9sa&Ph=G}>LC2XXVuue8gSMY;0s#G)Pfq{< literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/well_6.mts b/mods/a_mapgen_mods/mg_villages/schems/well_6.mts new file mode 100644 index 0000000000000000000000000000000000000000..875f352ebaa20cb1467e3e4b8f85feca868687bd GIT binary patch literal 189 zcmeYb3HD`RW?*GtV_^9Y1`O;B;wh8Zt5NvV0s84Ntgsu_feOMr@st%`FJlj4)}lag{$8Teo-pnMS+zdW%dwJ5$g zzqBYhwPH?kLIblKo0>t2ijdXxd8rIMaBgB=3WGR|my%gj5?`KK zk`bR?lvrHMz?_&_gis5TW#EIUP0mkB%1LDqf$_@|OHzyCi}Op1l2aLkic5f6i>-=t z5|iQ~Dl6tBCp0j-DWo_xo=I^^VKAD^%IBE2>5$^iG^2*IEi)L6C-d^GOjbJ)(lYbK pGNsQq40D$BTWj*2|F0}zaDlPrhr=GPM^h&~7fWGa_!q+54glb)SK$Bv literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/well_8.mts b/mods/a_mapgen_mods/mg_villages/schems/well_8.mts new file mode 100644 index 0000000000000000000000000000000000000000..1b9a4abb986cf10a9c4c19dfb94405ff8481ea29 GIT binary patch literal 318 zcmeYb3HD`RX5eCAV_^Lc1`ON`;wh#lxr{yG;#21$oC6+UYz!a7zmZTQN7w4B2B_mr=k_fU=sJH~^u41d=oW!Jfh%+kY zBqtnTl6c7=DKX=LK%%~}%q9j!?JmAFHZz4zonvew$?VRT-n8Cm$kJz*XnOOMB`Ku( z;@JmEm+v)xeBW^7{r^A*lLJ!jDNJb9e8r?OpmkatT>&MtrdHp-1g>TU}&k( Gc?JM%$$Vh| literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/schems/wheat_field.mts b/mods/a_mapgen_mods/mg_villages/schems/wheat_field.mts new file mode 100644 index 0000000000000000000000000000000000000000..1abd214b9f1f0803febf5f7221ae0d19835e188b GIT binary patch literal 111 zcmeYb3HD`RX5eICV&MG$pMixzAT6;dH#0BYsyIJ0C%!zjgh3=FH7&6;r^Ko}u_U!9 zzBs?MC^?mZAEvH6BQ>!k-hzQSF|(**PIAHl1|NwDg3LzA4oPPumzDjM|H9C%&nC&h JAoFCAIRLOQB= (pos.x-1) and x <= (pos.x + pos.bsizex + 1) -- area reserved for house + and z >= (pos.z-1) and z <= (pos.z + pos.bsizez + 1) then + village_area[ x ][ z ] = {village_nr, 4} + elseif nodrad <= flatradn or (xr == 0 and zr == 0) then -- irregular flat area around house + village_area[ x ][ z ] = {village_nr, 1} + elseif nodrad <= blenradn then -- terrain blend area + local blenprop = ((nodrad - flatradn) / (blenradn - flatradn)) + village_area[ x ][ z ] = {village_nr, -1 * blenprop} -- terrain blending + else -- no change to terrain + --village_area[xrm][zrm] = {village_nr, 0} + end + end + ni = ni + 1 + end + end +end diff --git a/mods/a_mapgen_mods/mg_villages/textures/aw.png b/mods/a_mapgen_mods/mg_villages/textures/aw.png new file mode 100644 index 0000000000000000000000000000000000000000..25f658c1393d5476ec9bbb61826c94eddd409783 GIT binary patch literal 2105 zcmV-92*&q`P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!~g&e!~vBn4jTXf2hK@EK~zXfg_e12 z6!#U!KXdH8>s?=Ku#Jr|SBx-6I0A)2AVEPbO+rb9gp`Vkwo;T{q9PIPA8D(qk*ZW_ z{%BQIEvljr_#;OlQcuwY2?S{am~yA)FuvEvu6Mn=vvc*$*g#WA`=r&*?#%BU-}imr zH;OC9|FNz!XF2$%vz)uqOLxx@sfa=#ps})}iS`W6?cOCa9~-steLHIDu;!Yg8k-=BmCgigJ_XzG*uxIgpQUtr>^7(2Ne`W!!#`%MP=KH8X9XuoWGtW5)Kj4 z9Z68-(6JkQZu1%rzxJ(ZuT%DkdXF4=i!&#FPfJr;0?ADUEE|T$%aWEtvpB9uAYFBs z(-5IPsdKSsg89u=v^Ru^h62o;5#qbgEWjB(&&iV~r#(;E-C$?Vp5rIKe2+*X&6U2A z=bK1K!*LyYMl8O#u8yq_r}*rmB>m$y54XpuSS~ZGgN#j7c>kYc(o2Uk-FY0#Wasv+ ztX;cy+WVB<4R-71byhB@A*d;ATUAT3?2roC?Akbktt(O_M*Em3Sj=yV@#ReoR7G_H zx-KvW(B#aLIY}Jb5i&(3LFnu2pZ0vu{GNH`-oD+-`L45s1bba^xHf3g7R_4lROqL9y;UKPKOTQFG@)n7(B8in5HIvM5Z|0}__uLD%_dDO@ z`UpJKn!>Uism}E?Kl)LYo=k-=tV#)_K@t&7?n@J$ESeG%k_5;Wi&9~QXdo&5HE~^w zcRwsqs#x;dL3a&)w(n`4e(EXIiQyBX%m3cksnI?oNGzz+)>OrFKRnFkOXtxxu3GU@ z_rNIE`VCgLxztoeIel%CKTCjESoZ^0Dh>@ogsc4}j&&9Ic&J2ceVAO?r72a7J6X#_ zxk61cCW(U~pP{VntBi-t=O0Pq+BVv{WlLWg7iYC`m5^qlOJDwSzCcYPz^3^+dBa5w z7y^$*|ENh_l|`EbG6l}XEg{D9c~Z%QBqr6CDgu9yWK2HNhImL}aci7e=@_G9MbukH zfLKVFC4*I4o92(_ax%0w%iAKnbGFDx!C`r8J-VioP6~()j1>DB%vu!WY*jpo?VA3e z+j7%8>-8!bReUtUVT*F5!l-c-bts#YK2?~MzV(ilSUX!s)if^LE|N|KSvDs@dm6%` z4*8NM$}-8K#t@p`D?z-;aYPr9$_=U$AxXeuVAMcWHTe^4>8W=ySdw7#QWYZV1cT$2 z^drZaK9z=~Mp59)7i|gx&99GTxzJOVA-2ek)o?u%rf+nnu+|dln_f5}QWzn!z-syx zIWpk6Nr!Q3Nc<6a9< zzC&gC?5I@cl86TU#KsCX6O$$_>99Pf;)(<*!rpOzgiOc8s*L785*1FQTKiANybKcdH?TM1@j1oQDj2+yRM^(5C2u5JLA&Ykfdz7 zoWD`_A&!ML+Js?>z~>ElFck46%C=qUoq#G3hG#YtRt%oov69_8pWx9)H%=+Y3om|; z-jN(L>rx~|B{CBp?jcHsBaT(F1yj^R^(Th?UVZ2Zw7MOCRO6!e^E%cZ5b848I8AFI5 z{g9e6Lj9>g;y|kLD)V|}%fL-v|WK_EYSqkvg1V+&ioIk<3pOr*?Y@v_x^kUQoF z^OD>5!hR-mMQR%7@x+$L=^4sP|4atPD;TnURoMiQfI_+|AgH+Tvdr4zm zg2Ay0!C2jWfjqmfvOCt*)y07Wzr&Eh{l?dy<;c;aWJbn`MnYVdJ$Ld-UKB(sltEuC zZ(oN#=wbBSq3P2Pw)-l(V_pv4=Kc2bd&mq8lStK*GeZPrM=hKcWA|femd&kU^COD{ j=RE&-_vPu6pJwoHG0Kt(3I?fZ00000NkvXXu0mjfd|dfQ literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/textures/aw20150916.png b/mods/a_mapgen_mods/mg_villages/textures/aw20150916.png new file mode 100644 index 0000000000000000000000000000000000000000..0d3758976778414a0824c126e0e6322b87200010 GIT binary patch literal 186157 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 -!btPb$6#a3m01Kv=!3&)Em|YxKG~MGg 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

gbU}%9mog?YbQy?Df)p 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 KMNUMnLSTY88S%vc literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/textures/d0.png b/mods/a_mapgen_mods/mg_villages/textures/d0.png new file mode 100644 index 0000000000000000000000000000000000000000..394368e6f735b9a5a9a17f4dcf70d23f843071a7 GIT binary patch literal 266 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP)GqV7b2=nUH2S6do64!_l=ltB<)VvY~=c3falGGH1 z^30M91$R&1fbd2>aiF3iPZ!4!i_=FZ$8t3o@H7j5WcmCr{cnwiu*`2k^Nkm#Z(G8d z$(x~O=IbVYz-(J3Yl5^xLzTj1p>OxfUQbxk&HCUe&y><A8}S>+Gz@BhdWC0%K--|Unn&~^q-S3j3^P6igP)e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00DAIL_t(I%e|95NYnus#(&;* z7eXO%Lm$Y69T_J|4Sgsm7FdI#LAl;iS-6PN=cu?iC=^sE4He`j*3hBc>fjuLhY}8o zACLtm=o0^*!+-5xdP2|oKFr8zy_gJk<+|4M-=@60-6G<; z8#Y~N6u7z<16A>;#E}@*Y}Gq5Hfriv>M;CyekPqMzLWC=_)&0ZwtIE<(y+c253L%V?~O00TN)KvXG9XTL1t6 M07*qoM6N<$g8x$7PXGV_ literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/textures/d20.png b/mods/a_mapgen_mods/mg_villages/textures/d20.png new file mode 100644 index 0000000000000000000000000000000000000000..4fcf627556cea4a8dfbd1b4a19815ce1470ed58a GIT binary patch literal 527 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 B+A9D6 literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/textures/d70.png b/mods/a_mapgen_mods/mg_villages/textures/d70.png new file mode 100644 index 0000000000000000000000000000000000000000..0802047136fe69b9796f8ddeb3b882050157440b GIT binary patch literal 527 zcmV+q0`UEbP)e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00DPNL_t(I%iWXDOOyc+hM(Q= z6SsAh6aneWM}U{{c-;J{{4%f* z1i>;;0G{}TS(_UGtc+Iis{Q8h;RIk?sK5fL`njE|9tWP2yV+W>$CcU#Pdg~*np0fG znBCr9o$^@js6h2!=es$4x#A07$#bL^+ZHpru5%Bb3WWc=eucT^9e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00DkUL_t(I%iWVrDCBV%$3H)B zty*o{Tqw<^i6qlHc-bw}?qSz~jF)wtlO(w)!b#+!4JB-}Z8?xVh&jxJzXP`^xwx3f zI80f#I54FQ=DUX_n$YCn;QRE{)ARKG_Vm2Ki$fXE4)_4ubuKv(q5&v*U%b`T(y8Uy zB~^W`+y`WPYwG|$0|k$gfsww+e$B}rYgR|B_iR9tG%+(NS5dh<^`0$Y0T{YZq`IN< zn>H1U5k}Ob^yW88Ri+9eA9ScAji3J1?_aaBEK9&nynrLeo}&{*#D0o^|Na`0gl_Bx z*L8EZ{UqQ@mm)1WlZ#h>;rw=lrI9auN-x)OYuE%<1B61M{Ae_~9pA;?LGX{9atS*! zAgolO4EcALT-<`<{^YE+x>A$(|1W0IsMPtzeV0~E%SQtrg-*4j#~ zvn0>_sG5?Ck8F4Y#?%>rDWE%%dnk0+9l_zAA=Om4m7SFxzGvMD;XB|4>`yso^Q_PF Y4?>!$04c}wG5`Po07*qoM6N<$g8p^tXaE2J literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/mg_villages/trees.lua b/mods/a_mapgen_mods/mg_villages/trees.lua new file mode 100644 index 00000000..a4c6539b --- /dev/null +++ b/mods/a_mapgen_mods/mg_villages/trees.lua @@ -0,0 +1,234 @@ +-- this code is taken from https://github.com/VanessaE/dreambuilder_game/blob/master/mods/default/trees.lua + +local c_air = minetest.get_content_id("air") +local c_ignore = minetest.get_content_id("ignore") +local c_tree = minetest.get_content_id("default:tree") +local c_leaves = minetest.get_content_id("default:leaves") +local c_sapling = minetest.get_content_id("default:sapling"); +local c_junglesapling = minetest.get_content_id("default:junglesapling"); +local c_snow = minetest.get_content_id("default:inv"); +local c_msnow_top = minetest.get_content_id( 'moresnow:snow_top' ); + +local c_msnow_leaves1 = minetest.get_content_id( 'default:leaves' ); +local c_msnow_leaves2 = minetest.get_content_id( 'default:leaves' ); +if( minetest.registered_nodes[ 'moresnow:autumnleaves_tree' ] ) then + c_msnow_leaves1 = minetest.get_content_id( 'moresnow:autumnleaves_tree' ); +end +if( minetest.registered_nodes[ 'moresnow:winterleaves_tree' ] ) then + c_msnow_leaves2 = minetest.get_content_id( 'moresnow:winterleaves_tree' ); +end + +mg_villages.grow_tree = function(data, a, pos, is_apple_tree, seed, snow) + --[[ + NOTE: Tree-placing code is currently duplicated in the engine + and in games that have saplings; both are deprecated but not + replaced yet + ]]-- + local leaves_type = c_leaves; + if( snow + or data[ a:index(pos.x, pos.y, pos.z) ] == c_snow + or data[ a:index(pos.x, pos.y+1, pos.z) ] == c_snow ) then + leaves_type = c_msnow_leaves2; + end + + local hight = math.random(4, 5) + for x_area = -2, 2 do + for y_area = -1, 2 do + for z_area = -2, 2 do + if math.random(1,30) < 23 then --randomize leaves + local area_l = a:index(pos.x+x_area, pos.y+hight+y_area-1, pos.z+z_area) --sets area for leaves + if data[area_l] == c_air or data[area_l] == c_ignore or data[area_l]== c_snow then --sets if it's air or ignore + if( snow and c_msnow_leaves1 and math.random( 1,5 )==1) then + data[area_l] = c_msnow_leaves1; + else + data[area_l] = leaves_type --add leaves now + end + end + -- put a snow top on some leaves + if ( snow and math.random(1,3)==1 )then + mg_villages.trees_add_snow(data, a:index(pos.x+x_area, pos.y+hight+y_area, pos.z+z_area), c_air, c_ignore, c_snow) + end + end + end + end + end + for tree_h = 0, hight-1 do -- add the trunk + local area_t = a:index(pos.x, pos.y+tree_h, pos.z) --set area for tree + if data[area_t] == c_air or data[area_t] == c_leaves or data[area_t] == c_sapling or data[area_t] == c_snow or data[area_t] == c_msnow_top or data[area_t] == c_msnow_leaves1 or data[area_t] == c_msnow_leaves2 then --sets if air + data[area_t] = c_tree --add tree now + end + end +end + +local c_jungletree = minetest.get_content_id("default:jungletree") +local c_jungleleaves = minetest.get_content_id("default:jungleleaves") + +mg_villages.grow_jungletree = function(data, a, pos, seed, snow) + --[[ + NOTE: Tree-placing code is currently duplicated in the engine + and in games that have saplings; both are deprecated but not + replaced yet + ]]-- + local leaves_type = c_jungleleaves; + if( snow + or data[ a:index(pos.x, pos.y, pos.z) ] == c_snow + or data[ a:index(pos.x, pos.y+1, pos.z) ] == c_snow ) then + leaves_type = c_msnow_leaves1; + end + + local hight = math.random(8, 12) + for x_area = -3, 3 do + for y_area = -2, 2 do + for z_area = -3, 3 do + if math.random(1,30) < 23 then --randomize leaves + local area_l = a:index(pos.x+x_area, pos.y+hight+y_area-1, pos.z+z_area) --sets area for leaves + if data[area_l] == c_air or data[area_l] == c_ignore then --sets if it's air or ignore + data[area_l] = leaves_type --add leaves now + end + end + end + end + end + for tree_h = 0, hight-1 do -- add the trunk + local area_t = a:index(pos.x, pos.y+tree_h, pos.z) --set area for tree + if data[area_t] == c_air or data[area_t] == c_jungleleaves or data[area_t] == c_junglesapling or data[area_t] == c_snow or data[area_t] == c_msnow_top then --sets if air + data[area_t] = c_jungletree --add tree now + end + end + for roots_x = -1, 1 do + for roots_z = -1, 1 do + if math.random(1, 3) >= 2 then --randomize roots + if a:contains(pos.x+roots_x, pos.y-1, pos.z+roots_z) and data[a:index(pos.x+roots_x, pos.y-1, pos.z+roots_z)] == c_air then + data[a:index(pos.x+roots_x, pos.y-1, pos.z+roots_z)] = c_jungletree + elseif a:contains(pos.x+roots_x, pos.y, pos.z+roots_z) and data[a:index(pos.x+roots_x, pos.y, pos.z+roots_z)] == c_air then + data[a:index(pos.x+roots_x, pos.y, pos.z+roots_z)] = c_jungletree + end + end + end + end +end + +-- taken from minetest_game/mods/default/trees.lua +mg_villages.trees_add_pine_needles = function(data, vi, c_air, c_ignore, c_snow, c_pine_needles) + if data[vi] == c_air or data[vi] == c_ignore or data[vi] == c_snow then + data[vi] = c_pine_needles + end +end + +mg_villages.trees_add_snow = function(data, vi, c_air, c_ignore, c_snow) + if data[vi] == c_air or data[vi] == c_ignore then + data[vi] = c_snow + end +end + +mg_villages.grow_pinetree = function(data, a, pos, snow) + local x, y, z = pos.x, pos.y, pos.z + local maxy = y + math.random(9, 13) -- Trunk top + + local c_air = minetest.get_content_id("air") + local c_ignore = minetest.get_content_id("ignore") + local c_pinetree = minetest.get_content_id("default:pine_tree") + local c_pine_needles = minetest.get_content_id("default:pine_needles") + local c_snow = minetest.get_content_id("default:snow") + local c_snowblock = minetest.get_content_id("default:snowblock") + local c_dirtsnow = minetest.get_content_id("default:dirt_with_snow") + + -- Scan for snow nodes near sapling +-- local snow = false + for yy = y - 1, y + 1 do + for zz = z - 1, z + 1 do + local vi = a:index(x - 1, yy, zz) + for xx = x - 1, x + 1 do + local nodid = data[vi] + if nodid == c_snow + or nodid == c_snowblock + or nodid == c_dirtsnow then + snow = true + end + vi = vi + 1 + end + end + end + + -- Upper branches layer + local dev = 3 + for yy = maxy - 1, maxy + 1 do + for zz = z - dev, z + dev do + local vi = a:index(x - dev, yy, zz) + local via = a:index(x - dev, yy + 1, zz) + for xx = x - dev, x + dev do + if math.random() < 0.95 - dev * 0.05 then + mg_villages.trees_add_pine_needles(data, vi, c_air, c_ignore, c_snow, + c_pine_needles) + if snow then + mg_villages.trees_add_snow(data, via, c_air, c_ignore, c_snow) + end + end + vi = vi + 1 + via = via + 1 + end + end + dev = dev - 1 + end + + -- Centre top nodes + mg_villages.trees_add_pine_needles(data, a:index(x, maxy + 1, z), c_air, c_ignore, c_snow, + c_pine_needles) + mg_villages.trees_add_pine_needles(data, a:index(x, maxy + 2, z), c_air, c_ignore, c_snow, + c_pine_needles) -- Paramat added a pointy top node + if snow then + mg_villages.trees_add_snow(data, a:index(x, maxy + 3, z), c_air, c_ignore, c_snow) + end + + -- Lower branches layer + local my = 0 + for i = 1, 20 do -- Random 2x2 squares of needles + local xi = x + math.random(-3, 2) + local yy = maxy + math.random(-6, -5) + local zi = z + math.random(-3, 2) + if yy > my then + my = yy + end + for zz = zi, zi+1 do + local vi = a:index(xi, yy, zz) + local via = a:index(xi, yy + 1, zz) + for xx = xi, xi + 1 do + mg_villages.trees_add_pine_needles(data, vi, c_air, c_ignore, c_snow, + c_pine_needles) + if snow then + mg_villages.trees_add_snow(data, via, c_air, c_ignore, c_snow) + end + vi = vi + 1 + via = via + 1 + end + end + end + + local dev = 2 + for yy = my + 1, my + 2 do + for zz = z - dev, z + dev do + local vi = a:index(x - dev, yy, zz) + local via = a:index(x - dev, yy + 1, zz) + for xx = x - dev, x + dev do + if math.random() < 0.95 - dev * 0.05 then + mg_villages.trees_add_pine_needles(data, vi, c_air, c_ignore, c_snow, + c_pine_needles) + if snow then + mg_villages.trees_add_snow(data, via, c_air, c_ignore, c_snow) + end + end + vi = vi + 1 + via = via + 1 + end + end + dev = dev - 1 + end + + -- Trunk + for yy = y, maxy do + local vi = a:index(x, yy, z) + data[vi] = c_pinetree + end + +end + diff --git a/mods/a_mapgen_mods/mg_villages/village_types.lua b/mods/a_mapgen_mods/mg_villages/village_types.lua new file mode 100644 index 00000000..5a8bd634 --- /dev/null +++ b/mods/a_mapgen_mods/mg_villages/village_types.lua @@ -0,0 +1,123 @@ + +-- DOCUMENTATION: mg_villages.village_type_data has entries in the following form: +-- key = { data values } with key beeing the name of the village type +-- meaning of the data values: +-- min, max: the village size will be choosen randomly between these two values; +-- the actual village will have a radius about twice as big (including sourrounding area) +-- space_between_buildings=2 How much space is there between the buildings. 1 or 2 are good values. +-- The higher, the further the buildings are spread apart. +-- mods = {'homedecor','moreblocks'} List of mods that are required for the buildings of this village type. +-- List all the mods the blocks used by your buildings which are not in default. +-- texture = 'wool_white.png' Texture used to show the location of the village when using the +-- vmap command. +-- name_prefix = 'Village ', +-- name_postfix = '' When creating village names for single houses which are spawned outside +-- of villages, the village name will consist of name_prefix..village_name..name_postfix +-- sapling_divisor = 1 Villages are sourrounded by a flat area that may contain trees. Increasing this +-- value decreses the mount of trees placed. +-- plant_type = 'farming:wheat_8' Type of plant that is placed around villages. +-- plant_frequency = 1 The higher this value is, the less plants are placed. + +local village_type_data_list = { + + nore = { min = 20, max = 40, space_between_buildings=1, mods={}, texture = 'default_stone_brick.png', + replacement_function = mg_villages.replacements_nore }, + taoki = { min = 30, max = 70, space_between_buildings=1, mods={}, texture = 'default_brick.png' , + sapling_divisor = 5, plant_type = 'farming:cotton_8', plant_frequency = 1, + replacement_function = mg_villages.replacements_taoki }, + + medieval = { min = 25, max = 60, space_between_buildings=2, mods={'cottages'}, texture = 'cottages_darkage_straw.png', -- they often have straw roofs + sapling_divisor = 10, plant_type = 'farming:wheat_8', plant_frequency = 1, + replacement_function = mg_villages.replacements_medieval, + roadsize_list = {2,3,4,5,6}, +-- road_materials = {'default:cobble','default:gravel','default:stonebrick','default:coalblock'}, + }, --roadsize_list = {1,1,2,3,4} }, + charachoal = { min = 10, max = 15, space_between_buildings=1, mods={'cottages'}, texture = 'default_coal_block.png', + replacement_function = mg_villages.replacements_charachoal }, + lumberjack = { min = 10, max = 30, space_between_buildings=1, mods={'cottages'}, texture = 'default_tree.png', name_prefix = 'Camp ', + sapling_divisor = 1, plant_type = 'default:junglegrass', plant_frequency = 24, + replacement_function = mg_villages.replacements_lumberjack }, + claytrader = { min = 10, max = 20, space_between_buildings=1, mods={'cottages'}, texture = 'default_clay.png', + replacement_function = mg_villages.replacements_claytrader }, + logcabin = { min = 15, max = 30, space_between_buildings=1, mods={'cottages'}, texture = 'default_wood.png', + replacement_function = mg_villages.replacements_logcabin }, + grasshut = { min = 10, max = 40, space_between_buildings=1, mods={'dryplants'}, texture = 'dryplants_reed.png', + replacement_function = mg_villages.replacements_grasshut }, + tent = { min = 5, max = 20, space_between_buildings=2, mods={'cottages'}, texture = 'wool_white.png', name_preifx = 'Tent at', + replacement_function = mg_villages.replacements_tent }, + + -- these sub-types may occour as single houses placed far from villages + tower = { only_single = 1, name_prefix = 'Tower at ', mods={'cottages'}, texture = 'default_mese.png', + replacement_function = mg_villages.replacements_tower }, + chateau = { only_single = 1, name_prefix = 'Chateau ', texture = 'default_gold_block.png', + replacement_function = mg_villages.replacements_chateau }, + forge = { only_single = 1, name_prefix = 'Forge at '}, + tavern = { only_single = 1, name_prefix = 'Inn at '}, + well = { only_single = 1, name_prefix = 'Well at ', + replacement_function = mg_villages.replacements_medieval }, + trader = { only_single = 1, name_prefix = 'Trading post ' }, + sawmill = { only_single = 1, name_prefix = 'Sawmill at ' }, + + farm_tiny = { only_single = 1, name_prefix = 'House '}, + farm_full = { only_single = 1, name_prefix = 'Farm '}, + single = { only_single = 1, name_prefix = 'House '}, -- fallback + +} + +-- NOTE: Most values of village types added with mg_villages.add_village_type can still be changed later on by +-- changing the global variable mg_villages.village_type_data[ village_type ] +-- Village types where one or more of the required mods (listed in v.mods) are missing will not be +-- available. +-- You can add your own village type by i.e. calling +-- mg_villages.add_village_type( 'town', { min = 10, max = 30, space_between_buildings = 2, mods = {'moreblocks','homedecor'}, texture='default_diamond_block.png'} ); +-- This will add a new village type named 'town', which will only be available if the mods moreblocks and homedecor are installed. +-- It will show the texture of the diamond block when showing the position of a village of that type in the map displayed by the /vmap command. + + +-- some villages require special mods as building material for their houses; +-- figure out which village types can be used +mg_villages.add_village_type = function( type_name, v ) + local found = true; + if( not( v.mods )) then + v.mods = {}; + end + for _,m in ipairs( v.mods ) do + if( not( minetest.get_modpath( m ))) then + -- this village type will not be used because not all required mods are installed + return false; + end + end + + if( not( v.only_single ) and (not(v.min) or not(v.max))) then + mg_villages.print( mg_villages.DEBUG_LEVEL_NORMAL, 'Error: Village type '..tostring( type_name )..' lacks size information.'); + return false; + end + + -- set some default values + if( not( v.sapling_divisor )) then + v.sapling_divisor = 10; + end + if( not( v.plant_type )) then + v.plant_type = 'default:grass_5'; + if( not( minetest.registered_nodes[ v.plant_type ])) then + v.plant_type = 'default:dry_shrub'; + end + end + if( not( v.plant_frequency )) then + v.plant_frequency = 3; + end + + -- this village type is supported by the mods installed and may be used + v.supported = 1; + + mg_villages.village_type_data[ type_name ] = v; + return true; +end + + +-- build a list of all useable village types the mg_villages mod comes with +mg_villages.village_type_data = {}; +for k,v in pairs( village_type_data_list ) do + mg_villages.add_village_type( k, v ); +end +village_type_data_list = nil; diff --git a/mods/a_mapgen_mods/mg_villages/villages.lua b/mods/a_mapgen_mods/mg_villages/villages.lua new file mode 100644 index 00000000..14d9dacd --- /dev/null +++ b/mods/a_mapgen_mods/mg_villages/villages.lua @@ -0,0 +1,922 @@ +-- this contains the functions to actually generate the village structure in a table; +-- said table will hold information about which building will be placed where, +-- how the buildings are rotated, where the roads will be, which replacement materials +-- will be used etc. + +local function is_village_block(minp) + local x, z = math.floor(minp.x/80), math.floor(minp.z/80) + local vcc = mg_villages.VILLAGE_CHECK_COUNT + return (x%vcc == 0) and (z%vcc == 0) +end + +-- called by mapgen.lua and spawn_player.lua +mg_villages.villages_at_point = function(minp, noise1) + if not is_village_block(minp) then return {} end + local vcr, vcc = mg_villages.VILLAGE_CHECK_RADIUS, mg_villages.VILLAGE_CHECK_COUNT + -- Check if there's another village nearby + for xi = -vcr, vcr, vcc do + for zi = -vcr, 0, vcc do + if xi ~= 0 or zi ~= 0 then + local mp = {x = minp.x + 80*xi, z = minp.z + 80*zi} + local pi = PseudoRandom(mg_villages.get_bseed(mp)) + local s = pi:next(1, 400) + local x = pi:next(mp.x, mp.x + 79) + local z = pi:next(mp.z, mp.z + 79) + if s <= mg_villages.VILLAGE_CHANCE and noise1:get2d({x = x, y = z}) >= -0.3 then return {} end + end + end + end + local pr = PseudoRandom(mg_villages.get_bseed(minp)) + if pr:next(1, 400) > mg_villages.VILLAGE_CHANCE then return {} end -- No village here + local x = pr:next(minp.x, minp.x + 79) + local z = pr:next(minp.z, minp.z + 79) + if noise1:get2d({x = x, y = z}) < -0.3 then return {} end -- Deep in the ocean + + -- fallback: type "nore" (that is what the mod originally came with) + local village_type = 'nore'; + village_type = mg_villages.village_types[ pr:next(1, #mg_villages.village_types )]; -- select a random type + -- if this is the first village for this world, take a medieval one + if( (not( mg_villages.all_villages ) or mg_villages.anz_villages < 1) and minetest.get_modpath("cottages") and mg_villages.FIRST_VILLAGE_TYPE) then + village_type = mg_villages.FIRST_VILLAGE_TYPE; + end + + if( not( mg_villages.village_type_data[ village_type ] )) then + mg_villages.village_type_data[ village_type ] = { min = mg_villages.VILLAGE_MIN_SIZE, max = mg_villages.VILLAGE_MAX_SIZE }; + end + local size = pr:next(mg_villages.village_type_data[ village_type ].min, mg_villages.village_type_data[ village_type ].max) +-- local height = pr:next(5, 20) + local height = pr:next(1, 5) + -- villages of a size >= 40 are always placed at a height of 1 + if( size >= 40 ) then + height = 1; + -- slightly smaller but still relatively large villages have a deterministic height now as well + elseif( size >= 30 ) then + height = 40-height; + elseif( size >= 25 ) then + height = 35-height; + -- even smaller villages need to have a height depending on their sourroundings (at least they're pretty small!) + end + +-- print("A village of type \'"..tostring( village_type ).."\' of size "..tostring( size ).." spawned at: x = "..x..", z = "..z) + --print("A village spawned at: x = "..x..", z = "..z) + return {{vx = x, vz = z, vs = size, vh = height, village_type = village_type}} +end + + + +--local function dist_center2(ax, bsizex, az, bsizez) +-- return math.max((ax+bsizex)*(ax+bsizex),ax*ax)+math.max((az+bsizez)*(az+bsizez),az*az) +--end + +local function inside_village2(bx, sx, bz, sz, village, vnoise) + return mg_villages.inside_village(bx, bz, village, vnoise) and mg_villages.inside_village(bx+sx, bz, village, vnoise) and mg_villages.inside_village(bx, bz+sz, village, vnoise) and mg_villages.inside_village(bx+sx, bz+sz, village, vnoise) +end + +local function choose_building(l, pr, village_type) + --::choose:: + local btype + while true do + local p = pr:next(1, 3000) + + if( not( mg_villages.village_type_data[ village_type ] ) + or not( mg_villages.village_type_data[ village_type ][ 'building_list'] )) then + mg_villages.print( mg_villages.DEBUG_LEVEL_INFO, 'Unsupported village type: '..tostring( village_type )..' for house at '..tostring(bx)..':'..tostring(bz)..'.'); + -- ...and crash in the next few lines (because there is no real solution for this problem) + end + + for _, b in ipairs( mg_villages.village_type_data[ village_type ][ 'building_list'] ) do + if ( mg_villages.BUILDINGS[ b ] and mg_villages.BUILDINGS[ b ].max_weight + and mg_villages.BUILDINGS[ b ].max_weight[ village_type ] and mg_villages.BUILDINGS[ b ].max_weight[ village_type ] >= p) then + +-- for b, i in ipairs(mg_villages.BUILDINGS) do +-- if i.weight[ village_type ] and i.weight[ village_type ] > 0 and i.max_weight and i.max_weight[ village_type ] and i.max_weight[ village_type ] >= p then + btype = b + break + end + end + -- in case no building was found: take the last one that fits + if( not( btype )) then + for i=#mg_villages.BUILDINGS,1,-1 do + if ( mg_villages.BUILDINGS[i] and mg_villages.BUILDINGS[i].weight + and mg_villages.BUILDINGS[i].weight[ village_type ] and mg_villages.BUILDINGS[i].weight[ village_type ] > 0 ) then + btype = i; + i = 1; + end + end + end + if( not( btype )) then + return 1; + end + if( #l<1 + or not( mg_villages.BUILDINGS[btype].avoid ) + or mg_villages.BUILDINGS[btype].avoid=='' + or not( mg_villages.BUILDINGS[ l[#l].btype ].avoid ) + or mg_villages.BUILDINGS[btype].avoid ~= mg_villages.BUILDINGS[ l[#l].btype ].avoid) then + + if mg_villages.BUILDINGS[btype].pervillage ~= nil then + local n = 0 + for j=1, #l do + if( l[j].btype == btype or (mg_villages.BUILDINGS[btype].typ and mg_villages.BUILDINGS[btype].typ == mg_villages.BUILDINGS[ l[j].btype ].typ)) then + n = n + 1 + end + end + --if n >= mg_villages.BUILDINGS[btype].pervillage then + -- goto choose + --end + if n < mg_villages.BUILDINGS[btype].pervillage then + return btype + end + else + return btype + end + end + end + --return btype +end + +local function choose_building_rot(l, pr, orient, village_type) + local btype = choose_building(l, pr, village_type) + local rotation + if mg_villages.BUILDINGS[btype].no_rotate then + rotation = 0 + else + if mg_villages.BUILDINGS[btype].orients == nil then + mg_villages.BUILDINGS[btype].orients = {0,1,2,3} + end + rotation = (orient+mg_villages.BUILDINGS[btype].orients[pr:next(1, #mg_villages.BUILDINGS[btype].orients)])%4 + end + local bsizex = mg_villages.BUILDINGS[btype].sizex + local bsizez = mg_villages.BUILDINGS[btype].sizez + if rotation%2 == 1 then + bsizex, bsizez = bsizez, bsizex + end + -- some buildings are mirrored + local mirror = nil; + -- some buildings may be too difficult for mirroring (=many nodebox-nodes that can't be mirrored well by rotation) or + -- be too symmetric to be worth the trouble + if( not(mg_villages.BUILDINGS[btype].nomirror) and pr:next( 1,2 )==1 ) then + mirror = true; + end + return btype, rotation, bsizex, bsizez, mirror +end + +local function placeable(bx, bz, bsizex, bsizez, l, exclude_roads, orientation) + for _, a in ipairs(l) do + -- with < instead of <=, space_between_buildings can be zero (important for towns where houses are closely packed) + if (a.btype ~= "road" or not exclude_roads) and math.abs(bx+bsizex/2-a.x-a.bsizex/2)<(bsizex+a.bsizex)/2 and math.abs(bz+bsizez/2-a.z-a.bsizez/2)<(bsizez+a.bsizez)/2 then + -- dirt roads which go at a 90 degree angel to the current road are not a problem + if( not( orientation ) or a.o%2 == orientation%2 ) then + return false + end + end + end + return true +end + +local function road_in_building(rx, rz, rdx, rdz, roadsize, l) + if rdx == 0 then + return not placeable(rx-roadsize+1, rz, 2*roadsize-2, 0, l, true) + else + return not placeable(rx, rz-roadsize+1, 0, 2*roadsize-2, l, true) + end +end + +local function when(a, b, c) + if a then return b else return c end +end + +mg_villages.road_nr = 0; + +local function generate_road(village, l, pr, roadsize_list, road_materials, rx, rz, rdx, rdz, vnoise, space_between_buildings, iteration_depth) + local roadsize = math.floor(roadsize_list[ iteration_depth ]/2); + if( not( roadsize ) or roadsize==0) then + roadsize = mg_villages.FIRST_ROADSIZE; + end + local roadsize_a = roadsize; + local roadsize_b = roadsize; + if( roadsize_list[ iteration_depth ] % 2==1 ) then + roadsize_a = roadsize+1; + end + local vx, vz, vh, vs = village.vx, village.vz, village.vh, village.vs + local village_type = village.village_type; + local calls_to_do = {} + local rxx = rx + local rzz = rz + local mx, m2x, mz, m2z, mmx, mmz + mx, m2x, mz, m2z = rx, rx, rz, rz + local orient1, orient2 + if rdx == 0 then + orient1 = 0 + orient2 = 2 + else + orient1 = 3 + orient2 = 1 + end + local btype; + local rotation; + local bsizex; + local bsizez; + local mirror; + -- we have one more road + mg_villages.road_nr = mg_villages.road_nr + 1; + local first_building_a = false; + local first_building_b = false; + while mg_villages.inside_village(rx, rz, village, vnoise) and not road_in_building(rx, rz, rdx, rdz, roadsize_a, l) do + if iteration_depth > 1 and pr:next(1, 4) == 1 and first_building_a then + --generate_road(vx, vz, vs, vh, l, pr, roadsize-1, rx, rz, math.abs(rdz), math.abs(rdx)) + calls_to_do[#calls_to_do+1] = {rx=rx+(roadsize_a - 0)*rdx, rz=rz+(roadsize_a - 0)*rdz, rdx=math.abs(rdz), rdz=math.abs(rdx)} + m2x = rx + (roadsize_a - 0)*rdx + m2z = rz + (roadsize_a - 0)*rdz + rx = rx + (2*roadsize_a - 0)*rdx + rz = rz + (2*roadsize_a - 0)*rdz + end + --else + --::loop:: + local exitloop = false + local bx + local bz + local tries = 0 + while true do + if not mg_villages.inside_village(rx, rz, village, vnoise) or road_in_building(rx, rz, rdx, rdz, roadsize_a, l) then + exitloop = true + break + end + local village_type_sub = village_type; + if( mg_villages.medieval_subtype and village_type_sub == 'medieval' and math.abs(village.vx-rx)>20 and math.abs(village.vz-rz)>20) then + village_type_sub = 'fields'; + end + btype, rotation, bsizex, bsizez, mirror = choose_building_rot(l, pr, orient1, village_type_sub) + bx = rx + math.abs(rdz)*(roadsize_a+1) - when(rdx==-1, bsizex-1, 0) + bz = rz + math.abs(rdx)*(roadsize_a+1) - when(rdz==-1, bsizez-1, 0) + if placeable(bx, bz, bsizex, bsizez, l) and inside_village2(bx, bsizex, bz, bsizez, village, vnoise) then + break + end + if tries > 5 then + rx = rx + rdx + rz = rz + rdz + tries = 0 + else + tries = tries + 1 + end + --goto loop + end + if exitloop then break end + rx = rx + (bsizex+space_between_buildings)*rdx + rz = rz + (bsizez+space_between_buildings)*rdz + mx = rx - 2*rdx + mz = rz - 2*rdz + l[#l+1] = {x=bx, y=vh, z=bz, btype=btype, bsizex=bsizex, bsizez=bsizez, brotate = rotation, road_nr = mg_villages.road_nr, side=1, o=orient1, mirror=mirror } + first_building_a = true; + --end + end + rx = rxx + rz = rzz + while mg_villages.inside_village(rx, rz, village, vnoise) and not road_in_building(rx, rz, rdx, rdz, roadsize_b, l) do + if roadsize_b > 1 and pr:next(1, 4) == 1 and first_building_b then + --generate_road(vx, vz, vs, vh, l, pr, roadsize-1, rx, rz, -math.abs(rdz), -math.abs(rdx)) + calls_to_do[#calls_to_do+1] = {rx=rx+(roadsize_b - 0)*rdx, rz=rz+(roadsize_b - 0)*rdz, rdx=-math.abs(rdz), rdz=-math.abs(rdx)} + m2x = rx + (roadsize_b - 0)*rdx + m2z = rz + (roadsize_b - 0)*rdz + rx = rx + (2*roadsize_b - 0)*rdx + rz = rz + (2*roadsize_b - 0)*rdz + end + --else + --::loop:: + local exitloop = false + local bx + local bz + local tries = 0 + while true do + if not mg_villages.inside_village(rx, rz, village, vnoise) or road_in_building(rx, rz, rdx, rdz, roadsize_b, l) then + exitloop = true + break + end + local village_type_sub = village_type; + if( mg_villages.medieval_subtype and village_type_sub == 'medieval' and math.abs(village.vx-rx)>(village.vs/3) and math.abs(village.vz-rz)>(village.vs/3)) then + village_type_sub = 'fields'; + end + btype, rotation, bsizex, bsizez, mirror = choose_building_rot(l, pr, orient2, village_type_sub) + bx = rx - math.abs(rdz)*(bsizex+roadsize_b) - when(rdx==-1, bsizex-1, 0) + bz = rz - math.abs(rdx)*(bsizez+roadsize_b) - when(rdz==-1, bsizez-1, 0) + if placeable(bx, bz, bsizex, bsizez, l) and inside_village2(bx, bsizex, bz, bsizez, village, vnoise) then + break + end + if tries > 5 then + rx = rx + rdx + rz = rz + rdz + tries = 0 + else + tries = tries + 1 + end + --goto loop + end + if exitloop then break end + rx = rx + (bsizex+space_between_buildings)*rdx + rz = rz + (bsizez+space_between_buildings)*rdz + m2x = rx - 2*rdx + m2z = rz - 2*rdz + l[#l+1] = {x=bx, y=vh, z=bz, btype=btype, bsizex=bsizex, bsizez=bsizez, brotate = rotation, road_nr = mg_villages.road_nr, side=2, o=orient2, mirror=mirror} + first_building_b = true; + --end + end + if road_in_building(rx, rz, rdx, rdz, roadsize, l) then + mmx = rx - 2*rdx + mmz = rz - 2*rdz + end + mx = mmx or rdx*math.max(rdx*mx, rdx*m2x) + mz = mmz or rdz*math.max(rdz*mz, rdz*m2z) + local rxmin; + local rxmax; + local rzmin; + local rzmax; + if rdx == 0 then + rxmin = rx - roadsize_a + 1 + rxmax = rx + roadsize_b - 1 + rzmin = math.min(rzz, mz) + rzmax = math.max(rzz, mz) + -- prolong the main road to the borders of the village + if( mg_villages.road_nr == 1 ) then + while( mg_villages.inside_village_area(rxmin, rzmin, village, vnoise)) do + rzmin = rzmin-1; + rzmax = rzmax+1; + end + rzmin = rzmin-1; + rzmax = rzmax+1; + while( mg_villages.inside_village_area(rxmax, rzmax, village, vnoise)) do + rzmax = rzmax+1; + end + rzmax = rzmax+1; + end + else + rzmin = rz - roadsize_a + 1 + rzmax = rz + roadsize_b - 1 + rxmin = math.min(rxx, mx) + rxmax = math.max(rxx, mx) + -- prolong the main road to the borders of the village + if( mg_villages.road_nr == 1 ) then + while( mg_villages.inside_village_area(rxmin, rzmin, village, vnoise)) do + rxmin = rxmin-1; + rxmax = rxmax+1; + end + rxmin = rxmin-1; + rxmax = rxmax+1; + while( mg_villages.inside_village_area(rxmax, rzmax, village, vnoise)) do + rxmax = rxmax+1; + end + rxmax = rxmax+1; + end + end + l[#l+1] = {x = rxmin+1, y = vh, z = rzmin, btype = "road", + bsizex = rxmax - rxmin + 1, bsizez = rzmax - rzmin + 1, brotate = 0, road_nr = mg_villages.road_nr} + if( road_materials and road_materials[ iteration_depth ] and minetest.registered_nodes[ road_materials[ iteration_depth ]] ) then + l[#l].road_material = minetest.get_content_id( road_materials[ iteration_depth ] ); + end + + for _, i in ipairs(calls_to_do) do +-- local new_roadsize = roadsize -- - 1 + if pr:next(1, 100) <= mg_villages.BIG_ROAD_CHANCE then + --new_roadsize = roadsize + iteration_depth = iteration_depth + 1; + end + + --generate_road(vx, vz, vs, vh, l, pr, new_roadsize, i.rx, i.rz, i.rdx, i.rdz, vnoise) + calls[calls.index] = {village, l, pr, roadsize_list, road_materials, i.rx, i.rz, i.rdx, i.rdz, vnoise, space_between_buildings, iteration_depth-1} + calls.index = calls.index+1 + end +end + +local function generate_bpos(village, pr, vnoise, space_between_buildings) + local vx, vz, vh, vs = village.vx, village.vz, village.vh, village.vs + local l = {} + local rx = vx - vs + --[=[local l={} + local total_weight = 0 + for _, i in ipairs(mg_villages.BUILDINGS) do + if i.weight == nil then i.weight = 1 end + total_weight = total_weight+i.weight + i.max_weight = total_weight + end + local multiplier = 3000/total_weight + for _,i in ipairs(mg_villages.BUILDINGS) do + i.max_weight = i.max_weight*multiplier + end + for i=1, 2000 do + bx = pr:next(vx-vs, vx+vs) + bz = pr:next(vz-vs, vz+vs) + ::choose:: + --[[btype = pr:next(1, #mg_villages.BUILDINGS) + if mg_villages.BUILDINGS[btype].chance ~= nil then + if pr:next(1, mg_villages.BUILDINGS[btype].chance) ~= 1 then + goto choose + end + end]] + p = pr:next(1, 3000) + for b, i in ipairs(mg_villages.BUILDINGS) do + if i.max_weight > p then + btype = b + break + end + end + if mg_villages.BUILDINGS[btype].pervillage ~= nil then + local n = 0 + for j=1, #l do + if l[j].btype == btype then + n = n + 1 + end + end + if n >= mg_villages.BUILDINGS[btype].pervillage then + goto choose + end + end + local rotation + if mg_villages.BUILDINGS[btype].no_rotate then + rotation = 0 + else + rotation = pr:next(0, 3) + end + bsizex = mg_villages.BUILDINGS[btype].sizex + bsizez = mg_villages.BUILDINGS[btype].sizez + if rotation%2 == 1 then + bsizex, bsizez = bsizez, bsizex + end + if dist_center2(bx-vx, bsizex, bz-vz, bsizez)>vs*vs then goto out end + for _, a in ipairs(l) do + if math.abs(bx-a.x)<=(bsizex+a.bsizex)/2+2 and math.abs(bz-a.z)<=(bsizez+a.bsizez)/2+2 then goto out end + end + l[#l+1] = {x=bx, y=vh, z=bz, btype=btype, bsizex=bsizex, bsizez=bsizez, brotate = rotation} + ::out:: + end + return l]=]-- + local rz = vz + while mg_villages.inside_village(rx, rz, village, vnoise) do + rx = rx - 1 + end + rx = rx + 5 + calls = {index = 1} + -- the function below is recursive; we need a way to count roads + mg_villages.road_nr = 0; + local roadsize_list = {}; + for i=1,mg_villages.FIRST_ROADSIZE*2 do + roadsize_list[i] = i; + end + if( mg_villages.village_type_data[ village.village_type ].roadsize_list ) then + roadsize_list = mg_villages.village_type_data[ village.village_type ].roadsize_list; + end + generate_road(village, l, pr, roadsize_list, mg_villages.village_type_data[ village.village_type ].road_materials, rx, rz, 1, 0, vnoise, space_between_buildings, #roadsize_list) + local i = 1 + while i < calls.index do + generate_road(unpack(calls[i])) + i = i+1 + end + mg_villages.road_nr = 0; + return l +end + + +-- dirt roads seperate the wheat area around medieval villages into seperate fields and make it look better +local function generate_dirt_roads( village, vnoise, bpos, secondary_dirt_roads ) + local dirt_roads = {}; + if( not( secondary_dirt_roads)) then + return dirt_roads; + end + for _, pos in ipairs( bpos ) do + + local x = pos.x; + local z = pos.z; + local sizex = pos.bsizex; + local sizez = 2; + local orientation = 0; + local vx; + local vz; + local vsx; + local vsz; + -- prolong the roads; start with a 3x2 piece of road for testing + if( pos.btype == 'road' ) then + -- the road streches in x direction + if( pos.bsizex > pos.bsizez ) then + sizex = 3; -- start with a road of length 3 + sizez = 2; + vx = -1; vz = 0; vsx = 1; vsz = 0; + x = pos.x - sizex; + z = pos.z + math.floor((pos.bsizez-2)/2); -- aim for the middle of the road + orientation = 0; + -- if it is not possible to prolong the road at one end, then try the other + if( not( placeable( x, z, sizex, sizez, bpos, false, nil))) then + x = pos.x + pos.bsizex; + vx = 0; + orientation = 2; + end + -- the road stretches in z direction + else + sizex = 2; + sizez = 3; + vx = 0; vz = -1; vsx = 0; vsz = 1; + x = pos.x + math.floor((pos.bsizex-2)/2); -- aim for the middle of the road + z = pos.z - sizez; + orientation = 1; + if( not( placeable( x, z, sizex, sizez, bpos, false, nil))) then + z = pos.z + pos.bsizez; + vz = 0; + orientation = 3; + end + end + + else + if( pos.o == 0 ) then + x = pos.x-pos.side; + z = pos.z-2; + sizex = pos.bsizex+1; + sizez = 2; + vx = 0; vz = 0; vsx = 1; vsz = 0; + + elseif( pos.o == 2 ) then + x = pos.x-pos.side+2; + z = pos.z-2; + sizex = pos.bsizex+1; + sizez = 2; + vx = -1; vz = 0; vsx = 1; vsz = 0; + + elseif( pos.o == 1 ) then + x = pos.x-2; + z = pos.z-pos.side+2; + sizex = 2; + sizez = pos.bsizez+1; + vx = 0; vz = -1; vsx = 0; vsz = 1; + + else --if( pos.o == 3 ) then + x = pos.x-2; + z = pos.z-pos.side; + sizex = 2; + sizez = pos.bsizez+1; + vx = 0; vz = 0; vsx = 0; vsz = 1; + end + orientation = pos.o; + + end + + -- prolong the dirt road by 1 + while( placeable( x, z, sizex, sizez, bpos, false, nil) + and placeable( x, z, sizex, sizez, dirt_roads, false, orientation) + and mg_villages.inside_village_area(x, z, village, vnoise) + and mg_villages.inside_village_area(x+sizex, z+sizez, village, vnoise)) do + sizex = sizex + vsx; + sizez = sizez + vsz; + x = x + vx; + z = z + vz; + end + + -- the dirt road may exceed the village boundaries slightly, but it may not interfere with other buildings + if( not( placeable( x, z, sizex, sizez, bpos, false, nil)) + or not( placeable( x, z, sizex, sizez, dirt_roads, false, orientation))) then + sizex = sizex - vsx; + sizez = sizez - vsz; + x = x - vx; + z = z - vz; + end + + if( placeable( x, z, sizex, sizez, bpos, false, nil) + and placeable( x, z, sizex, sizez, dirt_roads, false, orientation)) then + dirt_roads[#dirt_roads+1] = {x=x, y=village.vh, z=z, btype="dirt_road", bsizex=sizex, bsizez=sizez, brotate = 0, o=orientation} + end + end + return dirt_roads; +end + + + + +local MIN_DIST = 1 + +local function pos_far_buildings(x, z, l) + for _, a in ipairs(l) do + if a.x - MIN_DIST <= x and x <= a.x + a.bsizex + MIN_DIST and + a.z - MIN_DIST <= z and z <= a.z + a.bsizez + MIN_DIST then + return false + end + end + return true +end + + +local function generate_walls(bpos, data, a, minp, maxp, vh, vx, vz, vs, vnoise) + for x = minp.x, maxp.x do + for z = minp.z, maxp.z do + local xx = (vnoise:get2d({x=x, y=z})-2)*20+(40/(vs*vs))*((x-vx)*(x-vx)+(z-vz)*(z-vz)) + if xx>=40 and xx <= 44 then + bpos[#bpos+1] = {x=x, z=z, y=vh, btype="wall", bsizex=1, bsizez=1, brotate=0} + end + end + end +end + + +-- determine which building is to be placed where +-- also choose which blocks to replace with which other blocks (to make villages more intresting) +mg_villages.generate_village = function(village, vnoise) + local vx, vz, vs, vh = village.vx, village.vz, village.vs, village.vh + local village_type = village.village_type; + local seed = mg_villages.get_bseed({x=vx, z=vz}) + local pr_village = PseudoRandom(seed) + + -- generate a name for the village + village.name = namegen.generate_village_name_with_prefix( pr_village, village ); + + -- only generate a new village if the data is not already stored + -- (the algorithm is fast, but village types and houses which are available may change later on, + -- and that might easily cause chaos if the village is generated again with diffrent input) + if( village.to_add_data and village.to_add_data.bpos and village.to_add_data.replacements and village.to_add_data.plantlist) then + --print('VILLAGE GENREATION: USING ALREADY GENERATED VILLAGE: Nr. '..tostring( village.nr )); + return; + end + + -- in the case of medieval villages, we later on want to add wheat fields with dirt roads; 1 wide dirt roads look odd + local space_between_buildings = 1; + if( mg_villages.village_type_data[ village_type ] and mg_villages.village_type_data[ village_type ].space_between_buildings) then + space_between_buildings = mg_villages.village_type_data[ village_type ].space_between_buildings; + end + + local bpos = {}; + local dirt_roads = {}; + local secondary_dirt_roads = nil; + if( village.to_add_data and village.to_add_data.bpos ) then + -- If it is a single building instead of a full village, then village.to_add_data.bpos will + -- already have been generated (but not the replacements and other data structures which still need to be generated here) + bpos = village.to_add_data.bpos; + else + -- actually generate the village structure + bpos = generate_bpos( village, pr_village, vnoise, space_between_buildings) + + -- if there is enough space, add dirt roads between the buildings (those will later be prolonged so that they reach the fields) + -- only add dirt roads if there are at least 3 buildings in the village + if( space_between_buildings >= 2 and village_type == 'medieval' and #bpos>3) then + secondary_dirt_roads = "dirt_road"; + end + + dirt_roads = generate_dirt_roads( village, vnoise, bpos, secondary_dirt_roads ); + end + + -- set fruits for all buildings in the village that need it - regardless weather they will be spawned + -- now or later; after the first call to this function here, the village data will be final + for _, pos in ipairs( bpos ) do + local binfo = mg_villages.BUILDINGS[pos.btype]; + if( binfo.farming_plus and binfo.farming_plus == 1 and mg_villages.fruit_list and not pos.furit) then + pos.fruit = mg_villages.fruit_list[ pr_village:next( 1, #mg_villages.fruit_list )]; + end + end + + -- a changing replacement list would also be pretty confusing + local p = PseudoRandom(seed); + -- if the village is new, replacement_list is nil and a new replacement list will be created + local replacements = mg_villages.get_replacement_table( village.village_type, p, nil ); + + local sapling_id = mg_villages.get_content_id_replaced( 'default:sapling', replacements ); + -- 1/sapling_p = probability of a sapling beeing placed + local sapling_p = 25; + if( mg_villages.sapling_probability[ sapling_id ] ) then + sapling_p = mg_villages.sapling_probability[ sapling_id ]; + end + + local c_plant = mg_villages.get_content_id_replaced( mg_villages.village_type_data[ village.village_type ].plant_type, replacements); + local plantlist = { + { id=sapling_id, p=sapling_p * mg_villages.village_type_data[ village.village_type ].sapling_divisor }, -- only few trees + { id=c_plant, p= mg_villages.village_type_data[ village.village_type ].plant_frequency }}; + + if( village.is_single_house and plantlist and #plantlist>0 ) then + local c_grass = mg_villages.get_content_id_replaced( 'default:grass_5', replacements); + plantlist[2] = { id=c_grass, p=10 }; + -- reduce the amount of plants grown so that the area stands out less from the sourroundings + plantlist[2].p = plantlist[2].p*3; + end + + -- store the generated data in the village table + village.to_add_data = {}; + village.to_add_data.bpos = bpos; + village.to_add_data.replacements = replacements.list; + village.to_add_data.dirt_roads = dirt_roads; + village.to_add_data.plantlist = plantlist; + + --print('VILLAGE GENREATION: GENERATING NEW VILLAGE Nr. '..tostring( village.nr )); +end + + +-- not all buildings contain beds so that mobs could live inside; some are just workplaces; +-- roads get only placed if there are enough inhabitants +mg_villages.count_inhabitated_buildings = function(village) + local bpos = village.to_add_data.bpos; + -- count the buildings + local anz_buildings = 0; + for i, pos in ipairs(bpos) do + if( pos.btype and not(pos.btype == 'road' )) then + local binfo = mg_villages.BUILDINGS[pos.btype]; + -- count buildings which can house inhabitants as well as those requiring workers + if( binfo and binfo.inh and binfo.inh ~= 0 ) then + anz_buildings = anz_buildings + 1; + end + end + end + return anz_buildings; +end + + +-- creates individual buildings outside of villages; +-- the data structure is like that of a village, except that bpos (=buildings to be placed) is already set; +-- Note: one building per mapchunk is more than enough (else it would look too crowded); +mg_villages.house_in_one_mapchunk = function( minp, mapchunk_size, vnoise ) + + local pr = PseudoRandom(mg_villages.get_bseed(minp)) + -- only each mg_villages.INVERSE_HOUSE_DENSITY th mapchunk gets a building + if( pr:next(1,mg_villages.INVERSE_HOUSE_DENSITY) > 1 ) then + return {}; + end + + + -- pseudorandom orientation + local orient1 = pr:next(0,3); + -- determine which kind of building to use + -- TODO: select only types fitting to that particular place + -- TODO: select only types that exist + -- the village type is "single" here - since not all houses which might fit into a village might do for lone standing houses + -- (i.e. church, forge, wagon, ..) + local btype, rotation, bsizex, bsizez, mirror = choose_building_rot({}, pr, orient1, 'single'); + if( not( bsizex )) then + mg_villages.print( mg_villages.DEBUG_LEVEL_INFO, 'FAILURE to generate a building.'); + btype, rotation, bsizex, bsizez, mirror = choose_building_rot({}, pr, orient1, 'nore'); + end + -- if no building was found, give up + if( not( bsizex ) or not(mg_villages.BUILDINGS[ btype ].weight)) then + return {}; + end + + + local village = {}; + -- store that this is not a village but a lone house + village.is_single_house = 1; + -- village height will be set to a value fitting the terrain later on + village.vh = 10; + -- this will force re-calculation of height + village.vs = 5; + -- find out the real village type of this house (which is necessary for the replacements); + -- the "single" type only indicates that this building may be used for one-house-villages such as this one + for k, _ in pairs( mg_villages.BUILDINGS[ btype ].weight ) do + if( k and k ~= 'single' ) then + village.village_type = k; + end + end + + + -- taken from paramats terrain blending code for single houses + local FFAPROP = 0.5 -- front flat area proportion of dimension + + local xdim, zdim -- dimensions of house plus front flat area + if rotation == 0 or rotation == 2 then + xdim = bsizex + zdim = bsizez + math.floor(FFAPROP * bsizez) + else + xdim = bsizex + math.floor(FFAPROP * bsizex) + zdim = bsizez + end + local blenrad = math.floor((math.max(xdim, zdim) + 16) / 2)+2 -- radius of blend area +--[[ + if( blenrad >= math.ceil(mapchunk_size/2)-2 ) then + blenrad = math.floor(mapchunk_size/2)-2; + end + local blencenx = pr:next(minp.x + blenrad, minp.x + mapchunk_size - blenrad - 1) -- blend area centre point + local blencenz = pr:next(minp.z + blenrad, minp.z + mapchunk_size - blenrad - 1) +--]] + local blencenx = pr:next(minp.x, minp.x + mapchunk_size - 1) -- blend area centre point + local blencenz = pr:next(minp.z, minp.z + mapchunk_size - 1) + + local minx = blencenx - math.ceil(xdim / 2) -- minimum point of house plus front flat area + local minz = blencenz - math.ceil(zdim / 2) + local bx, bz -- house minimum point + if rotation == 2 or rotation == 3 then -- N, E + bx = minx + bz = minz + elseif rotation == 1 then -- W + bx = minx + math.floor(FFAPROP * bsizex) + bz = minz + else -- rotation = 2, S + bx = minx + bz = minz + math.floor(FFAPROP * bsizez) + end + + village.vx = blencenx; + village.vz = blencenz; + village.vs = blenrad; + local village_id = tostring( village.vx )..':'..tostring( village.vz ); + + -- these values have to be determined once per village; afterwards, they need to be fixed + -- if a village has been generated already, it will continue to exist +-- if( mg_villages.all_villages[ village_id ] ) then +-- return village; +-- end + + if( mg_villages.all_villages and mg_villages.all_villages[ village_id ] and mg_villages.all_villages[ village_id ].optimal_height) then + village.optimal_height = mg_villages.all_villages[ village_id ].optimal_height; + village.vh = mg_villages.all_villages[ village_id ].optimal_height; + village.artificial_snow = mg_villages.all_villages[ village_id ].artificial_snow; + end + + village.to_add_data = {}; + village.to_add_data.bpos = { {x=bx, y=village.vh, z=bz, btype=btype, bsizex=bsizex, bsizez=bsizez, brotate = rotation, road_nr = 0, side=1, o=orient1, mirror=mirror }} + return village; +end + + +mg_villages.house_in_mapchunk_mark_intersection = function( villages, c, vnoise ) -- c: candidate for a new one-house-village + -- now check if this village can be placed here or if it intersects with another village in any critical manner; + -- the village area may intersect (=unproblematic; may even look nice), but the actual building must not be inside another village + + -- exclude misconfigured villages + if( not( c ) or not( c.to_add_data )) then + --print('WRONG DATA: '..minetest.serialize( c )); + c.areas_intersect = 1; + return; + end + + local bx = c.to_add_data.bpos[1].x; + local bz = c.to_add_data.bpos[1].z; + local bsizex = c.to_add_data.bpos[1].bsizex; + local bsizez = c.to_add_data.bpos[1].bsizez; + + -- make sure that the house does not intersect with the area of a village + for _,v in ipairs( villages ) do + local id = v.vx..':'..v.vz; + if( id and mg_villages.all_villages and mg_villages.all_villages[ id ] ) then + v = mg_villages.all_villages[ id ]; + end + + if( v.vx ~= c.vx and v.vz ~= c.vz ) then + local dist = math.sqrt( ( c.vx - v.vx ) * ( c.vx - v.vx ) + + ( c.vz - v.vz ) * ( c.vz - v.vz )); + if( dist < ( c.vs + v.vs )*1.1 ) then + mg_villages.print( mg_villages.DEBUG_LEVEL_WARNING, 'DROPPING house at '..c.vx..':'..c.vz..' because it is too close to '..v.vx..':'..c.vx); + c.areas_intersect = 1; + -- the other village can't be spawned either as we don't know which one will be loaded first + if( v.is_single_house ) then + v.areas_intersect = 1; + end + end + + if( not( v.is_single_house ) and + ( mg_villages.inside_village_terrain_blend_area( c.vx, c.vz, v, vnoise) + or mg_villages.inside_village_terrain_blend_area( bx, bz, v, vnoise) + or mg_villages.inside_village_terrain_blend_area((bx+bsizex), bz, v, vnoise) + or mg_villages.inside_village_terrain_blend_area((bx+bsizex), (bz+bsizez), v, vnoise) + or mg_villages.inside_village_terrain_blend_area( bx, (bz+bsizez), v, vnoise))) then + + mg_villages.print( mg_villages.DEBUG_LEVEL_WARNING, 'DROPPING house at '..c.vx..':'..c.vz..' due to intersection with village at '..id); + c.areas_intersect = 1; + -- the other village can't be spawned either as we don't know which one will be loaded first + if( v.is_single_house ) then + v.areas_intersect = 1; + end + end + end + end +end + + +-- we need to determine where single houses will be placed in neighbouring mapchunks as well because +-- they may be so close to the border that they will affect this mapchunk +mg_villages.houses_in_mapchunk = function( minp, mapchunk_size, villages ) + local village_noise = minetest.get_perlin(7635, 3, 0.5, 16); + + local village_candidates = {}; + local vcr = 2; --mg_villages.VILLAGE_CHECK_RADIUS + for xi = -vcr, vcr do + for zi = -vcr, vcr do + local new_village = mg_villages.house_in_one_mapchunk( + {x=minp.x+(xi*mapchunk_size), y=minp.y, z=minp.z+(zi*mapchunk_size)}, + mapchunk_size, + village_noise ); + if( new_village and new_village.vs and new_village.vx and new_village.vz ) then + table.insert( village_candidates, new_village ); + end + end + end + + for _,candidate in ipairs(village_candidates) do + -- mark all one-house-village-candidates that intersect with villages in this mapchunk + mg_villages.house_in_mapchunk_mark_intersection( villages, candidate, village_noise ); + -- mark all one-house-village-candidates that intersect with other candidates in this mapchunk + mg_villages.house_in_mapchunk_mark_intersection( village_candidates, candidate, village_noise ); + end + + -- now add those villages that do not intersect with others and which *may* at least be part of this mapchunk + local d = math.ceil( mapchunk_size / 2 ); + for _,candidate in ipairs(village_candidates) do + if( not( candidate.areas_intersect ) + and (candidate.vx > minp.x - d or candidate.vx < (mapchunk_size+d) ) + and (candidate.vz > minp.z - d or candidate.vz < (mapchunk_size+d) )) then + table.insert( villages, candidate ); + + -- there may be quite a lot of single houses added; plus they are less intresting than entire villages. Thus, logfile spam is reduced + mg_villages.print( mg_villages.DEBUG_LEVEL_WARNING, 'adding SINGLE HOUSE of type '..tostring( candidate.village_type ).. + ' to map at '..tostring( candidate.vx )..':'..tostring( candidate.vz )..'.'); + end + end + return villages; +end + + diff --git a/mods/a_mapgen_mods/quartz/init.lua b/mods/a_mapgen_mods/quartz/init.lua index daf6c364..a52d1881 100644 --- a/mods/a_mapgen_mods/quartz/init.lua +++ b/mods/a_mapgen_mods/quartz/init.lua @@ -166,21 +166,22 @@ end --Compatibility with stairsplus if minetest.get_modpath("moreblocks") and enable_stairsplus then - register_stair_slab_panel_micro("quartz", "block", "quartz:block", + --register_stair_slab_panel_micro("quartz", "block", "quartz:block", + register_panel_micro("quartz", "block", "quartz:block", {cracky=3}, {"quartz_block.png"}, "Quartz Block", "block", 0) - register_stair_slab_panel_micro("quartz", "chiseled", "quartz:chiseled", + register_panel_micro("quartz", "chiseled", "quartz:chiseled", {cracky=3}, {"quartz_chiseled.png"}, "Chiseled Quartz", "chiseled", 0) - register_stair_slab_panel_micro("quartz", "pillar", "quartz:pillar", + register_panel_micro("quartz", "pillar", "quartz:pillar", {cracky=3}, {"quartz_pillar_top.png", "quartz_pillar_top.png", "quartz_pillar_side.png"}, "Quartz Pillar", diff --git a/mods/a_mapgen_mods/village_gambit/README.md b/mods/a_mapgen_mods/village_gambit/README.md new file mode 100644 index 00000000..fd2a3630 --- /dev/null +++ b/mods/a_mapgen_mods/village_gambit/README.md @@ -0,0 +1,8 @@ + +New village type for https://github.com/Sokomine/mg_villages/ + +This mod does depend on mg_villages. + +The buildings found in this mod (in the schems/ folder) have been built by Gambit +for the peaceful_npc mod and have been extracted from the village he built +for them. See here: https://forum.minetest.net/memberlist.php?mode=viewprofile&u=398 diff --git a/mods/a_mapgen_mods/village_gambit/depends.txt b/mods/a_mapgen_mods/village_gambit/depends.txt new file mode 100644 index 00000000..306196c4 --- /dev/null +++ b/mods/a_mapgen_mods/village_gambit/depends.txt @@ -0,0 +1 @@ +mg_villages diff --git a/mods/a_mapgen_mods/village_gambit/init.lua b/mods/a_mapgen_mods/village_gambit/init.lua new file mode 100644 index 00000000..e31ac2a0 --- /dev/null +++ b/mods/a_mapgen_mods/village_gambit/init.lua @@ -0,0 +1,42 @@ + +village_gambit = {} + +village_gambit.replacements_gambit = function( housetype, pr, replacements ) + -- replace the wood - those are lumberjacks after all + local wood_type = mg_villages.replace_materials( replacements, pr, + {'default:wood'}, + {''}, + { 'default:wood', 'default:junglewood', 'mg:savannawood', 'mg:pinewood' }, + 'default:wood'); + mg_villages.replace_tree_trunk( replacements, wood_type ); + mg_villages.replace_saplings( replacements, wood_type ); + + mg_villages.replace_materials( replacements, pr, + {'stairs:stair_cobble', 'stairs:slab_cobble', 'default:cobble'}, + {'stairs:stair_', 'stairs:slab_', 'default:' }, + {'stonebrick', 'desert_stonebrick','sandstonebrick', 'sandstone','stone','desert_stone','stone_flat','desert_stone_flat','stone_bricks','desert_strone_bricks'}, + 'stonebrick'); + + return replacements; +end + +-- add a new village type for all those buildings +mg_villages.add_village_type( 'gambit', { min = 30, max = 60, space_between_buildings=2, mods={}, texture = 'default_tree_top.png', + replacement_function = village_gambit.replacements_gambit}); + +local path = minetest.get_modpath( 'village_gambit' )..'/schems/'; + +mg_villages.add_building( { scm="gambit_church_1_0_180", mts_path=path, weight={gambit=4}, inh=-1, typ='church', pervillage=1}); +mg_villages.add_building( { scm="gambit_cementry_0_180", mts_path=path, weight={gambit=1}, inh=0, typ='cementry', pervillage=1}); +mg_villages.add_building( { scm="gambit_field_1_1_90", mts_path=path, weight={gambit=1}, inh=0, typ='field'}); +mg_villages.add_building( { scm="gambit_forge_1_2_270", mts_path=path, weight={gambit=4}, inh=-1, typ='forge', pervillage=1}); +mg_villages.add_building( { scm="gambit_fountain_1_1_90", mts_path=path, weight={gambit=1/6}, inh=0,typ='fountain'}); +mg_villages.add_building( { scm="gambit_house_1_0_0", mts_path=path, weight={gambit=3, single=1}, inh=3, typ='house'}); +mg_villages.add_building( { scm="gambit_lamp_0_270", mts_path=path, weight={gambit=1}, inh=0, typ='lamp', avoid='lamp'}); +mg_villages.add_building( { scm="gambit_library_hotel_0_180", mts_path=path, weight={gambit=1, single=1}, inh=4, typ='hotel'}); +mg_villages.add_building( { scm="gambit_pub_1_0_0", mts_path=path, weight={gambit=1, single=1}, inh=1, typ='pub'}); +mg_villages.add_building( { scm="gambit_shed_open_chests_2_0", mts_path=path, weight={gambit=1}, inh=0, typ='shed'}); +mg_villages.add_building( { scm="gambit_shop_0_90", mts_path=path, weight={gambit=1}, inh=-1, typ='shop'}); +mg_villages.add_building( { scm="gambit_shop_large_0_0", mts_path=path, weight={gambit=1}, inh=1, typ='shop'}); +mg_villages.add_building( { scm="gambit_stable_1_2_90", mts_path=path, weight={gambit=1, single=1}, inh=1, typ='stable'}); +mg_villages.add_building( { scm="gambit_tower_1_0_270", mts_path=path, weight={gambit=1/6}, inh=-1, typ='tower'}); diff --git a/mods/a_mapgen_mods/village_gambit/schems/gambit_cementry_0_180.mts b/mods/a_mapgen_mods/village_gambit/schems/gambit_cementry_0_180.mts new file mode 100644 index 0000000000000000000000000000000000000000..8394ddf23b1e5c3e3cf91bcdbf715c8c07afe85b GIT binary patch literal 458 zcmeYb3HD`RX5eRFVc`A`1PnY3JSnMZiKRIuRwYHLsSJEDUUGg?QcfxZb7E!@gAhzG zEj2GWHNHGQKZQZKxCAIwYz3y`p{j*p3bRV{(sNSNixP{A83c3F*rX zi;^=KgitgWm*nTAG6=%NauSo`p+Yd@iZj#m;>#0rau|eD^7DbVf=IAC;*;VHF$GKF z4J+on4T%rZw23-_10p1*qaW0l_d zpL6bSeE;43|LX6p-1Tf)uQ=i#-`wK1ZIRTbqe9mIV_g$|zq8DEdz){<#|iH*<;_~K liGVr9NrX`lUYKlpPGWH}0|!tr$Eqkbg+UNzTTWt9d~r#B z9?*1TA*g9^F_7D!>V#otW|iip=cJ|=flL<6O^+|j%*jbiPc618$uCOIU=U8p&jJ1DOeJ3STX1Av|gbm1%Z}{)6o^BzPy`NuJ{j|{Y`DKxB@+;@xkFxvmSN`nJEiQH$Ki@Rp_kG%a&W6*{yH0KX zH7zUo*~=d*pLss@!~A*mGcE-GEiUP~#&LeW#h!mh9)1s(x%Xe@O?HjtG0 zyN`?EeZ}j_T80C6c{NrGu2`|FUDo34I~F(lL!USQi&$m9;pX}NW71#$cZxn!KDm01 tc1)2@?hJd=W6ODV)?LVA$yj~#ar^7;7_H>LHy{4%USa!>y)xB!F93~Z`9A;v literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/village_gambit/schems/gambit_field_1_1_90.mts b/mods/a_mapgen_mods/village_gambit/schems/gambit_field_1_1_90.mts new file mode 100644 index 0000000000000000000000000000000000000000..765adf46a39867a1bb02e8f021c6eb6881f3fffa GIT binary patch literal 230 zcmeYb3HD`RW?%>5|Ns9pa5C_vq^2d7=9E~a7bTXZ<}mQU_$5WDsSEdXxd8rJ1Fm7^wQc_MTgE)+zl37#| zU!GZ#5uaX^SX|7&oS0d}AXHoeq>8PIa}tx{p*r9u0M(VH<}mQXOh_v&%1ca6We|pG z0_lb6f|~>ugt$cnrZXq8EHOSUC%-&1FP%XcMYK4-vqk!$Db8V(^V55#m%piBWOwe& cjK zG6=zVX{mY1sSp)>FtOzPq@G z24R>YkZWM71as5l%QACv64O(QtxEEXk~0{DQ}XkHt_6``r^F}48)6EU#2Z%3c{?Rh zxJiMh?VxJw*R8Mr|G%Vkk*UVzT3RnP`|k;n$d#k%7%rRS@J(-@El@_@QYvc*-iCj=AYCm)xU+`^*rXi;^=Kgi=z|5=(PRtkP2R zl2hZ$^Yc>}xPWAiRZ>o3a(2a>+3=11s52i59;$mOJ K!>}?``3C?;NGJaQ literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/village_gambit/schems/gambit_library_hotel_0_180.mts b/mods/a_mapgen_mods/village_gambit/schems/gambit_library_hotel_0_180.mts new file mode 100644 index 0000000000000000000000000000000000000000..f897bf57c6f879c8028a271dd2e088290c57de87 GIT binary patch literal 911 zcmeYb3HD`RX5eAqWDxof0}O%;%!!#r48p}FK&sdZOvNYXCne>iG6=y0a}twaVmv9S zX^EvdB~~RxsX!GlURr8ia%y~eetrrAA508t3S0+RRuCpzoSB{%U!ItggV2zZn39rO z!~j>4l%JnnoRON7#vquR9$%K3larX9T5MI4UzD7|APh4ot28e?CpEn&vACE)5awc# zZy?SQg$aQ?QJk2UQe2Xsm&(8k)1ICK(kPsgpAYmthy-hkPl`9h6fB81teEpQJbUtL z1s-0PH`BhA{Z35({{R1_YEd2)o2ZW$Z_oXh;`Xtlv;70h57mIsF!3A~r|A-Ydpvu7 z*li5|ulDwb(ia>l{h+ze=IKbTyf<5y6eXPCifA#tH6D5fm zp~`9bCvS7vyI;@#WV-Fx)R&8{ip(_coARD1pZUMupv&du`hM`U2I!>V`|Ty)W_P_*1t9ixR)Q}@a*X8O%L2}+r-Y86Zoj| z;Q639@lBt*|8Jjdd_LOay!eifJD2^P^U3-`#kxP$4-Pakv-8PRNWa-*>TrNzoBO?W zYmy?53B5RS&5NC%?Z+|OH;Gb8;>39H$kzS)U_3H>zIaKU&4r(^t7jDyeq+t4l#svrbN* z7`tTNZqdI2+2J}?eY;9l>%H=h?{p8Gc6NhO{JuZRukB9VdQ|7JYhSSLo|sFavhkPC v{448pyFwn}lIvVCO;vE9Sfn zIW5$zz{AsdDXaSJkN@$voGMf`>|RYh%Ofm4jkky80UJ+(=(DC-2?CB2rCn9d71_i@ zJToX(JYiUB`qs;BsqBo+A4(oSDG^@J5p(cN{0fWxOfzdc57^h7?mBSx)Z=yfAAPgp zA4OMh{v=zgd2ihp-k47te$IQ#8Q(G0`~J-L;q$`}r?vmuv*29K+3>|rrKjB8{(GB4 zX#S`AFS91^)h*nV9$2Pn``YXIo~F&Q8xL(?ytsMe|DcSiIlhc9sVslrRM9N{xosUYD=ri| U+Y2rFRnB*?sqG2-$HM~u0NP{S+W-In literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/village_gambit/schems/gambit_shed_open_chests_2_0.mts b/mods/a_mapgen_mods/village_gambit/schems/gambit_shed_open_chests_2_0.mts new file mode 100644 index 0000000000000000000000000000000000000000..8c01e9d73c5644454d335c2425d941521763b686 GIT binary patch literal 283 zcmeYb3HD`RW?%)u{~*A?&A^kAnwD6aQ(~2pSyaLxj?9ZM&n(G^PcKR=E@lvdNu;Ib zC8x%h=jW#&w3Za5rZVusR3zsoCFP_tFehdfA(VhM2o{$B1&gh~6vPa;E}%7KsW}Y1 za8oi;i%S>;bJOF?GIMeg(^HGBO7e@6Gb-jJCp0j-S)4s`;LHK0BWn`Gq-PxETjDrD zc41>9Gl!y8MB@ZujniChF$rRtRuP`p8gKI{{ry<4z&NRRW}|?QL6hYRxx~~1iU%9K Qn^=RHuJSR+<=6EB05x%F5&!@I literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/village_gambit/schems/gambit_shop_0_90.mts b/mods/a_mapgen_mods/village_gambit/schems/gambit_shop_0_90.mts new file mode 100644 index 0000000000000000000000000000000000000000..5860aeea7b861f8ad3803e4d726b4b70af1d94d9 GIT binary patch literal 517 zcmeYb3HD`RX5eCAW8nG^1`K=*%!!#r41&4o@nxAgIf?11#a1QxMadZq0>vdjnPRKr zoW!K~^8EZ120@qzNCG0nlaiX2SejE}RZ^6i${+;erKRR2r$SWl!NijDlag{$8Q?k~ zM#5y1^7FHcGg5QX7zANL#hK}O@#Tp*ISj%m7DEjZf(e4$2Ne@e$ zWWW$Ci8rj6^EULhSd)UlozlRrR~H}uug_F`QzU%pOjXgcrFEijy}8)ewSLQsWp_Q#$DO~I>3m{G#IK2E*R`{6Jk<7Ax1KEyot7=*YW=Em;Uw-zy|i2Zi;CaQDE(%lXl^Gh zH{td7{(x_1CIoERvcE>Y^V>4jBqlW1lS-&^=rThuFc|Kf9r P)#r0EBH|b~$0Yy&V%Xo$ literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/village_gambit/schems/gambit_shop_large_0_0.mts b/mods/a_mapgen_mods/village_gambit/schems/gambit_shop_large_0_0.mts new file mode 100644 index 0000000000000000000000000000000000000000..363d667d4eb5ed53d3bc471f9d49f35049c28667 GIT binary patch literal 775 zcmeYb3HD`RX5eAqU=a8Z1q?zA%!!#r48p}FK&sdZOvNYXCne>iGVr9NrX`lewb`pX;EHcaw>yhZhCxKW=>9GdTOy%Nq$js z27?gH;+(`Jn7x89eM$NG*~J;DIcW^MFrnm()Z!8bxQgP;^t|};#GD)k;gtM*pa(!C z*lqDi@rIa!B|t$zn3W(eL;S%3bZ?GTQECdpqV$}^;$j9auta%AW=U$roVPPx2Q@qJ zv~CtZl9m0n{qb-6mG8FhKB>0hY0&YBlM@>*tJW;xUc&mrI4Gwg(?Fxd%Bk5k@DJnB zta{Uy5t#Zw*c9y|K=r0c~!@}`UaKK-Mw*zEM@ zYuIUfmi5nADtx)WZa&r~KR;F1-sI2Ep4vZJx&WK-_@V{ zxqp2AQ>n7QZFBUW*k{|h_P3oryT9a9@tppZ_7iID_CK$84y^d_xpJ2AwdH+r|FStw zt(TeE|LISq_)pb&x;69c_f3zg3*EbZ)2FLJ_Mbo7vDn+6c7NpkxcX=44yL+)b0X^s zjORU{{@U`8yF&l#UFUwruq7OO{=0qGKhyv3uf|W@eWJZd)A#QF)NhB6eg0qP=lT0v z{_Vnd+B^5(4ZPpZCu>#mB0lT=cka9++iuMZs!aX0-_gf1<()%@w5+22+uIpw-gTB2 zKNkOd*=Vx=<_`TE>h&ub&)S!W&YJw5uXxv{yC2W4oAlaa@iKSUvrm2%{mS{YzUg$3 zM&Q=m4e$3$cpv8ws8I6wc~L>u>c`6LORnBOPRD0Y?Jqj@=#>7ZvZs4K-@JOVa(dX4 LKa39#bMpfL@KJ76 literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/village_gambit/schems/gambit_stable_1_2_90.mts b/mods/a_mapgen_mods/village_gambit/schems/gambit_stable_1_2_90.mts new file mode 100644 index 0000000000000000000000000000000000000000..bb8f19dc7580d8bb1e7f479a2360deab61c005f2 GIT binary patch literal 564 zcmeYb3HD`RW)NoJWZ?V{0}Q+jyeX+^iKRIuR>dXxd8rKIFm6g_QAvDxW=TeTdQoC= zF#{h=0>~{(&0%0p%q(IMEG_|3#X!A4D!x2FKZQX6CX|zy1QFqZ=>*Hec_0fI;JlKe z)Kr8W$@xi1IjIanFr8_sdC92|(*$$V*rXi;^=C+Hw+8Qc{a5=DZE# z6>e7G2rd5h^Z);MVUtuldQ0zyp8lR^Y|-{5tRqM%!~gNh$n2z2g}3J{W`FpaY$qQ0 zOWR8_%m2d0w6#?sTLa(zXxwwzbnAhA?MJI`@2a$rc=_lez~d~`qZ!Xi~)0t@J`<~6>Jau zo|Ld1ICGZ4;(BcwgYKh!Tt(&E_1_77ezki65Ik5ZAh+hwY8A;_e%{ey{$^AvSC{BcC0z#Q&;%~lnQ(QdOaoU#eBC|shF6RZFUS>)*N3o h>)pw`@}iZG_zaQ@V;3_ox$$bXTEhNS@}kiqb^vF#{9FJ4 literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/village_gambit/schems/gambit_tower_1_0_270.mts b/mods/a_mapgen_mods/village_gambit/schems/gambit_tower_1_0_270.mts new file mode 100644 index 0000000000000000000000000000000000000000..7873b9d318dd85733a1d20dad8f425b78f063122 GIT binary patch literal 609 zcmeYb3HD`RW?*L!XJG%29Wd}RFehdfG4Q3NrX`liG6)x!0ELUKz*Ia` zPyi;Flb94=o}Zt>AP5rysfGygz)UJBN=;=Df++xLff^$OQ<0XMmz;{G3u0_;dVE=C zPEKNaYOz&Geo=A;!ht!7DJiK%48ke-`9Sx9NU#aZp#0YyS$#MSOP-$rgp2=GiGeWBD0}Nap0DP5c4McbS~+&;QiE zy7MtxdqiaO6Yishr145f7h(J$gVr_ zqmEnL|L2cb(?7m%2%jb&d;1e3rceKeCcILxALi}330UC v!Wo`i?3tLFwtC&G&#G7d+fK;daFqL4{a?w{74{X}PD#1kf0&nLXD$N({mm1% literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/village_ruins/README.md b/mods/a_mapgen_mods/village_ruins/README.md new file mode 100644 index 00000000..8f109b9e --- /dev/null +++ b/mods/a_mapgen_mods/village_ruins/README.md @@ -0,0 +1,8 @@ + +New village type for https://github.com/Sokomine/mg_villages/ + +This mod does depend on mg_villages. + +The buildings found in this mod (in the schems/ folder) have been built by +AgentNagel42. See https://forum.minetest.net/viewtopic.php?f=5&t=13297 + diff --git a/mods/a_mapgen_mods/village_ruins/depends.txt b/mods/a_mapgen_mods/village_ruins/depends.txt new file mode 100644 index 00000000..306196c4 --- /dev/null +++ b/mods/a_mapgen_mods/village_ruins/depends.txt @@ -0,0 +1 @@ +mg_villages diff --git a/mods/a_mapgen_mods/village_ruins/init.lua b/mods/a_mapgen_mods/village_ruins/init.lua new file mode 100644 index 00000000..2b66686d --- /dev/null +++ b/mods/a_mapgen_mods/village_ruins/init.lua @@ -0,0 +1,33 @@ + +village_ruins = {} + +village_ruins.replacements_ruins = function( housetype, pr, replacements ) + -- replace the wood - even though those houses use only a limited amount of wood + local wood_type = mg_villages.replace_materials( replacements, pr, + {'default:wood'}, + {''}, + { 'default:wood', 'default:junglewood', 'mg:savannawood', 'mg:pinewood' }, + 'default:wood'); + mg_villages.replace_tree_trunk( replacements, wood_type ); + mg_villages.replace_saplings( replacements, wood_type ); + return replacements; +end + +-- add a new village type for all those buildings +mg_villages.add_village_type( 'ruins', { min = 15, max = 30, space_between_buildings=1, mods={}, texture = 'default_gravel.png', + replacement_function = village_ruins.replacements_ruins}); + +local path = minetest.get_modpath( 'village_ruins' )..'/schems/'; + + +mg_villages.add_building( { scm="cabin", mts_path=path, weight={ruins=1, single=1}, typ='house', orients={1}}); +mg_villages.add_building( { scm="cabin_old", mts_path=path, weight={ruins=1, single=1}, typ='house', orients={1}}); +mg_villages.add_building( { scm="church", mts_path=path, weight={ruins=1}, typ='church', orients={1}, pervillage=1}); +mg_villages.add_building( { scm="church_old", mts_path=path, weight={ruins=1}, typ='church', orients={1}, pervillage=1}); +mg_villages.add_building( { scm="watchtower", mts_path=path, weight={ruins=1/8, single=1}, typ='tower', orients={1}}); +mg_villages.add_building( { scm="watchtower_old", mts_path=path, weight={ruins=1/8, single=1}, typ='tower', orients={1}}); +mg_villages.add_building( { scm="bunker", mts_path=path, weight={ruins=1/9, single=1}, typ='bunker', orients={1}}); + +mg_villages.add_building( { scm="wooden_house", mts_path=path, weight={ruins=1, single=1}, typ='house', orients={1}}); +mg_villages.add_building( { scm="watchtower_ruin",mts_path=path, weight={ruins=1/8, single=1}, typ='tower', orients={1}}); +mg_villages.add_building( { scm="watchtower2", mts_path=path, weight={ruins=1/8, single=1}, typ='tower', orients={1}}); diff --git a/mods/a_mapgen_mods/village_ruins/schems/bunker.mts b/mods/a_mapgen_mods/village_ruins/schems/bunker.mts new file mode 100644 index 0000000000000000000000000000000000000000..ea316a9ba7130d365680b8b6179e8326c26ef9a8 GIT binary patch literal 264 zcmeYb3HD`RW?*ArVPN?W1PojZ%!!#r3_>ZXX^EvdC04~Hsi`?hIr+)i3}P^`{G{T{ zl+47u`1G8_;$j9qn0QWNN=j-G122qUl3$dZ0hG?qFDkYwDM~B=u^9Ma(rKkdd5OuX z2=&Pssl_D>qDiSK#a2KfJ}JMXBtJL4JR`Ftl|cwDT#{b^5v!P!oRE;v;w0dZX3VI# z%tD!~g(1ygHtVUj7fch^WUP{uydiNz(n7*w;uT|smF`;`HNO8@ZkV9J5#d`S~df%!!#r41&caK&sdZ zOhLqXVQNeAi;^=Kc;MWk)KmlyY=m%1em+n$hy?46Pl`8Wzz{3}3i88DNh>YNOH58> z5Km9dP0UG2waUv+NsUj;%gjwINll42Vt`wpo|9Ny%pjVSno?{9B;u3uOG@%{XYW_@FTFWC2qI z$ATN#0c-X~MP`cr-kND}Z%ev!N^(kw=oybx3$@ufcGYg*pQW$gnkYXraiOne*sZ6H zWm|tgVTQcyVg$LWM7rm>x1%zZ38P E0Gq0!3IG5A literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/village_ruins/schems/cabin_old.mts b/mods/a_mapgen_mods/village_ruins/schems/cabin_old.mts new file mode 100644 index 0000000000000000000000000000000000000000..7851a6496d1c023a67b0e39c818183f467a98afb GIT binary patch literal 215 zcmeYb3HD`RW?*GtW8nM`20#{bVrCJ8P)cfAVrfo^Ra$CZa%y~eetrsrU~vghs@Mul zL4Uhe<^ literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/village_ruins/schems/church.mts b/mods/a_mapgen_mods/village_ruins/schems/church.mts new file mode 100644 index 0000000000000000000000000000000000000000..670fd06d237df53c91aed1326799df4ccab342aa GIT binary patch literal 709 zcmeYb3HD`RX5eBFVi5X|0T=`scv4c+5=(PRtV)VfQxUxK{QMLKUYJ~ZPGWH}19M_# z5rZ&HEH}TnxH36EDJdtFL9n<4C|7I+rs7fcmgE;DXD|rBROBQkK@6h5C^7EAi*F5vX(lb9TF$_|x{Px}Km2Pj`ZNc4J zx4b?Z$x`%A_vhwQA14?W**Txs+4INpzFTMedEM2TUvpJ*b=}S_oO3ts&PR)z&Op}l z*kdI%xAT9vCD{eL&OLv^(*MfOo>FE18Rt`5zV7U~m%IPr>VI5S+kg73eIRAY?>1lY z#a-U_ae?RT^6T_&Kfb%=(BDf%)2yaeoGbGEILlIAH}mf8ZS(%F|8vkz_I-D)^}PI? zGsWvSRNp%o^<{tTwmAF7(3|F0jIXRd!@rbn;k^@w6M5W_URX-?;hS+nOJ?!IDXD3Rr8y;5B}J*J2wr)9ehLF~VrCHoFHAvtPGWH} zgD{Mnn_pa9nVg@Ll#|LJSX=^BT5JWT;=y_aU_v>GNe~esn9j7+yyR4fm~cvdK2RTs z1PjC`#Tx>xKocy9H>{ZRHln+z*?`A5t@Y!7`8|x46WX08AJ9vgT9VsrAR;oqP+^gx zg5Y|aZI#!bSeQzMuksK*9+q5fSN4c6_lnGyZ-U3?iRFDgw*G|e(Qt>CdhCv8uiEu* zI)8az{;i#V5A9z)CB}@;zpO;H+)!Hj^3OL_x;s^`PpW!bAN;K{?&P=IXD^?$4zim4 zMSku3O}4)7f?<6ISt5OBFE3efK6%ys2Y(O$`tGIc*0$Pu+WeNnkhN@iU#=_X{m)Sf z`deIQJK^)b6t`dV_wK1V_tyN$j!ALv&s>~$*R1l)lV@Ky{tpeA@4f1yb!o?yeYNLS zpZ_>!pu*PEnrulXFm`deqC%Is5DZ|(ZnQe*bMJGTF1-#*#y}F@% z?fRYNd0D(#=eODXx4oL~ygivM|2aPc6dX9bKy1CXo3X++srlJg}EENja$uLNI<>YF=_`e0hF;3Ii`p ztR%lEIfH>YF|!DvFDEf2CAA2lCOs#yxR^mWB|pEY*a}2~&4^EmH^dYyi8rj6bJpLH zuR(!FTl(_<{SnV~JPs`A6t~`HG;4~;kB%ckE2jVOE<2{X_~zNjnr~HH^NX`IykbwJ y>IeLi&1ts##mK$2bk>+}wSCU_poKZ0+IUyl|#pzIkAlJ+V6C}9=KN(CCJa^1Z`Aj0CQ%bRd%GNUr UC+&a5E~#+Hy@Zt^l-vC;07FMIX8-^I literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/village_ruins/schems/watchtower_old.mts b/mods/a_mapgen_mods/village_ruins/schems/watchtower_old.mts new file mode 100644 index 0000000000000000000000000000000000000000..da259d2b0975487dd30c675ecf3e4678144a3e4a GIT binary patch literal 236 zcmeYb3HD`RW?*69WMKIZ0}Sj8!YQd~iKRIuR=N4b#g)nVNl7`W49tm{MGQhPnY7fr zwZgsZedE%!=ha{H tUtUf8cSpXsVbxsY9O31Gn{w}Wt)D;f&q=S+&L@8)uiYtTW^wQT1_11qWikK& literal 0 HcmV?d00001 diff --git a/mods/a_mapgen_mods/village_ruins/schems/watchtower_ruin.mts b/mods/a_mapgen_mods/village_ruins/schems/watchtower_ruin.mts new file mode 100644 index 0000000000000000000000000000000000000000..5f3ad8a33af3f1ee9dc458e23fd85c92a155b39c GIT binary patch literal 193 zcmeYb3HD`R0YXj&mUu1wBPO3F!P;DZT5`9d&$ zT54W$YJ7QqehLE*ObpE9h4D)Ai;^=c<|HRDFuAcEYT)d0Y>@QYyx^oWgYuNKEauY% zJ?C(G85wU-n%QX3$;r)qwf4j^q$o8N!7I= edge then + newpos = {x = -newedge, y = 10, z = pos.z} + elseif pos.x <= -edge then + newpos = {x = newedge, y = 10, z = pos.z} + end + + if pos.z >= edge then + newpos = {x = pos.x, y = 10, z = -newedge} + elseif pos.z <= -edge then + newpos = {x = pos.x, y = 10, z = newedge} + end + + -- Teleport the player + if newpos then + minetest.chat_send_player(name, "Please wait a few seconds. We will teleport you soon.") + local obj = minetest.add_entity(newpos, "worldedge:lock") + player:set_attach(obj, "", {x=0, y=0, z=0}, {x=0, y=0, z=0}) + waiting_list[name] = { + player = player, + pos = newpos, + obj = obj + } + obj:setpos(newpos) + end + end + end +end) + +function get_surface_pos(pos) + local minp = { + x = pos.x - radius - 1, + y = -10, + z = pos.z - radius - 1 + } + local maxp = { + x = pos.x + radius - 1, + y = 50, + z = pos.z + radius - 1 + } + + local c_air = minetest.get_content_id("air") + local c_ignore = minetest.get_content_id("ignore") + + local vm = minetest.get_voxel_manip() + local emin, emax = vm:read_from_map(minp, maxp) + local area = VoxelArea:new{MinEdge = emin, MaxEdge = emax} + local data = vm:get_data() + + local seen_air = false + local deepest_place = vector.new(pos) + deepest_place.y = 50 + + for x = minp.x, maxp.x do + for z = minp.z, maxp.z do + local solid = 0 + for y = deepest_place.y, -10, -1 do + local node = data[area:index(x, y, z)] + if y < deepest_place.y and node == c_air then + deepest_place = vector.new(x, y, z) + seen_air = true + end + if solid > 5 then + -- Do not find caves! + break + end + if node ~= c_air and node ~= c_ignore then + solid = solid + 1 + end + end + end + end + + if seen_air then + return deepest_place + else + return false + end +end + +minetest.register_entity("worldedge:lock", { + initial_properties = { + is_visible = false + }, + on_activate = function(staticdata, dtime_s) + --self.object:set_armor_groups({immortal = 1}) + end +}) \ No newline at end of file diff --git a/mods/a_server_mods/anticheat/README b/mods/a_server_mods/anticheat/README new file mode 100644 index 00000000..bd553872 --- /dev/null +++ b/mods/a_server_mods/anticheat/README @@ -0,0 +1,37 @@ +-- ANTI CHEAT by rnd +-- Copyright 2016 rnd +-- includes spectator mod by jp, modified/bugfixed by rnd + +------------------------------------------------------------------------- +-- 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 . +------------------------------------------------------------------------- + +features: + +0. what it does: + - succesffuly detect noclip/fly. Its just a matter of time when someone noclipping/flying is detected. + - players cant know when they are being watch since intervals are randomized + - lag resistant (see CHECK_AGAIN in settings) + +1. moderators can: + -see full reports with coordinates of location as cheats occur + -use /cstats to see latest detected cheater + -use /cdebug to see even suspected cheats to be verified later + -use /watch NAME to spectate suspect/detected cheater, /unwatch to return to normal + +managing moderators: + -edit names inside anticheatsettings.moderators in settings.lua + -Any player with kick privileges is moderator and is additionaly ignored by cheat checks. Use this for admin only - cheaters can then see who moderators are. + +2. this mod works well with basic_vote mod. After cheater has been positively detected anyone can use /vote to kick, remove interact or kill cheater. Vote in this case is cast anonymously, under the name #anticheat. \ No newline at end of file diff --git a/mods/a_server_mods/anticheat/anticheat_routines.bin b/mods/a_server_mods/anticheat/anticheat_routines.bin new file mode 100644 index 0000000000000000000000000000000000000000..20b6d1008eaacdcfd000b080f9b9d0a003736f9e GIT binary patch literal 3551 zcmc&$&2C%A6+ZJncP{@-Q&DXxYSg$8WTLVJ8oJ1ZOW1W9D{<0#!A%i01S3%vVTu$; z+O@i37VV0P>zWGjryf^EYSh^UoMP zeRz@{KJT1$$A_cy=Z9y#L3h#}Pj>I`-5+;HuezhduX}^Tot?w8;qmyeGnn*_PP?7S zy&2aY4_}Usx;y=soxgKphR6I~r&_8rqJ$BvaH1yTJYkG&b55FZY6(593r2|$VxKb+ zV@*r2sh=;ApWnbd_6sQ*Qd6Q7tte8dQZi8{=M8w9^Hw%gM2S{Z)1*_aRH9AJ8}K&g zt!ijTO(FSBDJYVRT9Qw<@jZ~7{P_p?(IvYCOtPKc2-ncR)))TsdiA6?IBpMy$K7$e zH)wZ8-A>Vu`n~bQuZ;$h>rU>LwTRA%3F54>va7d%3`T?()bu{SJ`HNX{V;gO z%w$!_AP*j>V#5LE{Vm-|e>faPXPwC@n@*?y5i(=#HFHAh}+41~;XdI)f^M=y{$NB!P;2>$bzgWmYGoh_j^S9g5; zJNAFMr2gMs(g%zWoy8k|S7xkeHq~GG8}U)k7fuw=P&~6-W4wY~Xu^;Qe&tXo*>sma z{AN~61rucwC~985@l8cShma_EoYzs{kaOZaQm+*T<1(osvJ=xY>x9qWB1bqpOXjoN~F6XsE; zH1=z&8>T>sRU);@B-V%(%WP^5cnz60O%2^TLI8Qas0+~BGSH z0$eUKUgx}y8g4C| zUyB*e%`jY@pUJdq#OoddzZqHDa#dmx;w19%;r)&{#l4fL80|+aN}>vWCK6cNvY$;e zyax+*@-b5P_@i4m|9yYHUAaC#=YtJ$-ecIHq@ZlAzzS(W#Yw@~v|#YnxlG56!uP2e z0jG;7a*|rk$1;5HGOPiMLwq>kbw#%idnB&pBInm2KIY_z4>v!)UWfQ_!0xK99wR;q zA5haFKIZmbuSI;!$-OVrxU`^m3*A~8*W7$QrSSGH(bT_KS3loG=}UeoFYz{9(&A&i zI9l>_yYZmgd9mtysq7VL9}NeS(Xfw-SnZ=pZ4Xb{ zRA~R$dCFP|6e}}FHc;LW#-0krVyRRrm&?`vq*|broNnJiJr$?SXp3xJ~!E*XE(9@@1%;@KVo;`c^i)X(K^p&T!r&CZ5 zG;67{=YE6+;+P&E{PgkD_M<0{KK+?*is#yc`PLwt32$m>IEenjLq{RM-E2lHFk-mtUbtL`z?w@&=pyT4(1L${;yIHH>$=c3gg(VrNTG1{l7 zU;YEz!@IYq80{f<_l%&5l~jooRh%K87oTA4>Bh#^@4xjlyDhowzU1cbN^Y?;@Qbc5 X&wbZ~p@+>(W+|pKS(Yrs@VNdPzc?F3 literal 0 HcmV?d00001 diff --git a/mods/a_server_mods/anticheat/anticheat_source.zip b/mods/a_server_mods/anticheat/anticheat_source.zip new file mode 100644 index 0000000000000000000000000000000000000000..eeacfe7d2defc848758eb10f13e97a2f4d7cd3f4 GIT binary patch literal 2234 zcmZ|R`9Bkm9|!QwO&?thStO!Sw&qBiM5b2X$!A7uxn`NGIfqd0$T?@uNM;$8D;;t* zN=cEj8FEFg31M#L>-+ub`*?i6-}meBc)uU-$Lk+>Vll!ZvH(ed1mKIG(q$T-v9@0V z0GL$(0Av9G0LjbW-O0_FBtd8x{Z3e^MaES>9cLjA&*JQ$YGm-DY$yTl;fj2 z)b(^-S2JO!H_JLVQ6C%OCl$Z)vu;2u&8Y)1FI)0Nw=p;u=+mcfS&xmiUw0IH&@kL2 zze{e{Tdr-v8>ImIcznY}=^E?N+$`mL6o8VZbT&U0KE2VA54m5uhV=WS;#qg9T8`iS z0Yy}-2*A|rIaiH0pfh8-EF1uA5bP_}&UnVGMfO1_G$bxJM|$1a0sH3EvOggzf#>*_ zz)@SwqtDY9Sq_#rnZ$r&5_p1RbM397xE$`M{#VwZH2Zzq%Jhk`pU}y$Ix46MhMy0) z4P;-{>M2L&Ug&PRrRy_VmTuIdp6H~@hI{pGxNxHPgIQUdJ$V|>+QrBGH+fWk>(Tk{ z67?z5P~ke|UgjPOC{*z%xr=Fu*BJIyvT)pUC7gJe?+>2}W#2dI8a%PI9&|f2`2&^s zHaKqBqq;2^VxATEH1SLZKFc)%$zwDIvg}ON-a*QZ8*yTqMH!`9x|FU%xC{CSy&Ap9 z*pU4j1F3gwDtaC_e8+jODUqR&1&zFdEct@tDQZFv&oTi}T?*q1T?=)yHB&{8WY9E4 zFwy&IISeK$hL&nFj558xM0oHtffw)DBES5}@kJQbngN?$bc%&pVDUcJW>jHw6dgBA ziw5XZ6<%;;=k_}J1ND`?QB!`I6$7HJL2?~n%pO{RB!(|a-i?|k*z?e=7!X(ptv6$k zN&O7eLMl80tuzrHQhP5*)F`vaP$6EdiQbQ2jV!$b7}+dtR~@PHZm!H9lvueQm+- zq`g87i^fbVPKFyH?=Ng;)oOG_SGT;QS*vyU_#AlXc!Y!-)>OZz4o|pC6Xv2jJ7MWJ z6@nyGCd5CIlcqzv$fS6|42Cs!@rvF2$5_se_=&lv_K&mMv@K=-PK7;h53oYgV?0#H z4>Hp=j3e;L`fHGaZ(nD^4>YmY^#8P$gq2s#L_jITI%hz1QBtwDBPvySac(ThUHMc4 z({-f4W+2%%NZ$Ww$nwJ8-EdSz5 z;-8O*a3ouw92TUq>Gk%qJoO%dJ1gN)E`dL^d^vEBc601)@1s}l&s6s4S>gV6@b8z4 zwi6*+ll3~tg=GQpN!v{Y&7rmb;4B&PxEYKSk!(e`-`u8+>nL`d0iGFY8O|<)X`QczbE929nFcAj-e1i5~Du^!Cp%G%9xi{jVuJY z=VnOtr#~OYSwt1kH3IhPs6xWWOG|PcvCVD1O(U*CL0a)XA6TAI{fhBZG(yslmF z9zaR#<60_hmTym(sT8~1--?~dn11`CP;I~&lyT%-6><5I1gu!OV(;S0UGLM&FSiEB zSdaI(dM->R5d;mln`-$bbsFax14Me`N%dFy;-3Q~Hfxq&ph)YHo5o=XaO#h6VbGiO zJlFbql=rz|zhCI=>?7M!onMCdH#!+?l1_pB^e9`!4^|hFdc#oqLc9Xc(`KTTO*uY zocPeW7t zFzR@9RO2f7`uiyzl$LbSDy-v?e^OuFsR{kP{nHQJ3U-deWj$xtw5H=vS`2wyE|(EK zhNJ`Ov=)my;$R1fl$f@_XClpdoSMG$KWdQWv_S2{7>B{|?v3*&caoIf_On=gdpUet z#7b#!Nj?o_7k()LfXd`eo7@Qjttq4HtJr8uQP`oI!MYI{> zf4g(;kHFDj#H-EL5OE&%10Dm%VY8%t?PXLVVZPV3D4 zR{Gw~&fpZTgTDT3H#lE(KH%VsqNO~`;_rm_3MqE07r2X!bnau_ uF7cmk`0pPmB)hAL|7VO{X6%m2zxV$Z2NokL_OBYa8`Ir;V^=5uz&`;%. +------------------------------------------------------------------------- +local cheat = {}; +local version = "10/09/2016"; + +anticheatsettings = {}; +dofile(minetest.get_modpath("anticheat").."/settings.lua") + +local CHEAT_TIMESTEP = anticheatsettings.CHEAT_TIMESTEP; +local CHECK_AGAIN = anticheatsettings.CHECK_AGAIN; +cheat.moderators = anticheatsettings.moderators; + + +anticheatdb = {}; -- data about detected cheaters + +cheat.suspect = ""; +cheat.players = {}; -- temporary cheat detection db +cheat.message = ""; +cheat.debuglist = {}; -- [name]=true -- who gets to see debug msgs + +cheat.scan_timer = 0; -- global scan of players +cheat.stat_timer = 0; -- used to collect stats + +cheat.nodelist = {}; +cheat.watcher = {}; -- list of watchers + +cheat.timestep = CHEAT_TIMESTEP; +-- list of forbidden nodes +cheat.nodelist = {["default:stone"] = false, ["default:cobble"]= false, ["default:dirt"] = false, ["default:sand"]=false,["default:tree"]= false}; + + +local punish_cheat = function(name) + + local player = minetest.get_player_by_name(name); + local ip = tostring(minetest.get_player_ip(name)); + + if not player then return end + local text=""; local logtext = ""; + + if cheat.players[name].cheattype == 1 then + text = "#anticheat: ".. name .. " was caught walking inside wall"; + logtext = os.date("%H:%M.%S").." #anticheat: ".. name .. " was caught walking inside wall at " .. minetest.pos_to_string(cheat.players[name].cheatpos); + player:set_hp(0); + elseif cheat.players[name].cheattype == 2 then + logtext= os.date("%H:%M.%S").." #anticheat: ".. name .. " was caught flying at " .. minetest.pos_to_string(cheat.players[name].cheatpos); + if cheat.players[name].cheatpos.y>5 then -- only above height 5 it directly damages flyer + text = "#anticheat: ".. name .. " was caught flying"; + player:set_hp(0); + end + end + + if text~="" then + minetest.chat_send_all(text); + end + + if logtext~="" then + minetest.log("action", logtext); + cheat.message = logtext; + + anticheatdb[ip] = {name = name, msg = logtext}; + + cheat.players[name].count=0; -- reset counter + cheat.players[name].cheattype = 0; + + for name,_ in pairs(cheat.moderators) do -- display full message to moderators + minetest.chat_send_player(name,logtext); + end + end +end + + +-- check position more closely + +-- uncomment when obfuscating: +--dofile(minetest.get_modpath("anticheat").."/anticheat_source.lua") + +local anticheat_routines=loadfile(minetest.get_modpath("anticheat").."/anticheat_routines.bin") +check_noclip, check_fly, check_player = anticheat_routines(minetest,cheat,CHECK_AGAIN,punish_cheat); + + +minetest.register_globalstep(function(dtime) + + cheat.scan_timer = cheat.scan_timer + dtime + + + -- GENERAL SCAN OF ALL PLAYERS + if cheat.scan_timer>cheat.timestep then + + + cheat.stat_timer = cheat.stat_timer + cheat.timestep; + -- dig xp stats every 2 minutes + if boneworld and cheat.stat_timer>120 then + cheat.stat_timer = 0; + local players = minetest.get_connected_players(); + for _,player in pairs(players) do + local pname = player:get_player_name(); + if cheat.players[pname].stats.state == 1 then -- only if dig xp loaded to prevent anomalous stats + if boneworld.digxp[pname] then + local deltadig = cheat.players[pname].stats.digxp; + cheat.players[pname].stats.digxp = boneworld.digxp[pname]; + deltadig = boneworld.digxp[pname]-deltadig; + cheat.players[pname].stats.deltadig = deltadig; + + if deltadig>cheat.players[pname].stats.maxdeltadig then + cheat.players[pname].stats.maxdeltadig = deltadig; + end + end + end + end + end + + + cheat.timestep = CHEAT_TIMESTEP + (2*math.random()-1)*2; -- randomize step so its unpredictable + cheat.scan_timer=0; + --local t = minetest.get_gametime(); + local players = minetest.get_connected_players(); + + for _,player in pairs(players) do + check_player(player); + end + + for name,_ in pairs(cheat.debuglist) do -- show suspects in debug + for _,player in pairs(players) do + local pname = player:get_player_name(); + if cheat.players[pname].count>0 then + minetest.chat_send_player(name, "name " .. pname .. ", cheat pos " .. minetest.pos_to_string(cheat.players[pname].cheatpos) .. " last clear pos " .. minetest.pos_to_string(cheat.players[pname].clearpos) .. " cheat type " .. cheat.players[pname].cheattype .. " cheatcount " .. cheat.players[pname].count ); + end + end + end + + + end +end) + +-- long range dig check + +local check_can_dig = function(pos, digger) + + local p = digger:getpos(); + if p.y<0 then p.y=p.y+2 else p.y=p.y+1 end -- head position + local dist = math.max(math.abs(p.x-pos.x),math.abs(p.y-pos.y),math.abs(p.z-pos.z)); + + + if dist>6 then -- here 5 + dist = math.floor(dist*100)/100; + local pname = digger:get_player_name(); + local logtext = "#long range dig: name " .. pname ..", distance " .. dist .. ", pos " .. minetest.pos_to_string(pos); + for name,_ in pairs(cheat.debuglist) do -- show to all watchers + minetest.chat_send_player(name,logtext) + + end + local ip = tostring(minetest.get_player_ip(pname)); + anticheatdb[ip] = {name = pname, msg = logtext}; + return false + end + + return true +end + +local set_check_can_dig = function(name) + local tabl = minetest.registered_nodes[name]; + if not tabl then return end + tabl.can_dig = check_can_dig; + minetest.override_item(name, {can_dig = check_can_dig}) + --minetest.register_node(":"..name, tabl); +end + +minetest.after(0, + function() + set_check_can_dig("default:stone"); + set_check_can_dig("default:stone_with_iron"); + set_check_can_dig("default:stone_with_copper"); + set_check_can_dig("default:stone_with_coal"); + set_check_can_dig("default:stone_with_gold"); + set_check_can_dig("default:stone_with_mese"); + set_check_can_dig("default:stone_with_diamond"); + end +) + + + + +-- DISABLED: lot of false positives +-- collects misc stats on players + +-- minetest.register_on_cheat( + -- function(player, c) + -- local name = player:get_player_name(); if name == nil then return end + -- local stats = cheat.players[name].stats; + -- if not stats[c.type] then stats[c.type] = 0 end + -- stats[c.type]=stats[c.type]+1; + -- end +-- ) + + + +local watchers = {}; -- for each player a list of watchers +minetest.register_on_joinplayer(function(player) -- init stuff on player join + local name = player:get_player_name(); if name == nil then return end + local pos = player:getpos(); + + if cheat.players[name] == nil then + cheat.players[name]={count=0,cheatpos = pos, clearpos = pos, lastpos = pos, cheattype = 0}; -- type 0: none, 1 noclip, 2 fly + end + + if cheat.players[name] and cheat.players[name].stats == nil then + cheat.players[name].stats = {maxdeltadig=0,deltadig = 0,digxp = 0, state = 0}; -- various statistics about player: max dig xp increase in 2 minutes, current dig xp increase + + minetest.after(5, -- load digxp after boneworld loads it + function() + if boneworld and boneworld.xp then + cheat.players[name].stats.digxp = boneworld.digxp[name] or 0; + cheat.players[name].stats.state = 1; + end + end + ) + + end + --state 0 = stats not loaded yet + + + watchers[name] = {}; -- for spectator mod + + local ip = tostring(minetest.get_player_ip(name)); + local msg = ""; + + -- check anticheat db + --check ip + if anticheatdb[ip] then + msg = "#anticheat: welcome back detected cheater, ip = " .. ip .. ", name " .. anticheatdb[ip].name .. ", new name = " .. name; + end; + --check names + for ip,v in pairs(anticheatdb) do + if v.name == name then + msg = "#anticheat: welcome back detected cheater, ip = " .. ip .. ", name = newname = " .. v.name; + break; + end + end + + if msg~="" then + for name,_ in pairs(cheat.moderators) do + minetest.chat_send_player(name,msg); + end + end + +end) + +minetest.register_chatcommand("cchk", { -- see cheat report + privs = { + interact = true + }, + func = function(name, param) + local privs = minetest.get_player_privs(name).privs; + if not cheat.moderators[name] and not privs then return end + + local player = minetest.get_player_by_name(param); + if not player then return end + check_player(player); + + + local players = minetest.get_connected_players(); + for name,_ in pairs(cheat.debuglist) do -- show suspects in debug + for _,player in pairs(players) do + local pname = player:get_player_name(); + if cheat.players[pname].count>0 then + minetest.chat_send_player(name, "name " .. pname .. ", cheat pos " .. minetest.pos_to_string(cheat.players[pname].cheatpos) .. " last clear pos " .. minetest.pos_to_string(cheat.players[pname].clearpos) .. " cheat type " .. cheat.players[pname].cheattype .. " cheatcount " .. cheat.players[pname].count ); + end + end + end + + + end +}) + + +minetest.register_chatcommand("crep", { -- see cheat report + privs = { + interact = true + }, + func = function(name, param) + local privs = minetest.get_player_privs(name).privs; + if not cheat.moderators[name] and not privs then return end + + if param == "" then + minetest.chat_send_player(name,"use: crep type, types: 0(default) cheat report, 1 connected player stats (".. version ..")"); + end + + param = tonumber(param) or 0; + + if param == 0 then -- show cheat report + local text = ""; + for ip,v in pairs(anticheatdb) do + if v and v.name and v.msg then + text = text .. "ip " .. ip .. " ".. v.msg .. "\n"; + end + end + if text ~= "" then + local form = "size [6,7] textarea[0,0;6.5,8.5;creport;CHEAT REPORT;".. text.."]" + minetest.show_formspec(name, "anticheatreport", form) + end + elseif param == 1 then -- show cheat stats + local text = ""; + local players = minetest.get_connected_players(); + for _,player in pairs(players) do + local pname = player:get_player_name(); + local ip = tostring(minetest.get_player_ip(pname)); + + + text = text .. "\nname " .. pname .. ", digxp " .. math.floor(1000*cheat.players[pname].stats.digxp)/1000 .. + ", deltadigxp(2min) " .. math.floor(1000*cheat.players[pname].stats.deltadig)/1000 .. ", maxdeltadigxp " .. math.floor(1000*cheat.players[pname].stats.maxdeltadig)/1000; -- .. " ".. string.gsub(dump(cheat.players[pname].stats), "\n", " "); + if anticheatdb[ip] then text = text .. " (DETECTED) ip ".. ip .. ", name " .. anticheatdb[ip].name end + end + if text ~= "" then + local form = "size [10,8] textarea[0,0;10.5,9.;creport;CHEAT STATISTICS;".. text.."]" + minetest.show_formspec(name, "anticheatreport", form) + end + end + -- suspects info + local players = minetest.get_connected_players(); + for _,player in pairs(players) do + local pname = player:get_player_name(); + if cheat.players[pname].count>0 then + minetest.chat_send_player(name, "name " .. pname .. ", cheat pos " .. minetest.pos_to_string(cheat.players[pname].cheatpos) .. " last clear pos " .. minetest.pos_to_string(cheat.players[pname].lastpos) .. " cheat type " .. cheat.players[pname].cheattype .. " cheatcount " .. cheat.players[pname].count ); + end + end + + end +}) + +minetest.register_chatcommand("cdebug", { -- toggle cdebug= display of stats on/off for this player + privs = { + interact = true + }, + func = function(name, param) + local privs = minetest.get_player_privs(name).privs; + if not cheat.moderators[name] and not privs then return end + + if cheat.debuglist[name] == nil then cheat.debuglist[name] = true else cheat.debuglist[name] = nil end; + + minetest.chat_send_player(name,"#anticheat: " .. version); + if cheat.debuglist[name]==true then + minetest.chat_send_player(name,"#anticheat: display of debug messages is ON"); + else + minetest.chat_send_player(name,"#anticheat: display of debug messages is OFF"); + end + end +}) + + + + +------------------------------------------------------ +-- [Mod] Spectator Mode [git] [spectator_mode] +-- https://github.com/minetest-mods/spectator_mode +-- by jp » Tue Dec 08, 2015 15:34 +-- modified/bugfixes by rnd +------------------------------------------------------ + + +local original_pos = {} + +local function unwatching(name) + local watcher = minetest.get_player_by_name(name) + local privs = minetest.get_player_privs(name) + + if watcher and default.player_attached[name] == true then + watcher:set_detach() + + + local pos = original_pos[watcher] + if pos then + -- setpos seems to be very unreliable + -- this workaround helps though + minetest.after(0.1, function() + watcher:setpos(pos) + end) + original_pos[watcher] = nil + end + cheat.watcher[name]=nil; + + minetest.after(5, + function() + default.player_attached[name] = false + watcher:set_eye_offset({x=0, y=0, z=0}, {x=0, y=0, z=0}) + watcher:set_nametag_attributes({color = {a=255, r=255, g=255, b=255}}) + + watcher:hud_set_flags({ + healthbar = true, + minimap = true, + breathbar = true, + hotbar = true, + wielditem = true, + crosshair = true + }) + + watcher:set_properties({ + visual_size = {x=1, y=1}, + makes_footstep_sound = true, + collisionbox = {-0.3, -1, -0.3, 0.3, 1, 0.3} + }) + end + ) + -- if not privs.interact and cheat.moderators[name] == true then + -- privs.interact = true + -- minetest.set_player_privs(name, privs) + -- end + + + + end +end + +minetest.register_chatcommand("watch", { + params = "", + description = "", + privs = {interact=true}, + func = function(name, param) + + local privs = minetest.get_player_privs(name) + if not cheat.moderators[name] and not privs.kick then return end + local watcher = minetest.get_player_by_name(name) + + + if param == "" then -- no name given - select a suspect automatically + local players = minetest.get_connected_players(); + for _,player in pairs(players) do + local pname = player:get_player_name(); + if cheat.players[pname].count>0 then + param = pname; + cheat.suspect = param; + break; + end + end + if param == "" and cheat.suspect~="" then param = cheat.suspect end -- if none found watch last suspect + end + + local target = minetest.get_player_by_name(param); + + if not target then return end + if not cheat.players[param] then return end + + + local canwatch = false; + for ip,v in pairs(anticheatdb) do + if v.name == param then + canwatch = true; + break; + end + end + + local ip = tostring(minetest.get_player_ip(param)); + if anticheatdb[ip] then canwatch = true end -- can watch since this ip was detected before + + + if canwatch or cheat.players[param].count>0 or param == cheat.suspect or privs.kick then + else + minetest.chat_send_player(name, "ordinary watchers can only watch cheat suspects of detected cheaters"); + return + end + + if target and watcher ~= target then + if default.player_attached[name] == true then + unwatching(param) + else + original_pos[watcher] = watcher:getpos() + end + + -- show inventory + local tinv = target:get_inventory():get_list("main"); + for i,v in pairs(tinv) do tinv[i] = v:to_string(); end + tinv = dump(tinv); + local form = "size [6,7] textarea[0,0;6.5,8.5;creport;INVENTORY LIST;".. tinv.."]" + minetest.show_formspec(name, "watch_inventory", form) + + + default.player_attached[name] = true + watcher:set_attach(target, "", {x=0, y=-5, z=-20}, {x=0, y=0, z=0}) + watcher:set_eye_offset({x=0, y=-5, z=-20}, {x=0, y=0, z=0}) + watcher:set_nametag_attributes({color = {a=0}}) + + watcher:hud_set_flags({ + healthbar = false, + minimap = false, + breathbar = false, + hotbar = false, + wielditem = false, + crosshair = false + }) + + watcher:set_properties({ + visual_size = {x=0, y=0}, + makes_footstep_sound = false, + collisionbox = {0} + }) + + -- privs.interact = nil + -- minetest.set_player_privs(name, privs) + + cheat.watcher[name]=true; + watchers[param][name] = true; -- register name as watcher of param + + + return true, "Watching '"..param.."' at "..minetest.pos_to_string(vector.round(target:getpos())) + end + + return false, "Invalid parameter ('"..param.."')." + end +}) + +minetest.register_chatcommand("unwatch", { + description = "", + privs = {interact=true}, + func = function(name, param) + unwatching(name) + -- unregister name as watcher + for pname,val in pairs (watchers) do + if val[name] then watchers[pname][name] = nil; end + end + + end +}) + +minetest.register_on_leaveplayer(function(player) + local name = player:get_player_name() + for pname,_ in pairs (watchers[name]) do + unwatching(pname); -- all watchers do /unwatch + end + watchers[name] = nil; +end) \ No newline at end of file diff --git a/mods/a_server_mods/anticheat/settings.lua b/mods/a_server_mods/anticheat/settings.lua new file mode 100644 index 00000000..371021c6 --- /dev/null +++ b/mods/a_server_mods/anticheat/settings.lua @@ -0,0 +1,36 @@ +-- ANTI CHEAT by rnd +-- Copyright 2016 rnd +-- includes modified/bugfixed spectator mod by jp + +------------------------------------------------------------------------- +-- 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 . +------------------------------------------------------------------------- + + +-- SETTINGS -------------------------------------------------------------- +anticheatsettings.CHEAT_TIMESTEP = 15; -- check all players +anticheatsettings.CHECK_AGAIN = 15; -- after player found in bad position check again after this to make sure its not lag, this should be larger than expected lag in seconds + +-- moderators list, those players can use cheat debug and will see full cheat message +anticheatsettings.moderators = { +["rnd"]=true, +["sasha2"]=true, +["maikerumine"]=true, +["sorcerykid"]=true, +["Zorg"]=true, +["AspireMint"]=true, +["843jdc"]=true, +["Fixer"] = true, +} +-- END OF SETTINGS -------------------------------------------------------- \ No newline at end of file diff --git a/mods/a_server_mods/basic_vote/README.md b/mods/a_server_mods/basic_vote/README.md new file mode 100644 index 00000000..a2f3b294 --- /dev/null +++ b/mods/a_server_mods/basic_vote/README.md @@ -0,0 +1,5 @@ +basic_vote - simple voting for minetest + +Start vote simply with chatcommand "vote". for vote to suceed at least 50% of connected players must vote and there must be more yes votes than no votes. Player with kick privs has a lot of vote pover. + +- add custom votes easily by defining vote types and what voting does \ No newline at end of file diff --git a/mods/a_server_mods/basic_vote/depends.txt b/mods/a_server_mods/basic_vote/depends.txt new file mode 100644 index 00000000..13780753 --- /dev/null +++ b/mods/a_server_mods/basic_vote/depends.txt @@ -0,0 +1 @@ +anticheat? \ No newline at end of file diff --git a/mods/a_server_mods/basic_vote/init.lua b/mods/a_server_mods/basic_vote/init.lua new file mode 100644 index 00000000..d33f3eec --- /dev/null +++ b/mods/a_server_mods/basic_vote/init.lua @@ -0,0 +1,348 @@ +-- basic vote by rnd, 2015 + +local basic_vote = {}; + +-- SETTINGS ---------------------------------------------------------------------- + +-- DEFINE VOTE TYPES + +basic_vote.types = { -- [type] = { description , votes_needed , timeout, command, help_description} +[1] = {"ban %s for 2 minutes" , -3 , 30, "ban", "Ban player for 2 minutes"}, -- -3 means strictly more than 3 players need to vote ( so 4 or more) +[2] = {"remove interact of %s" , 0.5, 120, "remove_interact", "Remove 'interact' privilege from player"}, -- 0.5 means at least 50% need to vote +[3] = {"give interact to %s" , 0.5 , 120, "give_interact", "Give 'interact' privilege to player"}, +[4] = {"kill %s" , -3 , 30, "kill", "Kill player"}, +[5] = {"poison %s" , -3 , 30, "poison", "Poison player"}, +[6] = {"teleport %s to vote starter" , -3 , 30, "teleport", "Teleport player to you"}, +[7] = {"change name color of %s",-2,30,"name color","Change name of player"}, +[8] = {"mutelate %s",-2,30,"mutelate", "Mute and kill player when talking"}, +[9] = {"unmutelate",-2,30,"unmutelate","Undo effects of mutelate"}, +[10] = {"ask",1.0,30,"ask","put a question up for voting"} +}; +basic_vote.modreq = 2; -- more that this number of moderators from "anticheat" mod must vote for mod to succeed + +-- needed for poison vote +local vote_poison_state = {}; +basic_vote_poison = function(name) + + local player = minetest.get_player_by_name(name); + + if not vote_poison_state[name] then + vote_poison_state[name] = 60; + end + + vote_poison_state[name] = vote_poison_state[name] - 1; + if vote_poison_state[name]<=0 then + vote_poison_state[name] = nil; return; + end + + if player then + if player:get_hp()>0 then + player:set_hp(player:get_hp()-4); + end + end + + minetest.after(2, function() basic_vote_poison(name) end) + +end + +basic_vote.kicklist = {}; +basic_vote.talklist = {}; +basic_vote.huds = {}; + +-- for hud votes + +local hud_definition = +{ + hud_elem_type = "image", + scale = {x=-50,y=-50}, + text = "default_stone.png", + size = { x=50, y=50 }, + offset = { x=0, y=0}, +} + + +-- DEFINE WHAT HAPPENS WHEN VOTE SUCCEEDS +basic_vote.execute = function(type, name, reason) + + if type == 1 then + local ip = tostring(minetest.get_player_ip(name)); + basic_vote.kicklist[ip] = minetest.get_gametime(); -- remembers start time + minetest.kick_player(name, reason) + + elseif type == 2 then + + local privs = core.get_player_privs(name);privs.interact = false + core.set_player_privs(name, privs); minetest.auth_reload() + + elseif type == 3 then + + local privs = core.get_player_privs(name);privs.interact = true; + core.set_player_privs(name, privs); minetest.auth_reload() + + elseif type == 4 then + + local player = minetest.get_player_by_name(name); if not player then return end + player:set_hp(0); + + elseif type == 5 then + + local player = minetest.get_player_by_name(name); if not player then return end + if not vote_poison_state[name] then + basic_vote_poison(name); + end + + elseif type == 6 then + + local player = minetest.get_player_by_name(name); if not player then return end + local vname = basic_vote.vote.voter; local vplayer = minetest.get_player_by_name(vname); + if not vplayer then return end + player:setpos(vplayer:getpos()); + + elseif type == 7 then + + local player = minetest.get_player_by_name(name); if not player then return end + player:set_nametag_attributes({color = basic_vote.vote.reason}); + + elseif type == 8 then + local player = minetest.get_player_by_name(name); if not player then return end + basic_vote.talklist[name]=1; + + elseif type == 9 then + local player = minetest.get_player_by_name(name); if not player then return end + basic_vote.talklist[name]=nil; + + elseif type == 10 then + --basic_vote.huds[name]=player:hud_add(hud_definition); + + end + +end + +-- for ban vote +minetest.register_on_prejoinplayer( + function(name, ip) + local name; + if basic_vote.kicklist[ip] then + + local t = minetest.get_gametime(); + t=t-basic_vote.kicklist[ip]; + if t>120 then + basic_vote.kicklist[ip] = nil; + else + return "You have been temporarily banned from the server." + end + end + + end +) + +-- for talking votes + +minetest.register_on_chat_message( + function(name, message) + + + if basic_vote.talklist[name] then + if basic_vote.talklist[name] == 1 then -- kill + local player = minetest.get_player_by_name(name); + if not player then return end + if not player:get_inventory():is_empty("main") then + local p = player:getpos(); + p.x=math.floor(p.x);p.y=math.floor(p.y);p.z=math.floor(p.z); + minetest.chat_send_all("<" .. name .. "> please come get my bones at " .. minetest.pos_to_string(p)) + end + player:set_hp(0); + return true + end + end + + end +) + + + + + +-- END OF SETTINGS --------------------------------------------------------------- + +basic_vote.votes = 0; -- vote count +basic_vote.modscore = 0; -- how many moderators voted - need 3 for vote to succeed +basic_vote.voters = {}; -- who voted already +basic_vote.state = 0; -- 0 no vote, 1 vote in progress,2 timeout +basic_vote.vote = {time = 0,type = 0, name = "", reason = "", votes_needed = 0, timeout = 0, }; -- description of current vote + + +basic_vote.requirements = {[0]=0} +basic_vote.vote_desc="" +for i=1,#basic_vote.types do + basic_vote.vote_desc = basic_vote.vote_desc .. "Type " .. i .. " (" ..basic_vote.types[i][4].. "): ".. basic_vote.types[i][5].."\n" +end + +local function get_description(vote) + local type_str = string.format(basic_vote.types[basic_vote.vote.type][1], basic_vote.vote.name) + local timeout = math.max(0, vote.timeout - os.difftime(os.time(), vote.time_start)) + if vote.reason == nil or vote.reason == "" then + return string.format("## VOTE by %s to %s. Timeout in %ds.", vote.voter, type_str, timeout) + else + return string.format("## VOTE by %s to %s with reason: '%s'. Timeout in %ds.", vote.voter, type_str, vote.reason, timeout) + end +end + +-- starts a new vote +minetest.register_chatcommand("vote", { + privs = { + interact = true + }, + params = "[[ []] | types]", + description = "Start a vote. '/vote types' for a list of types, '/vote' without arguments to see current voting progress", + func = function(name, param) + + if basic_vote.state~=0 then + minetest.chat_send_player(name,"Vote already in progress:") + minetest.chat_send_player(name,get_description(basic_vote.vote)); + return + elseif param == "" then + minetest.chat_send_player(name,"No vote in progress.") + return + end + local player = minetest.get_player_by_name(name); + + -- split string param into parameters + local paramt = string.split(param, " ") + for i = #paramt+1,3 do paramt[i]="" end + + + if paramt[1] == "types" then minetest.chat_send_player(name, basic_vote.vote_desc) return end + + basic_vote.vote.time = minetest.get_gametime(); + basic_vote.vote.type = tonumber(paramt[1]); + -- check for text-based types + -- if basic_vote.vote.type == nil then + -- for i=1,#basic_vote.types do + -- if paramt[1] == basic_vote.types[i][4] then + -- basic_vote.vote.type = i + -- end + -- end + -- end + + if not basic_vote.types[basic_vote.vote.type] then + minetest.chat_send_player(name,"Error: Invalid syntax or type. Use '/help vote' for help.") + return + end + + -- if not basic_vote.vote.type then minetest.chat_send_player(name,"Error: Invalid syntax or type. Use '/help vote' for help.") return end + + basic_vote.vote.name=paramt[2] or "an unknown player"; + basic_vote.vote.voter = name; + basic_vote.vote.reason = string.match(param, "%w+ [%w_-]+ (.+)") + basic_vote.vote.votes_needed = basic_vote.types[ basic_vote.vote.type ][2]; + basic_vote.vote.timeout = basic_vote.types[ basic_vote.vote.type ][3]; + basic_vote.vote.time_start = os.time(); + + + --check if target valid player + if basic_vote.vote.name == "" then + minetest.chat_send_player(name,"Error: No player specified.") + return + elseif not minetest.get_player_by_name(basic_vote.vote.name) and basic_vote.vote.type~= 1 then + minetest.chat_send_player(name,"Error: The specified player is currently not connected.") + return + end + + -- check anticheat db + local ip = tostring(minetest.get_player_ip(basic_vote.vote.name)); + if anticheatdb and anticheatdb[ip] then -- #anticheat mod: makes detected cheater more succeptible to voting + if anticheatsettings.moderators[name] then -- moderator must call vote + basic_vote.vote.votes_needed=0; -- just need 1 vote + name = "an anonymous player"; -- so cheater does not see who voted - anonymous vote + end + end + + basic_vote.votes = 0; basic_vote.modscore = 0; basic_vote.voters = {}; + + local type_str = string.format(basic_vote.types[basic_vote.vote.type][1], basic_vote.vote.name) + + if basic_vote.vote.reason == nil or basic_vote.vote.reason == "" then + minetest.chat_send_all(string.format("## VOTE started (by %s to %s).\nSay '/y' to vote 'yes'. Timeout in %ds.", name, type_str, basic_vote.vote.timeout)) + else + minetest.chat_send_all(string.format("## VOTE started (by %s to %s) with reason: '%s'.\nSay '/y' to vote 'yes'. Timeout in %ds.", name, type_str, basic_vote.vote.reason, basic_vote.vote.timeout)) + end + + basic_vote.state = 1; minetest.after(basic_vote.vote.timeout, function() + if basic_vote.state == 1 then basic_vote.state = 2;basic_vote.update(); end + end) + end + } +) + +-- check if enough votes for vote to succeed or fail vote if timeout +basic_vote.update = function() + local players=minetest.get_connected_players(); + local count = #players; + + local votes_needed; + + if basic_vote.vote.votes_needed>0 then + votes_needed = basic_vote.vote.votes_needed*count; -- percent of all players + if basic_vote.vote.votes_needed>=0.5 then -- more serious vote, to prevent ppl voting serious stuff with few players on server, at least 6 votes needed + if votes_needed<6 then votes_needed = 6 end + end + + else + votes_needed = -basic_vote.vote.votes_needed; -- number instead + end + + if basic_vote.state == 2 then -- timeout + minetest.chat_send_all("## VOTE failed. ".. basic_vote.votes .." voted (needed more than ".. votes_needed ..")."); + basic_vote.state = 0;basic_vote.vote = {time = 0,type = 0, name = "", reason = ""}; return + end + if basic_vote.state~=1 then return end -- no vote in progress + + -- check if enough votes + + if basic_vote.modscore> basic_vote.modreq then -- enough moderators voted for vote to succeed + basic_vote.votes = votes_needed+1; + end + + if basic_vote.votes>votes_needed then -- enough voters + minetest.chat_send_all("## VOTE succeded. "..basic_vote.votes .." voted."); + local type = basic_vote.vote.type; + basic_vote.execute(basic_vote.vote.type,basic_vote.vote.name, basic_vote.vote.reason) + basic_vote.state = 0;basic_vote.vote = {time = 0,type = 0, name = "", reason = ""}; + + end +end + +local cast_vote = function (name,param) + if basic_vote.state~=1 then + -- vote not in progress + minetest.chat_send_player(name,"Error: No vote in progress."); + return + end + local ip = tostring(minetest.get_player_ip(name)); + if basic_vote.voters[ip] then + minetest.chat_send_player(name,"Error: You already voted."); + return + else + -- mark as already voted + basic_vote.voters[ip]=true + end + basic_vote.votes = basic_vote.votes+1; + if anticheatsettings and anticheatsettings.moderators[name] then -- moderator from anticheat mod + basic_vote.modscore=basic_vote.modscore+1; + end + local privs = core.get_player_privs(name);if privs.kick then basic_vote.votes = 100; end + basic_vote.update(); minetest.chat_send_player(name,"Vote received."); +end + +minetest.register_chatcommand("y", { + privs = { + interact = true + }, + params = "", + description = "Vote 'Yes.' in the current vote (see vote command)", + func = function(name, param) + cast_vote(name,param) + end + } +) diff --git a/mods/z_extra_mods/boneworld/depends.txt b/mods/a_server_mods/boneworld/depends.txt similarity index 100% rename from mods/z_extra_mods/boneworld/depends.txt rename to mods/a_server_mods/boneworld/depends.txt diff --git a/mods/a_server_mods/boneworld/init.lua b/mods/a_server_mods/boneworld/init.lua new file mode 100644 index 00000000..4925c139 --- /dev/null +++ b/mods/a_server_mods/boneworld/init.lua @@ -0,0 +1,361 @@ +-- boneworld by rnd, 2016 + +-- for more interesting bone gameplay: + +-- you no longer get extra bones if you pick bones from player with same ip address (no suicide bone farming) +-- each player has experience points (xp) +-- when you die you loose 20% of your xp, half of that is stored in bones +-- (when you kill other player you get 10% of his xp) +-- if you pick up bones you get xp stored in bones +-- if you pick up other player bones you get 20% of average of your and bone owner xp award in extra bones (for example if you have 10 xp and you pick noob bone will get 2 bones instead of normally 1) + +local version = "10/07/16" + +local worldpath = minetest.get_worldpath(); +os.execute( "mkdir "..worldpath.. "\\boneworld") -- directory used to save xp data +boneworld = {}; +boneworld.xp = {}; -- bone collect xp +boneworld.digxp = {}; -- mining xp + +-- those players get special dig xp when they join +boneworld.vipdig = {["ADMIN"]=1000000} + + +--boneworld.killxp = {}; -- xp obtained through kills + +boneworld.wastedxp = 0; -- xp thats stored in bones and not yet reclaimed +-- idea: vote on table ( select player checkbox) to select who should receive wasted xp after it accumulates 10? xp + + +local share_bones_time = tonumber(minetest.setting_get("share_bones_time")) or 1200 +--local share_bones_time = tonumber(minetest.setting_get("share_bones_time")) or 20; +local share_bones_time_early = tonumber(minetest.setting_get("share_bones_time_early")) or share_bones_time / 4 + + +local function is_owner(pos, name) + local owner = minetest.get_meta(pos):get_string("owner") + if owner == "" or owner == name or minetest.check_player_privs(name, "protection_bypass") then + return true + end + return false +end + + +local on_timer = function(pos, elapsed) + local meta = minetest.get_meta(pos) + local time = meta:get_int("time")+elapsed; + if time >= share_bones_time then + + meta:set_string("infotext", meta:get_string("owner").."'s old bones (died ".. meta:get_string("date") .."), bone xp " ..math.floor(meta:get_float("xp")*100)/100); + meta:set_string("owner", "") + + else + + if meta:get_int("active") == 0 then -- store data in bones, 1x + meta:set_int("active",1); + local owner = meta:get_string("owner"); + meta:set_string("date",os.date("%x")); + meta:set_string("owner_orig",owner); + meta:set_string("ip", tostring(minetest.get_player_ip(owner))); + if not minetest.get_player_by_name(owner) then -- mob bones + boneworld.xp[owner] = 0.1 -- 0.1th of noob player xp in mobs bone + time=0.9*share_bones_time; -- 10x shorter old bone time + else + boneworld.xp[owner] = boneworld.xp[owner] or 1; + time = 0; + end + + if boneworld.xp[owner]<1 then + meta:set_float("xp", 0.01) -- mobs or bones with 0 xp + else + meta:set_float("xp", 0.1); -- player bones give 0.1 xp, same as 10 mob bones + end + + boneworld.wastedxp = boneworld.wastedxp + meta:get_float("xp"); + meta:set_string("infotext"," Here lies " .. owner .. ", bone xp " .. math.floor(meta:get_float("xp")*100)/100); + end + + + meta:set_int("time", time) + return true + end +end + +local on_punch = function(pos, node, player) + if(not is_owner(pos, player:get_player_name())) then + return + end + + if(minetest.get_meta(pos):get_string("infotext") == "") then + return + end + + local inv = minetest.get_meta(pos):get_inventory() + local player_inv = player:get_inventory() + local has_space = true + + for i=1,inv:get_size("main") do + local stk = inv:get_stack("main", i) + if player_inv:room_for_item("main", stk) then + inv:set_stack("main", i, nil) + player_inv:add_item("main", stk) + else + has_space = false + break + end + end + + -- remove bones if player emptied them + if has_space then + local meta = minetest.get_meta(pos); + local active = meta:get_int("active") == 1; + local puncher = player:get_player_name(); + + -- award extra bones/xp if you collect bones from different ip player + --debug + if active and meta:get_string("ip")~= tostring(minetest.get_player_ip(puncher)) then + local xp = meta:get_float("xp");if xp==0 then xp = 0.01 end + -- average of owners xp (at time of death) and puncher xp will be awarded as extra bones + -- with every 10 more xp one bone + + local count; + if boneworld.xp[puncher]>100 then -- dont give more bones when bone xp exceeds 100 + count = 1 + 0.1*100; + else + count = 1+0.1*boneworld.xp[puncher]; + end + + count = math.floor(count); + minetest.chat_send_player(puncher, "you find " .. count .. " bones in the corpse."); + + if player_inv:room_for_item("main", ItemStack("bones:bones "..count)) then + player_inv:add_item("main", ItemStack("bones:bones "..count)) + else + minetest.add_item(pos,ItemStack("bones:bones "..count)) + end + + -- add xp from bones to player who retrieved bones; + + boneworld.xp[puncher] = boneworld.xp[puncher] + meta:get_float("xp"); + boneworld.wastedxp = boneworld.wastedxp - meta:get_float("xp"); + end + + + minetest.remove_node(pos) + end +end + + +-- load xp +minetest.register_on_joinplayer( + function(player) + local name = player:get_player_name(); + if not boneworld.xp[name] then -- load xp + local filename = worldpath .. "\\boneworld\\" .. name..".xp"; + local f = io.open(filename, "r"); + if not f then -- file does not yet exist + boneworld.xp[name] = 1; + boneworld.digxp[name] = 0; + else + local str = f:read("*a") or 1; + local words = {}; + for w in str:gmatch("%S+") do + words[#words+1]=w + end + boneworld.xp[name] = tonumber(words[1] or 1); + boneworld.digxp[name] = tonumber(words[2] or 0); + f:close(); + end + end + + if boneworld.vipdig[name] then + if boneworld.digxp[name] 2 or digxp>1 then -- save xp for serious players only + local filename = worldpath .. "\\boneworld\\" .. name..".xp"; + + local f = io.open(filename, "w"); + if not f then return end + f:write(bonexp .. " " .. digxp); + f:close(); + else + -- dont save, player didnt do anything + end + end + +) + +minetest.register_on_dieplayer( -- -1 bone xp each time you die; otherwise no motivation to be careful + function(player) + local name = player:get_player_name(); + local xp = boneworld.xp[name] or 1; + if xp>2 then + xp=xp-1 + else + xp = 1; + end + boneworld.xp[name]=xp; + end +) + + +local tweak_bones = function() + local name = "bones:bones"; + local table = minetest.registered_nodes[name]; + --table.on_construct = on_construct; + table.on_punch = on_punch; + table.on_timer = on_timer; + minetest.register_node(":"..name, table); +end + +minetest.after(0,tweak_bones); + +minetest.register_chatcommand("xp", { + description = "xp name - show bone collecting experience of target player " .. version, + privs = { + interact = true + }, + func = function(name, param) + + local msg; + if param == "" then + local xp = math.floor((boneworld.xp[name])*100)/100; + local digxp = math.floor((boneworld.digxp[name])*100)/100; + --local killxp = math.floor((boneworld.killxp[name])*100)/100; + msg = "xp name - show experience of target player" + .."\n# "..name .. " has " .. xp .. " bone collecting experience, ".. digxp .. " digging experience" + .. " (can dig to ".. math.floor(200+50*math.sqrt(digxp)) .. ")" + .. "\nTotal xp stored in bones in world is " .. math.floor(boneworld.wastedxp*100)/100; + else + local xp = math.floor((boneworld.xp[param] or 1)*100)/100; + local digxp = math.floor((boneworld.digxp[param] or 0)*100)/100; + --local killxp = math.floor((boneworld.killxp[name])*100)/100; + msg = "xp name - show experience of target player (10.04.16)" + .."\n# "..param .. " has " .. xp .. " bone collecting experience, ".. digxp .. " digging experience"; + + end + minetest.chat_send_player(name, msg); + end +}) + + +-- limit digging to above -(200+xp*5) +local old_is_protected = minetest.is_protected +function minetest.is_protected(pos, name) + + if pos.y>-200 or name == "" then + return old_is_protected(pos, name) + end + + --to do : digxp here!! + local digxp = boneworld.digxp[name] or 0; + + local maxdepth = 200+50*math.sqrt(digxp); + if pos.y<-maxdepth then + minetest.chat_send_player(name, "You can only dig above -"..math.floor(maxdepth) .. ". Get more dig experience to dig deeper"); + local player = minetest.get_player_by_name(name); if not player then return true end + --if pos.y<-maxdepth-5 then player:setpos({x=0,y=1,z=0}) end + return true + end + return old_is_protected(pos, name) +end + +-- mining xp + +-- how much mining xp digging minerals yields +boneworld.mineralxp = { +["default:stone"] = 0.01, +["default:stone_with_coal"] = 0.03, +["es:desert_stone_with_coal"] = 0.06, +["default:stone_with_iron"] = 0.1, +["es:desert_stone_with_iron"] = 0.2, +["default:stone_with_copper"] = 0.3, +["default:stone_with_gold"] = 0.5, +["es:desert_stone_with_gold"] = 0.5, +["default:stone_with_mese"] = 0.85, +["default:stone_with_diamond"] = 1.25, +["es:stone_with_emeralds"] = 1.25, +["es:stone_with_rubys"] = 1.5, +["es:stone_with_aikerums"] = 1.75, +["es:stone_with_infiniums"] = 3, +["es:stone_with_purpelliums"] = 3, +["es:depleted_uraniums"] = 0.5, +} + + +local after_dig_node = function(pos, oldnode, oldmetadata, digger) + local nodename = oldnode.name; + local name = digger:get_player_name(); + local digxp = boneworld.mineralxp[nodename] or 0; digxp = digxp*0.1; -- bonus xp + local xp = boneworld.digxp[name]; + xp = boneworld.digxp[name] + digxp; + boneworld.digxp[name] = xp; + + -- extra reward with small probability + if xp<100 or nodename == "default:stone" or digxp == 0 then return end + + local P; + if xp>10000 then + P=0.5 + else + P = (xp/10000+0.0001)*0.5; + end + + if math.random(1/P) == 1 then + P=1; + end + + if P==1 then + + local player_inv = digger:get_inventory() + local stk = ItemStack(nodename); + if player_inv:room_for_item("main", stk) then + --minetest.chat_send_player(name, "Congratulations! You found extra " .. nodename) + player_inv:add_item("main", stk) + end + end + + --minetest.chat_send_all(name .. " digged " .. nodename .. " for " .. digxp .. " mining xp ") +end + +local set_after_dig_node = function(name) + local tabl = minetest.registered_nodes[name]; + if not tabl then return end + minetest.override_item(name, {after_dig_node = after_dig_node}) +end + +minetest.after(0, + function() + set_after_dig_node("default:stone"); + set_after_dig_node("default:stone_with_iron"); + set_after_dig_node("default:stone_with_copper"); + set_after_dig_node("default:stone_with_coal"); + set_after_dig_node("default:stone_with_gold"); + set_after_dig_node("default:stone_with_mese"); + set_after_dig_node("default:stone_with_diamond"); + + set_after_dig_node("es:stone_with_emeralds"); + set_after_dig_node("es:stone_with_rubys"); + set_after_dig_node("es:stone_with_aikerums"); + set_after_dig_node("es:stone_with_infiniums"); + set_after_dig_node("es:stone_with_purpelliums"); + set_after_dig_node("es:depleted_uraniums"); + set_after_dig_node("es:desert_stone_with_coal"); + set_after_dig_node("es:desert_stone_with_iron"); + set_after_dig_node("es:desert_stone_with_gold"); + end +) + diff --git a/mods/a_server_mods/death_messages/depends.txt b/mods/a_server_mods/death_messages/depends.txt index e69de29b..f191ce69 100644 --- a/mods/a_server_mods/death_messages/depends.txt +++ b/mods/a_server_mods/death_messages/depends.txt @@ -0,0 +1 @@ +chat2? diff --git a/mods/a_server_mods/death_messages/init.lua b/mods/a_server_mods/death_messages/init.lua index 0079ca7e..9d23e049 100644 --- a/mods/a_server_mods/death_messages/init.lua +++ b/mods/a_server_mods/death_messages/init.lua @@ -48,9 +48,13 @@ messages.water = { " failed at swimming lessons.", " tried to impersonate an anchor.", " forgot he wasn't a fish.", - " drank themselves to death.", - " failed to achieve the underwater challenge.", - " blew one too many bubbles." + " blew one too many bubbles.", + " kinda screwed up.", + " couldn't fight very well.", + " got 0wn3d.", + " got SMOKED.", + " got hurted by Oerkki.", + " got blowed up." } -- Burning death messages @@ -59,27 +63,21 @@ messages.fire = { " got a little too warm.", " got too close to the camp fire.", " just got roasted, hotdog style.", - " gout burned up. More light that way." + " got burned up. More light that way." } - +--[[ -- Other death messages messages.other = { " died.", " did something fatal.", " gave up on life.", " is somewhat dead now.", - " kinda screwed up.", - " couldn't fight very well.", - " got 0wn3d.", - " got SMOKED.", - " got hurted by Oerkki.", - " got blowed up.", - " forgot about gravity.", - " is a Rusher.", - " loves 2b2t.", - " passed out -permanently." + " passed out -permanently.", + " thinks 2b2t is too hard", + " is a rusher.", + " loves maikerumine's youtube channel!" } - +]] function get_message(mtype) if RANDOM_MESSAGES then return messages[mtype][math.random(1, #messages[mtype])] @@ -92,31 +90,49 @@ minetest.register_on_dieplayer(function(player) local player_name = player:get_player_name() local node = minetest.registered_nodes[minetest.get_node(player:getpos()).name] local pos = player:getpos() - local death = {x=0, y=1000, z=0} + local death = {x=0, y=-2, z=0} if minetest.is_singleplayer() then player_name = "You" end - - - - -- Death by lava if node.groups.lava ~= nil then - minetest.chat_send_all(player_name .. get_message("lava")) + minetest.chat_send_all(player_name .. get_message("lava")) -- Death by drowning elseif player:get_breath() == 0 then - minetest.chat_send_all(player_name .. get_message("water")) + minetest.chat_send_all(player_name .. get_message("water")) -- Death by fire elseif node.name == "fire:basic_flame" then - minetest.chat_send_all(player_name .. get_message("fire")) + minetest.chat_send_all(player_name .. get_message("fire")) -- Death by something else else - minetest.chat_send_all(player_name .. get_message("other")) + --minetest.chat_send_all(player_name .. get_message("other")) end - player:setpos(death) - minetest.chat_send_all(player_name ..(" GG")) - +end) +--bigfoot code +-- bigfoot547's death messages +minetest.register_on_punchplayer(function(player, hitter) + if not (player or hitter) then + return false + end + if not hitter:get_player_name() == "" then + return false + end + minetest.after(0, function() + if player:get_hp() == 0 and hitter:get_player_name() ~= "" then + minetest.chat_send_all(player:get_player_name().." was killed by "..hitter:get_player_name()..".") + --chat2_send_message(players[i], (player:get_player_name().." was killed by "..hitter:get_player_name().."."), 0xFF0000) + if player=="" or hitter=="" then return end -- no mob killers/victims + return true + elseif hitter:get_player_name() == "" and player:get_hp() == 0 then + minetest.chat_send_all(player:get_player_name().." was killed by "..hitter:get_luaentity().name..".") --error + --minetest.chat_send_all(player:get_player_name().." was killed by "..hitter:get_luaentity().name..".") --error + --chat2_send_message(players[i], (player:get_player_name().." was killed by "..hitter:get_luaentity().name.."."), 0xFF0000) + if player=="" or hitter=="" then return end -- no mob killers/victims + else + return false + end + end) end) ----------------------------------------------------------------------------------------------- diff --git a/mods/bones/README.txt b/mods/bones/README.txt index cf99bc8b..91bcd109 100644 --- a/mods/bones/README.txt +++ b/mods/bones/README.txt @@ -1,17 +1,12 @@ Minetest Game mod: bones ======================== +See license.txt for license information. -License of source code: ------------------------ -Copyright (C) 2012 PilzAdam - -WTFPL - -License of media (textures and sounds) --------------------------------------- -Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) -http://creativecommons.org/licenses/by-sa/3.0/ - -Authors of media files +Authors of source code ---------------------- -All textures: paramat +Originally by PilzAdam (MIT) +Various Minetest developers and contributors (MIT) + +Authors of media (textures) +--------------------------- +All textures: paramat (CC BY-SA 3.0) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 8c355426..9542cab0 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -149,7 +149,7 @@ local function may_replace(pos, player) end local drop = function(pos, itemstack) - local obj = core.add_item(pos, itemstack:take_item(itemstack:get_count())) + local obj = minetest.add_item(pos, itemstack:take_item(itemstack:get_count())) if obj then obj:setvelocity({ x = math.random(-10, 10) / 9, @@ -180,14 +180,14 @@ minetest.register_on_dieplayer(function(player) local pos = vector.round(player:getpos()) local player_name = player:get_player_name() - -- check if it's possible to place bones, if not go 1 higher + -- check if it's possible to place bones, if not find space near player if bones_mode == "bones" and not may_replace(pos, player) then - pos.y = pos.y + 1 - end - - -- still cannot place bones? change mode to 'drop' - if bones_mode == "bones" and not may_replace(pos, player) then - bones_mode = "drop" + local air = minetest.find_node_near(pos, 1, {"air"}) + if air and not minetest.is_protected(air, player_name) then + pos = air + else + bones_mode = "drop" + end end if bones_mode == "drop" then diff --git a/mods/bones/license.txt b/mods/bones/license.txt new file mode 100644 index 00000000..fe525841 --- /dev/null +++ b/mods/bones/license.txt @@ -0,0 +1,58 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 PilzAdam +Copyright (C) 2012-2016 Various Minetest developers and contributors + +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. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media (textures) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2016 paramat + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + diff --git a/mods/bones/textures/bones_bottom.png b/mods/bones/textures/bones_bottom.png index 859c6bbe243f4f1f7397a95007df53e52432a00b..899ae3b38e8da8b76dc820adef3f455d693f21ee 100644 GIT binary patch delta 256 zcmV+b0ssEw1)KtqB!2;OQb$4nuFf3k00009a7bBm000ie000ie0hKEb8vpK8bmvtF`8__ny8tY3TqLreUUdAw?J9$Ae)Z5(`RBkhY7&Hju z6T0X<{478>698BnB{Qdgu&JKDYTz#=32%|ye(B)Q)_@O54&Yn@3g1`uYFoEl-N21l z9VD_re?~M%VxE1h8q0hNPly8`7k53?bA3f9AjROTO6Lc=aVk`x@+BMq0000Cc~Ebn$ZjPcvs8>O@? z%Opu`+m50rilQV*;y6YK4F&^_<50KTbzRrC?bT{kRezNr2rn-$old7|ngbpH@;uM7 ztlRCjZHp$8N!zvz!$^{Z5aM}$Hk)Nx_WS#bF;3I;kffBdEGvp46NaH>S+B3J$H&LM z?*l+l6oe4NFkIIK06`F@(tD2m(TAJRW0=4;rPkX&RPg5C4>9nPnNqSXI^ee2!#UCWP$wds&v7rU`-| z&vQbE@B8cZdN3GJN*RVRO*0HbLI^_$IrMW~_vz^g049^k0WS!Gq9}xr(P-rRzF`=5 zcXtfW^Xv7R=lM8}P1Bsu=K$b1&h_>6<>jU4c}0gAEX%6v8UWB@v8d}>k|dU8zrMcS y-`^>vs;Y7v=XqWb1e&H5Md3IOrS#vwfByjkgJ0kD14Ksv0000GZx^prw85kJYlDyqrfHV;NblzPLq&N#aB8wRq_>O=u<5X=v zX`mo`iKnkC`yDnJF%C7m8@oX|)_A%&hGq}*pJ^0OQ`TOZQ zTY)CdOI7c4Z_g?25lsAZ_&TRz>cjW>)mDe<1C=K%*%VRwW%ZF`8rr9WCwAV6(ms^B zERJ=7{M8$cjX@uSo24BtaWgM1HQeaI)5v_}tZe6>-X`gMa|aja)t0;7IUAZUdB6U4 z{O9kB&Y3TW_!s z00J*bL_t(2&vjAFO7l<@oW|U8^|orcr6#o2KtqwXl)5Oc1Xtq1XYmbO`7FLh7w%kD zl!BB9Ce^l={t=RTlk_UzA|T&FXEg`r9A?gBuCA_p-}gL^5Px!Zb_Sr|@1LBU^!t6s zaSX$#*Xy3=MNwp$W;UDMisN`PnUqSUY&N@IuU}tZKR-X0%cWAP-EJ=yi&PNDaj{r@ ze}CWF+1b%FjdLEyvFp0?`8*6mDP^rzE0@d9&(B|9U*qxk`}jX}T+iq8j4>g^_V)H)>gjaKIk#=w_kAr0g27;5S=P(T%U=sh zDIvsWvstZHx?vaqX0utE{^sTe!0qkr|2&GKG;}_n*MAm^MYUQT3lueFes(nZZ~7wHl>s?mbN2=NLv#^%w{v&w$q;;92~f=Td&tON@?oPb={|@CjiIC z$GWZq$Z+LyoO4R4Wm!T9(=>a%p2iq^dwXMy`MzH+m%H6A0LO7oPfwf8rssJ8q?FZa zHAxZxTNf7>Ns{dE@9Vn$@$oSn4wX{HVv!KydER_JFO^DCO2=`OQoFmm{{Tux8Owd= R&Q$;a002ovPDHLkV1noBFLeL_ diff --git a/mods/bones/textures/bones_rear.png b/mods/bones/textures/bones_rear.png index 4cfe236d5d6017af2f7879cbc0ba8b1d8434b6e4..bf66d5f38f4ba6c5f27e34c30a8e328c20062bf5 100644 GIT binary patch delta 279 zcmV+y0qFky1hN8?9;)NV9#AK zAiO%mUb+Ipu=-YDGUN^3qUbmK2Df@}$CH&o`P}bzq5J)+{+(`T0R~5es5vsy*b-%w@Rrj%WT_ze0&73+kfru@9%fJU6Le1h?|?6 zEX(@7cU|}V{QN8kg2Un9c^-h5mlpuf&(DmpaU6Z$|NQ)9jOBR_Ac~@*D6C-^2q702 z7vner08o}?p68r%&bd;mX_~64wAM+ID5Z!I#c@2F&CGkTSoD1_r5uLg{rw%l-Q694 zq9_0m$8pNC6n{cYA2{c2+jd=N6aa(}0J^TzT3e^nX*Qb$L9kpd4IYL8fRvI_iho5Z zEsEml>B+jhyc9x6DXXe7tZACMt~Z;_q%O-+YaNE6Qp(a=$8o$^EIvLy4BqeeP1B@l zs+9=j0RVm9_kVrgwk-gwu4~`-<2b&$x-$59 zJW@(s*ZunXGM&|GWtIkDF~+hi3&ZgB_0?c0r5VQP0QkPo7$bxLAZ^>)wmqNEr{D-7 zwr%6T`uX`0LQqQA>$PPptE!4~ZgAVSlu{|>e!riV4uZg>NsQTD*VT3X@bJJnkD}=N z`x^jbY+cGeO;gu(-`?IV$8pj$bsR@2<$2zEy#|mZ$!4>;y}g}m@O|F|N|wvz@9!^T y%=5fF&&}C|VR$?q%d%XpR#6lgCmhF_&*y*LgC-Y8IQO>z0000pYb<$^{^0#KxAe# z=A2`Uy4G1Xe{@w?+5NS}FBv+YhWH`}amsfbJ9^w$1jI;N8Gg?Ok}iVsAsQKS@uVP# z1fH0JwigRekyvOzWP-s}7JUO^-x@~HGDxeO6hVYz&|xdEAJxQa{h zJO5qb%L(ql8wK;U#I^e7P}x^uxfp^tJla>)#~1WO1oY5@zg_+TMw{=pVzo$d00000 LNkvXXu0mjfo-=QU delta 676 zcmV;V0$cr|0=xx~B!3BTNLh0L01FcU01FcV0GgZ_00007bV*G`2jB+@5(O@+yR0k# z00LV{L_t(2&yA5yOY1-wg+X1VQM^-|WI&S1nplBuW~p z5=fea$#*B}qCeo?XL}A02hQI8{e6~YK@fVN8LKA(G@XBfum>1hxI zbzPgLi4fwOruqK<)^!~rR20Sg`+HfIo6UwXc6oUj$MLSvG>xWd>-C!N^?Dq~sjAvE z&1$uZqA1Vvs;Z8Uk1fl3etzz{?(6I8=jW%Ys;a8?Ow$AaN~x-d z4BEDx&1QrU0Ds8y8~}L3FgBZwVHmouzrMbXMx(>SLqQO>+ijYrzrVku(Fh?#2-)A? z2LN7{{r(U6y6nb?f!I-|tgOMNwpoVT?aMKBm(te{^)DC`ytf2%(pk z7sgm!*OXG%b<;FW)09%0Wf{-&!{JaAMS)W4`~G6FfPa5+cXyX0iC`E8{2zIq%d#xQ zactYR>$<`D~f_K z-fp*wqJMN<7e!H7mKftO41M1p4u^~}j^ixLisKk#%+9?D^Yb7G0HCTW+qT=b1pt0J zowjY;@Am~k`275QdwXMyX__XAVh{vT6zRHNRUMV*d5p1xgM&X1!8}!b8Kfit0000< KMNUMnLSTX}$4DIj diff --git a/mods/bones/textures/bones_top.png b/mods/bones/textures/bones_top.png index 198a8a2ddeb5de43a9579e6ba2ed5eff001b3876..08b156db6fdaa56ddb595f57504a9c77bc858dfb 100644 GIT binary patch delta 251 zcmV`E4i0?*-@pg(A-ZY)k?XA{-l4;V-{kL1hwpsn`#67c?SFQAv)M4lG)=p^y90nA z2tc+j)2WmaDJTp>N+|%eS}lz6a5w~jZnv9d z*&rAvO6g!QIO@=9wE#c}!8t!U91fJy%gf7Jtp)(SUa#Bj zDqg44X*QcG#~4RZ@3 z>F@X$7#RQm|Iq68*6Z}H((R16-|+eS?)Lk@;q;@k!T0<9;PU#&$A}5l)dQ2&(fN$y&fr44FCWD0d!JMQvg8b*k%9#00Cl4 zM??UK1szBL000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2jB_}01X&?H1Hq*000e1 jL_t&-(_>&51;_vZ0T2KI?3d$u00000NkvXXu0mjfP|UE8 literal 0 HcmV?d00001 diff --git a/mods/es/biome.lua b/mods/es/biome.lua index 6c705fa6..c6c35d83 100644 --- a/mods/es/biome.lua +++ b/mods/es/biome.lua @@ -772,7 +772,7 @@ end minetest.register_decoration({ deco_type = "schematic", - place_on = {"es:dry_dirt","es:strange_grass","es:strange_clay_brown"}, + place_on = {"es:dry_dirt","es:strange_grass","es:strange_clay_brown","default:dirt_with_dry_grass","default:dirt_with_grass"}, sidelen = 16, noise_params = { offset = -0.0003, @@ -782,7 +782,7 @@ end octaves = 3, persist = 0.66 }, - biomes = {"barren","clay"}, + biomes = {"barren","clay","savanna","sandstone_grassland"}, y_min = 2, y_max = 20, schematic = minetest.get_modpath("es").."/schematics/cabin_old.mts", diff --git a/mods/es/radiation.lua b/mods/es/radiation.lua index 8f1a5fc2..a362cf5c 100644 --- a/mods/es/radiation.lua +++ b/mods/es/radiation.lua @@ -177,6 +177,52 @@ local default_radiation_resistance_per_node = { ["technic:zinc_block"] = 36, ["tnt:tnt"] = 11, ["tnt:tnt_burning"] = 11, + ["es:lag_block"] = 1000, + ["es:lag_ice"] = 1000, + ["es:compressedcobble"] = 23, + ["es:granite"] = 10, + ["es:granite_bricks"] = 14, + ["es:marble"] = 12, + ["es:marble_bricks"] = 15, + ["es:stone_with_emeralds"] = 21, + ["es:stone_with_rubys"] = 22, + ["es:stone_with_aikerums"] = 23, + ["es:stone_with_infiniums"] = 0, + ["es:stone_with_purpelliums"] = 0, + ["es:stone_with_uraniums"] = 0, + ["es:emeraldblock"] = 20, + ["es:rubyblock"] = 30, + ["es:aikerumblock"] = 40, + ["es:infiniumblock"] = 50, + ["es:purpelliumblock"] = 60, + ["es:sand_with_diamond"] = 12, + ["es:boneblock"] = 39, + ["es:hgglass"] = 60, + ["es:hgglass2"] = 60, + ["es:steelblock"] = 60, + ["es:stoneblock"] = 60, + ["es:stonebrick"] = 60, + ["es:junglewood"] = 13, + ["es:messymese"] = 23, + ["es:what"] = 3, + ["es:vault"] = 22, + ["es:aiden_tree"] = 12, + ["es:old_tree"] = 10, + ["es:strange_clay_blue"] = 15, + ["es:strange_clay_red"] = 15, + ["es:strange_clay_maroon"] = 15, + ["es:strange_clay_brown"] = 15, + ["es:strange_clay_orange"] = 15, + ["es:strange_clay_black"] = 15, + ["es:strange_clay_grey"] = 15, + ["es:dry_dirt"] = 8.2, + ["es:desert_stone_with_gold"] = 60, + ["es:desert_stone_with_iron"] = 20, + ["es:desert_stone_with_coal"] = 34, + ["es:mud"] = 5.8, + ["es:mud_flowing"] = 3.8, + ["es:lava_source"] = 17, + ["es:lava_flowing"] = 8.5, } local default_radiation_resistance_per_group = { concrete = 16, diff --git a/mods/es/stair.lua b/mods/es/stair.lua index 6d122d81..083e9fbc 100644 --- a/mods/es/stair.lua +++ b/mods/es/stair.lua @@ -23,28 +23,28 @@ end ]] --TECHNIC STAIRS stairs.register_stair_and_slab("granite", "es:granite", - {cracky = 1}, + {cracky = 1,not_in_craft_guide=1}, {"technic_granite.png"}, "Granite Block Stair", "Granite Block Slab", default.node_sound_stone_defaults()) stairs.register_stair_and_slab("marble", "es:marble", - {cracky = 1}, + {cracky = 1,not_in_craft_guide=1}, {"technic_marble.png"}, "Marble Block Stair", "Marble Block Slab", default.node_sound_stone_defaults()) stairs.register_stair_and_slab("marble_bricks", "es:marble_bricks", - {cracky = 1}, + {cracky = 1,not_in_craft_guide=1}, {"technic_marble_bricks.png" }, "Marble Bricks Block Stair", "Marble Bricks Block Slab", default.node_sound_stone_defaults()) stairs.register_stair_and_slab("granite_bricks", "es:granite_bricks", - {cracky = 1}, + {cracky = 1,not_in_craft_guide=1}, {"technic_granite_bricks.png" }, "Granite Bricks Block Stair", "Granite Bricks Block Slab", @@ -53,42 +53,42 @@ stairs.register_stair_and_slab("granite_bricks", "es:granite_bricks", --Extreme Survival Stairs stairs.register_stair_and_slab("Ruby", "es:rubyblock", - {cracky = 1}, + {cracky = 1,not_in_craft_guide=1}, {"ruby_block.png"}, "Ruby Block Stair", "Ruby Block Slab", default.node_sound_stone_defaults()) stairs.register_stair_and_slab("Emerald", "es:emeraldblock", - {cracky = 1}, + {cracky = 1,not_in_craft_guide=1}, {"emerald_block.png"}, "Emerald Block Stair", "Emerald Block Slab", default.node_sound_stone_defaults()) stairs.register_stair_and_slab("Aikerum", "es:aikerumblock", - {cracky = 1}, + {cracky = 1,not_in_craft_guide=1}, {"aikerum_block.png"}, "Aikerum Block Stair", "Aikerum Block Slab", default.node_sound_stone_defaults()) stairs.register_stair_and_slab("Infinium", "es:infiniumblock", - {cracky = 1}, + {cracky = 1,not_in_craft_guide=1}, {"infinium_block.png"}, "Infinium Block Stair", "Infinium Block Slab", default.node_sound_stone_defaults()) stairs.register_stair_and_slab("Purpellium", "es:purpelliumblock", - {cracky = 1}, + {cracky = 1,not_in_craft_guide=1}, {"purpellium_block.png"}, "Purpellium Block Stair", "Purpellium Block Slab", default.node_sound_stone_defaults()) stairs.register_stair_and_slab("Dirt", "default:dirt", - {cracky = 3, crumbly = 3,}, + {cracky = 3, crumbly = 3,not_in_craft_guide=1}, {"default_dirt.png"}, "Dirt Block Stair", "Dirt Block Slab", diff --git a/mods/nyancat/init.lua b/mods/nyancat/init.lua index 0f1f6908..c8196ab3 100644 --- a/mods/nyancat/init.lua +++ b/mods/nyancat/init.lua @@ -54,7 +54,7 @@ minetest.register_abm({ --Stationary Liquid code minetest.register_node("nyancat:nyancat", { description = "Nyan Cat", - drawtype = "liquid", + --drawtype = "liquid", tiles = {"nyancat_side.png", "nyancat_side.png", "nyancat_side.png", "nyancat_side.png", "nyancat_back.png", "nyancat_front.png"}, @@ -69,23 +69,23 @@ minetest.register_node("nyancat:nyancat", { --climbable = true, is_ground_content = false, drop = "nyancat:nyancat", - drowning = 0, - liquidtype = "", - liquid_alternative_flowing = "nyancat:nyancat", - liquid_alternative_source = "nyancat:nyancat", - liquid_viscosity = 15, + --drowning = 0, + --liquidtype = "", + --liquid_alternative_flowing = "nyancat:nyancat", + --liquid_alternative_source = "nyancat:nyancat", + --liquid_viscosity = 15, post_effect_color = {a = 244, r = 190, g = 20, b = 70}, groups = {cracky = 2}, is_ground_content = false, legacy_facedir_simple = true, - iquid_renewable = false, - liquid_range = 0, + --iquid_renewable = false, + --liquid_range = 0, sounds = default.node_sound_glass_defaults(), }) minetest.register_node("nyancat:nyancat_rainbow", { description = "Nyan Cat Rainbow", - drawtype = "liquid", + --drawtype = "liquid", tiles = { "nyancat_rainbow.png^[transformR90", "nyancat_rainbow.png^[transformR90", @@ -106,17 +106,17 @@ minetest.register_node("nyancat:nyancat_rainbow", { --climbable = true, is_ground_content = false, drop = "nyancat:nyancat_rainbow", - drowning = 0, - liquidtype = "", - liquid_alternative_flowing = "nyancat:nyancat_rainbow", - liquid_alternative_source = "nyancat:nyancat_rainbow", - liquid_viscosity = 15, + --drowning = 0, + --liquidtype = "", + --liquid_alternative_flowing = "nyancat:nyancat_rainbow", + --liquid_alternative_source = "nyancat:nyancat_rainbow", + --liquid_viscosity = 15, post_effect_color = {a = 244, r = 190, g = 20, b = 70}, groups = {cracky = 2}, is_ground_content = false, legacy_facedir_simple = true, - iquid_renewable = false, - liquid_range = 0, + --liquid_renewable = false, + --liquid_range = 0, sounds = default.node_sound_glass_defaults(), }) diff --git a/mods/stairs/init.lua b/mods/stairs/init.lua index 7e256d60..65d4815c 100644 --- a/mods/stairs/init.lua +++ b/mods/stairs/init.lua @@ -345,61 +345,61 @@ local grp = {} --= Default Minetest stairs.register_all("tree", "default:tree", - {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3 ,not_in_craft_guide=1}, {"default_tree_top.png"}, "Wooden", stairs.wood) stairs.register_all("wood", "default:wood", - {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3,not_in_craft_guide=1}, {"default_wood.png"}, "Wooden", stairs.wood) stairs.register_all("jungletree", "default:jungletree", - {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3,not_in_craft_guide=1}, {"default_jungletree_top.png"}, "Wooden", stairs.wood) stairs.register_all("junglewood", "default:junglewood", - {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3,not_in_craft_guide=1}, {"default_junglewood.png"}, "Jungle Wood", stairs.wood) stairs.register_all("pine_tree", "default:pine_tree", - {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3,not_in_craft_guide=1}, {"default_pine_tree_top.png"}, "Wooden", stairs.wood) stairs.register_all("pine_wood", "default:pinewood", - {choppy = 2, oddly_breakable_by_hand = 1, flammable = 3}, + {choppy = 2, oddly_breakable_by_hand = 1, flammable = 3,not_in_craft_guide=1}, {"default_pine_wood.png"}, "Pine Wood", stairs.wood) stairs.register_all("acacia_tree", "default:acacia_tree", - {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3,not_in_craft_guide=1}, {"default_acacia_tree_top.png"}, "Wooden", stairs.wood) stairs.register_all("acacia_wood", "default:acacia_wood", - {choppy = 2, oddly_breakable_by_hand = 1, flammable = 3}, + {choppy = 2, oddly_breakable_by_hand = 1, flammable = 3,not_in_craft_guide=1}, {"default_acacia_wood.png"}, "Acacia Wood", stairs.wood) stairs.register_all("aspen_tree", "default:aspen_tree", - {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3,not_in_craft_guide=1}, {"default_aspen_tree_top.png"}, "Wooden", stairs.wood) stairs.register_all("aspen_wood", "default:aspen_wood", - {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3,not_in_craft_guide=1}, {"default_aspen_wood.png"}, "Aspen Wood", stairs.wood) @@ -411,13 +411,13 @@ stairs.register_all("cobble", "default:cobble", stairs.stone) stairs.register_all("desert_cobble", "default:desert_cobble", - {cracky = 3}, + {cracky = 3,not_in_craft_guide=1}, {"default_desert_cobble.png"}, "Desert Cobble", stairs.stone) stairs.register_stair("cloud", "default:cloud", - {unbreakable = 1}, + {unbreakable = 1,not_in_craft_guide=1}, {"default_cloud.png"}, "Cloud Stair", stairs.wool) @@ -437,92 +437,104 @@ minetest.override_item("stairs:slab_cloud", { }) ]] stairs.register_all("coal", "default:coalblock", - {cracky = 3}, + {cracky = 3,not_in_craft_guide=1}, {"default_coal_block.png"}, "Coal", stairs.stone) stairs.register_all("steelblock", "default:steelblock", - {cracky = 1, level = 2}, + {cracky = 1, level = 2,not_in_craft_guide=1}, {"default_steel_block.png"}, "Steel", stairs.stone) stairs.register_all("copperblock", "default:copperblock", - {cracky = 1, level = 2}, + {cracky = 1, level = 2,not_in_craft_guide=1}, {"default_copper_block.png"}, "Copper", stairs.stone) stairs.register_all("bronzeblock", "default:bronzeblock", - {cracky = 1, level = 2}, + {cracky = 1, level = 2,not_in_craft_guide=1}, {"default_bronze_block.png"}, "Bronze", stairs.stone) stairs.register_all("mese", "default:mese", - {cracky = 1, level = 2}, + {cracky = 1, level = 2,not_in_craft_guide=1}, {"default_mese_block.png"}, "Mese", stairs.stone) stairs.register_all("goldblock", "default:goldblock", - {cracky = 1}, + {cracky = 1,not_in_craft_guide=1}, {"default_gold_block.png"}, "Gold", stairs.stone) stairs.register_all("diamondblock", "default:diamondblock", - {cracky = 1, level = 3}, + {cracky = 1, level = 3,not_in_craft_guide=1}, {"default_diamond_block.png"}, "Diamond", stairs.stone) stairs.register_all("stone", "default:stone", - {cracky=3,stone=1, }, + {cracky=3,stone=1, not_in_craft_guide=1}, {"default_stone.png"}, "Stone", stairs.stone) stairs.register_all("desert_stone", "default:desert_stone", - {cracky = 3}, + {cracky = 3,not_in_craft_guide=1}, {"default_desert_stone.png"}, "Desert Stone", stairs.stone) stairs.register_all("mossycobble", "default:mossycobble", - {cracky = 3}, + {cracky = 3,not_in_craft_guide=1}, {"default_mossycobble.png"}, "Mossy Cobble", stairs.stone) stairs.register_all("brick", "default:brick", - {cracky = 3}, + {cracky = 3,not_in_craft_guide=1}, {"default_brick.png"}, "Brick", stairs.stone) +stairs.register_all("clay", "default:clay", + {crumbly = 3,not_in_craft_guide=1}, + {"default_clay.png"}, + "Clay", + stairs.dirt) + +stairs.register_all("dirt", "default:dirt", + {crumbly = 3,not_in_craft_guide=1}, + {"default_dirt.png"}, + "Dirt", + stairs.dirt) + stairs.register_all("sandstone", "default:sandstone", - {crumbly = 1, cracky = 3}, + {crumbly = 1, cracky = 3,not_in_craft_guide=1}, {"default_sandstone.png"}, "Sandstone", stairs.stone) stairs.register_all("glass", "default:glass", - {cracky = 3, oddly_breakable_by_hand = 3}, + {cracky = 3, oddly_breakable_by_hand = 3,not_in_craft_guide=1}, {"default_glass.png"}, "Glass", stairs.glass) stairs.register_all("obsidian_glass", "default:obsidian_glass", - {cracky = 2}, + {cracky = 2,not_in_craft_guide=1}, {"default_obsidian_glass.png"}, "Obsidian Glass", stairs.glass) --function stairs.register_all(subname, recipeitem, groups, images, desc, snds, alpha,light) stairs.register_all("meselamp", "default:meselamp", - {cracky = 3, oddly_breakable_by_hand = 3}, + {cracky = 3, oddly_breakable_by_hand = 3,not_in_craft_guide=1}, {"default_meselamp.png"}, "Meselamp", stairs.glass, @@ -531,31 +543,31 @@ stairs.register_all("meselamp", "default:meselamp", ) stairs.register_all("sandstonebrick", "default:sandstonebrick", - {cracky = 2}, + {cracky = 2,not_in_craft_guide=1}, {"default_sandstone_brick.png"}, "Sandstone Brick", stairs.stone) stairs.register_all("obsidian", "default:obsidian", - {cracky = 1, level = 2}, + {cracky = 1, level = 2,not_in_craft_guide=1}, {"default_obsidian.png"}, "Obsidian", stairs.stone) stairs.register_all("stonebrick", "default:stonebrick", - {cracky = 2}, + {cracky = 2,not_in_craft_guide=1}, {"default_stone_brick.png"}, "Stone Brick", stairs.stone) stairs.register_all("desert_stonebrick", "default:desert_stonebrick", - {cracky = 3}, + {cracky = 3,not_in_craft_guide=1}, {"default_desert_stone_brick.png"}, "Desert Stone Brick", stairs.stone) stairs.register_all("obsidianbrick", "default:obsidianbrick", - {cracky = 1, level = 3}, + {cracky = 1, level = 3,not_in_craft_guide=1}, {"default_obsidian_brick.png"}, "Obsidian Brick", stairs.stone) @@ -586,13 +598,13 @@ for i = 1, #colours, 1 do -- wood stair stairs.register_all(colours[i][1] .. "_wood", "cblocks:wood_" .. colours[i][1], - {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3,not_in_craft_guide=1}, {"default_wood.png^[colorize:" .. colours[i][3]}, colours[i][2] .. " Wooden", stairs.wood) stairs.register_all(colours[i][1] .. "_glass", "cblocks:glass_" .. colours[i][1], - {cracky = 3, oddly_breakable_by_hand = 3}, + {cracky = 3, oddly_breakable_by_hand = 3,not_in_craft_guide=1}, {"cblocks.png^[colorize:" .. colours[i][3]}, colours[i][2] .. " Glass", stairs.glass, true) @@ -630,7 +642,7 @@ end if minetest.get_modpath("farming") then stairs.register_all("straw", "farming:straw", - {snappy = 3, flammable = 4}, + {snappy = 3, flammable = 4,not_in_craft_guide=1}, {"farming_straw.png"}, "Straw", stairs.leaves) @@ -641,7 +653,7 @@ end if mobs and mobs.mod and mobs.mod == "redo" then -grp = {crumbly = 3, flammable = 2} +grp = {crumbly = 3, flammable = 2,not_in_craft_guide=1} stairs.register_all("cheeseblock", "mobs:cheeseblock", grp, @@ -877,7 +889,7 @@ if minetest.get_modpath("wool") then for i = 1, #colours, 1 do stairs.register_all("wool_" .. colours[i][1], "wool:" .. colours[i][1], - {snappy = 2, choppy = 2, oddly_breakable_by_hand = 3, flammable = 3}, + {snappy = 2, choppy = 2, oddly_breakable_by_hand = 3, flammable = 3,not_in_craft_guide=1}, {"wool_" .. colours[i][1] .. ".png"}, colours[i][2] .. " Wool", stairs.stone) @@ -890,7 +902,7 @@ end if minetest.get_modpath("es") then -grp = {cracky = 3} +grp = {cracky = 3,not_in_craft_guide=1} --Technic marble / Granite stairs.register_all("granite", "es:granite", @@ -949,19 +961,19 @@ stairs.register_all("purpellium", "es:purpelliumblock", stairs.stone) stairs.register_all("dirt", "default:dirt", - {crumbly = 2,oddly_breakable_by_hand=1}, + {crumbly = 2,oddly_breakable_by_hand=1,not_in_craft_guide=1}, {"default_dirt.png"}, "Dirt Block", stairs.stone) stairs.register_all("boneblock", "es:boneblock", - {crumbly = 2,oddly_breakable_by_hand=1}, + {crumbly = 2,oddly_breakable_by_hand=1,not_in_craft_guide=1}, {"bones_front.png"}, "Bone Block", stairs.stone) stairs.register_all("messymese", "es:messymese", - {crumbly = 2,oddly_breakable_by_hand=1}, + {crumbly = 2,oddly_breakable_by_hand=1,not_in_craft_guide=1}, {"default_clay.png^bubble.png^mese_cook_mese_crystal.png"}, "messymese", stairs.stone) @@ -970,7 +982,7 @@ end if minetest.get_modpath("quartz") then -grp = {cracky=3, oddly_breakable_by_hand=1} +grp = {cracky=3, oddly_breakable_by_hand=1,not_in_craft_guide=1} --Quartz stairs.register_all("quartzblock", "quartz:block", diff --git a/mods/tnt/textures/tnt_blast.png b/mods/tnt/textures/tnt_blast.png deleted file mode 100644 index bbb1096f5d81f68b0247f1bd386357f1c14c2579..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 855 zcmV-d1E~CoP)o&74tn0wNWtEkm#^jZ>SJP!74EEBU-F0SihuX3Ls`c>`{pYM;V{Pz0=Ql$KI zE%7{$!T1g-raXT7f}f5uUcEjC;P5cS7b}D@hO3*5uwod^oqJMMX4tk(Q4}cSVbTe2 zFC(OsoSuYet(im{?9=a>+^$^SfB1kD|FYXYA_x|I)2i`#D(IiI$wiI9a7ef5a2Z9s zxlp`(9x{z3Vl)HWEbd8mF~@aXF0Z%qt#hB&QdCxkQ_ zlOzdOHyQojmR`0J9yJVFYwR>l8IBX;IA$-%c>MGQCY>-C4*6^hLI~;%u`HK&S1a;l z%AN7JU2e}O@;oO}4pO9i8Y?>WjM+-iZ8``ca9x+BaNR;#h&s;xo4 z7w}FsING;)_4*tsC6`e|w;k}H?vt1*A3x5xT}(Oq@foAJ!|45=DB~fzO^3ff#Rwr7 z{TBi7?4XR4lIy#SNwh(0&FM*ql#;iX5hk6Wj7L!v*roDATCIdM8nRRYhle4PwdUpX z5XBC09McFk{PEWplu|tTHsI3;}TUTrW0;A2k5r9 heHdfdt!UP{&;J-adc&TrL81Tv002ovPDHLkV1k_AI z5d?s8T8>pFTW!Da>12)bUc@n5uNExh*x0M0qynWPImXH`N7;N;HQ*uxy*GYaOH50(eT4ZNIz z8W(&pv6=XgAlNUn7;#?a|>qPN1CcPuTiHA-%`+rA)s z@__b6s~&YF7epKwrqMJ4=gZ@}`T*l-tfG+w=riy4^FZc-b1t!FafK(gZJW(H{*D!Q zUH1s_rfF!NXG|mT@oDk>^@HnN2jzs2x7LEUj2a*ZZM3&VlUR-TW2tg%sH4n4`yQ@FY zs&WzwT;AKZrNiNnEb!h_-}lLXv1`)^O3HX#3o|W_w1gl{)-qB{X}%4Ux&IfCh;Q?p zXR7*xKjFdd{y^r!W*%tayom=<8@NyY>K_cFVmN3U7rx4>T9#Q>dyQ#4w2y ytExYc4=k~0od=SUn|bh7e-OW&-r~VpfA9;n;PF(;jD(y30000J!^tCfh^ z`rlh?+3WS%IT(+}&2#VUQFu^3>rfsnb0}jBCzA<)4`{9V`TliTvE6R}@IYGnE<6aX zQ2DsbgJ5x)2Uo+bx>@qJ))D}cBx&v>j^p+nDfzeNfp_3wFz9&jJQhV!<$mxIS`UZA zLCK&!olZrksyfj!hx*}xsw(H#w=}Gjy#u2tDtIuP&BFV`7*mY*|F|E-aZHKiCZKd} z^z{2dqxXXFAW4$z6Z*XVWlqYd%k%ttk)7`cz%L&j;JqNB-h~G@wKGt^AG`!O!SQ&! ai2rZc8DC!3*65S~0000P{(@P~opePCsLL^z=i4(nHq{rv- z;wg8w&5zgbupSuOxvDA_BjAe0b@^aSN6ZJJKG5-j#8DU@%qLOgKodIqIN&n}jFGU7 zKdz?_L>=g(4~#V!h5^CLMITsU?7GgmAGG=)gq5B3fhh$7fUox-r%OoN1FP|Y7zHBY z&$n(FzWXpSGns1RHO}>M1wIfB*7B|3Wjxmhw|_5$sP*voLXbuRfH;o1ZNOQU$%=S; zJ~*9D7x^HvU8;TG(_HSrWx90DbRH=3<^zrK`ugA(1j$ky!mGjH00000NkvXXu0mjf D@G;Vr diff --git a/mods/tnt/textures/tnt_gunpowder_burning_t_junction_animated.png b/mods/tnt/textures/tnt_gunpowder_burning_t_junction_animated.png deleted file mode 100644 index a556072c01baa3ad0c0dce4719974cbac8fc7063..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 672 zcmV;R0$=@!P)DbJt>;JPk}2=WZ%IF1@no`I4ip*(|r z6vEjw%@SZd9ybFMp>xg!k)+IlAn{lVwYMW2Ju2IikVHInjhl7r1=W9%Z?vqL>#HTjo~BYrQJOGBv+<_lid!?6R}GUwz)3qL;>h_BdQ zL~q`u0Dd5jW4RvOTo=`f+~Z@u;HZAr)&rx40urYlav-c-cLUE~yXg1($g^Lx10m_b zRXq^XNemgSat_1ryvYOrzVGXSG?|MGXIc|U(*tl_mnz-(czPhUPN#F3{XnLTCplp3 z!6)Nb#hwKC^8WXIv$XHq#j>n2nlw%6=DI)}$0SX`aU9As&}cNOD)V7#&GkT3rt*HE ze2psm0Xybg6ooNgaD4ytSJVS~y)eh>tK)bT%^-`Qouqhc5U0000eyp|f0$G^M#AJ-Xhs78PfcVE!N`?GdKstPm;I+{% z=6NOnarXzgU_Q;=d6|D$g9H5QqV^K61`{CwU$~g{;Ai7vbC5*0tErzOrEm00000NkvXXu0mjfvjA$o diff --git a/mods/tnt/textures/tnt_gunpowder_curved.png b/mods/tnt/textures/tnt_gunpowder_curved.png deleted file mode 100644 index cb8b4eacff8135621086125e0034f0f01de77f86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 268 zcmV+n0rUQeP)cU|G%*jJ0%Df7Vnzdt##MgCUU01|$jA@!smL=#_t(20T za|pu_%d)_Gk2FmYMG>TwnCF>(yxkbXT5BH1k=wRq04R!r-+H`h8dgfN)|%_O=8sml z)-nN7~!b)01xe-HUk;uT=ucLYIzBuVfq01@FlPaMbbbnP!1b3Q(f Sv?!tg0000ZBLLe6pzW?KSQTTe%Qf!UJ4umWuVJDjnMCiIsfMR=GY_TlMJ=9@- zW0CW}GTSYKq9_EI_x^6OZ@l-4m|U}2e2!#P*R=pm)AY-v9WZ&ekM&kuA^2G&|a z2){?BMF7`DkaOnweBzwrd_GfEm3r^VIkQ@=*zI<#*K4(XHma&ZL`W&oGz~dtZnqnk z%Y~E@`~AK@hxvT2fG(FyO)05}=yto+qA0Z0R|~W&gWlmMpvU7ujFA{4MNx1(9?hH7 zbY4M3^m@G-fEXjzTD2xyp`<>ZrHoVR$C0#5Q ay^Ak!rCtr@ct0-y0000= share_bones_time then - - meta:set_string("infotext", meta:get_string("owner").."'s old bones (died ".. meta:get_string("date") .."), xp " ..math.floor(meta:get_float("xp")*100)/100); - meta:set_string("owner", "") - - else - if meta:get_int("active") == 0 then -- store data in bones, 1x - meta:set_int("active",1); - local owner = meta:get_string("owner"); - meta:set_string("date",os.date("%x")); - meta:set_string("owner_orig",owner); - meta:set_string("ip", tostring(minetest.get_player_ip(owner))); - if not minetest.get_player_by_name(owner) then -- mob bones - boneworld.xp[owner] = 0.5 -- 1/2th of noob player xp in mobs bone - time=0.5*share_bones_time; -- 2x shorter old bone time - else - boneworld.xp[owner] = boneworld.xp[owner] or 1; - end - - if boneworld.xp[owner]==1 then - meta:set_float("xp", 0.1) - else - meta:set_float("xp", boneworld.xp[owner]*1.25*0.1); -- xp stored in bones - end - - boneworld.wastedxp = boneworld.wastedxp + meta:get_float("xp"); - meta:set_string("infotext"," Here lies " .. owner .. ", bone xp " .. math.floor(meta:get_float("xp")*100)/100); - end - meta:set_int("time", time) - return true - end -end - -local on_punch = function(pos, node, player) - if(not is_owner(pos, player:get_player_name())) then - return - end - - if(minetest.get_meta(pos):get_string("infotext") == "") then - return - end - - local inv = minetest.get_meta(pos):get_inventory() - local player_inv = player:get_inventory() - local has_space = true - - for i=1,inv:get_size("main") do - local stk = inv:get_stack("main", i) - if player_inv:room_for_item("main", stk) then - inv:set_stack("main", i, nil) - player_inv:add_item("main", stk) - else - has_space = false - break - end - end - - -- remove bones if player emptied them - if has_space then - local meta = minetest.get_meta(pos); - local active = meta:get_int("active") == 1; - local puncher = player:get_player_name(); - - -- award extra bones if you collect bones from different ip player - --debug - if active and meta:get_string("ip")~= tostring(minetest.get_player_ip(puncher)) then - - -- average of owners xp (at time of death) and puncher xp will be awarded as extra bones - -- with every 10 more xp one bone - local count = 1+0.2*(10*meta:get_float("xp")+boneworld.xp[puncher])/2.0; - count = math.floor(count); - minetest.chat_send_player(puncher, "you find " .. count .. " bones in the corpse."); - - if player_inv:room_for_item("main", ItemStack("bones:bones "..count)) then - player_inv:add_item("main", ItemStack("bones:bones "..count)) - else - minetest.add_item(pos,ItemStack("bones:bones "..count)) - end - end - - -- add xp from bones to player who retrieved bones; - - boneworld.xp[puncher] = boneworld.xp[puncher] + meta:get_float("xp"); - boneworld.wastedxp = boneworld.wastedxp - meta:get_float("xp"); - minetest.remove_node(pos) - end -end - --- award xp to killer --- minetest.register_on_punchplayer( - -- function(player, hitter, time_from_last_punch, tool_capabilities, dir, damage) - -- local hp = player:get_hp(); - - -- if hp>0 and hp-damage<=0 then -- hitter killed player - -- local pname = player:get_player_name(); - -- if not hitter:is_player() then return end - -- local hname = hitter:get_player_name(); - - - --award xp if you kill different ip player, 10% of his xp - - -- if tostring(minetest.get_player_ip(pname))~=tostring(minetest.get_player_ip(hname)) then - -- local pxp = boneworld.xp[pname]; - -- local addxp =pxp*0.1; - -- boneworld.xp[hname] = boneworld.xp[hname] + addxp; - -- boneworld.killxp[hname] = boneworld.killxp[hname] + addxp; - --minetest.chat_send_player(hname, "#You killed " .. pname .. ". As a reward you get ".. math.floor(addxp*100)/100 .. " experience."); - -- end - -- end - -- end --- ) - --- 20% of xp is lost upon death -minetest.register_on_dieplayer( - function(player) - local name = player:get_player_name(); - local xp = boneworld.xp[name] or 1; - local newxp = xp*0.8; - if newxp<1 then newxp = 1 end - local lossxp = xp - newxp; - - --minetest.chat_send_player(name, "#You lost ".. math.floor(lossxp*100)/100 .. " experience. Retrieve your bones to get 50% of lost experience back "); - boneworld.xp[name] = newxp; - end -) - - --- load xp -minetest.register_on_joinplayer( - function(player) - local name = player:get_player_name(); - if not boneworld.xp[name] then -- load xp - local filename = worldpath .. "\\boneworld\\" .. name..".xp"; - local f = io.open(filename, "r"); - if not f then -- file does not yet exist - boneworld.xp[name] = 1; - --boneworld.killxp[name] = 0; - return - end - local str = f:read("*a") or 1; - local words = {}; - for w in str:gmatch("%S+") do words[#words+1]=w end - boneworld.xp[name] = tonumber(words[1] or 1); - --boneworld.killxp[name] = tonumber(words[2] or 0); - f:close(); - end - end -) - --- save xp -minetest.register_on_leaveplayer( - function(player) - local name = player:get_player_name(); - local xp = boneworld.xp[name] or 1; - --debug - if xp > 1.5 then -- save xp for serious players only -- must have collected bones/killed at least 5 noobs - local filename = worldpath .. "\\boneworld\\" .. name..".xp"; - - local f = io.open(filename, "w"); - if not f then return end - f:write(xp);-- .. " " .. boneworld.killxp[name]); - f:close(); - else - -- dont save, player didnt do anything - end - end - -) - - -local tweak_bones = function() - local name = "bones:bones"; - local table = minetest.registered_nodes[name]; - table.on_punch = on_punch; - table.on_timer = on_timer; - minetest.register_node(":"..name, table); -end - -minetest.after(0,tweak_bones); - -minetest.register_chatcommand("xp", { - description = "xp name - show bone collecting experience of target player", - privs = { - interact = true - }, - func = function(name, param) - - if param == "" then - local xp = math.floor((boneworld.xp[name])*100)/100; - --local killxp = math.floor((boneworld.killxp[name])*100)/100; - msg = "xp name - show bone collecting experience of target player" - .."\n# "..name .. " has " .. xp .. " experience" - .. "\nTotal bone xp ( stored in bones ) " .. math.floor(boneworld.wastedxp*100)/100; - else - local xp = math.floor((boneworld.xp[param] or 1)*100)/100; - --local killxp = math.floor((boneworld.killxp[param])*100)/100; - msg = "# "..param .. " has " .. xp .. " experience" - end - minetest.chat_send_player(name, msg); - end -}); \ No newline at end of file diff --git a/mods/z_extra_mods/cblocks/init.lua b/mods/z_extra_mods/cblocks/init.lua index 126cc681..6697555a 100644 --- a/mods/z_extra_mods/cblocks/init.lua +++ b/mods/z_extra_mods/cblocks/init.lua @@ -29,7 +29,7 @@ minetest.register_node("cblocks:wood_" .. colours[i][1], { description = colours[i][2] .. " Wooden Planks", tiles = {"default_wood.png^[colorize:" .. colours[i][3]}, is_ground_content = false, - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, wood = 1,not_in_craft_guide=1}, sounds = default.node_sound_wood_defaults(), }) @@ -46,7 +46,7 @@ minetest.register_node("cblocks:stonebrick_" .. colours[i][1], { description = colours[i][2] .. " Stone Brick", tiles = {"default_stone_brick.png^[colorize:" .. colours[i][3]}, is_ground_content = false, - groups = {cracky = 2, stone = 1}, + groups = {cracky = 2, stone = 1,not_in_craft_guide=1}, sounds = default.node_sound_stone_defaults(), }) @@ -67,7 +67,7 @@ minetest.register_node( "cblocks:glass_" .. colours[i][1], { sunlight_propagates = true, use_texture_alpha = true, is_ground_content = false, - groups = {cracky = 3, oddly_breakable_by_hand = 3}, + groups = {cracky = 3, oddly_breakable_by_hand = 3,not_in_craft_guide=1}, sounds = default.node_sound_glass_defaults(), }) @@ -83,7 +83,7 @@ minetest.register_node( "cblocks:clay_" .. colours[i][1], { description = colours[i][2] .. " Clay", tiles = {"default_clay.png^[colorize:" .. colours[i][3]}, is_ground_content = false, - groups = {crumbly = 2, oddly_breakable_by_hand = 2}, + groups = {crumbly = 2, oddly_breakable_by_hand = 2,not_in_craft_guide=1}, sounds = default.node_sound_stone_defaults(), }) @@ -99,7 +99,7 @@ minetest.register_craft({ --wood stairs.register_stair_and_slab("wood_" .. colours[i][1], "cblocks:wood_" .. colours[i][1], - {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3,not_in_craft_guide=1}, {"default_wood.png^[colorize:" .. colours[i][3]}, "Wooden Stair", "Wooden Slab", @@ -108,7 +108,7 @@ stairs.register_stair_and_slab("wood_" .. colours[i][1], "cblocks:wood_" .. colo --stonebrick stairs.register_stair_and_slab("stonebrick_" .. colours[i][1], "cblocks:stonebrick_" .. colours[i][1], - {cracky = 3}, + {cracky = 3,not_in_craft_guide=1}, {"default_stone_brick.png^[colorize:" .. colours[i][3]}, "Stone Brick Stair", "Stone Brick Slab", diff --git a/mods/z_extra_mods/mobs_animal/bunny.lua b/mods/z_extra_mods/mobs_animal/bunny.lua index 95702ca3..ea2ad2f7 100644 --- a/mods/z_extra_mods/mobs_animal/bunny.lua +++ b/mods/z_extra_mods/mobs_animal/bunny.lua @@ -80,8 +80,8 @@ mobs:register_mob("mobs_animal:bunny", { damage = 5, }) ---mobs:register_spawn("mobs_animal:bunny", --- {"default:dirt_with_grass", "ethereal:prairie_dirt"}, 20, 10, 15000, 2, 31000, true) +mobs:register_spawn("mobs_animal:bunny", + {"default:dirt_with_grass", "ethereal:prairie_dirt"}, 20, 10, 15000, 2, 31000, true) mobs:register_egg("mobs_animal:bunny", S("Bunny"), "mobs_bunny_inv.png", 0) diff --git a/mods/z_extra_mods/mobs_animal/chicken.lua b/mods/z_extra_mods/mobs_animal/chicken.lua index 0f429ede..d6697efd 100644 --- a/mods/z_extra_mods/mobs_animal/chicken.lua +++ b/mods/z_extra_mods/mobs_animal/chicken.lua @@ -79,7 +79,7 @@ mobs:register_mob("mobs_animal:chicken", { }) mobs:register_spawn("mobs_animal:chicken", - {"default:dirt_with_grass", "ethereal:bamboo_dirt"}, 20, 10, 15000, 1, 31000, true) + {"default:dirt_with_grass", "ethereal:bamboo_dirt"}, 20, 10, 10000, 3, 31000, true) mobs:register_egg("mobs_animal:chicken", S("Chicken"), "mobs_chicken_inv.png", 0) diff --git a/mods/z_extra_mods/mobs_animal/cow.lua b/mods/z_extra_mods/mobs_animal/cow.lua index 72b3e447..540fc594 100644 --- a/mods/z_extra_mods/mobs_animal/cow.lua +++ b/mods/z_extra_mods/mobs_animal/cow.lua @@ -96,7 +96,7 @@ mobs:register_mob("mobs_animal:cow", { }) mobs:register_spawn("mobs_animal:cow", - {"default:dirt_with_grass", "ethereal:green_dirt"}, 20, 10, 15000, 1, 31000, true) + {"default:dirt_with_grass", "ethereal:green_dirt"}, 20, 10, 10000, 2, 31000, true) mobs:register_egg("mobs_animal:cow", S("Cow"), "default_grass.png", 1) diff --git a/mods/z_extra_mods/mobs_animal/sheep.lua b/mods/z_extra_mods/mobs_animal/sheep.lua index 37b91578..58b26c05 100644 --- a/mods/z_extra_mods/mobs_animal/sheep.lua +++ b/mods/z_extra_mods/mobs_animal/sheep.lua @@ -178,7 +178,7 @@ for _, col in pairs(all_colours) do end mobs:register_spawn("mobs_animal:sheep_white", - {"default:dirt_with_grass", "ethereal:green_dirt"}, 20, 10, 15000, 1, 31000, true) + {"default:dirt_with_grass", "ethereal:green_dirt"}, 20, 10, 10000, 2, 31000, true) -- compatibility diff --git a/mods/z_extra_mods/mobs_animal/warthog.lua b/mods/z_extra_mods/mobs_animal/warthog.lua index 68f0d4ce..4c9227b3 100644 --- a/mods/z_extra_mods/mobs_animal/warthog.lua +++ b/mods/z_extra_mods/mobs_animal/warthog.lua @@ -55,8 +55,8 @@ mobs:register_mob("mobs_animal:pumba", { end, }) ---mobs:register_spawn("mobs_animal:pumba", --- {"ethereal:mushroom_dirt", "default:dirt_with_dry_grass"}, 20, 10, 15000, 1, 31000, true) +mobs:register_spawn("mobs_animal:pumba", + {"ethereal:mushroom_dirt", "default:dirt_with_dry_grass"}, 20, 10, 10000, 1, 31000, true) mobs:register_egg("mobs_animal:pumba", S("Warthog"), "wool_pink.png", 1) diff --git a/mods/z_remove/cottages/nodes_historic.lua b/mods/z_remove/cottages/nodes_historic.lua index 8594d828..0577a370 100644 --- a/mods/z_remove/cottages/nodes_historic.lua +++ b/mods/z_remove/cottages/nodes_historic.lua @@ -58,14 +58,14 @@ minetest.register_node("cottages:loam", { -- create stairs if possible if( minetest.get_modpath("stairs") and stairs and stairs.register_stair_and_slab) then stairs.register_stair_and_slab("feldweg", "cottages:feldweg", - {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_craft_guide=1}, {"cottages_feldweg.png","default_dirt.png", "default_grass.png","default_grass.png","cottages_feldweg.png","cottages_feldweg.png"}, S("Dirt Road Stairs"), S("Dirt Road, half height"), default.node_sound_dirt_defaults()) stairs.register_stair_and_slab("loam", "cottages:loam", - {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_craft_guide=1}, {"default_sandstone.png"}, S("Loam Stairs"), S("Loam Slab"), @@ -73,7 +73,7 @@ if( minetest.get_modpath("stairs") and stairs and stairs.register_stair_and_slab if( minetest.registered_nodes["default:clay"]) then stairs.register_stair_and_slab("clay", "default:clay", - {crumbly=3}, + {crumbly=3,not_in_craft_guide=1}, {"default_clay.png"}, S("Clay Stairs"), S("Clay Slab"), diff --git a/mods/z_remove/games/checkers.lua b/mods/z_remove/games/checkers.lua new file mode 100644 index 00000000..65a5a298 --- /dev/null +++ b/mods/z_remove/games/checkers.lua @@ -0,0 +1,213 @@ +-- CHECKERS GAME + +local checkers ={}; +checkers.piece = "";checkers.time = 0; +checkers.pos = {} -- bottom left position of 8x8 checkerboard piece +checkers.piece_pos = {} -- position of pick up piece + +--game pieces + +local function draw_board() -- pos is bottom left position of checkerboard + + local pos = checkers.pos; + if pos == nil then return end + local node; + for i = 1,8 do + for j =1,8 do + node = minetest.get_node({x=pos.x+i-1,y=pos.y,z=pos.z-1}).name; + if (i+j) % 2 == 1 then + if node~="games:board_black" then minetest.set_node({x=pos.x+i-1,y=pos.y,z=pos.z+j-1},{name = "games:board_black"}) end + else + if node~="games:board_white" then minetest.set_node({x=pos.x+i-1,y=pos.y,z=pos.z+j-1},{name = "games:board_white"}) end + end + node = minetest.get_node({x=pos.x+i-1,y=pos.y+1,z=pos.z+j-1}).name; + if node~="air" then minetest.set_node({x=pos.x+i-1,y=pos.y+1,z=pos.z+j-1},{name = "air"}) end + end + end + + for i = 1,4 do -- place pieces + minetest.set_node({x=pos.x+2*i-1,y=pos.y+1,z=pos.z},{name = "games:checkers_red"}) + minetest.set_node({x=pos.x+2*i-2,y=pos.y+1,z=pos.z+1},{name = "games:checkers_red"}) + + minetest.set_node({x=pos.x+2*i-1,y=pos.y+1,z=pos.z+6},{name = "games:checkers_blue"}) + minetest.set_node({x=pos.x+2*i-2,y=pos.y+1,z=pos.z+7},{name = "games:checkers_blue"}) + end + + for i = 1,8 do -- place kings + node = minetest.get_node({x=pos.x+i-1,y=pos.y+1,z=pos.z-2}).name; + if node~="games:checkers_red_queen" then minetest.set_node({x=pos.x+i-1,y=pos.y+1,z=pos.z-2},{name = "games:checkers_red_queen"}) end + node = minetest.get_node({x=pos.x+i-1,y=pos.y,z=pos.z-2}).name; + if node~="games:board_white" then minetest.set_node({x=pos.x+i-1,y=pos.y,z=pos.z-2},{name = "games:board_white"}) end + + node = minetest.get_node({x=pos.x+i-1,y=pos.y+1,z=pos.z+9}).name; + if node~="games:checkers_blue_queen" then minetest.set_node({x=pos.x+i-1,y=pos.y+1,z=pos.z+9},{name = "games:checkers_blue_queen"}) end + node = minetest.get_node({x=pos.x+i-1,y=pos.y,z=pos.z+9}).name; + if node~="games:board_white" then minetest.set_node({x=pos.x+i-1,y=pos.y,z=pos.z+9},{name = "games:board_white"}) end + + end + +end + +minetest.register_node("games:checkers", { +description = "checkers crate", + tiles = {"moreblocks_iron_checker.png","crate.png","crate.png","crate.png","crate.png","crate.png"}, + groups = {oddly_breakable_by_hand=1}, + is_ground_content = false, + paramtype = "light", + light_source = 14, + sounds = default.node_sound_wood_defaults(), + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("infotext","checkers game block, punch to start game") + meta:set_int("time", minetest.get_gametime()); + meta:set_string("player1","");meta:set_string("player2",""); + meta:set_int("state",0); -- state 0 : waiting for players 1: active game + checkers.pos = {x = pos.x+1, y=pos.y-1, z=pos.z+1} + end, + on_punch = function(pos, node, player) + local name = player:get_player_name(); if name==nil then return end + local meta = minetest.get_meta(pos); + local state = meta:get_int("state"); + local name1 = meta:get_string("player1") + local name2 = meta:get_string("player2") + + if state == 1 then + local player1 = minetest.get_player_by_name(name1) + local player2 = minetest.get_player_by_name(name2) + local endgame = 0; + if not player1 or not player2 then endgame = 1 end + + if endgame == 0 then + local p = player1:getpos(); + local dist = math.abs(p.x-pos.x)+math.abs(p.y-pos.y)+math.abs(p.z-pos.z); + if dist>32 then endgame = 1 end + p = player2:getpos(); + dist = math.abs(p.x-pos.x)+math.abs(p.y-pos.y)+math.abs(p.z-pos.z); + if dist>16 then endgame = 1 end + end + + if endgame == 1 then + meta:set_int("state",0); meta:set_string("infotext", "checkers waiting for players, punch block to sign up."); + meta:set_string("player1","");meta:set_string("player2",""); + return + end + end + + local startgame = 0; + if name1=="" then + meta:set_string("player1",name); name1 = name; if name2~="" then startgame = 1;end + elseif name2=="" then + meta:set_string("player2",name); name2 = name; if name1~="" then startgame = 1;end + end + + if startgame == 0 and name~=name1 and name~=name2 then + return + end + + if startgame == 1 or state == 1 then + meta:set_int("state",1); + meta:set_string("infotext", "game of checkers started. players " .. name1 .. " and " .. name2); + checkers.pos = {x = pos.x+1, y=pos.y, z=pos.z+1} + draw_board() + end + end + } + ) + + +minetest.register_chatcommand("checkers", { + description = "Start a game of checkers and refresh board display", + privs = {kick=true}, + func = function(name,param) + draw_board();checkers.piece = "" + end + } +) + + +function register_piece(name, desc, tiles, punch) + minetest.register_node(name, { + description = desc, + drawtype = "nodebox", + paramtype = "light", + tiles = tiles, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=3}, + sounds = default.node_sound_defaults(), + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -0.3, 0.5}, + }, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -0.3, 0.5}, + + }, + on_punch= punch, + }) +end +function register_board(name,desc,tiles) + minetest.register_node(name, { + description = desc, + tiles = tiles, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=3}, + sounds = default.node_sound_defaults(), + on_punch = function(pos, node, player) -- place piece on board + local name = player:get_player_name(); if name == nil then return end + if checkers.pos.x == nil then minetest.chat_send_player(name,"punch checkers game block before playing.") return end + + local meta = minetest.get_meta({x=checkers.pos.x-1,y=checkers.pos.y,z=checkers.pos.z-1}); local state = meta:get_int("state"); + if state ~= 1 then minetest.chat_send_player(name,"punch checkers game block before playing.") return end + local name1 = meta:get_string("player1");local name2 = meta:get_string("player2"); + if name~=name1 and name~=name2 then return end + + if checkers.piece == "" then return end + local t = minetest.get_gametime(); if t-checkers.time <1 then return end; checkers.time = t; + local above = {x=pos.x,y=pos.y+1;z=pos.z}; + local x,y; x= above.z-checkers.pos.z+1; y=above.x-checkers.pos.x+1; + minetest.set_node(above, {name = checkers.piece}); + + local text = "#CHECKERS : " .. name .." moved: ".. checkers.piece_pos.z-checkers.pos.z+1 .. "," .. checkers.piece_pos.x-checkers.pos.x+1 .. " to " .. + x .. "," .. y; + + minetest.chat_send_player(name1,text);minetest.chat_send_player(name2,text); + checkers.piece = "" + end, + on_rightclick = function(pos, node, player, itemstack, pointed_thing) -- capture piece + local name = player:get_player_name(); if name == nil then return end + if checkers.pos.x == nil then minetest.chat_send_player(name,"punch checkers game block before playing.") return end + local meta = minetest.get_meta({x=checkers.pos.x-1,y=checkers.pos.y, z=checkers.pos.z-1}); local state = meta:get_int("state"); + if state ~= 1 then minetest.chat_send_player(name,"punch checkers game block before playing.") return end + local name1 = meta:get_string("player1");local name2 = meta:get_string("player2"); + if name~=name1 and name~=name2 then return end + if checkers.piece == "" then return end + minetest.chat_send_all(name .." captured piece at ".. checkers.piece_pos.z-checkers.pos.z+1 .. ","..checkers.piece_pos.x-checkers.pos.x+1) + checkers.piece = "" return + end + + }) +end + +local piece_punch = function(pos, node, player) -- pick up piece + local name = player:get_player_name(); if name == nil then return end + if checkers.pos.x == nil then minetest.chat_send_player(name,"punch checkers game block before playing.") return end + + local meta = minetest.get_meta({x=checkers.pos.x-1,y=checkers.pos.y,z=checkers.pos.z-1}); local state = meta:get_int("state"); + if state ~= 1 then minetest.chat_send_player(name,"punch checkers game block before playing.") return end + local name1 = meta:get_string("player1");local name2 = meta:get_string("player2"); + if name~=name1 and name~=name2 then return end + + if checkers.piece~="" then return end -- dont pick up another piece before last one was put down + + local t = minetest.get_gametime(); if t-checkers.time <1 then return end; checkers.time = t; + checkers.piece = node.name; minetest.set_node(pos, {name="air"}); + checkers.piece_pos = {x=pos.x,y=pos.y,z=pos.z}; +end + +register_board("games:board_white","white board",{"wool_white.png"}) +register_board("games:board_black","black board",{"wool_black.png"}) + +register_piece("games:checkers_blue","blue piece",{"wool_blue.png"},piece_punch) +register_piece("games:checkers_blue_queen","blue queen piece",{"queen_blue.png"},piece_punch) + +register_piece("games:checkers_red","red piece",{"wool_red.png"},piece_punch) +register_piece("games:checkers_red_queen","red piece",{"queen_red.png"},piece_punch) \ No newline at end of file diff --git a/mods/z_remove/games/depends.txt b/mods/z_remove/games/depends.txt new file mode 100644 index 00000000..331d858c --- /dev/null +++ b/mods/z_remove/games/depends.txt @@ -0,0 +1 @@ +default \ No newline at end of file diff --git a/mods/z_remove/games/init.lua b/mods/z_remove/games/init.lua new file mode 100644 index 00000000..cf6f4406 --- /dev/null +++ b/mods/z_remove/games/init.lua @@ -0,0 +1,8 @@ +-- rnd: collection of puzzle games for minetest +dofile(minetest.get_modpath("games").."/maze.lua") +dofile(minetest.get_modpath("games").."/sokoban.lua") +dofile(minetest.get_modpath("games").."/spleef.lua") +dofile(minetest.get_modpath("games").."/checkers.lua") +dofile(minetest.get_modpath("games").."/minesweeper.lua") +dofile(minetest.get_modpath("games").."/life.lua") +print("[games] loaded") \ No newline at end of file diff --git a/mods/z_remove/games/life.lua b/mods/z_remove/games/life.lua new file mode 100644 index 00000000..2da4c808 --- /dev/null +++ b/mods/z_remove/games/life.lua @@ -0,0 +1,104 @@ +-- game of life + +local life_table = {}; +local dim = 5; + +minetest.register_abm( + {nodenames = {"games:life"}, + interval = 5.0, + chance = 1, + action = function(pos) + + local meta = minetest.get_meta(pos); local infotext = meta:get_string("infotext"); + if infotext~="RUN" then return end + + if life_table[0]==nil then return end-- punch node again to initialize + + local table_new = {}; + local i,j,k,c,n,p; + local dp = {{-1,-1},{0,-1},{1,-1},{-1,0},{1,0},{-1,1},{0,1},{1,1}}; + for i = -dim,dim do + table_new[i]={}; + for j = -dim,dim do + c = life_table[i][j]; + n=0; + for k = 1,8 do + p={i+dp[k][1],j+dp[k][2]}; + if p[1]<-dim then p[1]=dim elseif p[1]>dim then p[1]=-dim end; + if p[2]<-dim then p[2]=dim elseif p[2]>dim then p[2]=-dim end; + if life_table[ p[1] ][ p[2] ]==1 then n=n+1 end + end + if c == 1 then --alive + if n>=2 and n<=3 then table_new[i][j]=1 + else + table_new[i][j]=0 + end + else -- dead + if n==3 then table_new[i][j]=1 else table_new[i][j]=0 end + end + end + end + + p={x=pos.x,y=pos.y+1,z=pos.z} + for i = -dim,dim do + for j = -dim,dim do + life_table[i][j]=table_new[i][j] + p.x = pos.x+i;p.z=pos.z+j; + if minetest.get_node(p).name=="air" then + if life_table[i][j]==1 then minetest.set_node(p,{name="stairs:slab_stone"}) end + else + if life_table[i][j]==0 then minetest.set_node(p,{name="air"}) end + end + end + end + + end, +}) + +local function init_game(pos) + local name; local i,j;local p = {x=pos.x;y=pos.y+1,z=pos.z}; + for i = -dim,dim do + life_table[i]={}; + for j = -dim,dim do + p.x = pos.x+i;p.z=pos.z+j + name = minetest.get_node(p).name; + if name == "air" then life_table[i][j]=0 else life_table[i][j]=1 end + if life_table[i][j]==1 then minetest.set_node(p,{name="stairs:slab_stone"}) end + + end + end +end + +minetest.register_node("games:life", { + description = "game of life, game field is 1 above ", + inventory_image = "default_tree.png", + wield_image = "default_tree.png", + wield_scale = {x=0.8,y=2.5,z=1.3}, + tiles = {"default_tree.png"}, + stack_max = 1, + groups = {oddly_breakable_by_hand=3}, + + on_punch = function(pos, node, puncher, pointed_thing) + + local name = puncher:get_player_name();if name == nil then return end + local privs = minetest.get_player_privs(name); + if not privs.ban then return end + + local meta = minetest.get_meta(pos) + local infotext = meta:get_string("infotext"); + if infotext=="RUN" then infotext ="STOP" else infotext="RUN" end + meta:set_string("infotext", infotext) + init_game(pos) + end + } +) + + + -- minetest.register_craft({ + -- output = "games:life", + -- recipe = { + -- {"default:stone","","default:stone"}, + -- {"","default:stone",""}, + -- {"default:stone","","default:stone"}, + -- } +-- }) \ No newline at end of file diff --git a/mods/z_remove/games/maze.lua b/mods/z_remove/games/maze.lua new file mode 100644 index 00000000..c11617ea --- /dev/null +++ b/mods/z_remove/games/maze.lua @@ -0,0 +1,189 @@ +-- maze generation +-- http://en.wikipedia.org/wiki/Maze_generation_algorithm#Depth-first_search, recursive backtracker +-- representation of node coordinate (row,coloumn)=(i,j) -> (i-1)*n+j, i=1..n, j=1...m +-- representation of walls: below node k --> k, left of node k --> k+m.n + +-- good overview of maze generation algorithms using javascript/html5 +-- http://www.jamisbuck.org/presentations/rubyconf2011/index.html#recursive-backtracker + +-- helper functions +--stack in lua +local stack={}; +function stack.push(s,e) s[#s+1]=e end +function stack.pop(s) local r = s[#s];s[#s]=nil;return r end +--function table2string(s) local r = ""; for i,v in pairs(s) do r = r.. " ["..i.."]=".. v ; end return r end + +function maze_deep_first_search(m,n,start,seed) -- returns a table of strings representing line renders + + local steps,maxsteps; steps= 0; maxsteps = 999999; + local maze = {} + maze.m = m; maze.n = n; + maze.unvisited = {};maze.stack = {}; maze.walls = {}; + maze.free = maze.m*maze.n; + local i,j,k + local nb,wall -- unvisited neighbbors, walls + + --init structures + for i=1,maze.m do + for j =1,maze.n do + k=(i-1)*maze.n+j;maze.unvisited[k]=true -- initially all cells unvisited + maze.walls[k]=true;maze.walls[k+maze.n*maze.m]=true; -- walls are there + end + end + + math.randomseed(seed) + maze.current = start + maze.unvisited [ maze.current ] = false; + maze.free = maze.free-1; maze.stack[1+#maze.stack] = maze.current + + while maze.free>0 and steps1 then -- down + k=(i-2)*maze.n+j; if maze.unvisited[k] then wall[#wall+1]=k+maze.n;nb[#nb+1]=k end + end + if i1 then --left + k=(i-1)*maze.n+j-1; if maze.unvisited[k] then wall[#wall+1]=k+1+maze.n*maze.m;nb[#nb+1]=k end + end + + --print(" unvisited neighbors " .. table2string(nb)) + if (#nb)>0 then -- if unvisited neighbors, choose random one as next current node + stack.push(maze.stack,maze.current) -- remember previous current node + k=math.random(#nb); -- pick random unvisited neighbor + maze.walls[wall[k]]=false; -- remove wall + --print(" removed wall ".. wall[k]) + k=nb[k]; + maze.current = k; -- new current cell + maze.unvisited[k]=false; maze.free = maze.free-1 -- one less unvisited + --print("new explore " .. k); + + elseif (#maze.stack)~=0 then -- no unvisited neighbors, backtrack using stack + + maze.current = stack.pop(maze.stack) + --print("backtrack to "..maze.current) + + else -- even stack is empty, just pick random unvisited cell + k = math.random(maze.free); j=1; + for i =1,maze.m*maze.n do + if maze.unvisited[i] then + if j==k then k=i; break end -- pick node + j=j+1 + end + end + --print(" stack empty, random pick " ..k) + maze.current=k;maze.unvisited[k]=false; maze.free = maze.free -1; + end + end -- of do + + -- render maze with chars, row by row + maze.ret = {}; + local hor;local vert; + local wall = "1" + + for i=1,maze.m do + hor="";vert=""; + k= (i-1)*maze.n; + -- horizontal + for j = 1, maze.n do + k=k+1; + -- if maze.walls[k+maze.n*maze.m] then vert=vert.."X." else vert=vert.. "0." end + -- if maze.walls[k] then hor=hor.."XX" else hor=hor.."X0" end + if maze.walls[k+maze.n*maze.m] then vert=vert..wall.."0" else vert=vert.. "00" end + if maze.walls[k] then hor=hor..wall..wall else hor=hor..wall.."0" end + end + maze.ret[1+#maze.ret]=hor..wall;maze.ret[1+#maze.ret]=vert..wall; + end + maze.ret[1+#maze.ret] = string.rep(wall,2*maze.n+1) + return maze.ret + end + +-- RUN PROGRAM + local maze=maze_deep_first_search(10,30,1,2015) + --for _,v in pairs(maze) do print(v) end + + + + core.register_privilege("maze", "Can create mazes") + minetest.register_chatcommand("maze", { + description = "/maze (optional m,n,start,seed) generates maze at players position, directed towards positive x,z axix", + privs = {maze = true}, + func = function(name, param) + local m,n,start, seed + if param == "" then m=10;n=10;start=1;seed=1 else + local words = {}; local word + for word in param:gmatch("%w+") do words[1+#words]= word end + if words[1]~=nil then m = tonumber(words[1]) else m = 10 end + if words[2]~=nil then n = tonumber(words[2]) else n = 10 end + if words[3]~=nil then start = tonumber(words[3]) else start = 1 end + if words[4]~=nil then seed = tonumber(words[4]) else seed = 1 end + end + if m*n>1000000 then minetest.chat_send_player(name, "limit maze size to 1000000 cells") return end + local player = minetest.env:get_player_by_name(name); if player==nil then return end + local pos = player:getpos();local p + local maze=maze_deep_first_search(m,n,start,seed) -- m,n,start,seed + local i,j,k;local p = {x=pos.x,y=pos.y,z=pos.z}; + for i,v in pairs(maze) do + p.x = pos.x+i + for k = 1,string.len(v) do + p.z=pos.z+k + if string.sub(v,k,k)=="1" then + minetest.set_node(p,{name="games:stone_maze"}) + else minetest.set_node(p,{name="air"}) + end + end + end + + +end, +}) + +minetest.register_node("games:glass_maze", { + description = "maze_glass", + drawtype = "glasslike_framed_optional", + tiles = {"maze_glass.png"}, + inventory_image = minetest.inventorycube("maze_glass.png"), + paramtype = "light", + sunlight_propagates = true, + is_ground_content = false, + groups = {immortal = 1,disable_jump=1}, + sounds = default.node_sound_glass_defaults(), +}) + +minetest.register_node("games:stone_maze", { + description = "maze_wall", + tiles = {"default_brick.png"}, + is_ground_content = true, + groups = {immortal = 1,disable_jump=1}, + legacy_mineral = true, + sounds = default.node_sound_stone_defaults(), + on_rightclick = function(pos, node, player, itemstack, pointed_thing) + local name = player:get_player_name(); if name == nil then return end + if minetest.is_protected(pos, name) then + return + end + local player_inv = player:get_inventory() + if player_inv:room_for_item("main", {"games:stone_maze"}) then + player_inv:add_item("main", "games:stone_maze") + minetest.remove_node(pos) -- remove bones + end + + + + + end +}) + + \ No newline at end of file diff --git a/mods/z_remove/games/minesweeper.lua b/mods/z_remove/games/minesweeper.lua new file mode 100644 index 00000000..7aaee616 --- /dev/null +++ b/mods/z_remove/games/minesweeper.lua @@ -0,0 +1,273 @@ +--Minesweeper +local minesweeper = {}; +minesweeper.games = {};-- games in progress + +minetest.register_node("games:minesweeper", { +description = "minesweeper", + tiles = {"default_copper_block.png"}, + groups = {oddly_breakable_by_hand=2}, + is_ground_content = false, + paramtype = "light", + light_source = 10, + sounds = default.node_sound_wood_defaults(), + + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos); + local width = 10;meta:set_int("width",width); + local height = 10;meta:set_int("height",height); + local count = 20;meta:set_int("count",count); + meta:set_string("player",""); -- whos playing + meta:set_int("t",0); -- start of game + + local form = "size[3,3] field[0.25,0.5;1,1;width;width ;"..width.."]".. + "field[2.25,0.5;1,1;height;height ;"..height.."]" .. + "field[0.25,1.5;1,1;count;count ;"..count.."]" .. + "button_exit[0.,2.5;1,1;OK;OK]"; + meta:set_string("formspec", form); + meta:set_string("owner", placer:get_player_name()); + meta:set_string("infotext","Minesweeper, punch or activate to start the game"); + end, + + on_receive_fields = function(pos, formname, fields, player) + if minetest.is_protected(pos, player:get_player_name()) then return end + if fields.OK then + local meta = minetest.get_meta(pos); + local width = tonumber(fields.width) or 5; + local height = tonumber(fields.height) or 5; + local count = tonumber(fields.count) or 5; + local form = "size[3,3] field[0.25,0.5;1,1;width;width ;"..width.."]".. + "field[2.25,0.5;1,1;height;height ;"..height.."]" .. + "field[0.25,1.5;1,1;count;count ;"..count.."]" .. + "button_exit[0.,2.5;1,1;OK;OK]"; + meta:set_string("formspec", form); + -- clear gamearea + + local i,j; + for i=1,width do + for j=1,height do + minetest.set_node({x=pos.x+i+1,y=pos.y,z=pos.z+j+1},{name = "air"}); + end + end + meta:set_int("mines",0); + meta:set_int("width",width); + meta:set_int("height",height); + meta:set_int("count", count); + meta:set_string("player",""); + meta:set_int("t",0); -- start of game + meta:set_string("infotext", "minesweeper game set. punch block to start game.") + + end + end, + + on_punch = function(pos, node, puncher, pointed_thing) + + if puncher:get_player_control().sneak then return end + + local meta = minetest.get_meta(pos); + -- can we start new game? not too soon and player not still playing + local t0 = meta:get_int("t"); + local t1 = minetest.get_gametime(); + if t1-t0<5 then return end + meta:set_int("t",t1); + local pname = meta:get_string("player"); + local name = puncher:get_player_name(); + local mines = meta:get_int("mines"); + + + if pname~=name then + local player = minetest.get_player_by_name(pname); + if player then + local p = player:getpos(); + local dist = math.sqrt((p.x-pos.x)^2+(p.y-pos.y)^2+(p.z-pos.z)^2); + if dist< 30 then minetest.chat_send_player(name, "games: minesweeper game still in progress") return end + end + elseif minesweeper.games[name] then -- if game in progress end it + + local finished = true; + + -- check if mines are marked correctly! + local width = meta:get_int("width"); + local height = meta:get_int("height"); + local count = meta:get_int("count"); + local i,j,mpos; + for i=1,width do + for j=1,height do + mpos = {x=pos.x+i+1,y=pos.y,z=pos.z+j+1}; + if minetest.get_node(mpos).name ~= "games:markmine" and minetest.get_meta(mpos):get_int("mine")==1 then -- FAIL + finished = false; + elseif minetest.get_node(mpos).name == "games:markmine" and minetest.get_meta(mpos):get_int("mine")==0 then + finished = false; + end + + end + end + + if not finished then + + minetest.chat_send_all("games: BOOM! ".. name .. " has failed to detect the mines properly ! ") + if mpos then minetest.swap_node(mpos,{name = "default:cobble"}) end + minesweeper.games[name]=nil; -- end game + return; + + else -- done + + + -- activates block below minesweeper game block upon game completion + local pos = {x=pos.x,y=pos.y-1,z=pos.z}; + local node = minetest.get_node(pos); if not node.name then return end -- error + local table = minetest.registered_nodes[node.name]; + if table and table.mesecons and table.mesecons.effector then + local effector=table.mesecons.effector; + if effector.action_on then + effector.action_on(pos,node,16) + end + end; + meta:set_string("infotext", name .. " just solved minesweeper level"); + meta:set_string("player",""); + minesweeper.games[name]=nil; + return + end + end + + -- no game yet, place mines + meta:set_string("player",name); + minesweeper.create_game(pos); + return + + + end + } +) + +minesweeper.create_game = function(pos) + + local meta = minetest.get_meta(pos); + local width = meta:get_int("width"); + local height = meta:get_int("height"); + local count = meta:get_int("count"); + local i,j; + for i=1,width do + for j=1,height do + minetest.set_node({x=pos.x+i+1,y=pos.y,z=pos.z+j+1},{name = "games:dirt"}); --?? + end + end + + local mines = 0; + local mtable = {}; + math.randomseed(minetest.get_gametime()); + + for i=1,count do -- place max up to count mines + local x = math.random(width); + local z = math.random(height); + if not mtable[{x,z}] then + mtable[{x,z}]=true + local mmeta = minetest.get_meta({x=pos.x+x+1,y=pos.y,z=pos.z+z+1}); + mmeta:set_int("mine",1); + mines=mines+1; + end + end + + local pname = meta:get_string("player"); + minesweeper.games[pname] = {pos=pos}; -- position of gameblock + meta:set_int("mines", mines); -- remaining mines + meta:set_string("infotext", "Minesweeper game started by "..pname..", there are ".. mines .. " mines. Mark all mines by double punch from distance. Mark area as safe by standing over it and punching. When you are done punch gameblock."); + minetest.chat_send_player(pname, "game: Minesweeper game started"); + +end + +local punch_minesweep = function(pos, node, puncher, pointed_thing) + + -- find closeby game and play + local gpos, dist; + for _,v in pairs(minesweeper.games) do + dist = math.sqrt((v.pos.x-pos.x)^2+(v.pos.y-pos.y)^2+(v.pos.z-pos.z)^2); + if dist<32 then gpos = v.pos end + end + + local name = puncher:get_player_name(); + if not gpos then + minetest.chat_send_player(name,"games: punch nearby game block for minesweeper to start playing.") + return + end + + local meta = minetest.get_meta(pos); + + + local ppos = puncher:getpos(); -- player position + --dist = math.sqrt((ppos.x-pos.x)^2+(ppos.y-pos.y)^2+(ppos.z-pos.z)^2); + + local mines = 0; + for i = -1,1 do + for j = -1,1 do + local mmeta = minetest.get_meta({x=pos.x+i,y=pos.y,z=pos.z+j}); + if mmeta:get_int("mine") == 1 then mines = mines +1 end + end + end + --minetest.chat_send_player(name, "Found " .. mines .. " nearby mines. Punch 2x to mark mine") + meta:set_string("infotext", "found ".. mines .. " nearby mines") + + -- try mark block as safe? + if meta:get_int("mine")==1 then + minetest.chat_send_all("games: BOOM! ".. name .. " has stepped on mine ") + minetest.swap_node(pos,{name = "games:markmine"}) + puncher:setpos({x=gpos.x,y=gpos.y+1,z=gpos.z}); + local gmeta = minetest.get_meta(gpos); + local pname = gmeta:get_string("player"); + minesweeper.games[name]=nil; -- end game + gmeta:set_string("player",""); + + -- activates block below minesweeper game with OFF upon fail + gpos.y=gpos.y-1; + local node = minetest.get_node(gpos); if not node.name then return end -- error + local table = minetest.registered_nodes[node.name]; + if table and table.mesecons and table.mesecons.effector then + local effector=table.mesecons.effector; + if effector.action_off then + effector.action_off(gpos,node,16) + end + end; + + return + else + minetest.swap_node(pos,{name = "default:dirt_with_grass"}) + end + +end + +local reveal_minesweep = function(pos, node, player, itemstack, pointed_thing) + + -- local t0 = meta:get_int("t"); + -- local t1 = minetest.get_gametime(); + -- if t1-t0<1 then -- un/mark mine + if node.name == "games:dirt" then + minetest.swap_node(pos,{name = "games:markmine"}) + else + minetest.swap_node(pos,{name = "games:dirt"}) + end + --meta:set_int("t",t1); + + end + + + + + + + +minetest.register_node("games:dirt", { + description = "Dirt with mines, punch from far to check for mines, stand near and punch to clear mine", + tiles = {"default_dirt.png"}, + groups = {immortal = 1}, + sounds = default.node_sound_dirt_defaults(), + on_punch = punch_minesweep, + on_rightclick = reveal_minesweep +}) + +minetest.register_node("games:markmine", { + description = "Dirt with mines, punch from far to check for mines, stand near and punch to clear mine", + tiles = {"default_lava.png"}, + groups = {immortal = 1}, + sounds = default.node_sound_dirt_defaults(), + on_punch = punch_minesweep, + on_rightclick = reveal_minesweep +}); diff --git a/mods/z_remove/games/sokoban.lua b/mods/z_remove/games/sokoban.lua new file mode 100644 index 00000000..1f3f2937 --- /dev/null +++ b/mods/z_remove/games/sokoban.lua @@ -0,0 +1,203 @@ +-- SOKOBAN GAME +-- by rnd + + +local sokoban = {}; +sokoban.push_time = 0 +sokoban.blocks = 0;sokoban.level = 0; sokoban.moves=0; +sokoban.load=0;sokoban.playername =""; sokoban.pos = {}; +local SOKOBAN_WALL = "games:stone_maze" +local SOKOBAN_FLOOR = "default:stone" +local SOKOBAN_GOAL = "default:tree" + + +minetest.register_node("games:crate", { -- block that player pushes around, basically main sokoban routine + description = "sokoban crate", + tiles = {"crate.png"}, + paramtype = "light", + light_source = 10, + is_ground_content = false, + groups = {immortal = 1}, + sounds = default.node_sound_wood_defaults(), + on_punch = function(pos, node, player) + local name = player:get_player_name(); if name==nil then return end + if sokoban.playername~=name then + if sokoban.playername == "" then + minetest.chat_send_player(name,"Please right click level loader block to load and play Sokoban") + return + end + minetest.chat_send_player(name,"Only ".. sokoban.playername .. " can play. To play new level please right click loader block and select level.") + return + end + local time = sokoban.push_time; local t = minetest.get_gametime(); + if t-time<1 then return end;sokoban.push_time = t + local p=player:getpos();local q={x=pos.x,y=pos.y,z=pos.z} + p.x=p.x-q.x;p.y=p.y-q.y;p.z=p.z-q.z + if math.abs(p.y+0.5)>0 then return end + if math.abs(p.x)>math.abs(p.z) then + if p.z<-0.5 or p.z>0.5 or math.abs(p.x)>1.5 then return end + if p.x+q.x>q.x then q.x= q.x-1 + else q.x = q.x+1 + end + else + if p.x<-0.5 or p.x>0.5 or math.abs(p.z)>1.5 then return end + if p.z+q.z>q.z then q.z= q.z-1 + else q.z = q.z+1 + end + end + + + if minetest.get_node(q).name=="air" then -- push crate + sokoban.moves = sokoban.moves+1 + local old_infotext = minetest.get_meta(pos):get_string("infotext"); + minetest.set_node(pos,{name="air"}) + minetest.set_node(q,{name="games:crate"}) + minetest.sound_play("default_dig_dig_immediate", {pos=q,gain=1.0,max_hear_distance = 24,}) + local meta = minetest.get_meta(q); + q.y=q.y-1; + if minetest.get_node(q).name==SOKOBAN_GOAL then + if old_infotext~="GOAL REACHED" then + sokoban.blocks = sokoban.blocks -1; + end + meta:set_string("infotext", "GOAL REACHED") + else + if old_infotext=="GOAL REACHED" then + sokoban.blocks = sokoban.blocks +1 + end + meta:set_string("infotext", "push crate on top of goal block") + end + end + local name = player:get_player_name(); if name==nil then return end + if sokoban.blocks~=0 then + minetest.chat_send_player(name,"move " .. sokoban.moves .. " : " ..sokoban.blocks .. " crates left "); + else + minetest.chat_send_all("games: ".. name .. " just solved sokoban level ".. sokoban.level .. " in " .. sokoban.moves .. " moves."); + local meta = minetest.get_meta(sokoban.pos); + meta:set_string("infotext", name .. " just solved sokoban level ".. sokoban.level .. " in " .. sokoban.moves .. " moves."); + + local imax = meta:get_int("imax"); local jmax = meta:get_int("jmax"); + + local i,j; + for i = 1,imax do + for j=1,jmax do + minetest.set_node({x= sokoban.pos.x+i,y=sokoban.pos.y,z=sokoban.pos.z+j}, {name = "air"}); -- clear level + end + end + + -- activates block below sokoban game block upon game completion + local pos = {x=sokoban.pos.x,y=sokoban.pos.y-1,z=sokoban.pos.z}; + local node = minetest.get_node(pos); if not node.name then return end -- error + local table = minetest.registered_nodes[node.name]; + if table and table.mesecons and table.mesecons.effector then + local effector=table.mesecons.effector; + effector.action_on(pos,node,16) + end; + sokoban.playername = ""; sokoban.level = 1 + end + end, +}) + + +minetest.register_node("games:sokoban", { -- level loader block +description = "sokoban crate", + tiles = {"default_brick.png","crate.png","crate.png","crate.png","crate.png","crate.png"}, + groups = {oddly_breakable_by_hand=1}, + is_ground_content = false, + paramtype = "light", + light_source = 14, + sounds = default.node_sound_wood_defaults(), + on_construct = function(pos) + local meta = minetest.get_meta(pos) + + local form = + "size[3,1]" .. -- width, height + "field[0,0.5;3,1;level;enter level 1 to 90;1]".. + "button_exit[2.5,0.25;1,1;OK;OK]" + meta:set_string("formspec", form) + meta:set_string("infotext","sokoban level loader, right click to select level") + meta:set_int("time", minetest.get_gametime()-300); + end, + on_punch = function(pos, node, player) -- make timer ready to enter + local name = player:get_player_name(); if name==nil then return end + local privs = minetest.get_player_privs(name); + if not privs.ban then return end + local meta = minetest.get_meta(pos) + minetest.chat_send_player(name,"Sokoban loader reset. Load level now.") + end, + on_receive_fields = function(pos, formname, fields, sender) + local name = sender:get_player_name(); if name==nil then return end + local privs = minetest.get_player_privs(name); + + if fields.OK ~= "OK" then return end + + local meta = minetest.get_meta(pos) + if not privs.kick and sokoban.playername~="" then + local player = minetest.get_player_by_name(sokoban.playername) + if player and name~= sokoban.playername then + local ppos = player:getpos(); + local dist = math.max(math.abs(pos.x-ppos.x),math.abs(pos.y-ppos.y),math.abs(pos.z-ppos.z)); + if dist<32 then + minetest.chat_send_player(name,sokoban.playername .. " is still playing. Wait until he is finished and then try again"); + return + end + end + end + + sokoban.pos = pos; + sokoban.playername = name + local lvl; + if tonumber(fields.level) ~=nil then + lvl = tonumber(fields.level)-1 + end + if lvl == nil then return end + if lvl <0 or lvl >89 then return end + + local file = io.open(minetest.get_modpath("games").."/sokoban.txt","r") + if not file then minetest.chat_send_player(name,"failed to open sokoban.txt") return end + local str = ""; local s; local p = {x=pos.x,y=pos.y,z=pos.z}; local i,j;i=0; + local lvl_found = false + while str~= nil do + str = file:read("*line"); + if str~=nil and str =="; "..lvl then lvl_found=true break end + end + if not lvl_found then file:close();return end + + sokoban.blocks = 0;sokoban.level = lvl+1; sokoban.moves=0; + local imax=0; local jmax = 0; + while str~= nil do + str = file:read("*line"); + if str~=nil then + if string.sub(str,1,1)==";" then + imax=i; + meta:set_int("imax",imax); meta:set_int("jmax", jmax); -- remember game dimensions + file:close(); minetest.chat_send_all("games: sokoban level "..sokoban.level .." loaded by ".. name .. ". It has " .. sokoban.blocks .. " boxes to push. "); return + end + i=i+1; + if string.len(str)>jmax then jmax = string.len(str) end -- determine max dimensions + for j = 1,string.len(str) do + p.x=pos.x+i;p.y=pos.y; p.z=pos.z+j; s=string.sub(str,j,j); + p.y=p.y-1; + if minetest.get_node(p).name~=SOKOBAN_FLOOR then minetest.set_node(p,{name=SOKOBAN_FLOOR}); end -- clear floor + p.y=p.y+1; + if s==" " and minetest.get_node(p).name~="air" then minetest.set_node(p,{name="air"}) end + if s=="#" and minetest.get_node(p).name~=SOKOBAN_WALL then minetest.set_node(p,{name=SOKOBAN_WALL}) end + if s=="$" then minetest.set_node(p,{name="games:crate"});sokoban.blocks=sokoban.blocks+1 end + if s=="." then p.y=p.y-1;minetest.set_node(p,{name=SOKOBAN_GOAL}); p.y=p.y+1;minetest.set_node(p,{name="air"}) end + --starting position + if s=="@" then + sender:setpos({x=p.x,y=p.y+3,z=p.z}); -- move player to start position + p.y=p.y-1;minetest.set_node(p,{name="default:glass"}); + p.y=p.y+1;minetest.set_node(p,{name="air"}) + p.y=p.y+2;minetest.set_node(p,{name="default:ladder"}) + end + if s~="@" then p.y = pos.y+2;minetest.set_node(p,{name="games:glass_maze"}); + else p.y=pos.y+2;minetest.set_node(p,{name="default:ladder"}) + end -- roof above to block jumps + + end + end + end + + file:close(); + end, +}) \ No newline at end of file diff --git a/mods/z_remove/games/sokoban.txt b/mods/z_remove/games/sokoban.txt new file mode 100644 index 00000000..f6c23512 --- /dev/null +++ b/mods/z_remove/games/sokoban.txt @@ -0,0 +1,1398 @@ +; 0 + ##### + # # + #$ # + ### $## + # $ $ # +### # ## # ###### +# # ## ##### ..# +# $ $ ..# +##### ### #@## ..# + # ######### + ####### +; 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 \ No newline at end of file diff --git a/mods/z_remove/games/spleef.lua b/mods/z_remove/games/spleef.lua new file mode 100644 index 00000000..b8c7fa30 --- /dev/null +++ b/mods/z_remove/games/spleef.lua @@ -0,0 +1,38 @@ +-- SPLEEF GAME + +local spleef_size = 15; +minetest.register_node("games:spleef", { +description = "spleef game", + tiles = {"default_copper_block.png"}, + groups = {oddly_breakable_by_hand=1}, + is_ground_content = false, + paramtype = "light", + light_source = 10, + sounds = default.node_sound_wood_defaults(), + on_punch = function(pos, node, player) + local name = player:get_player_name(); if name==nil then return end + for i = 1, spleef_size do -- init game area + for j = 1, spleef_size do + minetest.set_node({x=pos.x+i+1,y=pos.y,z=pos.z+j+1},{name = "games:spleefblock"}) + end + end + end +} +) + +minetest.register_node("games:spleefblock", { +description = "spleef game block", + tiles = {"default_copper_block.png"}, + groups = {dig_immediate=3}, + is_ground_content = false, + paramtype = "light", + light_source = 10, + sounds = default.node_sound_wood_defaults(), + after_place_node = function(pos, placer, itemstack, pointed_thing) + local inv = placer:get_inventory(); + inv:remove_item("main", ItemStack("games:spleefblock 90")) + minetest.set_node(pos,{name = "air"}) + itemstack:clear(); + end + } +) \ No newline at end of file diff --git a/mods/z_remove/games/textures/crate.png b/mods/z_remove/games/textures/crate.png new file mode 100644 index 0000000000000000000000000000000000000000..c3eb857e7eab539ac0bbb665c33c954dd7f40551 GIT binary patch literal 2674 zcmV-&3XS!NP)Z&D9ZEj*Q<0`#y#8pd})gh8_ z+7TBGX75XPQ)A~z^E$n9*b|E!SBd>Ve?6^yyKH|swE{H(h1Vv1%%y`;E^JWox|r!` zxToW-Vh(ERnZ(#){1Q>-l3gS3s+ecw;dBk$DQ3C`{KV>Fx>iVe20p3~TTj|_i(hul zKW^O5>k0(OK;b1e8F~2=l|0Nwo-xR)Z0rS-J}TxT8WofCQ8;||m5>Wz@dG{^LPAf& zFCJy1&l+N~#Kcr0#3Kh}>Og1GatZBmh)SeFS9AYm`+6LZ)F9(xHe90PLo);Mq+GOXkV~fkpIr>}lcvOG!cf6~?)x9twLss%7j>p7 zBH74uD8D6T;EF;fiRh zh1zxmn8DT)TN?IeR{pfEUJlj3z|7BV20$4X1zx z0z)qc#cqkb8fkE;C8TbqrSE&^!vibo-T1ebX&41pse|y~v zENo`o;yW4^fBBP!g+%m~hy)?Ewv6mO4vJVbC|5z2O>$l*BhUZVmD8I#rQu-#eN{kT zS={lUgemwD=)~1XhdO@Q)|+Z}Kh%G_>VCiW0w6voHM%Jwso*0O3khgY&c4coo>*-B z$}c=Dw3AxC%Ef&h=@gSKF?rq~DpaIQAM;31M1zi$tnjIxk^lR?bvvtEkCfZ7QkRjH zE52XX9~R}nqQMO-BnT%KeP$O@6*^w$kMr^8o{Fv;#HG*8ZKBM^N_2Q(d*Y2sOo_B@Yky7CkvnIFqi&uRqu=ka%rw%F+p`0 zZip!;0(tfGo00O*>sDRPmFUFXSXs0RXC3LXC#poa!p3(!B9VVt|%+M)Ypd|buXEqYMFs~mVhBp-h<)X{yH2MhDG3^c8P1Z&*! zw1VZrKSLYuXXcmFT43Aee~1?vY^k~1p>p2l&fAQNhk818$$UP7l8-867k1n8$ea2B5fIMO6bPn8dAE(ACJm-yNJLT zt9)wRq)a+$7mkbg(avS=r!w5$RRJc^3Uh3dk)e?#;!lTV{M*)gH&z0F-H$(>wJ!!n zm5raZ`L=|1iy1BzY)L6_f}Vl7a@yvTzL7hrQB4_LH7J9Mwv~*lWv_btzQee{a5)9= zl`@AAU}R?U@u%?jZHs>G3xTh@#>dm<#+CRCT$6U9}~u9ky2Lx2hsIc*Yn?5WMgc5UYEs2KS7op&`TTY2~#q4ojdviMEsiLYP#-*K-{O@eK_61}!Qv$FQVS`NVaPzn>IcHEZ(;;76^H zXo`uQOF;zyjbGN~4>LXR<+S>CW-J}9RzN;4D<4l(K&K@j5MxjRpCWpCc38rOrCjUB zJd%JylZyK$ZVT!AY4LsvJU|*ExCK*YVv8pG^~}`B2nguIOnX1m0-raP*JEwh6SaK! z+ABbd+iG@Vk+AMvcme>_(@-E9VDU!)E;%Y;CHjX%8&vGwSib2C7MBE-1ngObB+TZI zOUss0zKLxd`m)OezFjm{4(ytEF8T!K%%VX$eZU}x8Wk_%;e6sHtYWY-;jw2}>=~F6 z2yOc4F^e1~f{#opqLUFM^n^|wh`C@Y^d$P?C#!IbMxU$2CxB+-;%+rlTbmOPgJOAOH2(+eC=@OU2)lDAz9xflzd#sgbXqU z%Au37O}lVCRAG}0?7Q5&MlNh>X;Y^TyQ)*`I<vpNUz?5UYEmxmMBxhyPbyAB7ieKV5ohVrIC zEi7X1a(8|4x>q=J7|38+!qyG?ti=Jn*9`_%DcER%l^f^BS~aogxeW%+4NLf`TiAA` gb(0*IVGGUw4>d!?Y;ygNhX4Qo07*qoM6N<$g2jX(@&Et; literal 0 HcmV?d00001 diff --git a/mods/z_remove/games/textures/maze_glass.png b/mods/z_remove/games/textures/maze_glass.png new file mode 100644 index 0000000000000000000000000000000000000000..f04364f66816b7a0035134a23990e1e91bdce06a GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9oB=)|t_%!J0s;c^YKDte#@YY{ z8B2ovf*Bm1-ADs*lDyqr7&=&GJwVC}JR*x37`TN&n2}-D90{Nxdx@v7EBk$BQ7#3U z=94NiKp{y_7sn8e>&XQlGYS(KnAzDRG7cOnQs`r4IF`UXRU+)y2cRMbPgg&ebxsLQ E0CmYFVE_OC literal 0 HcmV?d00001 diff --git a/mods/z_remove/games/textures/moreblocks_iron_checker.png b/mods/z_remove/games/textures/moreblocks_iron_checker.png new file mode 100644 index 0000000000000000000000000000000000000000..d27f4df7646c69e299211b8bb8327eaca309fe19 GIT binary patch literal 850 zcmV-Y1FigtP) zLNJ+35JDi;>vhWIG60e!;rl+He)+`GQW}tuWtm2!L9^MUUate7sw%l$7Fm{&f*_#V z?IMK0G)>;$T_%$W-ENm?G)gX)V|#lWMNwE?UB#dIMW@BuU8f0^;K0A`F56MNtq!P^nbJ=H@2z z`JB;c#Qy$%I2^vBsxdT8qgt(sR4PTM)A=xvB#CzWC(kd>c%Fx%DEv3*I1Z8|5s?J0 z>yl0{V%s*gT8-&+N-~)w`uh6H)>fIxWP%cnG8hcFy}d=(b#z_Fd3OlH5O3}+C#uc=LMk1MD|KNarzt7gz z7PHxmbUKYVJ3FIPD&e{=g+hUJIvrY;MNCz(CU1;JW8wQggTdfm+~d%7Jv`54Hk%=3 zvsrq*9$^@Ad3lMd#t=daV20;*@>pJuK98J@Be0(4lTOg&USYBQxy0WrDzu%|T zYH@UQ#B}PRB@zTdfNk5zvds1MH9`mqg#uw1A^^*=828_Z&gXLs!$4J4uCA`gWHKm< zLMD^J^E~GBIi_jix-P1!a&mIQ-TfVLB~CVzLEQX#6V`sOvAVL#i}}L+-}hoP8nL^( zOQ+M}>-N`heSMuDH&^7+S=zm}Xf~Tvt5tS(c95?A_`&D3&ousOuploWgkW!Pk6y3$ z@lN06rg1}Ragm4i1MPMjRaH4XJ^kn>m0H4cJ(7z_a`_xW2mlPjpj0XmjYNsZ<7hFB zVzKx?c&%2WSS%t%A`#x~H=K8yp*dtWn^CD$uq+G9vPdK}9LFJygqY?t#bS{l2*_kI cBoYb!0rzZs#rZ#!x&QzG07*qoM6N<$f|0D3O8@`> literal 0 HcmV?d00001 diff --git a/mods/z_remove/games/textures/queen_blue.png b/mods/z_remove/games/textures/queen_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..56191a2fe0b6ca50acb9764acfbe4f18b90e57c9 GIT binary patch literal 473 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfxXNX$C5WSLllI>BT^B9x7-CYKcN zd8@@s;DoKCSnf;1|Nl!rnfX^Ml)Zo1pyiq0zqskl+i9y$Sl(S)(X#E)>^}CX0mAHoSABu4lV3(X@6I?{N2sN?iz0I zg)i29d;Ibv|LlK3_e3_Hcw=+9vvl45O&iwOnRo5yuFe!^_g}UsJ79MHuZ3ZCZGD?% z+n!8O;#dCG9r^P0Rg0NQYYUZ^Rq`dq)>KX4JT}F;wlhlh@9FGk@`?-+D@=AA^8xyc N!PC{xWt~$(69Dros0si8 literal 0 HcmV?d00001 diff --git a/mods/z_remove/games/textures/queen_red.png b/mods/z_remove/games/textures/queen_red.png new file mode 100644 index 0000000000000000000000000000000000000000..4625b0c57e2f30e4a0fbfb3229c8a641e5651fc8 GIT binary patch literal 480 zcmV<60U!Q}P)M=35N*@i3$pf3JQ!13ylj4kqiu!4GoqJ z4VDfLm<|q_4-cFV51kJWpAQeA4-cUb5Tg(fr4bRP5fP{n5vmdrs}d5d6BDiz6R;E% zu@n@u6cn@+6txr-ycQO}7Z<=67sMDC#TgmK85zhK8Oa$L%NZHX8XC?T8hw0Png9R* z0b)x>L;#2d9Y_EG010qNS#tmY3ljhU3ljkVnw%H_000McNliru-vb;AI4oPisZ;;} z0L@86K~xyi4b9tD!Y~v7(NR>8f=#GU1aeQ1MO%8z|9_mk&C?zT%a3?O<)}BOPC?>+ zPetSsACetH1y{uw`3py(1ezTzIRw3p9Xj{yQm^SYO?bAqEtpirBH|6zSecQ@_QOD& zIA)Px(aYU=_3Gf$=U(q4!EBrE{QUcMbItFHkY%)v;mkaiUzwO@mnzvkguT?Og_pjd zi&yJ!nzj^v+7%bmw$Um@YCFsqqtdtA!O9S*l{+DhqxbXV;**Tf#kA7bpw-DO-V*, a free/libre infinite +world block sandbox game. + +To install, just clone this repository into your "mods" directory. + +More Blocks code is licensed under the zlib license, textures are by Calinou and are licensed under CC BY-SA 3.0 Unported. + +**Forum topic:** diff --git a/mods/z_remove/moreblocks/aliases.lua b/mods/z_remove/moreblocks/aliases.lua new file mode 100644 index 00000000..15f7b6b2 --- /dev/null +++ b/mods/z_remove/moreblocks/aliases.lua @@ -0,0 +1,78 @@ +--[[ +More Blocks: alias definitions + +Copyright (c) 2011-2015 Calinou and contributors. +Licensed under the zlib license. See LICENSE.md for more information. +--]] + +-- More Blocks aliases: +minetest.register_alias("sweeper", "moreblocks:sweeper") +minetest.register_alias("circular_saw", "moreblocks:circular_saw") +minetest.register_alias("jungle_stick", "moreblocks:jungle_stick") + +-- Old block/item replacement: +minetest.register_alias("moreblocks:oerkkiblock", "default:mossycobble") +minetest.register_alias("moreblocks:screwdriver", "screwdriver:screwdriver") + +-- Node and item renaming: +minetest.register_alias("moreblocks:stone_bricks", "default:stonebrick") +minetest.register_alias("moreblocks:stonebrick", "default:stonebrick") +minetest.register_alias("moreblocks:junglewood", "default:junglewood") +minetest.register_alias("moreblocks:jungle_wood", "default:junglewood") + +for _, t in pairs(circular_saw.names) do + minetest.register_alias("moreblocks:" .. t[1] .. "_jungle_wood" .. t[2], + "moreblocks:" .. t[1] .. "_junglewood" .. t[2]) +end +minetest.register_alias("moreblocks:horizontaltree", "moreblocks:horizontal_tree") +minetest.register_alias("moreblocks:horizontaljungletree", "moreblocks:horizontal_jungle_tree") +minetest.register_alias("moreblocks:stonesquare", "moreblocks:stone_tile") +minetest.register_alias("moreblocks:circlestonebrick", "moreblocks:circle_stone_bricks") +minetest.register_alias("moreblocks:ironstonebrick", "moreblocks:iron_stone_bricks") +minetest.register_alias("moreblocks:fence_junglewood", "moreblocks:fence_jungle_wood") +minetest.register_alias("moreblocks:coalstone", "moreblocks:coal_stone") +minetest.register_alias("moreblocks:ironstone", "moreblocks:iron_stone") +minetest.register_alias("moreblocks:woodtile", "moreblocks:wood_tile") +minetest.register_alias("moreblocks:woodtile_full", "moreblocks:wood_tile_full") +minetest.register_alias("moreblocks:woodtile_centered", "moreblocks:wood_tile_centered") +minetest.register_alias("moreblocks:woodtile_up", "moreblocks:wood_tile_up") +minetest.register_alias("moreblocks:woodtile_down", "moreblocks:wood_tile_down") +minetest.register_alias("moreblocks:woodtile_left", "moreblocks:wood_tile_left") +minetest.register_alias("moreblocks:woodtile_right", "moreblocks:wood_tile_right") +minetest.register_alias("moreblocks:coalglass", "moreblocks:coal_glass") +minetest.register_alias("moreblocks:ironglass", "moreblocks:iron_glass") +minetest.register_alias("moreblocks:glowglass", "moreblocks:glow_glass") +minetest.register_alias("moreblocks:superglowglass", "moreblocks:super_glow_glass") +minetest.register_alias("moreblocks:trapglass", "moreblocks:trap_glass") +minetest.register_alias("moreblocks:trapstone", "moreblocks:trap_stone") +minetest.register_alias("moreblocks:cactuschecker", "moreblocks:cactus_checker") +minetest.register_alias("moreblocks:coalchecker", "moreblocks:coal_checker") +minetest.register_alias("moreblocks:ironchecker", "moreblocks:iron_checker") +minetest.register_alias("moreblocks:cactusbrick", "moreblocks:cactus_brick") +minetest.register_alias("moreblocks:cleanglass", "moreblocks:clean_glass") +minetest.register_alias("moreblocks:emptybookshelf", "moreblocks:empty_bookshelf") +minetest.register_alias("moreblocks:junglestick", "moreblocks:jungle_stick") +minetest.register_alias("moreblocks:splitstonesquare","moreblocks:split_stone_tile") +minetest.register_alias("moreblocks:allfacestree","moreblocks:all_faces_tree") + +-- ABM for horizontal trees (fix facedir): +local horizontal_tree_convert_facedir = {7, 12, 9, 18} + +minetest.register_abm({ + nodenames = {"moreblocks:horizontal_tree","moreblocks:horizontal_jungle_tree"}, + interval = 1, + chance = 1, + action = function(pos, node) + if node.name == "moreblocks:horizontal_tree" then + node.name = "default:tree" + else + node.name = "default:jungletree" + end + node.param2 = node.param2 < 3 and node.param2 or 0 + minetest.set_node(pos, { + name = node.name, + param2 = horizontal_tree_convert_facedir[node.param2 + 1] + }) + end, +}) + diff --git a/mods/z_remove/moreblocks/circular_saw.lua b/mods/z_remove/moreblocks/circular_saw.lua new file mode 100644 index 00000000..eed9f0e0 --- /dev/null +++ b/mods/z_remove/moreblocks/circular_saw.lua @@ -0,0 +1,399 @@ +--[[ +More Blocks: circular saw + +Copyright (c) 2011-2015 Calinou and contributors. +Licensed under the zlib license. See LICENSE.md for more information. +--]] + +local S = moreblocks.intllib + +circular_saw = {} + +circular_saw.known_stairs = setmetatable({}, { + __newindex = function(k, v) + local modname = minetest.get_current_modname() + print(("WARNING: mod %s tried to add node %s to the circular saw" + .. " manually."):format(modname, v)) + end, +}) + +-- This is populated by stairsplus:register_all: +circular_saw.known_nodes = {} + +-- How many microblocks does this shape at the output inventory cost: +-- It may cause slight loss, but no gain. +circular_saw.cost_in_microblocks = { + 1, 1, 1, 1, 1, 1, 1, 2, + 2, 3, 2, 4, 2, 4, 5, 6, + 7, 1, 1, 2, 4, 6, 7, 8, + 3, 1, 1, 2, 4, 4, 2, 6, + 7, 3, 7, 7, 4, 8, 3, 2, + 6, 2, 1, 3, 4, +} + +circular_saw.names = { + --{"micro", "_1"}, + --{"panel", "_1"}, + --{"micro", "_2"}, + --{"panel", "_2"}, + --{"micro", "_4"}, + --{"panel", "_4"}, + --{"micro", ""}, + --{"panel", ""}, + --{"micro", "_12"}, + --{"panel", "_12"}, + --{"micro", "_14"}, + --{"panel", "_14"}, + --{"micro", "_15"}, + --{"panel", "_15"}, + --{"stair", "_outer"}, + --{"stair", ""}, + --{"stair", "_inner"}, + --{"slab", "_1"}, + --{"slab", "_2"}, + --{"slab", "_quarter"}, + --{"slab", ""}, + --{"slab", "_three_quarter"}, + --{"slab", "_14"}, + --{"slab", "_15"}, + --{"stair", "_half"}, + --{"stair", "_alt_1"}, + --{"stair", "_alt_2"}, + --{"stair", "_alt_4"}, + --{"stair", "_alt"}, + --{"slope", ""}, + {"slope", "_half"}, + {"slope", "_half_raised"}, + {"slope", "_inner"}, + {"slope", "_inner_half"}, + {"slope", "_inner_half_raised"}, + {"slope", "_inner_cut"}, + {"slope", "_inner_cut_half"}, + {"slope", "_inner_cut_half_raised"}, + {"slope", "_outer"}, + {"slope", "_outer_half"}, + {"slope", "_outer_half_raised"}, + {"slope", "_outer_cut"}, + {"slope", "_outer_cut_half"}, + {"slope", "_outer_cut_half_raised"}, + {"slope", "_cut"}, +} + +function circular_saw:get_cost(inv, stackname) + for i, item in pairs(inv:get_list("output")) do + if item:get_name() == stackname then + return circular_saw.cost_in_microblocks[i] + end + end +end + +function circular_saw:get_output_inv(modname, material, amount, max) + if (not max or max < 1 or max > 99) then max = 99 end + + local list = {} + local pos = #list + + -- If there is nothing inside, display empty inventory: + if amount < 1 then + return list + end + + for i = 1, #circular_saw.names do + local t = circular_saw.names[i] + local cost = circular_saw.cost_in_microblocks[i] + local balance = math.min(math.floor(amount/cost), max) + pos = pos + 1 + list[pos] = modname .. ":" .. t[1] .. "_" .. material .. t[2] + .. " " .. balance + end + return list +end + + +-- Reset empty circular_saw after last full block has been taken out +-- (or the circular_saw has been placed the first time) +-- Note: max_offered is not reset: +function circular_saw:reset(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + inv:set_list("input", {}) + inv:set_list("micro", {}) + inv:set_list("output", {}) + meta:set_int("anz", 0) + + meta:set_string("infotext", + S("Circular Saw is empty (owned by %s)") + :format(meta:get_string("owner") or "")) +end + + +-- Player has taken something out of the box or placed something inside +-- that amounts to count microblocks: +function circular_saw:update_inventory(pos, amount) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + amount = meta:get_int("anz") + amount + + -- The material is recycled automaticly. + inv:set_list("recycle", {}) + + if amount < 1 then -- If the last block is taken out. + self:reset(pos) + return + end + + local stack = inv:get_stack("input", 1) + -- At least one "normal" block is necessary to see what kind of stairs are requested. + if stack:is_empty() then + -- Any microblocks not taken out yet are now lost. + -- (covers material loss in the machine) + self:reset(pos) + return + + end + local node_name = stack:get_name() or "" + local name_parts = circular_saw.known_nodes[node_name] or "" + local modname = name_parts[1] or "" + local material = name_parts[2] or "" + + inv:set_list("input", { -- Display as many full blocks as possible: + node_name.. " " .. math.floor(amount / 8) + }) + + -- The stairnodes made of default nodes use moreblocks namespace, other mods keep own: + if modname == "default" then + modname = "moreblocks" + end + + + + -- print("circular_saw set to " .. modname .. " : " + -- .. material .. " with " .. (amount) .. " microblocks.") + + -- 0-7 microblocks may remain left-over: + inv:set_list("micro", { + modname .. ":micro_" .. material .. "_bottom " .. (amount % 8) + }) + -- Display: + inv:set_list("output", + self:get_output_inv(modname, material, amount, + meta:get_int("max_offered"))) + -- Store how many microblocks are available: + meta:set_int("anz", amount) + + meta:set_string("infotext", + S("Circular Saw is working on %s (owned by %s)") + :format(material, meta:get_string("owner") or "")) +end + + +-- The amount of items offered per shape can be configured: +function circular_saw.on_receive_fields(pos, formname, fields, sender) + local meta = minetest.get_meta(pos) + local max = tonumber(fields.max_offered) + if max and max > 0 then + meta:set_string("max_offered", max) + -- Update to show the correct number of items: + circular_saw:update_inventory(pos, 0) + end +end + + +-- Moving the inventory of the circular_saw around is not allowed because it +-- is a fictional inventory. Moving inventory around would be rather +-- impractical and make things more difficult to calculate: +function circular_saw.allow_metadata_inventory_move( + pos, from_list, from_index, to_list, to_index, count, player) + return 0 +end + + +-- Only input- and recycle-slot are intended as input slots: +function circular_saw.allow_metadata_inventory_put( + pos, listname, index, stack, player) + -- The player is not allowed to put something in there: + if listname == "output" or listname == "micro" then + return 0 + end + + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stackname = stack:get_name() + local count = stack:get_count() + + -- Only alow those items that are offered in the output inventory to be recycled: + if listname == "recycle" then + if not inv:contains_item("output", stackname) then + return 0 + end + local stackmax = stack:get_stack_max() + local instack = inv:get_stack("input", 1) + local microstack = inv:get_stack("micro", 1) + local incount = instack:get_count() + local incost = (incount * 8) + microstack:get_count() + local maxcost = (stackmax * 8) + 7 + local cost = circular_saw:get_cost(inv, stackname) + if (incost + cost) > maxcost then + return math.max((maxcost - incost) / cost, 0) + end + return count + end + + -- Only accept certain blocks as input which are known to be craftable into stairs: + if listname == "input" then + if not inv:is_empty("input") then + if inv:get_stack("input", index):get_name() ~= stackname then + return 0 + end + end + if not inv:is_empty("micro") then + local microstackname = inv:get_stack("micro", 1):get_name():gsub("^.+:micro_", "", 1) + local cutstackname = stackname:gsub("^.+:", "", 1) + if microstackname ~= cutstackname then + return 0 + end + end + for name, t in pairs(circular_saw.known_nodes) do + if name == stackname and inv:room_for_item("input", stack) then + return count + end + end + return 0 + end +end + +-- Taking is allowed from all slots (even the internal microblock slot). +-- Putting something in is slightly more complicated than taking anything +-- because we have to make sure it is of a suitable material: +function circular_saw.on_metadata_inventory_put( + pos, listname, index, stack, player) + -- We need to find out if the circular_saw is already set to a + -- specific material or not: + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stackname = stack:get_name() + local count = stack:get_count() + + -- Putting something into the input slot is only possible if that had + -- been empty before or did contain something of the same material: + if listname == "input" then + -- Each new block is worth 8 microblocks: + circular_saw:update_inventory(pos, 8 * count) + elseif listname == "recycle" then + -- Lets look which shape this represents: + local cost = circular_saw:get_cost(inv, stackname) + circular_saw:update_inventory(pos, cost * count) + end +end + +function circular_saw.on_metadata_inventory_take( + pos, listname, index, stack, player) + -- If it is one of the offered stairs: find out how many + -- microblocks have to be substracted: + if listname == "output" then + -- We do know how much each block at each position costs: + local cost = circular_saw.cost_in_microblocks[index] + * stack:get_count() + + circular_saw:update_inventory(pos, -cost) + elseif listname == "micro" then + -- Each microblock costs 1 microblock: + circular_saw:update_inventory(pos, -stack:get_count()) + elseif listname == "input" then + -- Each normal (= full) block taken costs 8 microblocks: + circular_saw:update_inventory(pos, 8 * -stack:get_count()) + end + -- The recycle field plays no role here since it is processed immediately. +end + +gui_slots = "listcolors[#606060AA;#808080;#101010;#202020;#FFF]" + +function circular_saw.on_construct(pos) + local meta = minetest.get_meta(pos) + local fancy_inv = default.gui_bg..default.gui_bg_img..default.gui_slots + meta:set_string("formspec", "size[11,10]"..fancy_inv.. + "label[0,0;" ..S("Input\nmaterial").. "]" .. + "list[current_name;input;1.5,0;1,1;]" .. + "label[0,1;" ..S("Left-over").. "]" .. + "list[current_name;micro;1.5,1;1,1;]" .. + "label[0,2;" ..S("Recycle\noutput").. "]" .. + "list[current_name;recycle;1.5,2;1,1;]" .. + "field[0.3,3.5;1,1;max_offered;" ..S("Max").. ":;${max_offered}]" .. + "button[1,3.2;1,1;Set;" ..S("Set").. "]" .. + "list[current_name;output;2.8,0;8,6;]" .. + "list[current_player;main;1.5,6.25;8,4;]") + + meta:set_int("anz", 0) -- No microblocks inside yet. + meta:set_string("max_offered", 99) -- How many items of this kind are offered by default? + meta:set_string("infotext", S("Circular Saw is empty")) + + local inv = meta:get_inventory() + inv:set_size("input", 1) -- Input slot for full blocks of material x. + inv:set_size("micro", 1) -- Storage for 1-7 surplus microblocks. + inv:set_size("recycle", 1) -- Surplus partial blocks can be placed here. + inv:set_size("output", 6*8) -- 6x8 versions of stair-parts of material x. + + circular_saw:reset(pos) +end + + +function circular_saw.can_dig(pos,player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if not inv:is_empty("input") or + not inv:is_empty("micro") or + not inv:is_empty("recycle") then + return false + end + -- Can be dug by anyone when empty, not only by the owner: + return true +end + +minetest.register_node("moreblocks:circular_saw", { + description = S("Circular Saw"), + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.4, -0.5, -0.4, -0.25, 0.25, -0.25}, -- Leg + {0.25, -0.5, 0.25, 0.4, 0.25, 0.4}, -- Leg + {-0.4, -0.5, 0.25, -0.25, 0.25, 0.4}, -- Leg + {0.25, -0.5, -0.4, 0.4, 0.25, -0.25}, -- Leg + {-0.5, 0.25, -0.5, 0.5, 0.375, 0.5}, -- Tabletop + {-0.01, 0.4375, -0.125, 0.01, 0.5, 0.125}, -- Saw blade (top) + {-0.01, 0.375, -0.1875, 0.01, 0.4375, 0.1875}, -- Saw blade (bottom) + {-0.25, -0.0625, -0.25, 0.25, 0.25, 0.25}, -- Motor case + }, + }, + tiles = {"moreblocks_circular_saw_top.png", + "moreblocks_circular_saw_bottom.png", + "moreblocks_circular_saw_side.png"}, + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "facedir", + groups = {choppy = 2,oddly_breakable_by_hand = 2}, + sounds = default.node_sound_wood_defaults(), + on_construct = circular_saw.on_construct, + can_dig = circular_saw.can_dig, + -- Set the owner of this circular saw. + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + local owner = placer and placer:get_player_name() or "" + meta:set_string("owner", owner) + meta:set_string("infotext", + S("Circular Saw is empty (owned by %s)") + :format(owner)) + end, + + -- The amount of items offered per shape can be configured: + on_receive_fields = circular_saw.on_receive_fields, + allow_metadata_inventory_move = circular_saw.allow_metadata_inventory_move, + -- Only input- and recycle-slot are intended as input slots: + allow_metadata_inventory_put = circular_saw.allow_metadata_inventory_put, + -- Taking is allowed from all slots (even the internal microblock slot). Moving is forbidden. + -- Putting something in is slightly more complicated than taking anything because we have to make sure it is of a suitable material: + on_metadata_inventory_put = circular_saw.on_metadata_inventory_put, + on_metadata_inventory_take = circular_saw.on_metadata_inventory_take, +}) diff --git a/mods/z_remove/moreblocks/config.lua b/mods/z_remove/moreblocks/config.lua new file mode 100644 index 00000000..b077f98a --- /dev/null +++ b/mods/z_remove/moreblocks/config.lua @@ -0,0 +1,33 @@ +--[[ +More Blocks: configuration handling + +Copyright (c) 2011-2015 Calinou and contributors. +Licensed under the zlib license. See LICENSE.md for more information. +--]] + +moreblocks.config = {} + +local function getbool_default(setting, default) + local value = minetest.setting_getbool(setting) + if value == nil then + value = default + end + return value +end + + + +local function setting(settingtype, name, default) + if settingtype == "bool" then + moreblocks.config[name] = + getbool_default("moreblocks." .. name, default) + else + moreblocks.config[name] = + minetest.setting_get("moreblocks." .. name) or default + end +end + +-- Show stairs/slabs/panels/microblocks in creative inventory (true or false): +setting("bool", "stairsplus_in_creative_inventory", false) +setting("bool", "stairsplus_in_craft_guide", false) + diff --git a/mods/z_remove/moreblocks/crafting.lua b/mods/z_remove/moreblocks/crafting.lua new file mode 100644 index 00000000..f847697e --- /dev/null +++ b/mods/z_remove/moreblocks/crafting.lua @@ -0,0 +1,469 @@ +--[[ +More Blocks: crafting recipes + +Copyright (c) 2011-2015 Calinou and contributors. +Licensed under the zlib license. See LICENSE.md for more information. +--]] + +minetest.register_craft({ + output = "default:stick", + recipe = {{"default:dry_shrub"},} +}) + +minetest.register_craft({ + output = "default:stick", + recipe = {{"default:sapling"},} +}) + +minetest.register_craft({ + output = "default:stick", + recipe = {{"default:junglesapling"},} +}) + +minetest.register_craft({ + output = "default:wood", + recipe = { + {"default:stick", "default:stick"}, + {"default:stick", "default:stick"}, + } +}) + +minetest.register_craft({ + output = "default:junglewood", + recipe = { + {"moreblocks:jungle_stick", "moreblocks:jungle_stick"}, + {"moreblocks:jungle_stick", "moreblocks:jungle_stick"}, + } +}) + +minetest.register_craft({ + output = "default:dirt_with_grass", + type = "shapeless", + recipe = {"default:junglegrass", "default:dirt"}, +}) +--[[ +minetest.register_craft({ + output = "default:dirt_with_grass", + type = "shapeless", + recipe = {"default:mese", "default:dirt"}, +})]] + +minetest.register_craft({ + output = "default:mossycobble", + type = "shapeless", + recipe = {"default:junglegrass", "default:cobble"}, +}) + +minetest.register_craft({ + output = "default:mossycobble", + type = "shapeless", + recipe = {"default:mese_crystal_fragment", "default:cobble"}, +}) + +--[[minetest.register_craft({ + output = "moreblocks:wood_tile 9", + recipe = { + {"default:wood", "default:wood", "default:wood"}, + {"default:wood", "default:wood", "default:wood"}, + {"default:wood", "default:wood", "default:wood"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:wood_tile_flipped", + recipe = {{"moreblocks:wood_tile"},} +}) + +minetest.register_craft({ + output = "moreblocks:wood_tile_center 9", + recipe = { + {"default:wood", "default:wood", "default:wood"}, + {"default:wood", "moreblocks:wood_tile", "default:wood"}, + {"default:wood", "default:wood", "default:wood"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:wood_tile_full 4", + recipe = { + {"moreblocks:wood_tile", "moreblocks:wood_tile"}, + {"moreblocks:wood_tile", "moreblocks:wood_tile"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:wood_tile_up", + recipe = { + {"default:stick"}, + {"moreblocks:wood_tile_center"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:wood_tile_down", + recipe = { + {"moreblocks:wood_tile_center"}, + {"default:stick"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:wood_tile_left", + recipe = { + {"default:stick", "moreblocks:wood_tile_center"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:wood_tile_right", + recipe = { + {"moreblocks:wood_tile_center", "default:stick"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:junglestick 4", + recipe = {{"default:junglewood"},} +}) + +minetest.register_craft({ + output = "moreblocks:fence_jungle_wood 2", + recipe = { + {"moreblocks:jungle_stick", "moreblocks:jungle_stick", "moreblocks:jungle_stick"}, + {"moreblocks:jungle_stick", "moreblocks:jungle_stick", "moreblocks:jungle_stick"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:circle_stone_bricks 8", + recipe = { + {"default:stone", "default:stone", "default:stone"}, + {"default:stone", "", "default:stone"}, + {"default:stone", "default:stone", "default:stone"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:all_faces_tree 8", + recipe = { + {"default:tree", "default:tree", "default:tree"}, + {"default:tree", "", "default:tree"}, + {"default:tree", "default:tree", "default:tree"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:all_faces_jungle_tree 8", + recipe = { + {"default:jungletree", "default:jungletree", "default:jungletree"}, + {"default:jungletree", "", "default:jungletree"}, + {"default:jungletree", "default:jungletree", "default:jungletree"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:sweeper 4", + recipe = { + {"default:junglegrass"}, + {"default:stick"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:stone_tile 4", + recipe = { + {"default:cobble", "default:cobble"}, + {"default:cobble", "default:cobble"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:split_stone_tile", + recipe = { + {"moreblocks:stone_tile"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:split_stone_tile_alt", + recipe = { + {"moreblocks:split_stone_tile"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:grey_bricks 2", + type = "shapeless", + recipe = {"default:stone", "default:brick"}, +}) + +minetest.register_craft({ + output = "moreblocks:grey_bricks 2", + type = "shapeless", + recipe = {"default:stonebrick", "default:brick"}, +}) + +minetest.register_craft({ + output = "moreblocks:empty_bookshelf", + type = "shapeless", + recipe = {"moreblocks:sweeper", "default:bookshelf"}, +}) + +minetest.register_craft({ + output = "moreblocks:coal_stone_bricks 4", + recipe = { + {"moreblocks:coal_stone", "moreblocks:coal_stone"}, + {"moreblocks:coal_stone", "moreblocks:coal_stone"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:iron_stone_bricks 4", + recipe = { + {"moreblocks:iron_stone", "moreblocks:iron_stone"}, + {"moreblocks:iron_stone", "moreblocks:iron_stone"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:plankstone 4", + recipe = { + {"default:stone", "default:wood"}, + {"default:wood", "default:stone"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:plankstone 4", + recipe = { + {"default:wood", "default:stone"}, + {"default:stone", "default:wood"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:coal_checker 4", + recipe = { + {"default:stone", "default:coal_lump"}, + {"default:coal_lump", "default:stone"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:coal_checker 4", + recipe = { + {"default:coal_lump", "default:stone"}, + {"default:stone", "default:coal_lump"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:iron_checker 4", + recipe = { + {"default:steel_ingot", "default:stone"}, + {"default:stone", "default:steel_ingot"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:iron_checker 4", + recipe = { + {"default:stone", "default:steel_ingot"}, + {"default:steel_ingot", "default:stone"}, + } +}) + +minetest.register_craft({ + output = "default:chest_locked", + type = "shapeless", + recipe = {"default:steel_ingot", "default:chest"}, +}) +minetest.register_craft({ + output = "default:chest_locked", + type = "shapeless", + recipe = {"default:copper_ingot", "default:chest"}, +}) + +minetest.register_craft({ + output = "default:chest_locked", + type = "shapeless", + recipe = {"default:bronze_ingot", "default:chest"}, +}) + +minetest.register_craft({ + output = "default:chest_locked", + type = "shapeless", + recipe = {"default:gold_ingot", "default:chest"}, +}) + +minetest.register_craft({ + output = "moreblocks:iron_glass", + type = "shapeless", + recipe = {"default:steel_ingot", "default:glass"}, +}) + +minetest.register_craft({ + output = "default:glass", + type = "shapeless", + recipe = {"default:coal_lump", "moreblocks:iron_glass"}, +}) + + +minetest.register_craft({ + output = "moreblocks:coal_glass", + type = "shapeless", + recipe = {"default:coal_lump", "default:glass"}, +}) + +minetest.register_craft({ + output = "default:glass", + type = "shapeless", + recipe = {"default:steel_ingot", "moreblocks:coal_glass"}, +}) + +minetest.register_craft({ + output = "moreblocks:clean_glass", + type = "shapeless", + recipe = {"moreblocks:sweeper", "default:glass"}, +}) + +minetest.register_craft({ + output = "moreblocks:glow_glass", + type = "shapeless", + recipe = {"default:torch", "default:glass"}, +}) + +minetest.register_craft({ + output = "moreblocks:trap_glow_glass", + type = "shapeless", + recipe = {"default:mese_crystal_fragment", "default:glass", "default:torch"}, +}) + +minetest.register_craft({ + output = "moreblocks:trap_glow_glass", + type = "shapeless", + recipe = {"default:mese_crystal_fragment", "moreblocks:glow_glass"}, +}) + +minetest.register_craft({ + output = "moreblocks:super_glow_glass", + type = "shapeless", + recipe = {"default:torch", "default:torch", "default:glass"}, +}) + +minetest.register_craft({ + output = "moreblocks:super_glow_glass", + type = "shapeless", + recipe = {"default:torch", "moreblocks:glow_glass"}, +}) + + +minetest.register_craft({ + output = "moreblocks:trap_super_glow_glass", + type = "shapeless", + recipe = {"default:mese_crystal_fragment", "default:glass", "default:torch", "default:torch"}, +}) + +minetest.register_craft({ + output = "moreblocks:trap_super_glow_glass", + type = "shapeless", + recipe = {"default:mese_crystal_fragment", "moreblocks:super_glow_glass"}, +}) + +minetest.register_craft({ + output = "moreblocks:coal_stone", + type = "shapeless", + recipe = {"default:coal_lump", "default:stone"}, +}) + +minetest.register_craft({ + output = "default:stone", + type = "shapeless", + recipe = {"default:steel_ingot", "moreblocks:coal_stone"}, +}) + +minetest.register_craft({ + output = "moreblocks:iron_stone", + type = "shapeless", + recipe = {"default:steel_ingot", "default:stone"}, +}) + +minetest.register_craft({ + output = "default:stone", + type = "shapeless", + recipe = {"default:coal_lump", "moreblocks:iron_stone"}, +}) + +minetest.register_craft({ + output = "moreblocks:trap_stone", + type = "shapeless", + recipe = {"default:mese_crystal_fragment", "default:stone"}, +}) + +minetest.register_craft({ + output = "moreblocks:trap_glass", + type = "shapeless", + recipe = {"default:mese_crystal_fragment", "default:glass"}, +}) + +minetest.register_craft({ + output = "moreblocks:cactus_brick", + type = "shapeless", + recipe = {"default:cactus", "default:brick"}, +}) + +minetest.register_craft({ + output = "moreblocks:cactus_checker 4", + recipe = { + {"default:cactus", "default:stone"}, + {"default:stone", "default:cactus"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:cactuschecker 4", + recipe = { + {"default:stone", "default:cactus"}, + {"default:cactus", "default:stone"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:rope 3", + recipe = { + {"default:junglegrass"}, + {"default:junglegrass"}, + {"default:junglegrass"}, + } +}) + +minetest.register_craft({ + output = "moreblocks:cobble_compressed", + recipe = { + {"default:cobble", "default:cobble", "default:cobble"}, + {"default:cobble", "default:cobble", "default:cobble"}, + {"default:cobble", "default:cobble", "default:cobble"}, + } +}) + +minetest.register_craft({ + output = "default:cobble 9", + recipe = { + {"moreblocks:cobble_compressed"}, + } +}) + +minetest.register_craft({ + type = "cooking", output = "moreblocks:tar", recipe = "default:gravel", +})]] + +if minetest.setting_getbool("moreblocks.circular_saw_crafting") ~= false then -- “If nil or true then†+ minetest.register_craft({ + output = "moreblocks:circular_saw", + recipe = { + { "", "default:steel_ingot", "" }, + { "group:wood", "group:wood", "group:wood"}, + { "group:wood", "", "group:wood"}, + } + }) +end diff --git a/mods/z_remove/moreblocks/depends.txt b/mods/z_remove/moreblocks/depends.txt new file mode 100644 index 00000000..9207dab8 --- /dev/null +++ b/mods/z_remove/moreblocks/depends.txt @@ -0,0 +1,2 @@ +default +intllib? diff --git a/mods/z_remove/moreblocks/init.lua b/mods/z_remove/moreblocks/init.lua new file mode 100644 index 00000000..2919a308 --- /dev/null +++ b/mods/z_remove/moreblocks/init.lua @@ -0,0 +1,33 @@ +--[[ +===================================================================== +** More Blocks ** +By Calinou, with the help of ShadowNinja and VanessaE. + +Copyright (c) 2011-2015 Calinou and contributors. +Licensed under the zlib license. See LICENSE.md for more information. +===================================================================== +--]] + +moreblocks = {} + +local S +if minetest.get_modpath("intllib") then + S = intllib.Getter() +else + S = function(s) return s end +end +moreblocks.intllib = S + +local modpath = minetest.get_modpath("moreblocks") + +dofile(modpath .. "/config.lua") +dofile(modpath .. "/circular_saw.lua") +dofile(modpath .. "/stairsplus/init.lua") +dofile(modpath .. "/nodes.lua") +dofile(modpath .. "/redefinitions.lua") +dofile(modpath .. "/crafting.lua") +dofile(modpath .. "/aliases.lua") + +if minetest.setting_getbool("log_mods") then + minetest.log("action", S("[moreblocks] loaded.")) +end diff --git a/mods/z_remove/moreblocks/locale/de.txt b/mods/z_remove/moreblocks/locale/de.txt new file mode 100644 index 00000000..542f977f --- /dev/null +++ b/mods/z_remove/moreblocks/locale/de.txt @@ -0,0 +1,67 @@ +# Translation by Xanthin + +###init.lua### +[moreblocks] loaded. = [moreblocks] geladen. + +###nodes.lua### +Jungle Wood Fence = Tropenholzzaun +Empty Bookshelf = Leeres Buecherregal +Clean Glass = Klares Glas +Plankstone = Brettstein +Wooden Tile = Holzfliese +Full Wooden Tile = Vollholzfliese +Centered Wooden Tile = Holzfliese mittig +Up Wooden Tile = Holzfliese oben +Down Wooden Tile = Holzfliese unten +Left Wooden Tile = Holzfliese links +Right Wooden Tile = Holzfliese rechts +Circle Stone Bricks = Kreissteinziegel +Stone Tile = Steinfliese +Split Stone Tile = Geteilte Steinfliese +Glow Glass = Leuchtglas +Super Glow Glass = Superleuchtglas +Coal Glass = Kohleglas +Iron Glass = Eisenglas +Coal Checker = Karierte Kohle +Iron Checker = Kariertes Eisen +Trap Stone = Steinfalle +Trap Glass = Glasfalle +Trap Glow Glass = Leuchtglasfalle +Trap Super Glow Glass = Superleuchtglasfalle +Coal Stone = Kohlestein +Iron Stone = Eisenstein +Coal Stone Bricks = Kohlesteinziegel +Iron Stone Bricks = Eisensteinziegel +Cactus Checker = Karierter Kaktus +Cactus Brick = Kaktusziegel +Sweeper = Besen +Jungle Stick = Tropenholzstock +Rope = Seil +All-faces Tree = Baumscheibenstamm + +###circular_saw.lua### +Circular Saw = Kreissaege +Circular saw, empty (owned by %s) = Kreissaege, leer (gehoert %s) +Circular saw, working with %s (owned by %s) = Kreissaege, arbeitet mit %s (gehoert %s) +Circular saw, empty = Kreissaege, leer +Circular saw is empty (owned by %s) = Kreissaege ist leer (gehoert %s) + +Input\nmaterial = Ausgangs-\nmaterial +Left-over = Rest +Max = Anzahl +Set = Ok +Recycle\noutput = Wiederver-\nwerten + +###./stairsplus/*### +%s Stairs = %streppe +%s Slab = %sstufe +%s Panel = %spaneel +%s Microblock = %smikroblock + +%s Pane = %sscheibe +%s Fence = %szaun + +###ownership.lua### +someone = jemand +Sorry, %s owns that spot. = Tut mir leid, %s gehoert diese Stelle. + diff --git a/mods/z_remove/moreblocks/locale/es.txt b/mods/z_remove/moreblocks/locale/es.txt new file mode 100644 index 00000000..d11ba494 --- /dev/null +++ b/mods/z_remove/moreblocks/locale/es.txt @@ -0,0 +1,52 @@ +# Translation by kaeza + +[moreblocks] loaded. = [moreblocks] cargado. + +Jungle Wooden Planks = Tablones de madera de jungla +Empty Bookshelf = Estante para libros vacío +Clean Glass = Cristal Limpio +Plankstone = Tablones de piedra +Wooden Tile = Parquet +Full Wooden Tile = Parquet Completo +Centered Wooden Tile = Parquet Centrado +Up Wooden Tile = Parquet Superior +Down Wooden Tile = Parquet Inferior +Left Wooden Tile = Parquet Izquierdo +Right Wooden Tile = Parquet Derecho +Circle Stone Bricks = Bloques de Piedra Circulares +Stone Tile = Baldosa de Piedra +Split Stone Tile = Baldosas de Piedra Partida +Glow Glass = Cristal Brillante +Super Glow Glass = Cristal Súper Brillante +Coal Glass = Cristal con Carbón +Iron Glass = Cristal con Hierro +Coal Checker = Cuadros de Carbón +Iron Checker = Cuadros de Hierro +Trap Stone = Piedra Trampa +Trap Glass = Cristal Trampa +Coal Stone = Carbón y Piedra +Iron Stone = Hierro y Piedra +Cactus Checker = Cuadros de Cactus +Cactus Brick = Ladrillos de Cactus +Sweeper = Limpiador +Jungle Stick = Varita de Madera de Jungla +Horizontal Tree = Tronco de árbol horizontal +Horizontal Jungle Tree = Tronco de árbol de la jungla horizontal +Rope = Soga +All-faces Tree = Tronco de Ãrbol + +%s Stairs = Escalera de %s +%s Slab = Losa de %s +%s Panel = Panel de %s +%s Microblock = Microbloque de %s + +Wooden = Madera +Papyrus = Papiro +Dry Shrub = Arbusto Desértico +Sapling = Brote de Ãrbol +Wooden Planks = Tablones de Madera +Ladder = Escalera de Mano +Glass = Cristal + +%s Pane = Panel de %s +%s Fence = Valla de %s diff --git a/mods/z_remove/moreblocks/locale/fr.txt b/mods/z_remove/moreblocks/locale/fr.txt new file mode 100644 index 00000000..6bd7f98c --- /dev/null +++ b/mods/z_remove/moreblocks/locale/fr.txt @@ -0,0 +1,72 @@ +# Translation by Calinou + +###init.lua### +[moreblocks] loaded. = [moreblocks] a été chargé. + +Jungle Wooden Planks = Planches de bois de jungle +Empty Bookshelf = Ètagère vide +Clean Glass = Verre propre +Plankstone = Pierre-bois +Wooden Tile = Dalle en bois +Full Wooden Tile = Dalle en bois complète +Centered Wooden Tile = Dalle en bois centrée +Up Wooden Tile = Dalle en bois vers le haut +Down Wooden Tile = Dalle en bois vers le bas +Left Wooden Tile = Dalle en bois vers la gauche +Right Wooden Tile = Dalle en bois vers la droite +Circle Stone Bricks = Briques en pierre circulaires +Stone Tile = Dalle en pierre +Split Stone Tile = Dalle en pierre découpée +Glow Glass = Verre brillant +Super Glow Glass = Verre très brillant +Coal Glass = Verre de charbon +Iron Glass = Verre de fer +Coal Checker = Damier en charbon +Iron Checker = Damier en fer +Trap Stone = Pierre traversable +Trap Glass = Verre traversable +Trap Glow Glass = Verre brillant traversable +Trap Super Glow Glass = Verre très brillant traversable +Coal Stone = Pierre de charbon +Iron Stone = Pierre de fer +Coal Stone Bricks = Briques en pierre de charbon +Iron Stone Bricks = Briques en pierre de fer +Cactus Checker = Damier en cactus +Cactus Brick = Briques de cactus +Sweeper = Balai +Jungle Stick = Bâton en bois de jungle +Horizontal Tree = Tronc d'arbre horizontal +Horizontal Jungle Tree = Tronc d'arbre de jungle horizontal +Rope = Corde +All-faces Tree = Tronc d'arbre + +###redefinition.lua### +Wooden = bois +Papyrus = Papyrus +Dry Shrub = Buisson mort +Sapling = Pousse d'arbre +Wooden Planks = Planches de bois +Ladder = Échelle +Glass = Verre + +###circular_saw.lua### +Circular Saw = Scie circulaire +Circular saw, empty (owned by %s) = Scie circulaire, vide (propriété de %s) +Circular saw, working with %s (owned by %s) = Scie circulaire, manipule %s (propriété de %s) +Circular saw, empty = Scie circulaire, vide +Circular saw is empty (owned by %s) = Scie circulaire est vide (propriété de %s) + +Input material = Entrée du matériel +Rest/microblocks = Reste/microbloc +Max: = Max: +Set = Fixer +Recycle output = Recyclage + +###./stairsplus/*### +%s Stairs = Escaliers en %s +%s Slab = Demi-dalle en %s +%s Panel = Barre en %s +%s Microblock = Microbloc en %s + +%s Pane = Panneau en %s +%s Fence = Barrière en %s \ No newline at end of file diff --git a/mods/z_remove/moreblocks/locale/template.txt b/mods/z_remove/moreblocks/locale/template.txt new file mode 100644 index 00000000..2b882276 --- /dev/null +++ b/mods/z_remove/moreblocks/locale/template.txt @@ -0,0 +1,64 @@ +###init.lua### +[moreblocks] loaded. = + +###nodes.lua### +Jungle Wood Fence = +Empty Bookshelf = +Clean Glass = +Plankstone = +Wooden Tile = +Full Wooden Tile = +Centered Wooden Tile = +Up Wooden Tile = +Down Wooden Tile = +Left Wooden Tile = +Right Wooden Tile = +Circle Stone Bricks = +Stone Tile = +Split Stone Tile = +Glow Glass = +Super Glow Glass = +Coal Glass = +Iron Glass = +Coal Checker = +Iron Checker = +Trap Stone = +Trap Glass = +Trap Glow Glass = +Trap Super Glow Glass = +Coal Stone = +Iron Stone = +Coal Stone Bricks = +Iron Stone Bricks = +Cactus Checker = +Cactus Brick = +Sweeper = +Jungle Stick = +Rope = +All-faces Tree = + +###circular_saw.lua### +Circular Saw = +Circular saw, empty (owned by %s) = +Circular saw, working with %s (owned by %s) = +Circular saw, empty = +Circular saw is empty (owned by %s) = + +Input\nmaterial = +Left-over = +Max = +Set = +Recycle\noutput = + +###ownership.lua### +someone = +Sorry, %s owns that spot. = + +###./stairsplus/*### +%s Stairs = +%s Slab = +%s Panel = +%s Microblock = + +%s Pane = +%s Fence = diff --git a/mods/z_remove/moreblocks/models/moreblocks_slope.obj b/mods/z_remove/moreblocks/models/moreblocks_slope.obj new file mode 100644 index 00000000..22a833f3 --- /dev/null +++ b/mods/z_remove/moreblocks/models/moreblocks_slope.obj @@ -0,0 +1,26 @@ +# Blender v2.72 (sub 0) OBJ File: '' +# www.blender.org +mtllib moreblocks_slope.mtl +o Cube_Cube.002 +v 0.500000 0.500000 0.500000 +v -0.500000 0.500000 0.500000 +v -0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 -0.500000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vn 0.000000 -0.000000 1.000000 +vn 0.000000 -1.000000 -0.000000 +vn -1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 0.707100 -0.707100 +usemtl None +s off +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 4/3/2 3/4/2 5/1/2 6/2/2 +f 2/1/3 5/3/3 3/4/3 +f 1/2/4 4/3/4 6/4/4 +f 2/1/5 1/2/5 6/3/5 5/4/5 diff --git a/mods/z_remove/moreblocks/models/moreblocks_slope_cut.obj b/mods/z_remove/moreblocks/models/moreblocks_slope_cut.obj new file mode 100644 index 00000000..a9ea83dc --- /dev/null +++ b/mods/z_remove/moreblocks/models/moreblocks_slope_cut.obj @@ -0,0 +1,33 @@ +# Blender v2.72 (sub 0) OBJ File: '' +# www.blender.org +mtllib moreblocks_slope_cut.mtl +o moreblocks_slope_cut +v -0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 0.500000 +v 0.500000 0.500000 0.500000 +v -0.500000 -0.000000 0.500000 +v 0.500000 -0.500000 -0.500000 +v 0.500000 0.000000 -0.500000 +v -0.500000 -0.500000 -0.500000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 0.500000 +vt 1.000000 0.500000 +vt 0.000000 1.000000 +vt 0.500000 0.000000 +vt 0.500000 2.000000 +vn 0.000000 -0.000000 1.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -1.000000 -0.000000 +vn -0.408200 0.816500 -0.408200 +vn 0.000000 0.000000 -1.000000 +vn -1.000000 0.000000 0.000000 +usemtl None +s off +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 2/1/2 5/2/2 6/5/2 3/6/2 +f 2/3/3 1/6/3 7/1/3 5/2/3 +f 7/7/4 4/3/4 3/8/4 6/6/4 +f 5/1/5 7/2/5 6/4/5 +f 7/1/6 1/2/6 4/5/6 diff --git a/mods/z_remove/moreblocks/models/moreblocks_slope_half.obj b/mods/z_remove/moreblocks/models/moreblocks_slope_half.obj new file mode 100644 index 00000000..a6b1a562 --- /dev/null +++ b/mods/z_remove/moreblocks/models/moreblocks_slope_half.obj @@ -0,0 +1,28 @@ +# Blender v2.72 (sub 0) OBJ File: '' +# www.blender.org +mtllib moreblocks_slope_half.mtl +o Cube_Cube.002 +v 0.500000 -0.000000 0.500000 +v -0.500000 -0.000000 0.500000 +v -0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 -0.500000 +vt 1.000000 0.500000 +vt 0.000000 0.500000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vn 0.000000 -0.000000 1.000000 +vn 0.000000 -1.000000 -0.000000 +vn -1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 0.894400 -0.447200 +usemtl None +s off +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 4/3/2 3/4/2 5/5/2 6/6/2 +f 2/1/3 5/3/3 3/4/3 +f 1/2/4 4/3/4 6/4/4 +f 2/5/5 1/6/5 6/3/5 5/4/5 diff --git a/mods/z_remove/moreblocks/models/moreblocks_slope_half_raised.obj b/mods/z_remove/moreblocks/models/moreblocks_slope_half_raised.obj new file mode 100644 index 00000000..6f985e37 --- /dev/null +++ b/mods/z_remove/moreblocks/models/moreblocks_slope_half_raised.obj @@ -0,0 +1,32 @@ +# Blender v2.72 (sub 0) OBJ File: '' +# www.blender.org +mtllib moreblocks_slope_half_raised.mtl +o Cube.001 +v -0.500000 0.500000 0.500000 +v -0.500000 0.000000 -0.500000 +v -0.500000 -0.500000 -0.500000 +v -0.500000 -0.500000 0.500000 +v 0.500000 0.000000 -0.500000 +v 0.500000 -0.500000 -0.500000 +v 0.500000 0.500000 0.500000 +v 0.500000 -0.500000 0.500000 +vt 1.000000 1.000000 +vt 0.000000 0.500000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.500000 +vt 0.000000 1.000000 +vn -1.000000 0.000000 0.000000 +vn 0.000000 0.000000 -1.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -0.000000 1.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 0.894400 -0.447200 +usemtl None.001 +s off +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 2/5/2 5/2/2 6/3/2 3/4/2 +f 5/5/3 7/6/3 8/3/3 6/4/3 +f 7/1/4 1/6/4 4/3/4 8/4/4 +f 4/4/5 3/1/5 6/6/5 8/3/5 +f 2/4/6 1/1/6 7/6/6 5/3/6 diff --git a/mods/z_remove/moreblocks/models/moreblocks_slope_inner.obj b/mods/z_remove/moreblocks/models/moreblocks_slope_inner.obj new file mode 100644 index 00000000..d4a444ea --- /dev/null +++ b/mods/z_remove/moreblocks/models/moreblocks_slope_inner.obj @@ -0,0 +1,35 @@ +# Blender v2.72 (sub 0) OBJ File: '' +# www.blender.org +mtllib moreblocks_slope_inner.mtl +o Cube_Cube.000 +v 0.500000 0.500000 -0.500000 +v 0.500000 0.500000 0.500000 +v 0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 -0.500000 +v -0.500000 0.500000 0.500000 +v -0.500000 -0.500000 -0.500000 +v -0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 0.500000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn 0.000000 0.707100 -0.707100 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -0.000000 1.000000 +vn -0.707100 0.707100 0.000000 +usemtl None +s off +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 5/1/2 6/3/2 7/4/2 +f 5/1/3 2/2/3 6/4/3 +f 1/2/4 4/3/4 8/4/4 +f 8/1/5 4/2/5 3/3/5 7/4/5 +f 7/3/6 3/4/6 2/1/6 5/2/6 +f 2/1/7 1/2/7 8/3/7 +l 7 9 +l 2 9 diff --git a/mods/z_remove/moreblocks/models/moreblocks_slope_inner_cut.obj b/mods/z_remove/moreblocks/models/moreblocks_slope_inner_cut.obj new file mode 100644 index 00000000..b687b112 --- /dev/null +++ b/mods/z_remove/moreblocks/models/moreblocks_slope_inner_cut.obj @@ -0,0 +1,32 @@ +# Blender v2.72 (sub 0) OBJ File: '' +# www.blender.org +mtllib moreblocks_slope_inner_cut.mtl +o moreblocks_slope_inner_cut +v 0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 -0.500000 +v 0.500000 0.500000 -0.500000 +v 0.500000 0.500000 0.500000 +v -0.500000 -0.500000 0.500000 +v -0.500000 0.500000 0.500000 +v -0.500000 -0.500000 -0.500000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.500000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -0.000000 1.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 1.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn 0.000000 0.000000 -1.000000 +vn -0.577400 0.577400 -0.577400 +usemtl None +s off +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 5/1/2 1/2/2 4/3/2 6/4/2 +f 2/1/3 1/2/3 5/3/3 7/4/3 +f 6/1/4 4/2/4 3/3/4 +f 7/1/5 5/2/5 6/3/5 +f 2/1/6 7/2/6 3/4/6 +f 7/5/7 6/3/7 3/4/7 diff --git a/mods/z_remove/moreblocks/models/moreblocks_slope_inner_cut_half.obj b/mods/z_remove/moreblocks/models/moreblocks_slope_inner_cut_half.obj new file mode 100644 index 00000000..82a387bf --- /dev/null +++ b/mods/z_remove/moreblocks/models/moreblocks_slope_inner_cut_half.obj @@ -0,0 +1,34 @@ +# Blender v2.72 (sub 0) OBJ File: '' +# www.blender.org +mtllib moreblocks_slope_inner_cut_half.mtl +o moreblocks_slope_inner_cut_half +v 0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 -0.500000 +v 0.500000 0.000000 -0.500000 +v 0.500000 -0.000000 0.500000 +v -0.500000 -0.500000 0.500000 +v -0.500000 -0.000000 0.500000 +v -0.500000 -0.500000 -0.500000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.500000 +vt 0.000000 0.500000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.500000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -0.000000 1.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 1.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn 0.000000 0.000000 -1.000000 +vn -0.408200 0.816500 -0.408200 +usemtl None +s off +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 5/1/2 1/2/2 4/3/2 6/4/2 +f 2/1/3 1/2/3 5/5/3 7/6/3 +f 6/1/4 4/2/4 3/5/4 +f 7/1/5 5/2/5 6/3/5 +f 2/1/6 7/2/6 3/4/6 +f 7/7/7 6/5/7 3/6/7 diff --git a/mods/z_remove/moreblocks/models/moreblocks_slope_inner_cut_half_raised.obj b/mods/z_remove/moreblocks/models/moreblocks_slope_inner_cut_half_raised.obj new file mode 100644 index 00000000..8231ee44 --- /dev/null +++ b/mods/z_remove/moreblocks/models/moreblocks_slope_inner_cut_half_raised.obj @@ -0,0 +1,35 @@ +# Blender v2.72 (sub 0) OBJ File: '' +# www.blender.org +mtllib moreblocks_slope_inner_cut_half_raised.mtl +o moreblocks_slope_inner_cut_half_raised +v 0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 -0.500000 +v 0.500000 0.500000 -0.500000 +v 0.500000 0.500000 0.500000 +v -0.500000 -0.500000 0.500000 +v -0.500000 0.500000 0.500000 +v -0.500000 -0.500000 -0.500000 +v -0.500000 0.000000 -0.500000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.500000 +vt 1.000000 0.500000 +vt 0.500000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -0.000000 1.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 1.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn -0.000000 0.000000 -1.000000 +vn -0.408200 0.816500 -0.408200 +usemtl None +s off +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 5/1/2 1/2/2 4/3/2 6/4/2 +f 2/1/3 1/2/3 5/3/3 7/4/3 +f 6/1/4 4/2/4 3/3/4 +f 7/1/5 5/2/5 6/3/5 8/5/5 +f 2/1/6 7/2/6 8/6/6 3/4/6 +f 8/7/7 6/3/7 3/4/7 diff --git a/mods/z_remove/moreblocks/models/moreblocks_slope_inner_half.obj b/mods/z_remove/moreblocks/models/moreblocks_slope_inner_half.obj new file mode 100644 index 00000000..3e54dead --- /dev/null +++ b/mods/z_remove/moreblocks/models/moreblocks_slope_inner_half.obj @@ -0,0 +1,35 @@ +# Blender v2.72 (sub 0) OBJ File: '' +# www.blender.org +mtllib moreblocks_slope_inner_half.mtl +o Cube_Cube.001 +v 0.500000 0.000000 -0.500000 +v 0.500000 -0.000000 0.500000 +v 0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 -0.500000 +v -0.500000 -0.000000 0.500000 +v -0.500000 -0.500000 -0.500000 +v -0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 0.500000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn 0.000000 0.894400 -0.447200 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -0.000000 1.000000 +vn -0.447200 0.894400 0.000000 +usemtl None.002 +s off +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 5/1/2 6/3/2 7/4/2 +f 5/1/3 2/2/3 6/4/3 +f 1/2/4 4/3/4 8/4/4 +f 8/1/5 4/2/5 3/3/5 7/4/5 +f 7/3/6 3/4/6 2/1/6 5/2/6 +f 2/1/7 1/2/7 8/3/7 +l 7 9 +l 2 9 diff --git a/mods/z_remove/moreblocks/models/moreblocks_slope_inner_half_raised.obj b/mods/z_remove/moreblocks/models/moreblocks_slope_inner_half_raised.obj new file mode 100644 index 00000000..e6c22058 --- /dev/null +++ b/mods/z_remove/moreblocks/models/moreblocks_slope_inner_half_raised.obj @@ -0,0 +1,38 @@ +# Blender v2.72 (sub 0) OBJ File: '' +# www.blender.org +mtllib moreblocks_slope_inner_half_raised.mtl +o Cube_Cube.003 +v 0.500000 0.500000 -0.500000 +v 0.500000 0.500000 0.500000 +v 0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 -0.500000 +v -0.500000 0.500000 0.500000 +v -0.500000 0.000000 -0.500000 +v -0.500000 -0.500000 0.500000 +v -0.500000 0.000000 -0.500000 +v -0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 0.500000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.500000 +vt 0.000000 0.500000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 0.894400 -0.447200 +vn 0.000000 -0.000000 1.000000 +vn -0.447200 0.894400 0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 0.000000 -1.000000 +vn -1.000000 0.000000 0.000000 +usemtl None.003 +s off +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 5/1/2 2/2/2 6/4/2 +f 7/3/3 3/4/3 2/1/3 5/2/3 +f 2/2/4 1/3/4 8/4/4 +f 7/1/5 9/2/5 4/3/5 3/4/5 +f 6/5/6 1/2/6 4/3/6 9/4/6 +f 7/4/7 5/1/7 6/6/7 9/3/7 +l 2 10 +l 7 10 diff --git a/mods/z_remove/moreblocks/models/moreblocks_slope_outer.obj b/mods/z_remove/moreblocks/models/moreblocks_slope_outer.obj new file mode 100644 index 00000000..b8f4e9e9 --- /dev/null +++ b/mods/z_remove/moreblocks/models/moreblocks_slope_outer.obj @@ -0,0 +1,25 @@ +# Blender v2.72 (sub 0) OBJ File: '' +# www.blender.org +mtllib moreblocks_slope_outer.mtl +o Cube_Cube.004 +v 0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 -0.500000 +v 0.500000 0.500000 0.500000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -0.000000 1.000000 +vn -0.707100 0.707100 0.000000 +vn 0.000000 0.707100 -0.707100 +usemtl None +s off +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 5/2/2 1/3/2 4/4/2 +f 2/3/3 1/4/3 5/1/3 +f 5/1/4 3/3/4 2/4/4 +f 5/2/5 4/3/5 3/4/5 diff --git a/mods/z_remove/moreblocks/models/moreblocks_slope_outer_cut.obj b/mods/z_remove/moreblocks/models/moreblocks_slope_outer_cut.obj new file mode 100644 index 00000000..e6cbfb48 --- /dev/null +++ b/mods/z_remove/moreblocks/models/moreblocks_slope_outer_cut.obj @@ -0,0 +1,23 @@ +# Blender v2.72 (sub 0) OBJ File: '' +# www.blender.org +mtllib moreblocks_slope_outer_cut.mtl +o Cube.002 +v 0.500000 0.500000 0.500000 +v -0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 -0.500000 +vt 1.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.000000 1.000000 +vt 0.500000 1.000000 +vn 0.000000 -0.000000 1.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn -0.577400 0.577400 -0.577400 +usemtl None.004 +s off +f 1/1/1 2/2/1 3/3/1 +f 4/3/2 1/4/2 3/2/2 +f 3/2/3 2/3/3 4/4/3 +f 2/3/4 1/5/4 4/2/4 diff --git a/mods/z_remove/moreblocks/models/moreblocks_slope_outer_cut_half.obj b/mods/z_remove/moreblocks/models/moreblocks_slope_outer_cut_half.obj new file mode 100644 index 00000000..bd641941 --- /dev/null +++ b/mods/z_remove/moreblocks/models/moreblocks_slope_outer_cut_half.obj @@ -0,0 +1,24 @@ +# Blender v2.72 (sub 0) OBJ File: '' +# www.blender.org +mtllib moreblocks_slope_outer_cut_half.mtl +o Cube.003 +v 0.500000 -0.000000 0.500000 +v -0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 -0.500000 +vt 1.000000 0.500000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.000000 0.500000 +vt 0.000000 1.000000 +vt 0.500000 1.000000 +vn 0.000000 -0.000000 1.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn -0.408200 0.816500 -0.408200 +usemtl None.005 +s off +f 1/1/1 2/2/1 3/3/1 +f 4/3/2 1/4/2 3/2/2 +f 3/2/3 2/3/3 4/5/3 +f 2/3/4 1/6/4 4/2/4 diff --git a/mods/z_remove/moreblocks/models/moreblocks_slope_outer_cut_half_raised.obj b/mods/z_remove/moreblocks/models/moreblocks_slope_outer_cut_half_raised.obj new file mode 100644 index 00000000..c65e08dd --- /dev/null +++ b/mods/z_remove/moreblocks/models/moreblocks_slope_outer_cut_half_raised.obj @@ -0,0 +1,28 @@ +# Blender v2.72 (sub 0) OBJ File: '' +# www.blender.org +mtllib moreblocks_slope_outer_cut_half_raised.mtl +o Cube_Cube.005 +v -0.500000 -0.000000 0.500000 +v -0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 0.500000 +v 0.500000 0.500000 0.500000 +v 0.500000 -0.500000 -0.500000 +v 0.500000 0.000000 -0.500000 +vt 0.000000 0.500000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 0.500000 +vn 0.000000 -0.000000 1.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn -0.408200 0.816500 -0.408200 +vn -0.707100 0.000000 -0.707100 +usemtl None.006 +s off +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 4/5/2 3/2/2 5/3/2 6/6/2 +f 2/5/3 5/3/3 3/4/3 +f 1/2/4 4/3/4 6/4/4 +f 2/3/5 1/6/5 6/1/5 5/2/5 diff --git a/mods/z_remove/moreblocks/models/moreblocks_slope_outer_half.obj b/mods/z_remove/moreblocks/models/moreblocks_slope_outer_half.obj new file mode 100644 index 00000000..7bbb38de --- /dev/null +++ b/mods/z_remove/moreblocks/models/moreblocks_slope_outer_half.obj @@ -0,0 +1,27 @@ +# Blender v2.72 (sub 0) OBJ File: '' +# www.blender.org +mtllib moreblocks_slope_outer_half.mtl +o Cube.004 +v -0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 0.500000 +v 0.500000 -0.000000 0.500000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.500000 +vt 0.000000 0.500000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -0.000000 1.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 0.894400 -0.447200 +vn -0.447200 0.894400 0.000000 +usemtl None.007 +s off +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 5/5/2 1/3/2 4/4/2 +f 3/4/3 5/6/3 4/3/3 +f 2/4/4 5/2/4 3/3/4 +f 1/4/5 5/1/5 2/3/5 diff --git a/mods/z_remove/moreblocks/models/moreblocks_slope_outer_half_raised.obj b/mods/z_remove/moreblocks/models/moreblocks_slope_outer_half_raised.obj new file mode 100644 index 00000000..51a929a2 --- /dev/null +++ b/mods/z_remove/moreblocks/models/moreblocks_slope_outer_half_raised.obj @@ -0,0 +1,34 @@ +# Blender v2.72 (sub 0) OBJ File: '' +# www.blender.org +mtllib moreblocks_slope_outer_half_raised.mtl +o Cube_Cube.006 +v -0.500000 -0.000000 0.500000 +v -0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 0.500000 +v 0.500000 0.500000 0.500000 +v 0.500000 -0.500000 -0.500000 +v 0.500000 0.000000 -0.500000 +v -0.500000 0.000000 -0.500000 +v -0.500000 -0.500000 -0.500000 +vt 0.000000 0.500000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 0.500000 +vn 0.000000 -0.000000 1.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 0.894400 -0.447200 +vn -1.000000 0.000000 0.000000 +vn -0.447200 0.894400 0.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 -1.000000 -0.000000 +usemtl None.008 +s off +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 4/5/2 3/2/2 5/3/2 6/6/2 +f 7/3/3 4/5/3 6/2/3 +f 1/6/4 7/1/4 8/2/4 2/3/4 +f 7/3/5 1/4/5 4/5/5 +f 6/1/6 5/2/6 8/3/6 7/6/6 +f 5/5/7 3/2/7 2/3/7 8/4/7 diff --git a/mods/z_remove/moreblocks/nodes.lua b/mods/z_remove/moreblocks/nodes.lua new file mode 100644 index 00000000..a7e6b76c --- /dev/null +++ b/mods/z_remove/moreblocks/nodes.lua @@ -0,0 +1,372 @@ +--[[ +More Blocks: node definitions + +Copyright (c) 2011-2015 Calinou and contributors. +Licensed under the zlib license. See LICENSE.md for more information. +--]] + +local S = moreblocks.intllib + +local sound_wood = default.node_sound_wood_defaults() +local sound_stone = default.node_sound_stone_defaults() +local sound_glass = default.node_sound_glass_defaults() +local sound_leaves = default.node_sound_leaves_defaults() + +local function tile_tiles(name) + local tex = "moreblocks_" ..name.. ".png" + return {tex, tex, tex, tex, tex.. "^[transformR90", tex.. "^[transformR90"} +end + +local nodes = { +--[[ ["wood_tile"] = { + description = S("Wooden Tile"), + groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + tiles = {"default_wood.png^moreblocks_wood_tile.png", + "default_wood.png^moreblocks_wood_tile.png", + "default_wood.png^moreblocks_wood_tile.png", + "default_wood.png^moreblocks_wood_tile.png", + "default_wood.png^moreblocks_wood_tile.png^[transformR90", + "default_wood.png^moreblocks_wood_tile.png^[transformR90"}, + sounds = sound_wood, + }, + ["wood_tile_flipped"] = { + description = S("Wooden Tile"), + groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + tiles = {"default_wood.png^moreblocks_wood_tile.png^[transformR90", + "default_wood.png^moreblocks_wood_tile.png^[transformR90", + "default_wood.png^moreblocks_wood_tile.png^[transformR90", + "default_wood.png^moreblocks_wood_tile.png^[transformR90", + "default_wood.png^moreblocks_wood_tile.png^[transformR180", + "default_wood.png^moreblocks_wood_tile.png^[transformR180"}, + sounds = sound_wood, + no_stairs = true, + }, + ["wood_tile_center"] = { + description = S("Centered Wooden Tile"), + groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + tiles = {"default_wood.png^moreblocks_wood_tile_center.png"}, + sounds = sound_wood, + }, + ["wood_tile_full"] = { + description = S("Full Wooden Tile"), + groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + tiles = tile_tiles("wood_tile_full"), + sounds = sound_wood, + }, + ["wood_tile_up"] = { + description = S("Upwards Wooden Tile"), + groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + tiles = {"default_wood.png^moreblocks_wood_tile_up.png"}, + sounds = sound_wood, + no_stairs = true, + }, + ["wood_tile_down"] = { + description = S("Downwards Wooden Tile"), + groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + tiles = {"default_wood.png^[transformR180^moreblocks_wood_tile_up.png^[transformR180"}, + sounds = sound_wood, + no_stairs = true, + }, + ["wood_tile_left"] = { + description = S("Leftwards Wooden Tile"), + groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + tiles = {"default_wood.png^[transformR270^moreblocks_wood_tile_up.png^[transformR270"}, + sounds = sound_wood, + no_stairs = true, + }, + ["wood_tile_right"] = { + description = S("Rightwards Wooden Tile"), + groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + tiles = {"default_wood.png^[transformR90^moreblocks_wood_tile_up.png^[transformR90"}, + sounds = sound_wood, + no_stairs = true, + }, + ["circle_stone_bricks"] = { + description = S("Circle Stone Bricks"), + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["grey_bricks"] = { + description = S("Stone Bricks"), + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["coal_stone_bricks"] = { + description = S("Coal Stone Bricks"), + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["iron_stone_bricks"] = { + description = S("Iron Stone Bricks"), + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["stone_tile"] = { + description = S("Stone Tile"), + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["split_stone_tile"] = { + description = S("Split Stone Tile"), + tiles = {"moreblocks_split_stone_tile_top.png", + "moreblocks_split_stone_tile.png"}, + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["split_stone_tile_alt"] = { + description = S("Checkered Stone Tile"), + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["tar"] = { + description = S("Tar"), + groups = {cracky = 2, tar_block = 1}, + sounds = sound_stone, + }, + ["cobble_compressed"] = { + description = S("Compressed Cobblestone"), + groups = {cracky = 1}, + sounds = sound_stone, + }, + ["plankstone"] = { + description = S("Plankstone"), + groups = {cracky = 3}, + tiles = tile_tiles("plankstone"), + sounds = sound_stone, + }, + ["iron_glass"] = { + description = S("Iron Glass"), + drawtype = "glasslike_framed_optional", + --tiles = {"moreblocks_iron_glass.png", "moreblocks_iron_glass_detail.png"}, + tiles = {"moreblocks_iron_glass.png"}, + paramtype = "light", + sunlight_propagates = true, + groups = {snappy = 2, cracky = 3, oddly_breakable_by_hand = 3}, + sounds = sound_glass, + }, + ["coal_glass"] = { + description = S("Coal Glass"), + drawtype = "glasslike_framed_optional", + --tiles = {"moreblocks_coal_glass.png", "moreblocks_coal_glass_detail.png"}, + tiles = {"moreblocks_coal_glass.png"}, + paramtype = "light", + sunlight_propagates = true, + groups = {snappy = 2, cracky = 3, oddly_breakable_by_hand = 3}, + sounds = sound_glass, + }, + ["clean_glass"] = { + description = S("Clean Glass"), + drawtype = "glasslike_framed_optional", + --tiles = {"moreblocks_clean_glass.png", "moreblocks_clean_glass_detail.png"}, + tiles = {"moreblocks_clean_glass.png"}, + paramtype = "light", + sunlight_propagates = true, + groups = {snappy = 2, cracky = 3, oddly_breakable_by_hand = 3}, + sounds = sound_glass, + }, + ["cactus_brick"] = { + description = S("Cactus Brick"), + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["cactus_checker"] = { + description = S("Cactus Checker"), + groups = {cracky = 3}, + tiles = {"default_stone.png^moreblocks_cactus_checker.png", + "default_stone.png^moreblocks_cactus_checker.png", + "default_stone.png^moreblocks_cactus_checker.png", + "default_stone.png^moreblocks_cactus_checker.png", + "default_stone.png^moreblocks_cactus_checker.png^[transformR90", + "default_stone.png^moreblocks_cactus_checker.png^[transformR90"}, + sounds = sound_stone, + }, + ["empty_bookshelf"] = { + description = S("Empty Bookshelf"), + tiles = {"default_wood.png", "default_wood.png", + "moreblocks_empty_bookshelf.png"}, + groups = {snappy = 2, choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = sound_wood, + no_stairs = true, + }, + ["coal_stone"] = { + description = S("Coal Stone"), + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["iron_stone"] = { + description = S("Iron Stone"), + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["coal_checker"] = { + description = S("Coal Checker"), + tiles = {"default_stone.png^moreblocks_coal_checker.png", + "default_stone.png^moreblocks_coal_checker.png", + "default_stone.png^moreblocks_coal_checker.png", + "default_stone.png^moreblocks_coal_checker.png", + "default_stone.png^moreblocks_coal_checker.png^[transformR90", + "default_stone.png^moreblocks_coal_checker.png^[transformR90"}, + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["iron_checker"] = { + description = S("Iron Checker"), + tiles = {"default_stone.png^moreblocks_iron_checker.png", + "default_stone.png^moreblocks_iron_checker.png", + "default_stone.png^moreblocks_iron_checker.png", + "default_stone.png^moreblocks_iron_checker.png", + "default_stone.png^moreblocks_iron_checker.png^[transformR90", + "default_stone.png^moreblocks_iron_checker.png^[transformR90"}, + groups = {cracky = 3}, + sounds = sound_stone, + }, + ["trap_stone"] = { + description = S("Trap Stone"), + walkable = false, + groups = {cracky = 3}, + sounds = sound_stone, + no_stairs = true, + }, + ["trap_glass"] = { + description = S("Trap Glass"), + drawtype = "glasslike_framed_optional", + --tiles = {"moreblocks_trap_glass.png", "default_glass_detail.png"}, + tiles = {"moreblocks_trap_glass.png"}, + paramtype = "light", + sunlight_propagates = true, + walkable = false, + groups = {snappy = 2, cracky = 3, oddly_breakable_by_hand = 3}, + sounds = sound_glass, + no_stairs = true, + }, + ["fence_jungle_wood"] = { + description = S("Jungle Wood Fence"), + drawtype = "fencelike", + tiles = {"default_junglewood.png"}, + inventory_image = "default_fence_overlay.png^default_junglewood.png^default_fence_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_overlay.png^default_junglewood.png^default_fence_overlay.png^[makealpha:255,126,126", + paramtype = "light", + selection_box = { + type = "fixed", + fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7}, + }, + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + sounds = sound_wood, + no_stairs = true, + }, + ["all_faces_tree"] = { + description = S("All-faces Tree"), + tiles = {"default_tree_top.png"}, + groups = {tree = 1,snappy = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = sound_wood, + furnace_burntime = 30, + }, + ["all_faces_jungle_tree"] = { + description = S("All-faces Jungle Tree"), + tiles = {"default_jungletree_top.png"}, + groups = {tree = 1,snappy = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = sound_wood, + furnace_burntime = 30, + }, + ["glow_glass"] = { + description = S("Glow Glass"), + drawtype = "glasslike_framed_optional", + --tiles = {"moreblocks_glow_glass.png", "moreblocks_glow_glass_detail.png"}, + tiles = {"moreblocks_glow_glass.png"}, + paramtype = "light", + sunlight_propagates = true, + light_source = 11, + groups = {snappy = 2, cracky = 3, oddly_breakable_by_hand = 3}, + sounds = sound_glass, + }, + ["trap_glow_glass"] = { + description = S("Trap Glow Glass"), + drawtype = "glasslike_framed_optional", + --tiles = {"moreblocks_trap_glass.png", "moreblocks_glow_glass_detail.png"}, + tiles = {"moreblocks_trap_glass.png"}, + paramtype = "light", + sunlight_propagates = true, + light_source = 11, + walkable = false, + groups = {snappy = 2, cracky = 3, oddly_breakable_by_hand = 3}, + sounds = sound_glass, + no_stairs = true, + }, + ["super_glow_glass"] = { + description = S("Super Glow Glass"), + drawtype = "glasslike_framed_optional", + --tiles = {"moreblocks_super_glow_glass.png", "moreblocks_super_glow_glass_detail.png"}, + tiles = {"moreblocks_super_glow_glass.png"}, + paramtype = "light", + sunlight_propagates = true, + light_source = 15, + groups = {snappy = 2, cracky = 3, oddly_breakable_by_hand = 3}, + sounds = sound_glass, + }, + ["trap_super_glow_glass"] = { + description = S("Trap Super Glow Glass"), + drawtype = "glasslike_framed_optional", + --tiles = {"moreblocks_trap_super_glow_glass.png", "moreblocks_super_glow_glass_detail.png"}, + tiles = {"moreblocks_trap_super_glow_glass.png"}, + paramtype = "light", + sunlight_propagates = true, + light_source = 15, + walkable = false, + groups = {snappy = 2, cracky = 3, oddly_breakable_by_hand = 3}, + sounds = sound_glass, + no_stairs = true, + }, + ["rope"] = { + description = S("Rope"), + drawtype = "signlike", + inventory_image = "moreblocks_rope.png", + wield_image = "moreblocks_rope.png", + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "wallmounted", + walkable = false, + climbable = true, + selection_box = {type = "wallmounted",}, + groups = {snappy = 3, flammable = 2}, + sounds = sound_leaves, + no_stairs = true, + },]] +} + +for name, def in pairs(nodes) do + def.tiles = def.tiles or {"moreblocks_" ..name.. ".png"} + minetest.register_node("moreblocks:" ..name, def) + minetest.register_alias(name, "moreblocks:" ..name) + if not def.no_stairs then + local groups = {} + for k, v in pairs(def.groups) do groups[k] = v end + stairsplus:register_all("moreblocks", name, "moreblocks:" ..name, { + description = def.description, + groups = groups, + tiles = def.tiles, + sunlight_propagates = def.sunlight_propagates, + light_source = def.light_source, + sounds = def.sounds, + }) + end +end + + +-- Items + +--[[minetest.register_craftitem("moreblocks:sweeper", { + description = S("Sweeper"), + inventory_image = "moreblocks_sweeper.png", +}) + +minetest.register_craftitem("moreblocks:jungle_stick", { + description = S("Jungle Stick"), + inventory_image = "moreblocks_junglestick.png", + groups = {stick= 1}, +})]] + +minetest.register_craftitem("moreblocks:nothing", { + inventory_image = "invisible.png", + on_use = function() end, +}) + diff --git a/mods/z_remove/moreblocks/ownership.lua b/mods/z_remove/moreblocks/ownership.lua new file mode 100644 index 00000000..1c2431ba --- /dev/null +++ b/mods/z_remove/moreblocks/ownership.lua @@ -0,0 +1,41 @@ +--[[ +More Blocks: ownership handling + +Copyright (c) 2011-2015 Calinou and contributors. +Licensed under the zlib license. See LICENSE.md for more information. +--]] + +local S = moreblocks.gettext + +function moreblocks.node_is_owned(pos, placer) + local ownername = false + if type(IsPlayerNodeOwner) == "function" then -- node_ownership mod + if HasOwner(pos, placer) then -- returns true if the node is owned + if not IsPlayerNodeOwner(pos, placer:get_player_name()) then + if type(getLastOwner) == "function" then -- ...is an old version + ownername = getLastOwner(pos) + elseif type(GetNodeOwnerName) == "function" then -- ...is a recent version + ownername = GetNodeOwnerName(pos) + else + ownername = S("someone") + end + end + end + + elseif type(isprotect)=="function" then -- glomie's protection mod + if not isprotect(5, pos, placer) then + ownername = S("someone") + end + elseif type(protector)=="table" and type(protector.can_dig)=="function" then -- Zeg9's protection mod + if not protector.can_dig(5, pos, placer) then + ownername = S("someone") + end + end + + if ownername ~= false then + minetest.chat_send_player( placer:get_player_name(), S("Sorry, %s owns that spot."):format(ownername) ) + return true + else + return false + end +end diff --git a/mods/z_remove/moreblocks/redefinitions.lua b/mods/z_remove/moreblocks/redefinitions.lua new file mode 100644 index 00000000..9dc7ae37 --- /dev/null +++ b/mods/z_remove/moreblocks/redefinitions.lua @@ -0,0 +1,100 @@ +--[[ +More Blocks: redefinitions of default stuff + +Copyright (c) 2011-2015 Calinou and contributors. +Licensed under the zlib license. See LICENSE.md for more information. +--]] + +-- Redefinitions of some default crafting recipes: + +minetest.register_craft({ + output = "default:sign_wall 4", + recipe = { + {"default:wood", "default:wood", "default:wood"}, + {"default:wood", "default:wood", "default:wood"}, + {"", "default:stick", ""}, + } +}) + +minetest.register_craft({ + output = "default:ladder 4", + recipe = { + {"default:stick", "", "default:stick"}, + {"default:stick", "default:stick", "default:stick"}, + {"default:stick", "", "default:stick"}, + } +}) + +minetest.register_craft({ + output = "default:paper 4", + recipe = { + {"default:papyrus", "default:papyrus", "default:papyrus"}, + } +}) + +minetest.register_craft({ + output = "default:rail 24", + recipe = { + {"default:steel_ingot", "", "default:steel_ingot"}, + {"default:steel_ingot", "default:stick", "default:steel_ingot"}, + {"default:steel_ingot", "", "default:steel_ingot"}, + } +}) + +minetest.register_craft({ + type = "toolrepair", + additional_wear = -0.10, -- Tool repair buff (10% bonus instead of 2%). +}) + +-- Redefinitions of some default nodes +-- =================================== + +-- Let there be light. This makes some nodes let light pass through: +minetest.override_item("default:ladder", { + paramtype = "light", + sunlight_propagates = true, +}) + +minetest.override_item("default:sapling", { + paramtype = "light", + sunlight_propagates = true, +}) + +minetest.override_item("default:dry_shrub", { + paramtype = "light", + sunlight_propagates = true, +}) + +minetest.override_item("default:papyrus", { + paramtype = "light", + sunlight_propagates = true, +}) + +minetest.override_item("default:fence_wood", { + paramtype = "light", + sunlight_propagates = true, +}) + +minetest.override_item("default:junglegrass", { + paramtype = "light", + sunlight_propagates = true, +}) + +minetest.override_item("default:junglesapling", { + paramtype = "light", + sunlight_propagates = true, +}) + +minetest.override_item("default:grass_1", { + inventory_image = "default_grass_3.png", -- Use a bigger inventory image. + wield_image = "default_grass_3.png", + paramtype = "light", + sunlight_propagates = true, +}) + +for i = 2, 5 do + minetest.override_item("default:grass_" ..i, { + paramtype = "light", + sunlight_propagates = true, + }) +end diff --git a/mods/z_remove/moreblocks/stairsplus/API.md b/mods/z_remove/moreblocks/stairsplus/API.md new file mode 100644 index 00000000..2db0f2b3 --- /dev/null +++ b/mods/z_remove/moreblocks/stairsplus/API.md @@ -0,0 +1,24 @@ +API documentation for Stairs+ +============================= + +* `stairsplus:register_all(modname, subname, recipeitem, fields)` + Registers a stair, slab, panel, microblock, and any other types of + nodes to be added in the future. + This also registers the node with the circular saw. + Example: + ```lua + stairsplus:register_all("moreblocks", "wood", "defaut:wood", { + description = "Wooden", + tiles = {"default_wood.png"}, + groups = {oddly_breakabe_by_hand=1}, + sounds = default.node_sound_wood_defaults(), + }) + ``` +The following register only a particular type of microblock. +You will probably never want to use them directly: + +* `stairsplus:register_stair(modname, subname, recipeitem, fields)` +* `stairsplus:register_slab(modname, subname, recipeitem, fields)` +* `stairsplus:register_panel(modname, subname, recipeitem, fields)` +* `stairsplus:register_micro(modname, subname, recipeitem, fields)` + diff --git a/mods/z_remove/moreblocks/stairsplus/aliases.lua b/mods/z_remove/moreblocks/stairsplus/aliases.lua new file mode 100644 index 00000000..64125428 --- /dev/null +++ b/mods/z_remove/moreblocks/stairsplus/aliases.lua @@ -0,0 +1,75 @@ +--[[ +More Blocks: alias definitions + +Copyright (c) 2011-2015 Calinou and contributors. +Licensed under the zlib license. See LICENSE.md for more information. +--]] + +local function register_stairsplus_alias(modname, origname, newname) + minetest.register_alias(modname.. ":slab_" ..origname, "moreblocks:slab_" ..newname) + minetest.register_alias(modname.. ":slab_" ..origname.. "_inverted", "moreblocks:slab_" ..newname.. "_inverted") + minetest.register_alias(modname.. ":slab_" ..origname.. "_wall", "moreblocks:slab_" ..newname.. "_wall") + minetest.register_alias(modname.. ":slab_" ..origname.. "_quarter", "moreblocks:slab_" ..newname.. "_quarter") + minetest.register_alias(modname.. ":slab_" ..origname.. "_quarter_inverted", "moreblocks:slab_" ..newname.. "_quarter_inverted") + minetest.register_alias(modname.. ":slab_" ..origname.. "_quarter_wall", "moreblocks:slab_" ..newname.. "_quarter_wall") + minetest.register_alias(modname.. ":slab_" ..origname.. "_three_quarter", "moreblocks:slab_" ..newname.. "_three_quarter") + minetest.register_alias(modname.. ":slab_" ..origname.. "_three_quarter_inverted", "moreblocks:slab_" ..newname.. "_three_quarter_inverted") + minetest.register_alias(modname.. ":slab_" ..origname.. "_three_quarter_wall", "moreblocks:slab_" ..newname.. "_three_quarter_wall") + minetest.register_alias(modname.. ":stair_" ..origname, "moreblocks:stair_" ..newname) + minetest.register_alias(modname.. ":stair_" ..origname.. "_inverted", "moreblocks:stair_" ..newname.. "_inverted") + minetest.register_alias(modname.. ":stair_" ..origname.. "_wall", "moreblocks:stair_" ..newname.. "_wall") + minetest.register_alias(modname.. ":stair_" ..origname.. "_wall_half", "moreblocks:stair_" ..newname.. "_wall_half") + minetest.register_alias(modname.. ":stair_" ..origname.. "_wall_half_inverted", "moreblocks:stair_" ..newname.. "_wall_half_inverted") + minetest.register_alias(modname.. ":stair_" ..origname.. "_half", "moreblocks:stair_" ..newname.. "_half") + minetest.register_alias(modname.. ":stair_" ..origname.. "_half_inverted", "moreblocks:stair_" ..newname.. "_half_inverted") + minetest.register_alias(modname.. ":stair_" ..origname.. "_right_half", "moreblocks:stair_" ..newname.. "_right_half") + minetest.register_alias(modname.. ":stair_" ..origname.. "_right_half_inverted", "moreblocks:stair_" ..newname.. "_right_half_inverted") + minetest.register_alias(modname.. ":stair_" ..origname.. "_wall_half", "moreblocks:stair_" ..newname.. "_wall_half") + minetest.register_alias(modname.. ":stair_" ..origname.. "_wall_half_inverted", "moreblocks:stair_" ..newname.. "_wall_half_inverted") + minetest.register_alias(modname.. ":stair_" ..origname.. "_inner", "moreblocks:stair_" ..newname.. "_inner") + minetest.register_alias(modname.. ":stair_" ..origname.. "_inner_inverted", "moreblocks:stair_" ..newname.. "_inner_inverted") + minetest.register_alias(modname.. ":stair_" ..origname.. "_outer", "moreblocks:stair_" ..newname.. "_outer") + minetest.register_alias(modname.. ":stair_" ..origname.. "_outer_inverted", "moreblocks:stair_" ..newname.. "_outer_inverted") + minetest.register_alias(modname.. ":panel_" ..origname.. "_bottom", "moreblocks:panel_" ..newname.. "_bottom") + minetest.register_alias(modname.. ":panel_" ..origname.. "_top", "moreblocks:panel_" ..newname.. "_top") + minetest.register_alias(modname.. ":panel_" ..origname.. "_vertical", "moreblocks:panel_" ..newname.. "_vertical") + minetest.register_alias(modname.. ":micro_" ..origname.. "_bottom", "moreblocks:micro_" ..newname.. "_bottom") + minetest.register_alias(modname.. ":micro_" ..origname.. "_top", "moreblocks:micro_" ..newname.. "_top") +end + +register_stairsplus_alias("stairsplus", "stone", "stone") +register_stairsplus_alias("stairsplus", "wood", "wood") +register_stairsplus_alias("stairsplus", "pinewood", "pinewood") +register_stairsplus_alias("stairsplus", "cobble", "cobble") +register_stairsplus_alias("stairsplus", "brick", "brick") +register_stairsplus_alias("stairsplus", "sandstone", "sandstone") +register_stairsplus_alias("stairsplus", "glass", "glass") +register_stairsplus_alias("stairsplus", "tree", "tree") +register_stairsplus_alias("stairsplus", "jungletree", "jungletree") +register_stairsplus_alias("stairsplus", "pinetree", "pinetree") +register_stairsplus_alias("stairsplus", "desert_stone", "desert_stone") +register_stairsplus_alias("stairsplus", "steelblock", "steelblock") +register_stairsplus_alias("stairsplus", "mossycobble", "mossycobble") + +register_stairsplus_alias("moreblocks", "coalstone", "coal_stone") +register_stairsplus_alias("moreblocks", "junglewood", "jungle_wood") +register_stairsplus_alias("moreblocks", "circlestonebrick", "circle_stone_bricks") +register_stairsplus_alias("moreblocks", "ironstone", "iron_stone") +register_stairsplus_alias("moreblocks", "coalglass", "coal_glass") +register_stairsplus_alias("moreblocks", "ironglass", "iron_glass") +register_stairsplus_alias("moreblocks", "glowglass", "glow_glass") +register_stairsplus_alias("moreblocks", "superglowglass", "super_glow_glass") +register_stairsplus_alias("moreblocks", "coalchecker", "coal_checker") +register_stairsplus_alias("moreblocks", "ironchecker", "iron_checker") +register_stairsplus_alias("moreblocks", "cactuschecker", "cactus_checker") +register_stairsplus_alias("moreblocks", "ironstonebrick", "iron_stone_bricks") +register_stairsplus_alias("moreblocks", "stonesquare", "stone_tile") +register_stairsplus_alias("moreblocks", "splitstonesquare", "split_stone_tile") +register_stairsplus_alias("moreblocks", "woodtile", "wood_tile") +register_stairsplus_alias("moreblocks", "woodtile_centered", "wood_tile_centered") +register_stairsplus_alias("moreblocks", "woodtile_full", "wood_tile_full") + + + + + diff --git a/mods/z_remove/moreblocks/stairsplus/conversion.lua b/mods/z_remove/moreblocks/stairsplus/conversion.lua new file mode 100644 index 00000000..13966b66 --- /dev/null +++ b/mods/z_remove/moreblocks/stairsplus/conversion.lua @@ -0,0 +1,139 @@ +--[[ +More Blocks: conversion + +Copyright (c) 2011-2015 Calinou and contributors. +Licensed under the zlib license. See LICENSE.md for more information. +--]] + +-- Function to convert all stairs/slabs/etc nodes from +-- inverted, wall, etc to regular + 6d facedir + +local dirs1 = {21, 20, 23, 22, 21} +local dirs2 = {15, 8, 17, 6, 15} +local dirs3 = {14, 11, 16, 5, 14} + +function stairsplus:register_6dfacedir_conversion(modname, material) + --print("Register stairsplus 6d facedir conversion") + --print('ABM for '..modname..' "'..material..'"') + + local objects_list1 = { + modname.. ":slab_" ..material.. "_inverted", + modname.. ":slab_" ..material.. "_quarter_inverted", + modname.. ":slab_" ..material.. "_three_quarter_inverted", + modname.. ":stair_" ..material.. "_inverted", + modname.. ":stair_" ..material.. "_wall", + modname.. ":stair_" ..material.. "_wall_half", + modname.. ":stair_" ..material.. "_wall_half_inverted", + modname.. ":stair_" ..material.. "_half_inverted", + modname.. ":stair_" ..material.. "_right_half_inverted", + modname.. ":panel_" ..material.. "_vertical", + modname.. ":panel_" ..material.. "_top", + } + + local objects_list2 = { + modname.. ":slab_" ..material.. "_wall", + modname.. ":slab_" ..material.. "_quarter_wall", + modname.. ":slab_" ..material.. "_three_quarter_wall", + modname.. ":stair_" ..material.. "_inner_inverted", + modname.. ":stair_" ..material.. "_outer_inverted", + modname.. ":micro_" ..material.. "_top" + } + + for _, object in pairs(objects_list1) do + local flip_upside_down = false + local flip_to_wall = false + + local dest_object = object + + if string.find(dest_object, "_inverted") then + flip_upside_down = true + dest_object = string.gsub(dest_object, "_inverted", "") + end + + if string.find(object, "_top") then + flip_upside_down = true + dest_object = string.gsub(dest_object, "_top", "") + end + + if string.find(dest_object, "_wall") then + flip_to_wall = true + dest_object = string.gsub(dest_object, "_wall", "") + end + + if string.find(dest_object, "_vertical") then + flip_to_wall = true + dest_object = string.gsub(dest_object, "_vertical", "") + end + + if string.find(dest_object, "_half") and not string.find(dest_object, "_right_half") then + dest_object = string.gsub(dest_object, "_half", "_right_half") + elseif string.find(dest_object, "_right_half") then + dest_object = string.gsub(dest_object, "_right_half", "_half") + end + + --print(" +---> convert " ..object) + --print(" | to " ..dest_object) + + minetest.register_abm({ + nodenames = {object}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local fdir = node.param2 or 0 + + if flip_upside_down and not flip_to_wall then + nfdir = dirs1[fdir + 2] + elseif flip_to_wall and not flip_upside_down then + nfdir = dirs2[fdir + 1] + elseif flip_to_wall and flip_upside_down then + nfdir = dirs3[fdir + 2] + end + minetest.set_node(pos, {name = dest_object, param2 = nfdir}) + end + }) + end + + for _, object in pairs(objects_list2) do + local flip_upside_down = false + local flip_to_wall = false + + local dest_object = object + + if string.find(dest_object, "_inverted") then + flip_upside_down = true + dest_object = string.gsub(dest_object, "_inverted", "") + end + + if string.find(dest_object, "_top") then + flip_upside_down = true + dest_object = string.gsub(dest_object, "_top", "") + end + + if string.find(dest_object, "_wall") then + flip_to_wall = true + dest_object = string.gsub(dest_object, "_wall", "") + end + + --print(" +---> convert " ..object) + --print(" | to " ..dest_object) + + minetest.register_abm({ + nodenames = {object}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local fdir = node.param2 + local nfdir = 20 + + if flip_upside_down and not flip_to_wall then + nfdir = dirs1[fdir + 1] + elseif flip_to_wall and not flip_upside_down then + nfdir = dirs2[fdir + 2] + + end + minetest.set_node(pos, {name = dest_object, param2 = nfdir}) + end + }) + end +end + diff --git a/mods/z_remove/moreblocks/stairsplus/init.lua b/mods/z_remove/moreblocks/stairsplus/init.lua new file mode 100644 index 00000000..4936f1e7 --- /dev/null +++ b/mods/z_remove/moreblocks/stairsplus/init.lua @@ -0,0 +1,56 @@ +--[[ +More Blocks: Stairs+ + +Copyright (c) 2011-2015 Calinou and contributors. +Licensed under the zlib license. See LICENSE.md for more information. +--]] + +-- Nodes will be called :{stair,slab,panel,micro}_ + +local modpath = minetest.get_modpath("moreblocks").. "/stairsplus" + +stairsplus = {} +stairsplus.expect_infinite_stacks = false + +if not minetest.get_modpath("unified_inventory") +and minetest.setting_getbool("creative_mode") then + stairsplus.expect_infinite_stacks = true +end + +function stairsplus:register_all(modname, subname, recipeitem, fields) + fields = fields or {} + fields.groups = fields.groups or {} + if not moreblocks.config.stairsplus_in_creative_inventory then + fields.groups.not_in_creative_inventory = 1 + end + if not moreblocks.config.stairsplus_in_craft_guide then + fields.groups.not_in_craft_guide = 1 + end + --self:register_stair(modname, subname, recipeitem, fields) + --self:register_slab (modname, subname, recipeitem, fields) + self:register_slope(modname, subname, recipeitem, fields) + self:register_panel(modname, subname, recipeitem, fields) + self:register_micro(modname, subname, recipeitem, fields) + -- self:register_6dfacedir_conversion(modname, subname) -- Not needed as of Q3 2013, uncomment to fix old maps. + circular_saw.known_nodes[recipeitem] = {modname, subname} +end + +--function register_stair_slab_panel_micro(modname, subname, recipeitem, groups, images, description, drop, light) +function register_panel_micro(modname, subname, recipeitem, groups, images, description, drop, light) + stairsplus:register_all(modname, subname, recipeitem, { + groups = groups, + tiles = images, + description = description, + drop = drop, + light_source = light + }) +end + +-- dofile(modpath.. "/aliases.lua") -- Not needed as of Q2 2013, uncomment to fix old maps. +-- dofile(modpath.. "/conversion.lua") -- Not needed as of Q2 2013, uncomment to fix old maps. +--dofile(modpath .. "/stairs.lua") +--dofile(modpath .. "/slabs.lua") +dofile(modpath .. "/slopes.lua") +dofile(modpath .. "/panels.lua") +dofile(modpath .. "/microblocks.lua") +dofile(modpath .. "/registrations.lua") diff --git a/mods/z_remove/moreblocks/stairsplus/microblocks.lua b/mods/z_remove/moreblocks/stairsplus/microblocks.lua new file mode 100644 index 00000000..19dcf20f --- /dev/null +++ b/mods/z_remove/moreblocks/stairsplus/microblocks.lua @@ -0,0 +1,136 @@ +--[[ +More Blocks: microblock definitions + +Copyright (c) 2011-2015 Calinou and contributors. +Licensed under the zlib license. See LICENSE.md for more information. +--]] + +local S = moreblocks.intllib + +-- Node will be called :micro_ + +function register_micro(modname, subname, recipeitem, groups, images, description, drop, light) + return stairsplus:register_micro(modname, subname, recipeitem, { + groups = groups, + tiles = images, + description = description, + drop = drop, + light_source = light, + sounds = default.node_sound_stone_defaults(), + }) +end + +function stairsplus:register_micro(modname, subname, recipeitem, fields) + local defs = { + [""] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0, 0, 0.5}, + }, + }, + ["_1"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0, -0.4375, 0.5}, + }, + }, + ["_2"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0, -0.375, 0.5}, + }, + }, + ["_4"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0, -0.25, 0.5}, + }, + }, + ["_12"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0, 0.25, 0.5}, + }, + }, + ["_14"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0, 0.375, 0.5}, + }, + }, + ["_15"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0, 0.4375, 0.5}, + }, + } + } + + local desc = S("%s Microblock"):format(fields.description) + for alternate, def in pairs(defs) do + def.drawtype = "nodebox" + def.paramtype = "light" + def.paramtype2 = "facedir" + def.on_place = minetest.rotate_node + for k, v in pairs(fields) do + def[k] = v + end + def.description = desc + if fields.drop then + def.drop = modname.. ":micro_" ..fields.drop..alternate + end + minetest.register_node(":" ..modname.. ":micro_" ..subname..alternate, def) + end + + minetest.register_alias(modname.. ":micro_" ..subname.. "_bottom", modname.. ":micro_" ..subname) + + -- Some saw-less recipes: + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":micro_" .. subname .. " 7", + recipe = {modname .. ":stair_" .. subname .. "_inner"}, + }) + + minetest.register_craft({ + output = modname .. ":micro_" .. subname .. " 6", + type = "shapeless", + recipe = {modname .. ":stair_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":micro_" .. subname .. " 5", + recipe = {modname .. ":stair_" .. subname .. "_outer"}, + }) + --[[ + minetest.register_craft({ + type = "shapeless", + output = modname .. ":micro_" .. subname .. " 4", + recipe = {modname .. ":slab_" .. subname}, + }) + ]] + minetest.register_craft({ + type = "shapeless", + output = modname .. ":micro_" .. subname .. " 4", + recipe = {modname .. ":stair_" .. subname .. "_alt"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":micro_" .. subname .. " 3", + recipe = {modname .. ":stair_" .. subname .. "_right_half"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":micro_" .. subname .. " 2", + recipe = {modname .. ":panel_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = recipeitem, + recipe = {modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname}, + }) +end diff --git a/mods/z_remove/moreblocks/stairsplus/panels.lua b/mods/z_remove/moreblocks/stairsplus/panels.lua new file mode 100644 index 00000000..2220fe42 --- /dev/null +++ b/mods/z_remove/moreblocks/stairsplus/panels.lua @@ -0,0 +1,115 @@ +--[[ +More Blocks: panel definitions + +Copyright (c) 2011-2015 Calinou and contributors. +Licensed under the zlib license. See LICENSE.md for more information. +--]] + +local S = moreblocks.intllib + +-- Node will be called :panel_ + +function register_panel(modname, subname, recipeitem, groups, images, description, drop, light) + return stairsplus:register_panel(modname, subname, recipeitem, { + groups = groups, + tiles = images, + description = description, + drop = drop, + light_source = light, + sounds = default.node_sound_stone_defaults(), + }) +end + +function stairsplus:register_panel(modname, subname, recipeitem, fields) + local defs = { + [""] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, 0, 0.5}, + }, + }, + ["_1"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, -0.4375, 0.5}, + }, + }, + ["_2"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, -0.375, 0.5}, + }, + }, + ["_4"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, -0.25, 0.5}, + }, + }, + ["_12"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, 0.25, 0.5}, + }, + }, + ["_14"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, 0.375, 0.5}, + }, + }, + ["_15"] = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 0, 0.5, 0.4375, 0.5}, + }, + } + } + + local desc = S("%s Panel"):format(fields.description) + for alternate, def in pairs(defs) do + def.drawtype = "nodebox" + def.paramtype = "light" + def.paramtype2 = "facedir" + def.on_place = minetest.rotate_node + for k, v in pairs(fields) do + def[k] = v + end + def.description = desc + if fields.drop then + def.drop = modname.. ":panel_" ..fields.drop..alternate + end + minetest.register_node(":" ..modname.. ":panel_" ..subname..alternate, def) + end + minetest.register_alias(modname.. ":panel_" ..subname.. "_bottom", modname.. ":panel_" ..subname) + + -- Some saw-less recipes: + + minetest.register_craft({ + output = modname .. ":panel_" .. subname .. " 12", + recipe = { + {recipeitem, ""}, + {recipeitem, recipeitem}, + }, + }) + + minetest.register_craft({ + output = modname .. ":panel_" .. subname .. " 12", + recipe = { + {"", recipeitem}, + {recipeitem, recipeitem}, + }, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":panel_" .. subname, + recipe = {modname .. ":micro_" .. subname, modname .. ":micro_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = recipeitem, + recipe = {modname .. ":panel_" .. subname, modname .. ":panel_" .. subname, modname .. ":panel_" .. subname, modname .. ":panel_" .. subname}, + }) +end diff --git a/mods/z_remove/moreblocks/stairsplus/registrations.lua b/mods/z_remove/moreblocks/stairsplus/registrations.lua new file mode 100644 index 00000000..a80c3e98 --- /dev/null +++ b/mods/z_remove/moreblocks/stairsplus/registrations.lua @@ -0,0 +1,104 @@ +--[[ +More Blocks: registrations + +Copyright (c) 2011-2015 Calinou and contributors. +Licensed under the zlib license. See LICENSE.md for more information. +--]] + +local default_nodes = { -- Default stairs/slabs/panels/microblocks: + "stone", + "cobble", + "mossycobble", + "brick", + "sandstone", + "steelblock", + "goldblock", + "copperblock", + "bronzeblock", + "diamondblock", + "desert_stone", + "desert_cobble", + "meselamp", + "glass", + "tree", + "wood", + "jungletree", + "junglewood", + "pine_tree", + "pine_wood", + "acacia_tree", + "acacia_wood", + "obsidian", + "obsidian_glass", + "stonebrick", + "desert_stonebrick", + "sandstonebrick", + "obsidianbrick", +} + +local es_nodes = { -- es stairs/slabs/panels/microblocks: + "rubyblock", + "aikerumblock", + "emeraldblock", + "infiniumblock", + "boneblock", +} + + + + +for _, name in pairs(default_nodes) do + local nodename = "default:" .. name + local ndef = minetest.registered_nodes[nodename] + if ndef then + local groups = {} + for k, v in pairs(ndef.groups) + -- Ignore wood and stone groups to not make them usable in crafting: + do if k ~= "wood" and k ~= "stone" then + groups[k] = v + end + end + local drop + if type(ndef.drop) == "string" then + drop = ndef.drop:sub(9) + end + stairsplus:register_all("moreblocks", name, nodename, { + description = ndef.description, + drop = drop, + groups = groups, + sounds = ndef.sounds, + tiles = ndef.tiles, + sunlight_propagates = true, + light_source = ndef.light_source + }) + end +end + + +for _, name in pairs(default_nodes) do + local nodename = "es:" .. name + local ndef = minetest.registered_nodes[nodename] + if ndef then + local groups = {} + for k, v in pairs(ndef.groups) + -- Ignore wood and stone groups to not make them usable in crafting: + do if k ~= "wood" and k ~= "stone" then + groups[k] = v + end + end + local drop + if type(ndef.drop) == "string" then + drop = ndef.drop:sub(9) + end + stairsplus:register_all("moreblocks", name, nodename, { + description = ndef.description, + drop = drop, + groups = groups, + sounds = ndef.sounds, + tiles = ndef.tiles, + sunlight_propagates = true, + light_source = ndef.light_source + }) + end +end + diff --git a/mods/z_remove/moreblocks/stairsplus/slabs.lua b/mods/z_remove/moreblocks/stairsplus/slabs.lua new file mode 100644 index 00000000..4875f22b --- /dev/null +++ b/mods/z_remove/moreblocks/stairsplus/slabs.lua @@ -0,0 +1,205 @@ +--[[ +More Blocks: slab definitions + +Copyright (c) 2011-2015 Calinou and contributors. +Licensed under the zlib license. See LICENSE.md for more information. +--]] + +local S = moreblocks.intllib + +-- Node will be called :slab_ + +function register_slab(modname, subname, recipeitem, groups, images, description, drop, light) + return stairsplus:register_slab(modname, subname, recipeitem, { + groups = groups, + tiles = images, + description = description, + drop = drop, + light_source = light, + sounds = default.node_sound_stone_defaults(), + }) +end + +function stairsplus:register_slab(modname, subname, recipeitem, fields) + local defs = { + [""] = 8, + ["_quarter"] = 4, + ["_three_quarter"] = 12, + ["_1"] = 1, + ["_2"] = 2, + ["_14"] = 14, + ["_15"] = 15, + } + local desc_base = S("%s Slab"):format(fields.description) + for alternate, num in pairs(defs) do + local def = { + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, (num/16)-0.5, 0.5}, + } + } + def.drawtype = "nodebox" + def.paramtype = "light" + def.paramtype2 = "facedir" + def.on_place = minetest.rotate_node + for k, v in pairs(fields) do + def[k] = v + end + def.description = ("%s (%d/16)"):format(desc_base, num) + if fields.drop then + def.drop = modname.. ":slab_" .. fields.drop .. alternate + end + minetest.register_node(":" .. modname .. ":slab_" .. subname .. alternate, def) + end + minetest.register_alias("stairs:slab_" .. subname, modname .. ":slab_" .. subname) + + -- Some saw-less recipes: + + minetest.register_craft({ + output = modname .. ":slab_" .. subname .. " 6", + recipe = {{recipeitem, recipeitem, recipeitem}}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slab_" .. subname, + recipe = {modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname}, + }) + + -- uncomment this rule when conflict is no longer likely to happen + -- https://github.com/minetest/minetest/issues/2881 + -- minetest.register_craft({ + -- type = "shapeless", + -- output = modname .. ":slab_" .. subname, + -- recipe = {modname .. ":panel_" .. subname, modname .. ":panel_" .. subname}, + -- }) + + -- then remove these two + minetest.register_craft({ + output = modname .. ":slab_" .. subname, + recipe = {{modname .. ":panel_" .. subname, modname .. ":panel_" .. subname}}, + }) + + minetest.register_craft({ + output = modname .. ":slab_" .. subname, + recipe = { + {modname .. ":panel_" .. subname}, + {modname .. ":panel_" .. subname}, + }, + }) + ------------------------------ + + minetest.register_craft({ + type = "shapeless", + output = recipeitem, + recipe = {modname .. ":slab_" .. subname, modname .. ":slab_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = recipeitem, + recipe = {modname .. ":slab_" .. subname .. "_quarter", modname .. ":slab_" .. subname .. "_quarter", modname .. ":slab_" .. subname .. "_quarter", modname .. ":slab_" .. subname .. "_quarter"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = recipeitem, + recipe = {modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = recipeitem, + recipe = {modname .. ":slab_" .. subname .. "_three_quarter", modname .. ":slab_" .. subname .. "_quarter"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = recipeitem, + recipe = {modname .. ":slab_" .. subname .. "_14", modname .. ":slab_" .. subname .. "_2"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = recipeitem, + recipe = {modname .. ":slab_" .. subname .. "_15", modname .. ":slab_" .. subname .. "_1"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slab_" .. subname, + recipe = {modname .. ":slab_" .. subname .. "_quarter", modname .. ":slab_" .. subname .. "_quarter"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slab_" .. subname, + recipe = {modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slab_" .. subname, + recipe = {modname .. ":slab_" .. subname .. "_1", modname .. ":slab_" .. subname .. "_1", modname .. ":slab_" .. subname .. "_1", modname .. ":slab_" .. subname .. "_1", modname .. ":slab_" .. subname .. "_1", modname .. ":slab_" .. subname .. "_1", modname .. ":slab_" .. subname .. "_1", modname .. ":slab_" .. subname .. "_1"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slab_" .. subname .. "_quarter", + recipe = {modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slab_" .. subname .. "_quarter", + recipe = {modname .. ":slab_" .. subname .. "_1", modname .. ":slab_" .. subname .. "_1", modname .. ":slab_" .. subname .. "_1", modname .. ":slab_" .. subname .. "_1"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slab_" .. subname .. "_2", + recipe = {modname .. ":slab_" .. subname .. "_1", modname .. ":slab_" .. subname .. "_1"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slab_" .. subname .. "_three_quarter", + recipe = {modname .. ":slab_" .. subname, modname .. ":slab_" .. subname .. "_quarter"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slab_" .. subname .. "_three_quarter", + recipe = {modname .. ":slab_" .. subname .. "_quarter", modname .. ":slab_" .. subname .. "_quarter", modname .. ":slab_" .. subname .. "_quarter"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slab_" .. subname .. "_three_quarter", + recipe = {modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slab_" .. subname .. "_14", + recipe = {modname .. ":slab_" .. subname .. "_three_quarter", modname .. ":slab_" .. subname .. "_2"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slab_" .. subname .. "_14", + recipe = {modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2", modname .. ":slab_" .. subname .. "_2"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slab_" .. subname .. "_15", + recipe = {modname .. ":slab_" .. subname .. "_14", modname .. ":slab_" .. subname .. "_1"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slab_" .. subname .. " 3", + recipe = {modname .. ":stair_" .. subname, modname .. ":stair_" .. subname}, + }) +end diff --git a/mods/z_remove/moreblocks/stairsplus/slopes.lua b/mods/z_remove/moreblocks/stairsplus/slopes.lua new file mode 100644 index 00000000..c2133965 --- /dev/null +++ b/mods/z_remove/moreblocks/stairsplus/slopes.lua @@ -0,0 +1,346 @@ +--[[ +More Blocks: slope definitions + +Copyright (c) 2011-2015 Calinou and contributors. +Licensed under the zlib license. See LICENSE.md for more information. +--]] + +local S = moreblocks.intllib +--[[ +local box_slope = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, -0.25, 0.5}, + {-0.5, -0.25, -0.25, 0.5, 0, 0.5}, + {-0.5, 0, 0, 0.5, 0.25, 0.5}, + {-0.5, 0.25, 0.25, 0.5, 0.5, 0.5} + } +} +]] +local box_slope_half = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, -0.375, 0.5}, + {-0.5, -0.375, -0.25, 0.5, -0.25, 0.5}, + {-0.5, -0.25, 0, 0.5, -0.125, 0.5}, + {-0.5, -0.125, 0.25, 0.5, 0, 0.5}, + } +} + +local box_slope_half_raised = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.125, 0.5}, + {-0.5, 0.125, -0.25, 0.5, 0.25, 0.5}, + {-0.5, 0.25, 0, 0.5, 0.375, 0.5}, + {-0.5, 0.375, 0.25, 0.5, 0.5, 0.5}, + } +} + +--============================================================== + +local box_slope_inner = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, -0.25, 0.5}, + {-0.5, -0.5, -0.25, 0.5, 0, 0.5}, + {-0.5, -0.5, -0.5, 0.25, 0, 0.5}, + {-0.5, 0, -0.5, 0, 0.25, 0.5}, + {-0.5, 0, 0, 0.5, 0.25, 0.5}, + {-0.5, 0.25, 0.25, 0.5, 0.5, 0.5}, + {-0.5, 0.25, -0.5, -0.25, 0.5, 0.5}, + } +} + +local box_slope_inner_half = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, -0.375, 0.5}, + {-0.5, -0.375, -0.25, 0.5, -0.25, 0.5}, + {-0.5, -0.375, -0.5, 0.25, -0.25, 0.5}, + {-0.5, -0.25, -0.5, 0, -0.125, 0.5}, + {-0.5, -0.25, 0, 0.5, -0.125, 0.5}, + {-0.5, -0.125, 0.25, 0.5, 0, 0.5}, + {-0.5, -0.125, -0.5, -0.25, 0, 0.5}, + } +} + +local box_slope_inner_half_raised = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.125, 0.5}, + {-0.5, 0.125, -0.25, 0.5, 0.25, 0.5}, + {-0.5, 0.125, -0.5, 0.25, 0.25, 0.5}, + {-0.5, 0.25, -0.5, 0, 0.375, 0.5}, + {-0.5, 0.25, 0, 0.5, 0.375, 0.5}, + {-0.5, 0.375, 0.25, 0.5, 0.5, 0.5}, + {-0.5, 0.375, -0.5, -0.25, 0.5, 0.5}, + } +} + +--============================================================== + +local box_slope_outer = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, -0.25, 0.5}, + {-0.5, -0.25, -0.25, 0.25, 0, 0.5}, + {-0.5, 0, 0, 0, 0.25, 0.5}, + {-0.5, 0.25, 0.25, -0.25, 0.5, 0.5} + } +} + +local box_slope_outer_half = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, -0.375, 0.5}, + {-0.5, -0.375, -0.25, 0.25, -0.25, 0.5}, + {-0.5, -0.25, 0, 0, -0.125, 0.5}, + {-0.5, -0.125, 0.25, -0.25, 0, 0.5} + } +} + +local box_slope_outer_half_raised = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.125, 0.5}, + {-0.5, 0.125, -0.25, 0.25, 0.25, 0.5}, + {-0.5, 0.25, 0, 0, 0.375, 0.5}, + {-0.5, 0.375, 0.25, -0.25, 0.5, 0.5} + } +} + +-- Node will be called :slope_ + +function register_slope(modname, subname, recipeitem, groups, images, description, drop, light) + return stairsplus:register_slope(modname, subname, recipeitem, { + groups = groups, + tiles = images, + description = description, + drop = drop, + light_source = light, + sounds = default.node_sound_stone_defaults(), + }) +end + +function stairsplus:register_slope(modname, subname, recipeitem, fields) + local defs = { + --[[ + [""] = { + mesh = "moreblocks_slope.obj", + collision_box = box_slope, + selection_box = box_slope, + + }, + ]] + ["_half"] = { + mesh = "moreblocks_slope_half.obj", + collision_box = box_slope_half, + selection_box = box_slope_half, + }, + ["_half_raised"] = { + mesh = "moreblocks_slope_half_raised.obj", + collision_box = box_slope_half_raised, + selection_box = box_slope_half_raised, + }, + +--============================================================== + + ["_inner"] = { + mesh = "moreblocks_slope_inner.obj", + collision_box = box_slope_inner, + selection_box = box_slope_inner, + }, + ["_inner_half"] = { + mesh = "moreblocks_slope_inner_half.obj", + collision_box = box_slope_inner_half, + selection_box = box_slope_inner_half, + }, + ["_inner_half_raised"] = { + mesh = "moreblocks_slope_inner_half_raised.obj", + collision_box = box_slope_inner_half_raised, + selection_box = box_slope_inner_half_raised, + }, + +--============================================================== + + ["_inner_cut"] = { + mesh = "moreblocks_slope_inner_cut.obj", + collision_box = box_slope_inner, + selection_box = box_slope_inner, + }, + ["_inner_cut_half"] = { + mesh = "moreblocks_slope_inner_cut_half.obj", + collision_box = box_slope_inner_half, + selection_box = box_slope_inner_half, + }, + ["_inner_cut_half_raised"] = { + mesh = "moreblocks_slope_inner_cut_half_raised.obj", + collision_box = box_slope_inner_half_raised, + selection_box = box_slope_inner_half_raised, + }, + +--============================================================== + + ["_outer"] = { + mesh = "moreblocks_slope_outer.obj", + collision_box = box_slope_outer, + selection_box = box_slope_outer, + }, + ["_outer_half"] = { + mesh = "moreblocks_slope_outer_half.obj", + collision_box = box_slope_outer_half, + selection_box = box_slope_outer_half, + }, + ["_outer_half_raised"] = { + mesh = "moreblocks_slope_outer_half_raised.obj", + collision_box = box_slope_outer_half_raised, + selection_box = box_slope_outer_half_raised, + }, + +--============================================================== + + ["_outer_cut"] = { + mesh = "moreblocks_slope_outer_cut.obj", + collision_box = box_slope_outer, + selection_box = box_slope_outer, + }, + ["_outer_cut_half"] = { + mesh = "moreblocks_slope_outer_cut_half.obj", + collision_box = box_slope_outer_half, + selection_box = box_slope_outer_half, + }, + ["_outer_cut_half_raised"] = { + mesh = "moreblocks_slope_outer_cut_half_raised.obj", + collision_box = box_slope_outer_half_raised, + selection_box = box_slope_outer_half_raised, + }, + ["_cut"] = { + mesh = "moreblocks_slope_cut.obj", + collision_box = box_slope_outer, + selection_box = box_slope_outer, + }, + } + + local desc = S("%s Slope"):format(fields.description) + for alternate, def in pairs(defs) do + def.drawtype = "mesh" + def.paramtype = "light" + def.paramtype2 = "facedir" + def.on_place = minetest.rotate_node + for k, v in pairs(fields) do + def[k] = v + end + def.description = desc + if fields.drop then + def.drop = modname.. ":slope_" ..fields.drop..alternate + end + minetest.register_node(":" ..modname.. ":slope_" ..subname..alternate, def) + end + + -- Some saw-less recipes: + + minetest.register_craft({ + type = "shapeless", + output = recipeitem, + recipe = {modname .. ":slope_" .. subname, modname .. ":slope_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = recipeitem, + recipe = {modname .. ":slope_" .. subname .. "_half", modname .. ":slope_" .. subname .. "_half_raised"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = recipeitem, + recipe = {modname .. ":slope_" .. subname .. "_half", modname .. ":slope_" .. subname .. "_half", + modname .. ":slope_" .. subname .. "_half", modname .. ":slope_" .. subname .. "_half"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = recipeitem, + recipe = {modname .. ":slope_" .. subname .. "_outer", modname .. ":slope_" .. subname .. "_inner"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = recipeitem, + recipe = {modname .. ":slope_" .. subname .. "_outer_half", modname .. ":slope_" .. subname .. "_inner_half_raised"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = recipeitem, + recipe = {modname .. ":slope_" .. subname .. "_outer_half_raised", modname .. ":slope_" .. subname .. "_inner_half"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = recipeitem, + recipe = {modname .. ":slope_" .. subname .. "_outer_cut", modname .. ":slope_" .. subname .. "_inner_cut"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = recipeitem, + recipe = {modname .. ":slope_" .. subname .. "_outer_cut_half", modname .. ":slope_" .. subname .. "_inner_cut_half_raised"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = recipeitem, + recipe = {modname .. ":slope_" .. subname .. "_cut", modname .. ":slope_" .. subname .. "_cut"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slab_" .. subname, + recipe = {modname .. ":slope_" .. subname .. "_half", modname .. ":slope_" .. subname .. "_half"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slab_" .. subname, + recipe = {modname .. ":slope_" .. subname .. "_outer_half", modname .. ":slope_" .. subname .. "_inner_half"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slab_" .. subname, + recipe = {modname .. ":slope_" .. subname .. "_outer_cut_half", modname .. ":slope_" .. subname .. "_inner_cut_half"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slope_" .. subname .. "_half_raised", + recipe = {modname .. ":slope_" .. subname .. "_half", modname .. ":slope_" .. subname .. "_half", + modname .. ":slope_" .. subname .. "_half"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slope_" .. subname .. "_half_raised", + recipe = {modname .. ":slab_" .. subname, modname .. ":slope_" .. subname .. "_half"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slope_" .. subname .. "_inner_half_raised", + recipe = {modname .. ":slab_" .. subname, modname .. ":slope_" .. subname .. "_inner_half"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slope_" .. subname .. "_outer_half_raised", + recipe = {modname .. ":slab_" .. subname, modname .. ":slope_" .. subname .. "_outer_half"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":slope_" .. subname .. "_inner_cut_half_raised", + recipe = {modname .. ":slab_" .. subname, modname .. ":slope_" .. subname .. "_inner_cut_half"}, + }) +end diff --git a/mods/z_remove/moreblocks/stairsplus/stairs.lua b/mods/z_remove/moreblocks/stairsplus/stairs.lua new file mode 100644 index 00000000..3be0e23b --- /dev/null +++ b/mods/z_remove/moreblocks/stairsplus/stairs.lua @@ -0,0 +1,221 @@ +--[[ +More Blocks: stair definitions + +Copyright (c) 2011-2015 Calinou and contributors. +Licensed under the zlib license. See LICENSE.md for more information. +--]] + +local S = moreblocks.intllib + +-- Node will be called :stair_ + +function register_stair(modname, subname, recipeitem, groups, images, description, drop, light) + return stairsplus:register_stair(modname, subname, recipeitem, { + groups = groups, + tiles = images, + description = description, + drop = drop, + light_source = light, + sounds = default.node_sound_stone_defaults(), + }) +end + +function stairsplus:register_stair(modname, subname, recipeitem, fields) + local defs = { + [""] = { + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + {-0.5, 0, 0, 0.5, 0.5, 0.5}, + }, + }, + }, + ["_half"] = { + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0, 0, 0.5}, + {-0.5, 0, 0, 0, 0.5, 0.5}, + }, + }, + }, + ["_right_half" ]= { + node_box = { + type = "fixed", + fixed = { + {0, -0.5, -0.5, 0.5, 0, 0.5}, + {0, 0, 0, 0.5, 0.5, 0.5}, + }, + }, + }, + ["_inner"] = { + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + {-0.5, 0, 0, 0.5, 0.5, 0.5}, + {-0.5, 0, -0.5, 0, 0.5, 0}, + }, + }, + }, + ["_outer"] = { + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + {-0.5, 0, 0, 0, 0.5, 0.5}, + }, + }, + }, + ["_alt"] = { + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0, 0}, + {-0.5, 0, 0, 0.5, 0.5, 0.5}, + }, + }, + }, + ["_alt_1"] = { + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.0625, -0.5, 0.5, 0, 0}, + {-0.5, 0.4375, 0, 0.5, 0.5, 0.5}, + }, + }, + }, + ["_alt_2"] = { + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.125, -0.5, 0.5, 0, 0}, + {-0.5, 0.375, 0, 0.5, 0.5, 0.5}, + }, + }, + }, + ["_alt_4"] = { + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.25, -0.5, 0.5, 0, 0}, + {-0.5, 0.25, 0, 0.5, 0.5, 0.5}, + }, + }, + }, + } + + local desc = S("%s Stairs"):format(fields.description) + for alternate, def in pairs(defs) do + def.drawtype = "nodebox" + def.paramtype = "light" + def.paramtype2 = "facedir" + def.on_place = minetest.rotate_node + for k, v in pairs(fields) do + def[k] = v + end + def.description = desc + if fields.drop then + def.drop = modname .. ":stair_" .. fields.drop .. alternate + end + minetest.register_node(":" .. modname .. ":stair_" .. subname .. alternate, def) + end + minetest.register_alias("stairs:stair_" .. subname, modname .. ":stair_" .. subname) + + -- Some saw-less recipes: + + minetest.register_craft({ + output = modname .. ":stair_" .. subname .. " 8", + recipe = { + {recipeitem, "", ""}, + {recipeitem, recipeitem, ""}, + {recipeitem, recipeitem, recipeitem}, + }, + }) + + minetest.register_craft({ + output = modname .. ":stair_" .. subname .. " 8", + recipe = { + {"", "", recipeitem}, + {"", recipeitem, recipeitem}, + {recipeitem, recipeitem, recipeitem}, + }, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname, + recipe = {modname .. ":panel_" .. subname, modname .. ":slab_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname, + recipe = {modname .. ":panel_" .. subname, modname .. ":panel_" .. subname, modname .. ":panel_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname .. "_outer", + recipe = {modname .. ":micro_" .. subname, modname .. ":slab_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname .. "_half", + recipe = {modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname .. "_half", + recipe = {modname .. ":panel_" .. subname, modname .. ":micro_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname .. "_right_half", + recipe = {modname .. ":stair_" .. subname .. "_half"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname, + recipe = {modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname .. "_inner", + recipe = {modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname .. "_outer", + recipe = {modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname, modname .. ":micro_" .. subname}, + }) + + minetest.register_craft({ + type = "shapeless", + output = modname .. ":stair_" .. subname, + recipe = {modname .. ":panel_" .. subname, modname .. ":panel_" .. subname, modname .. ":panel_" .. subname}, + }) + + minetest.register_craft({ -- See mirrored variation of the recipe below. + output = modname .. ":stair_" .. subname .. "_alt", + recipe = { + {modname .. ":panel_" .. subname, ""}, + {"" , modname .. ":panel_" .. subname}, + }, + }) + + minetest.register_craft({ -- Mirrored variation of the recipe above. + output = modname .. ":stair_" .. subname .. "_alt", + recipe = { + {"" , modname .. ":panel_" .. subname}, + {modname .. ":panel_" .. subname, ""}, + }, + }) +end diff --git a/mods/z_remove/moreblocks/textures/moreblocks_circular_saw_bottom.png b/mods/z_remove/moreblocks/textures/moreblocks_circular_saw_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..1522829716f2582ee386505735a34cc566c137f2 GIT binary patch literal 579 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47)1hnLR^7dMn*;^CMFgZ7It=a zPEJm4Zf+hP9$sEvetv!d0RcflK_MX_VPRnr5fL#lF>!Hm2?+^FNl9sGX&D(Ad3kvS z1qDS#MP+4Wb#-+O4Gk?VEnQt*0|NsS6BAQYQ!6Vg8yg!}D-Aa*O%GcwZ##8wJ0Pj; zZLj0&pyTVP>+h)P@2DH-q!s9_8|bVT?4lR!sviPE1`+PM5gvw-9(qw;M$ysHF<$yH zF){IerU?lNiGGHO{-%k6W=Z~rNdaa_Kt@thT3T9WsAXojRaTf~R)ke{m}z#nRZh5B zPPk=GgjG(YbxuxBQH*VIadCN~eMOQ(MY3aMqE%(GLshb4RaI4OZEbUw>x2mt9wx5> z1>7r77sn6@N!EkDeuoVN*e>KB3!Zetk0CHnQ6pMKY=K;(s`xX8H@n;(F@-pVF5cE9 zy!}b~nd&V}j#H~*RMJ#D{t3K2kl1`XDE(qy%4)MLN0u&ix4ptoo;n17Z$G!&B)DVY zf^5?{R}ZeA(X&G+IPGj@*LU^w2S-@u#T?H6_E`OWkJRQj{e~BR*VP+;i)2shZ8h7q zHiR#%d&M2SJ2hGMvyZR8cmD1o(|+%DeD3nss&4K(5&B@mV#oEXZ_V5zks*F$cT2d) z{R%t9gO!rTVt>lgue{`2+@~bFHFRc?MV8e3mU%i>0%;Nx9tiwrT*{i?mVbJc6VTTT Mp00i_>zopr0FjTrHUIzs literal 0 HcmV?d00001 diff --git a/mods/z_remove/moreblocks/textures/moreblocks_circular_saw_side.png b/mods/z_remove/moreblocks/textures/moreblocks_circular_saw_side.png new file mode 100644 index 0000000000000000000000000000000000000000..ce9e16f7cacc3aa82b5994fab11fe89663367bdd GIT binary patch literal 478 zcmV<40U`d0P)?6crT}78Vv47Z(^97#SHE8X6iK8yg%P93CDXA0HneARrlG>R7EdTMKD-LEm%k~SV=NjNG@7RGG9(LVNNk&Pc>mtHeydPVo)|> zQ8sB;I%-xqYFIjJRyAu^I&4=tY*;#MSvz=QKzL(8d1F9&V?l#zMY6K8+1c6b+v=+T z007EKL_t&-8CAi}O2a@D2GH+LzD#D4)TBEpQhWj5!q;~txDpYOZp7NuiD~}sb=`CL zh-)-l5kBob)awB|H#tln1mhy>*kcUAsGyfYpVi{{lFtvbc(xJB7>d<@Ey1B>Hn>&h zUyD-12Ve-ckv UH#?H2X8-^I07*qoM6N<$f{v%C82|tP literal 0 HcmV?d00001 diff --git a/mods/z_remove/moreblocks/textures/moreblocks_circular_saw_top.png b/mods/z_remove/moreblocks/textures/moreblocks_circular_saw_top.png new file mode 100644 index 0000000000000000000000000000000000000000..96f3350cfa99f5c36abecf0f29b83c6d52f3e150 GIT binary patch literal 441 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfiU6MwS63?yH!DpK8!Zo8EpIz@ zZ#y8V?QO5)>!9Q7sO#^j=?^5G^a7o<0-bdOo%MoU^nzXWLqNzN!d*AQ!!W|rDAGeO z%F8ImOF!PvG{Mgx(a$i^-!w7MEXm(6DZnf#&@405GBeyNE7UYA%rYy&Dm%=5NP1G@Q) zr;B5Vge2?1K)=HV0uBeae^c|7ap%yoYv3;Uzq^1XYDw6IOIBuHZ&Kal1fwR~mpzkd z?>$auFb1q+VTD7TqZEh3$PKTm@3ohH0GxQj& zdwg|$?0r2;cgv@DPJUfdY>?K*e~;U3M(OLhkGF{Idpq-**;Us|GPw#KyL^{j^1mZ! e71rbNi(T42ZR&a literal 0 HcmV?d00001 diff --git a/mods/z_remove/moreblocks/textures/moreblocks_wood_tile_up.png b/mods/z_remove/moreblocks/textures/moreblocks_wood_tile_up.png new file mode 100644 index 0000000000000000000000000000000000000000..3f6a2f24c06fcb40814cf4a14ee49ea7c22eba98 GIT binary patch literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}MSxF;YqYzjtCfbEm8Q3yy03$d zucNNNqo%);UZAsXptD}Ei(as+eh3H|M0glRcp61|=tX%M#dzt*`m>LYBnFx# z`5Pt$m?Z_8WrkX2hFfKYnr4MrW<^+KhnZ%FTjhkCChg%WpcM?Bu6{1-oD!M= gamestate.coin_total then + minetest.chat_send_player(name, "You cleared the board!") + + mario.remove_turtles(gamestate.id) + gamestate.coin_count = 0 + gamestate.level = gamestate.level + 1 + gamestate.speed = gamestate.level + 1 + + minetest.after(3.0, function() + minetest.chat_send_player(name, "Starting Level "..gamestate.level) + -- place schematic + local schem = minetest.get_modpath("mario").."/schems/mario.mts" + minetest.place_schematic(vector.add(gamestate.pos, {x=-1,y=-2,z=-2}),schem,0, "air", true) + + -- Set start positions + mario.game_reset(gamestate.id, player) + minetest.sound_play("mario-game-start", {pos = pos,max_hear_distance = 6,gain = 1.0,}) + end) + end + + if gamestate.score / score_for_life_award >= 1 + gamestate.awarded_lives then + minetest.chat_send_player(name, "You reached " .. gamestate.score .. " points and earned an extra life!") + gamestate.lives = gamestate.lives + 1 + gamestate.awarded_lives = gamestate.awarded_lives + 1 + end +end + +-- A player got a mushroom, update the state +function mario.on_player_got_mushroom(player, points) + local name = player:get_player_name() + local gamestate = mario.get_game_by_player(name) + if not gamestate then return end + gamestate.score = gamestate.score + points + minetest.chat_send_player(name, points .. " bonus points!") + minetest.sound_play("mario-bonus", {object = player, max_hear_distance = 6}) +end + +-- The player died! +function mario.on_player_death(id, player) + local gamestate = mario.games[id] + if not gamestate then return end + + gamestate.lives = gamestate.lives - 1 + if gamestate.lives < 1 then + minetest.chat_send_player(gamestate.player_name,"Game Over") + mario.game_end(id) + minetest.sound_play("mario-game-over", {max_hear_distance = 6, object=player}) + elseif gamestate.lives == 1 then + minetest.chat_send_player(gamestate.player_name,"This is your last life") + mario.game_reset(id, player) + minetest.sound_play("mario-continue", {max_hear_distance = 6, object=player}) + else + minetest.chat_send_player(gamestate.player_name,"You have ".. gamestate.lives .." lives left") + mario.game_reset(id, player) + minetest.sound_play("mario-continue", {max_hear_distance = 6, object=player}) + end +end + +-- Get the game that the given player is playing +function mario.get_game_by_player(player_name) + for _,gamestate in pairs(mario.games) do + if gamestate.player_name == player_name then + return gamestate + end + end +end + +--------------------------------------------------------- +--- Private functions (only can be used inside this file) + + +-- Called every 0.5 seconds for each player that is currently playing +local function on_player_gamestep(player, gameid) + local player_pos = player:getpos() + local positions = { + {x=0.5,y=0.5,z=0.25}, + {x=-0.5,y=0.5,z=-0.25}, + } + for _,pos in pairs(positions) do + pos = vector.round(vector.add(player_pos, pos)) + local node = minetest.get_node(pos) + local nodedef = minetest.registered_nodes[node.name] + + if nodedef and nodedef.on_player_collision then + nodedef.on_player_collision(pos, player, gameid) + end + end +end + +------------------- +--- Execution code + + +-- Time counters +local tmr_gamestep = 0 +minetest.register_globalstep(function(dtime) + tmr_gamestep = tmr_gamestep + dtime; + if tmr_gamestep > 0.2 then + for id,player in pairs(mario.players) do + on_player_gamestep(player, id) + end + tmr_gamestep = 0 + end +end) + +minetest.register_on_leaveplayer(function(player) + local name = player:get_player_name() + for id,game in pairs(mario.games) do + if game.player_name == name then + mario.game_end(id) + end + end +end) + +minetest.register_on_shutdown(function() + minetest.log("action", "Server shuts down. Ending all mario games") + for id,game in pairs(mario.games) do + mario.game_end(id) + end +end) + +-- Chatcommand to end the game for the current player +minetest.register_chatcommand("mario_exit", { + params = "", + description = "Loads and saves all rooms", + func = function(name, param) + local gamestate = mario.get_game_by_player(name) + if gamestate then + mario.game_end(gamestate.id) + minetest.chat_send_player(name, "You are no longer playing mario") + else + minetest.chat_send_player(name, "You are not currently in a mario game") + end + end +}) diff --git a/mods/z_remove/myArcade/mario/hud.lua b/mods/z_remove/myArcade/mario/hud.lua new file mode 100644 index 00000000..d9bf346e --- /dev/null +++ b/mods/z_remove/myArcade/mario/hud.lua @@ -0,0 +1,44 @@ + + +local hud_table = {} + +function mario.update_hud(id, player) + local game = mario.games[id] + player = player or minetest.get_player_by_name(game.player_name) + if not player then + return + elseif not game then + mario.remove_hud(player) + return + end + local coins_left = game.coin_total - game.coin_count + local hudtext = "Score " .. game.score + .. "\nLevel " .. game.level + .. "\nLives " .. game.lives + .. "\nCoins " .. coins_left + + local hud = hud_table[game.player_name] + if not hud then + hud = player:hud_add({ + hud_elem_type = "text", + position = {x = 0, y = 1}, + offset = {x=100, y = -100}, + scale = {x = 100, y = 100}, + number = 0xff2227, --color + text = hudtext + }) + hud_table[game.player_name] = hud + else + player:hud_change(hud, "text", hudtext) + end +end + + +function mario.remove_hud(player, playername) + local name = playername or player:get_player_name() + local hud = hud_table[name] + if hud then + player:hud_remove(hud) + hud_table[name] = nil + end +end diff --git a/mods/z_remove/myArcade/mario/init.lua b/mods/z_remove/myArcade/mario/init.lua new file mode 100644 index 00000000..c9202d08 --- /dev/null +++ b/mods/z_remove/myArcade/mario/init.lua @@ -0,0 +1,80 @@ +mario = {} + +dofile(minetest.get_modpath("mario").."/pipes.lua") +dofile(minetest.get_modpath("mario").."/blocks.lua") +dofile(minetest.get_modpath("mario").."/portal.lua") +dofile(minetest.get_modpath("mario").."/turtle.lua") +dofile(minetest.get_modpath("mario").."/gamestate.lua") +dofile(minetest.get_modpath("mario").."/hud.lua") + + +minetest.register_node("mario:placer",{ + description = "Mario", + tiles = { + "mario_border.png", + "mario_border.png", + "mario_border.png", + "mario_border.png", + "mario_border.png", + "mario_border.png^mario_m.png", + }, + drawtype = "normal", + paramtype = "light", + groups = {cracky = 1}, + on_rightclick = function(pos, node, player, itemstack, pointed_thing) + mario.game_start(pos, player, { + schematic = minetest.get_modpath("mario").."/schems/mario.mts", + scorename = "mario:classic_board", + }) + end, +}) +minetest.register_node("mario:placer2",{ + description = "Mario", + tiles = { + "mario_border.png", + "mario_border.png", + "mario_border.png", + "mario_border.png", + "mario_border.png", + "mario_border.png^mario_m.png", + }, + drawtype = "normal", + paramtype = "light", + groups = {cracky = 1,not_in_creative_inventory=1}, + on_rightclick = function(pos, node, player, itemstack, pointed_thing) + local schem = minetest.get_modpath("mario").."/schems/mario.mts" + minetest.place_schematic({x=pos.x-1,y=pos.y-1,z=pos.z-2},schem,0, "air", true) + end, +}) + +minetest.register_node("mario:exit",{ + description = "Exit", + tiles = { + "mario_grey.png", + "mario_grey.png", + "mario_grey.png", + "mario_grey.png", + "mario_grey.png", + "mario_grey.png^mario_exit.png", + }, + drawtype = "normal", + paramtype = "light", + groups = {cracky = 1,not_in_creative_inventory=1}, + on_rightclick = function(pos, node, player, itemstack, pointed_thing) + local name = player:get_player_name() + local game = mario.get_game_by_player(name) + if not game then + minetest.chat_send_player(name, "You aren't running a game at the moment") + pos.z = pos.z - 3 + player:moveto(pos) + else + mario.game_end(game.id) + end + end, +}) + +-- Register with the myhighscore mod +myhighscore.register_game("mario:classic_board", { + description = "Mario", + icon = "mario_border.png^mario_m.png", +}) diff --git a/mods/z_remove/myArcade/mario/pipes.lua b/mods/z_remove/myArcade/mario/pipes.lua new file mode 100644 index 00000000..26e2a61b --- /dev/null +++ b/mods/z_remove/myArcade/mario/pipes.lua @@ -0,0 +1,70 @@ +local pipe_box = { + type = "fixed", + fixed = {{-0.375, -0.5, -0.375, 0.375, 0.5, 0.375},}} +local pipe_elbow_box = { + type = "fixed", + fixed = {{-0.375, -0.5, -0.375, 0.375, 0.375, 0.375}, + {-0.375, -0.375, 0.375, 0.375, 0.375, -0.5},}} +local pipe_end_box = { + type = "fixed", + fixed = {{-0.375, -0.5, -0.375, 0.375, 0.375, 0.375}, + {-0.5, 0.3125, -0.5, 0.5, 0.5, 0.5},}} + +minetest.register_node("mario:pipe",{ + description = "Pipe", + tiles = { + "mario_pipe_end_sm.png", + "mario_pipe_end_sm.png", + "mario_pipe.png", + "mario_pipe.png", + "mario_pipe.png", + "mario_pipe.png", + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + pointable = false, + groups = {cracky = 1,not_in_creative_inventory=1}, + node_box = pipe_box, + on_place = minetest.rotate_node, + +}) + +minetest.register_node("mario:pipe_elbow",{ + description = "Pipe Elbow", + tiles = { + "mario_pipe.png", + "mario_pipe_end_sm.png^mario_pipe_elbow_ic.png", + "mario_pipe.png^mario_pipe_elbow.png^[transformFX", + "mario_pipe.png^mario_pipe_elbow.png", + "mario_pipe.png", + "mario_pipe_end_sm.png^mario_pipe_elbow_ic.png^[transformFY", + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + pointable = false, + groups = {cracky = 1,not_in_creative_inventory=1}, + node_box = pipe_elbow_box, + on_place = minetest.rotate_node, +}) + +minetest.register_node("mario:pipe_end",{ + description = "Pipe End", + tiles = { + "mario_pipe_end_sm.png", + "mario_pipe_end_sm.png", + "mario_pipe.png^mario_pipe_end_ring.png", + "mario_pipe.png^mario_pipe_end_ring.png", + "mario_pipe.png^mario_pipe_end_ring.png", + "mario_pipe.png^mario_pipe_end_ring.png", + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + pointable = false, + groups = {cracky = 1,not_in_creative_inventory=1}, + node_box = pipe_end_box, + on_place = minetest.rotate_node, +}) + diff --git a/mods/z_remove/myArcade/mario/portal.lua b/mods/z_remove/myArcade/mario/portal.lua new file mode 100644 index 00000000..6b1c82cc --- /dev/null +++ b/mods/z_remove/myArcade/mario/portal.lua @@ -0,0 +1,49 @@ +minetest.register_node("mario:portal", { + description = "Portal", + drawtype = "glasslike", + tiles = {"mario_glass.png"}, + paramtype = "light", + sunlight_propagates = true, + alpha = 150, + paramtype2 = "facedir", + walkable = false, + is_ground_content = false, + groups = {cracky = 1,not_in_creative_inventory=1}, + on_turtle_collision = function(pos, obj, gameid) + obj:setpos({x=pos.x,y=pos.y+12,z=pos.z}) + end +}) +minetest.register_node("mario:portal_left", { + description = "Portal Left", + drawtype = "glasslike", + tiles = {"mario_border.png"}, + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "facedir", + --walkable = false, + is_ground_content = false, + groups = {cracky = 1,not_in_creative_inventory=1}, + on_player_collision = function(pos, player, gameid) + player:setpos(vector.add(pos,{x=31, y=0, z=0})) + end, + on_turtle_collision = function(pos, obj, gameid) + obj:setpos(vector.add(pos,{x=31, y=0, z=0})) + end +}) +minetest.register_node("mario:portal_right", { + description = "Portal Right", + drawtype = "glasslike", + tiles = {"mario_border.png"}, + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "facedir", + --walkable = false, + is_ground_content = false, + groups = {cracky = 1,not_in_creative_inventory=1}, + on_player_collision = function(pos, player, gameid) + player:setpos(vector.add(pos,{x=-31, y=0, z=0})) + end, + on_turtle_collision = function(pos, obj, gameid) + obj:setpos(vector.add(pos,{x=31, y=0, z=0})) + end +}) diff --git a/mods/z_remove/myArcade/mario/schems/mario.mts b/mods/z_remove/myArcade/mario/schems/mario.mts new file mode 100644 index 0000000000000000000000000000000000000000..9b9d22c61de384084909d4ca1e404d6b04c8d632 GIT binary patch literal 562 zcmeYb3HD`RVNhWZWMHjF2MqiS+_{NGnfX>pMVZOj49tm{MGOKEk%G*E)cDk#r2KLQ z9;ll9qLkDkn2z+E#NuKGE`(y3vVxq%WS}xWgiL&DUJ6_`zo;ZJ2c|DMKQj-mGAFSl zEx#z2K@h4FtTH|)HLZj}2t}wUGd-gOW<+{XY9)-FT9H{&G3V{f+k8z10xsLvZjHOZ zzUbe&{dx;rCy1?*)t_Pcc~RlavgIkh4lFH;G`fCGvN*2MHEVZ3hT*0YQ&z^T(P6aP zCX{6VW#(-DS9T!+@~-n)=GP=XpCPKgIxYWopVQ^fAHRo|F3o)>U;Ntdm;| zH@9h5_;-8$($bsX%BwCF zm&b+n{F{I5-Ta548?EfaOP$z0zA3Q|j}5b0H&@!~@X4*5%I8kcmrCnBXf9NFxOB?T zt+QTES~5$;WXY5I!XOdl#MPTbxTAAEg%qxju-|!2aiL1;)?W`_X&kS*EWFy(espMVZOj49tm{MGOKEk%G*E)cDk#r2KLQ z9;ll9qLkDkn2z+E#NuKGE`(y3vVxq%WS}xWgiL&DUJ6_`zo;ZJ2c|DMKQj-mGAFSl zEx#z2K@h4FtTH|)HLZj}2t}wUGd-gOW<+{XY9)-FT9H{&G3V{f*L{Z+1X|ezUN8N% z_+std+OKb2SLt2|vRr*_&U+QN!vzV;N_?UO1-ce#yz)(wU#yY!)@k9<6KcWB$~JCd z{c$6z^SXy9{Oge-TLO%-na51ujW1e7;AfZ+w|THF>5I1&Gp;Z8w^;RN_1xu!ai?DkpVN+OEcm+Y(cOBiiZ^$=@x<=Qgi=KXJ}0k=pwgB>i0D6OVj-WfxfcX3EO8 zH2a-)&!$cNU0ZkSI8V*I`~0=no;6#wf2o|yzo7rGkQ0Yui-6NUsT;--P8>fI>V%wx z;=E@1chBVa?DBMScG@@H=~U688>?0wIV3iF@2VZ)Yu3lSo+L17Q`F~z(n;ByU(URG WD>2xwHROPi@TdEK7_ELQxB~z{Py>np literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/mario/sounds/mario-1-up.ogg b/mods/z_remove/myArcade/mario/sounds/mario-1-up.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f0a08ab33181ad65054bebd0fbdc191bc4cb9d8b GIT binary patch literal 28681 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≫SdVIvpL^@ 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≫E0e>f96 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 aQO1!c|1khIy?E*82EwFJ>5KCR!G8iQuz>pj literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/mario/sounds/mario-continue.ogg b/mods/z_remove/myArcade/mario/sounds/mario-continue.ogg new file mode 100644 index 0000000000000000000000000000000000000000..270f2f71b52fe3e6b79447199f8bf1f7c9fb5290 GIT binary patch literal 19741 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 T3V)PLcYfK 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 literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/mario/sounds/mario-game-over.ogg b/mods/z_remove/myArcade/mario/sounds/mario-game-over.ogg new file mode 100644 index 0000000000000000000000000000000000000000..9c6641169d050526f644db81dd67c44c6e52507c GIT binary patch literal 56498 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

    jK1%Flb}MP*efEl~<#>jiBl?@(l`s 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
    C(9pYAaDeI-R?R4%!DLq0wwW7t!k}23iILm)h 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 literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/mario/sounds/mario-game-start.ogg b/mods/z_remove/myArcade/mario/sounds/mario-game-start.ogg new file mode 100644 index 0000000000000000000000000000000000000000..0d90de2a7a840b8b6167666d73e5274b3c5a4f7f GIT binary patch literal 59419 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 RfpGu;002ovPDHLkV1oJ%n&1Ec literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/mario/textures/mario_brick.png b/mods/z_remove/myArcade/mario/textures/mario_brick.png new file mode 100644 index 0000000000000000000000000000000000000000..f74e35cef5c4448a39011819166e2a677f0c4352 GIT binary patch literal 384 zcmV-`0e}99P)ISPmmToUhOc-AT3`=U+9-GgUVzf`0L(xRT#09cVC|Z;$#ZGo;+hOj;@N2MHPBmq z0KRnSSI0nm06O=(%`tym(k?k{hQj&vxw#u{zPQV-R5mZRB8G#2NTXp^PG6lL(#zt%mtq>p5 z6arHS?5$n~d=3TvX9l%B-}&~}w_eGtv+7A4rEP$0(Wwn`b%AQ9RpBnSP?TXXxF5qm eaW-lCBf$^fFjDFgEmbK10000Gcn$3-0cGXco4d3RmzV7BUtBLOM)#~Z1*EhFQb7Lr`TNi7mt{O( z5Cnp~!wWv`wUH8fJKeJ30VaC4)XnGwW?m(*(&j4|vTU9!1eBA1hR z-XvuYH=ncfr2Fj2JV5}Tk1nabDAONk5Q6vH3lt*{DdG8AiDoP50)wmuKA^M)V+=}- zy@WFoDb2W2x6u2m5r6?ksmaZ zf9vpgwHRfr_)dRy;0vyA4EdbkUA@B2ZkyrIu>EEMqYY_l7>yc4SLYl+Xtt70 zy;dd&1X{yjsF^Kz{OfDtg9}!ci;+vNXvEc72P7ZRC(WyFAuri@S|SJp@j)Bkmppth zcXtYNL?f<-KsYrI0Q!3?xi-dR1S;Eq?cl6kuBAhz23UC%MQ&tM1DCqv%2a5+a}V7@ dJJ1aQ{sR@5(ayIo{1^ZL002ovPDHLkV1oa~6W0I$ literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/mario/textures/mario_exit.png b/mods/z_remove/myArcade/mario/textures/mario_exit.png new file mode 100644 index 0000000000000000000000000000000000000000..8807f8e6bedf0a211ffdf113b1b8bf9db180a74b GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)10n#SDCV`VO53if|Tq zL>4nJa0`Jj3i)`tIEGl9e%tTJ#h}2!a{NW2 z?cVt}GaX%CTw2)7EcD1s$t3^A1Ff%x)9%lh%cZwLXYDlI4ZQ3Atgv&56ias#UE{Zd i>rt%Gy=~_E3m9xv<(SvZjg$kL%i!ti=d#Wzp$PyAzB`!! literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/mario/textures/mario_glass.png b/mods/z_remove/myArcade/mario/textures/mario_glass.png new file mode 100644 index 0000000000000000000000000000000000000000..c0edad20a338bb36a4efaf165153260aaa37bf84 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE(}Zz*$h1Awl{nQif|Tq zL>4nJa0`Jj|RbCY4MB3JH0-IEGl9PEL?uU7R4&!^FYB Yz#_oF*lNG32q??o>FVdQ&MBb@00U+nS^xk5 literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/mario/textures/mario_grey.png b/mods/z_remove/myArcade/mario/textures/mario_grey.png new file mode 100644 index 0000000000000000000000000000000000000000..4be435a2576984633abdb998ac2d5ef2d7335f17 GIT binary patch literal 481 zcmV<70UrK|P)InN0d7e| zK~y-)Ws^%1r63Rlvp=A|``=Yjpl37mXbdY2o1!Wyu_0HCS> z%sH8J0^sh>oHI8@1ZIY+GUp^B5Ro;^ecvB3?Y(oJClNud6%j#1hzRDK)LPSxsv;t& z>OX<=JoBV62Bj3XZOcu)cY5yt-1klIJtIW~T5IL^`(b9dJ7)HuO%b7#lJWL^Plsw| zhzMg0&hyNyEB89>x-NR}j4|@r-SII7&+~l9ulL0x^QsaNlv47$)>`w#^}LpdFz3X~ zIF5r_D-rQ=%&I2vAB%9=aO$JWtm1UDwuH7Dz;r(V7)^kG#{rVyem*<3oRKSS?)j*KONU zSwt|iWDyZb|DF5&e`ss%Lwz-FiLDC1`{3@$Lx4DrgWh}EUpdW;)>;m)RZ8J`9wLH2 XsXHm0y+%M;00000NkvXXu0mjfYG%*` literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/mario/textures/mario_m.png b/mods/z_remove/myArcade/mario/textures/mario_m.png new file mode 100644 index 0000000000000000000000000000000000000000..ce4963a3ea012abd88e1a54eca251b12fc9e20dd GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)0tpW-&;2x;8rlMK}vQ zB8wRqxP?HN@zUM8KR`kD5>H=O_WN8?g6tZ$J7TJULV=zxjv*GOlM^H|4sayPBqaRc zPqtR*RA$b}n!%xYM7`}YLkaH=lVsBajAx@;_OxAPy&>|5OMFh8!?gx)V`d=W-luVB j`NRd>9juGlcz|x&y-6Utx=3vc&~OG%S3j3^P64nJa0`PlBg3pY5H=O_WN8?BGNK{Hkeleg*JJ*IEGl9o*R6S_lN>dw_x!d zhPNhjr(~{UHt?wJpA_ezXggO`Wy%r02u`o16*>BMnw5gI9wt}1sQCYz_v_czr)vYY zrKp};P{|N7(M0+8J2SUWRk?i}rwhgJ3h%OTY00nY4m~m1y*F%|{*6bHg>5SJPSU=t zO2TioH>>SoHx}$a?UL=ovNo2Fi(#VKsVj>+-c@-$ec9-D^|H#XS$RT>52-&)G3Whp k&?I4xkDJP$_V}0lB{tnt7EPRe0qA-LPgg&ebxsLQ0G&K(#Q*>R literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/mario/textures/mario_mushroom_bottom.png b/mods/z_remove/myArcade/mario/textures/mario_mushroom_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..fe5e2a8e11538ebcb0df0cc617f476b8748cc9ec GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)10n#SDCV`VO53if|Tq zL>4nJa0`PlBg3pY5H=O_WN8?B1V>b)>H#;0=g*%_m(a@IR3AvY>I|2I5w uinx6D&~?tR{SR_-RCffgGqC%AjQPS{C8a%T+B<+&FnGH9xvX4nJa0`PlBg3pY5H=O_WN8?B31&GGxIhAg_e7|IEGl9o*V4Q*KEMktUn~=jKe=;7#UtpDi}NkSSZA;@y>CeS3QFEcNt5Jih-}%)NLQDY_k( zj`(1_BJU9U%H52@(*&M;QhTsC`_QC+x7lX(J_{C-Wq&HLHZrwm_qumYoIdl@KTdHz aD}HTnBu~g0we3JBGkCiCxvX4nJa0`PlBg3pY5H=O_WN8?BIagtR#O>)LOVQN978NlFAcuU+hV}8S$SFG zU-!)82Wtx2F0fy^8+poKSbgeafd+;J0^-+VPpmko=RPmLgqdN&6+t&%U$zE=mA+>t zWOFs1n4IpLC1CpF#7yCTd3l>w&YyF?NS8}-vB0kkquxW-Dw?-E@3k#)-!j{1T50(5 zU*;TtI-iP9sts)Z%fH6#r2Cm|o3A9KpP!hZmhW}#tkj-~x6QAw+wI5e#wUHZWy$Xj s4-Y3FSu@A%->;?Ir~fFsCRf97ExhXO6=e=qpdT1KUHx3vIVCg!01jzxf&c&j literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/mario/textures/mario_mushroom_top_g.png b/mods/z_remove/myArcade/mario/textures/mario_mushroom_top_g.png new file mode 100644 index 0000000000000000000000000000000000000000..98238f28e7cfd97a1d22230f2dd33ae1e2ed2547 GIT binary patch literal 312 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)10n#SDCV`VO53if|Tq zL>4nJa0`PlBg3pY5H=O_WN8?B9@{`_fGx=3LW)yaSX9Iy)@X9@2~=o%wm}b zjRgzdH#65JRLzzPTE1rDt)3Lc#Pc^kDKT&`*hOl1-3e4qG5_K6q#~4o!Go`5=7LF# z2Q*feuL(H*BPH?G8SRM^WSz=-{Vm;2uXUZ*e_bKy|J98jP6j=k{B*gx_ve%I+$JqM zzvQyQ%?NwVqhXKiO8$yV+&S`%-}Adtih0P)49ul&dZIKWlu$?$Te94?bXTXo(40H;gLf;<% z@VW3|cp4rHKNfl#KTM!}V@&Ri$*nNL;Cxh1>n7g@7zw0C^>k5SBS=uOmllx}B_jVz z)QWbZTx5cS0HPG*4QR%2lfmj#;&y4h!q~W1;I)Q zZ6mHE^BU0yI7+V8OxGM-6>m+A{Y%LxTqI*2CaPZ8wZ0qZ&8NG;Wq7Cz)Nt7Y{AwUK zvA2WU#H@WP$hX@49U2B}S7DaCyG(arrPy6p=hy*iFm<^KVOOaacnOyK9M~gg002ovPDHLkV1l!5qgns} literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/mario/textures/mario_pipe_elbow.png b/mods/z_remove/myArcade/mario/textures/mario_pipe_elbow.png new file mode 100644 index 0000000000000000000000000000000000000000..994e2b5b36ce66d6fee21e28499b3116d34e9256 GIT binary patch literal 350 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE(}Zz*$h1Awl{nQif|Tq zL>4nJa0`JjLX#WBR<^xR1s{SG?_xZJ;U z(xvl9h?dJlE~ynx%!^L62UTm7olk#sf~9}U(a3w|#kZKF&!2* z#t(tIU+dqba86k4W!C%g=1bG9FHLrQO-OFpbdxE|X>xkAfN}hV+jEWoD>bfma8phw zl@QlDZ*BctvH5Ai_5AM=)2A^o$bRqL$Z*EHK$amuj^B+jp!3Quh6-LF=bi2C9Qoaj zM;4rxO8E0D&h){0mf%Utn{$tf-kLQf`k~v)9rN>S>o=P-Gkn?9J#&TgKURhduLZcT sw6RRS*M6tZoQc71^>%afx!v^)+!-0mpLO^N1HH}Q>FVdQ&MBb@0G%R-e*gdg literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/mario/textures/mario_pipe_elbow_ic.png b/mods/z_remove/myArcade/mario/textures/mario_pipe_elbow_ic.png new file mode 100644 index 0000000000000000000000000000000000000000..9b2daa62083a30cc6d404cbe9162856f4962ea86 GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE(}Zz*$h1Awl{nQif|Tq zL>4nJa0`Jj`}GtxiJ09Qnw}U#hfdai+f!u jzWegmp4GXx{~hF)_$)ckZsTzopur5Du6{1-oD!M*J9ONeib00W|p{LDWwpz>SB z{+8tUl(HQ$wU`|FKxNk~E`g1e>OeqT5V*ZozW(4S_z>Db#|!p?4#Cf>?c0pE6Jq)e zyidHH)RiV)1Iv*JI0wywgQKq)?{zfxt7jTY=B07Um9Dx_PL*RVy}Rn$f`{#!ib#Wo zLyr0+wl2vDksXRoq=kp!euC2ktR$;*6KUE{L-=Ys%|^D%V;xOYwyJm>@^ooWDFd6b zb(adB60Q=L0ozX8`r^^BY%(Qor5j`Z4?`rTWjyae!(qUJGbCT{g1ga_pokC7pLoA! S+#YcN00004nJa0`JjZIe166M z|Bmuq5@#lGD20?Job#RdHbP8T`9K55tFvy*Y}Y^jaX*ncbxUw?M$xmzgDbbkFiEfe l;^6m3=R;AzWs~}yjC&hJ=Ka0j_5x@$gQu&X%Q~loCIGF&K#c$Z literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/mario/textures/mario_pipe_end_sm.png b/mods/z_remove/myArcade/mario/textures/mario_pipe_end_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..e80bad11243d33e0473a4de11d607ad95c4a9e07 GIT binary patch literal 281 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE(|OTO$-8`j~+4wif|Tq zL>4nJa0`JjwdEx z26=a0-b#KI`K9SG>m8rF4b!;z_O!J8+iMrqV(rF#NI-~5r(vhk$+GSf$N47Mol95f zWW89g#pM+gxah#F$y+Y}d^Ep-TjRrxiZ5HuN~;PkDH|+*BELp%!?|^9Pi=KFxV5*j zitTkm`DYe0P5URW&r7LqpP=>3xS%+8jiT+D*S{zBImW&B>rR+{UWY|UKVknyx0gqF a@4d*={58GkCiCxvX4nJa0`JjbY5AE=PQ)78&qol`;+0OkoMF#rGn literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/mario/textures/mario_turtle.png b/mods/z_remove/myArcade/mario/textures/mario_turtle.png new file mode 100644 index 0000000000000000000000000000000000000000..f3e5709803866ee3c1688b68e8e01c6949b3c35f GIT binary patch literal 2485 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 literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/mario/turtle.lua b/mods/z_remove/myArcade/mario/turtle.lua new file mode 100644 index 00000000..262997e8 --- /dev/null +++ b/mods/z_remove/myArcade/mario/turtle.lua @@ -0,0 +1,171 @@ + +local ghosts_death_delay = 5 + + +local turtles = { + {"turtle1","Ferk"}, + {"turtle2","Don"}, + {"turtle3","Max"}, + {"turtle4","Nathan"}, + } +for i in ipairs(turtles) do + local itm = turtles[i][1] + local desc = turtles[i][2] + + minetest.register_entity("mario:"..itm, { + hp_max = 1, + physical = true, + collide_with_objects = true, + visual = "sprite", + visual_size = {x = 1, y = 1}, + textures = { + "mario_turtle.png", + "mario_turtle.png", + "mario_turtle.png", + "mario_turtle.png", + "mario_turtle.png", + "mario_turtle.png", + }, + + collisionbox = {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25}, + is_visible = true, + automatic_rotate = true, + automatic_face_movement_dir = -90, -- set yaw direction in degrees, false to disable + makes_footstep_sound = false, + direction = {x=1, y=0, z=0}, + acceleration = {x=0, y=-10, z=0}, + speed = 3, + + update_velocity = function(self) + local velocity = vector.multiply(self.direction, self.speed) + self.object:setvelocity(velocity) + end, + + on_step = function(self, dtime) + -- every 1 second + self.timer = (self.timer or 0) + dtime + if self.timer < 1 then return end + self.timer = 0 + + -- Do we have game state? if not just die + local gamestate = mario.games[self.gameid] + if not gamestate then + minetest.log("action", "Removing turtle without game assigned") + self.object:remove() + return + end + + -- Make sure we are in the right state by keeping track of the reset time + -- if the reset time changed it's likely the game got resetted while the entity wasn't loaded + if self.last_reset then + if self.last_reset ~= gamestate.last_reset then + minetest.log("action", "Removing turtle remaining after reset ") + self.object:remove() + end + else + self.last_reset = gamestate.last_reset + end + + -- Make sure we have a targetted player + if not self.target then + self.target = minetest.get_player_by_name(gamestate.player_name) + end + local player = self.target + + -- find distance to the player + local dist = vector.distance(self.object:getpos(), player:getpos()) + if dist < 1 then + mario.on_player_death(self.gameid, player) + end + + local velocity = self.object:getvelocity() + + -- if our velocity is close to zero, we are in collision + if math.abs(velocity.x) < 0.25 then + -- Check if there's a portal or some other node + local pos = self.object:getpos() + pos.y = pos.y + 0.5 + local node = minetest.get_node(pos) + if minetest.registered_nodes[node.name].on_turtle_collision then + minetest.registered_nodes[node.name].on_turtle_collision(pos, self.object, self.gameid) + else + self.direction.x = -self.direction.x + end + if(self.direction.x == 0) then + self.direction.x = 1 + end + end + self:update_velocity() + end, +--[[ + -- If there's no player just stop + if not player then + self.set_velocity(self, 0) + return + end + + local s = self.object:getpos() -- ghost + local p = player:getpos() -- player + + -- find distance from ghost to player + local distance = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5 + if distance < 1.5 then + -- player touches ghost!! + + + -- Ghost catches the player! + gamestate.lives = gamestate.lives - 1 + if gamestate.lives < 1 then + minetest.chat_send_player(gamestate.player_name,"Game Over") + mario.game_end(self.gameid) + minetest.sound_play("mario_death", {pos = boardcenter,max_hear_distance = 20, object=player, loop=false}) + + elseif gamestate.lives == 1 then + minetest.chat_send_player(gamestate.player_name,"This is your last life") + mario.game_reset(self.gameid, player) + else + minetest.chat_send_player(gamestate.player_name,"You have ".. gamestate.lives .." lives left") + mario.game_reset(self.gameid, player) + end + --end + mario.update_hud(self.gameid, player) + + + + else + local vec = {x=p.x-s.x, y=p.y-s.y, z=p.z-s.z} + local yaw = (math.atan(vec.z/vec.x)+math.pi/2) + if p.x > s.x then + yaw = yaw + math.pi + end + -- face player and move backwards/forwards + self.object:setyaw(yaw) + if gamestate.power_pellet then + self.set_velocity(self, -gamestate.speed) --negative velocity + else + self.set_velocity(self, gamestate.speed) + end + end + end, + --]] + + -- This function should return the saved state of the entity in a string + get_staticdata = function(self) + return (self.gameid or "") .. ";" .. (self.last_reset or "") + end, + + -- This function should load the saved state of the entity from a string + on_activate = function(self, staticdata) + self:update_velocity() + self.object:setacceleration(self.acceleration) + self.object:set_armor_groups({immortal=1}) + if staticdata and staticdata ~= "" then + local data = string.split(staticdata, ";") + if #data == 2 then + self.gameid = data[1] + self.last_reset = tonumber(data[2]) + end + end + end + }) +end diff --git a/mods/z_remove/myArcade/modpack.txt b/mods/z_remove/myArcade/modpack.txt new file mode 100644 index 00000000..e69de29b diff --git a/mods/z_remove/myArcade/myhighscore/api.lua b/mods/z_remove/myArcade/myhighscore/api.lua new file mode 100644 index 00000000..f1e84f80 --- /dev/null +++ b/mods/z_remove/myArcade/myhighscore/api.lua @@ -0,0 +1,75 @@ + +-- Store any information we might need for the games that will use highscore +-- (icons, description, or whatever) +myhighscore.registered_games = {} + +-- This table will contain a table for each registered game which +-- will be an array of player scores +myhighscore.scores = {} + +-- How many scores to keep saved per game +local stored_scores = 50 + +-- Name of the folder to save the scores to +-- each game highscore list will be saved in a file inside this directory +local score_directory = minetest.get_worldpath().."/myhighscores/" + +-- You can register a new arcade game using this function +-- The definition will get added to the table of registered games. +function myhighscore.register_game(name, definition) + definition.description = definition.description or name + myhighscore.registered_games[name] = definition + myhighscore.load_scores(name) +end + +-- Returns true if score from A is smaller than score from B +-- Used for sorting the score arra +function myhighscore.is_score_higher(scoreA, scoreB) + return scoreA.score > scoreB.score +end + +-- Saves a given score for the given game. "score" will be a table containing at least: +-- player (player name) and score (points) +function myhighscore.save_score(name, score) + local scores = myhighscore.scores[name] + + -- Check first if the last score is higher + if scores[stored_scores] and + myhighscore.is_score_higher(scores[stored_scores], score) then + return false + end + + table.insert(scores, score) + -- sort the array + table.sort(scores, myhighscore.is_score_higher) + -- check position and remove any extra ones + local pos = 0 + for i,sc in pairs(scores) do + if sc == score then + pos = i + elseif i > stored_scores then + scores[i] = nil + end + end + -- save it to disk + local f, err = io.open(score_directory .. name, "w") + f:write(minetest.serialize(scores)) + f:close() + -- return the position we hold on the list + return pos +end + + +-- Read scores from disk for the given game, or initialize the scores table if not present +function myhighscore.load_scores(name) + local f, err = io.open(score_directory .. name, "r") + local data = {} + if f then + data = minetest.deserialize(f:read("*a")) or {} + f:close() + end + myhighscore.scores[name] = data +end + +-- Create the scores directory if it doesn't exist! +minetest.mkdir(score_directory) diff --git a/mods/z_remove/myArcade/myhighscore/init.lua b/mods/z_remove/myArcade/myhighscore/init.lua new file mode 100644 index 00000000..854be706 --- /dev/null +++ b/mods/z_remove/myArcade/myhighscore/init.lua @@ -0,0 +1,5 @@ + +myhighscore = {} + +dofile(minetest.get_modpath("myhighscore").."/api.lua") +dofile(minetest.get_modpath("myhighscore").."/scoreboard.lua") diff --git a/mods/z_remove/myArcade/myhighscore/scoreboard.lua b/mods/z_remove/myArcade/myhighscore/scoreboard.lua new file mode 100644 index 00000000..0c3bb483 --- /dev/null +++ b/mods/z_remove/myArcade/myhighscore/scoreboard.lua @@ -0,0 +1,94 @@ + + + + +local button_form = "size[6,8;]".. + "background[0,0;6,8;myhighscore_form_bg.png]".. + "label[2,0.5;HIGH SCORES]".. + "button[1,1;4,1;game;label]".. + "button_exit[2,7;2,1;exit;Exit]" + +--place holders +local game_name = "the game" +local game_player_name = "the player" +local game_player_score = "648138" + +local function show_formspec_for_game(playername, gamename) + local def = myhighscore.registered_games[gamename] + local scores = myhighscore.scores[gamename] or {} + -- Obtain a comma separated list of scores to display + local scorelist = "" + for _,score in pairs(scores) do + scorelist = scorelist .." ".. minetest.formspec_escape(score.player) .. + "\t\t\t\t " .." ".. score.score .."," + end + + minetest.show_formspec(playername, "myhighscores:score_" .. gamename, "size[6,8;]".. + "background[0,0;6,8;myhighscore_form_bg.png]".. + "label[1,0.5;HIGH SCORES FOR "..def.description.."]".. + "label[1.25,1.5;PLAYER]".. + "label[3.5,1.5;SCORE]".. + "textlist[0.5,2;5,5;;"..scorelist.."]".. + "button_exit[3,7;2,1;exit;Exit]") +end + + +minetest.register_node("myhighscore:score_board", { + description = "Score Board", + tiles = { + "myhighscore_top.png", + "myhighscore_back.png", + "myhighscore_side.png^[transformFX", + "myhighscore_side.png", + "myhighscore_back.png", + "myhighscore_front.png", + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 1}, + node_box = { + type = "fixed", + fixed = { + {-0.375, -0.5, -0.5, 0.375, -0.1875, 0.5}, + {-0.375, -0.5, 0.1875, 0.375, 0.5, 0.5}, + {-0.1875, -0.5, -0.3125, -0.125, 0, -0.25}, + {-0.375, -0.5, 0, -0.3125, 0.5, 0.5}, + {0.3125, -0.5, 0, 0.375, 0.5, 0.5}, + {-0.375, 0.4375, 0, 0.375, 0.5, 0.5}, + } + }, + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_string("infotext", "High Scores") + + local textlist = "" + for game,def in pairs(myhighscore.registered_games) do + textlist = textlist .." ".. minetest.formspec_escape(def.description) .. "," + end + + meta:set_string("formspec", "size[6,8;]".. + "background[0,0;6,8;myhighscore_form_bg.png]".. + "label[2,0.5;HIGH SCORES]".. + "label[1.3,1;Choose a game for its score]".. + "textlist[0.5,1.6;5,5;gameid;"..textlist.."]".. + "button_exit[2,7;2,1;exit;Exit]") + + end, + on_receive_fields = function(pos, formname, fields, sender) + local meta = minetest.env:get_meta(pos) + local playername = sender:get_player_name() + if fields.gameid then + local event = minetest.explode_textlist_event(fields.gameid) + -- find which game it is + local i, game = 0, nil + repeat + game = next(myhighscore.registered_games, game) + i = i + 1 + until not game or i == event.index + if game then + show_formspec_for_game(playername, game) + end + end + end, +}) diff --git a/mods/z_remove/myArcade/myhighscore/textures/myhighscore_back.png b/mods/z_remove/myArcade/myhighscore/textures/myhighscore_back.png new file mode 100644 index 0000000000000000000000000000000000000000..fb51dcfc2dc7b60de70ae4328883f9dfe9acc05b GIT binary patch literal 409 zcmV;K0cQS*P)zs=o7t)>j))(Knc=!FWagTv=7<1*{{WP$D!3>CSOD{qCMxId3%I-Cx~QTw&zzdO zdoir4pM*)*%#fL@K>%W?dQ~lEE`6Fj&6C?x&NS8C!KXR8Eb3~w(H=5gO_SOLA$eml zV*oz}PkK6%BM$^}UDrRr**LdOd4WtB(@lnEenW$FzeA`lTcj$>(lu5V@{BGwij$Fbr+@=O}8{aaoO00000NkvXXu0mjf Dp@OT( literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/myhighscore/textures/myhighscore_form_bg.png b/mods/z_remove/myArcade/myhighscore/textures/myhighscore_form_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..d6a8e1889152535e1292b60ea3cead3ec3b91d3e GIT binary patch literal 471 zcmeAS@N?(olHy`uVBq!ia0vp^3qY8I4M=vMPuB%fY)RhkE%y{W;-5;PJdx@v7EBk#e2>~hPe`mdcMlq&%x;TbZ+)Tn2CuJkbT^U>UL`-h#It&5v9 zRUKG57#tfo1W2YBn-~NYI0Q(ilpF*Um{=G|q+A-*9LRAd&|gG2^XIg(zZZD!p)_pIRE5w-R|+b|HE<*rD{SLX`>k{9F=*QB{7y#d3W^Nk>t;et=NI$sbF6>2Yl-*9EF zGdWin%SZs?|YhAdzu+jN=zwnStDjfRRu}x zc00TW$Kw$qf)E1C%pfADwE_TseEo~_hXVj0=L`VYZnyaO^A6|33v$j75vVEvz(fR> z%LOC>pcQ+e<9v8osSpvAQV?pbD5b1^=A2viTWjx562aMS;oJA;o8N1#sI@{wU_QIE zE~Rg8jN$|#gsYJv(j0w@x6(iBeVgBFg3EUkzx;Vvx$oU`&Uh-nn%YL<>~7@mPmljq zusnhG-uFFADIkgce*dl@old8JzNM5}EIq1b#uy{bjGN7dX2!1TTD0eRW{imEx2POZy=>Y9u#Exdd6v7EyVt(&wQXDN`(AU- zI?uD_oGU)Ys4>RtF794thN^A)G0TF?!Lfsvz3K0QM zRUtFizlf|j?`HOZhzRccMno(|7MmFW`~%=yW{+}~JS zRZC%JJ}q>)B7%rm1q7f%#xrv%Q}##ZZXVt4?Q~OB^#Nc(@120%gUrPD`(0{90000k}@P)wJQv6%t< z2QXrpi4ID@0dRR~bR02NJ%FnU9T!J(Xugb%;;K3rX6BQGOS&RLL>vVJU@#o{%siOs z(06llbI2IohTE5Ns*2m&+v6`t@4X@dcZXN+kuBLaL1n?(nZT$WN_V;ol`n|<4+lFR zR3ie-8S$j~1d)_nG1-YAsG5)xG9R9sIwVvTc~;Dm%wO#14Qi*!Xx%}GEm4Ao(VnIURK3h&gpw0x z#(vtdrsVx6_I-bH|8hmAX{y%RvA+MV@;uKq&vUKoTD|vbt<@jP2|Tj7lGObG0000< KMNUMnLSTZCuJ;1~ literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/aliases.lua b/mods/z_remove/myArcade/pacmine/aliases.lua new file mode 100644 index 00000000..dfdd4aae --- /dev/null +++ b/mods/z_remove/myArcade/pacmine/aliases.lua @@ -0,0 +1,11 @@ + + +local nodes = { + "wall", "floor", "wallc", "walle", "walk_wall","glass","glassw", + "cherrys","apple","orange","strawberry", + "pellet_1","pellet_2","block2","portalr","portall" +} + +for _,itm in pairs(nodes) do + minetest.register_alias("mypacman:"..itm, "pacmine:"..itm) +end diff --git a/mods/z_remove/myArcade/pacmine/blocks.lua b/mods/z_remove/myArcade/pacmine/blocks.lua new file mode 100644 index 00000000..262901ba --- /dev/null +++ b/mods/z_remove/myArcade/pacmine/blocks.lua @@ -0,0 +1,75 @@ +local sbox = { + type = "fixed", + fixed = { + {-0.45, -0.45, -0.45, 0.45, 0.45, 0.45} + } + } +local cbox = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5} + } + } +local blocks = { +{"Floor", "floor", "floor","floor",0,true}, +{"Wall", "wall", "wall","floor",11,true}, +{"Wallc", "wallc", "wallc","floor",11,true}, +{"Walle", "walle", "walle","floor",11,true}, +{"Wall Walkthrough","walk_wall","wall","floor",11,false}, +} +for i in ipairs(blocks) do +local des = blocks[i][1] +local itm = blocks[i][2] +local i1 = blocks[i][3] +local i2 = blocks[i][4] +local lit = blocks[i][5] +local tf = blocks[i][6] + +minetest.register_node("pacmine:"..itm, { + description = des, + tiles = { + "pacmine_"..i1..".png", + "pacmine_"..i2..".png", + "pacmine_walls.png", + "pacmine_walls.png", + "pacmine_walls.png", + "pacmine_walls.png", + }, + drawtype = "normal", + paramtype = "light", + paramtype2 = "facedir", + light_source = lit, + pointable = false, + walkable = tf, + groups = {disable_jump = 1, immortal=1, not_in_creative_inventory = 1}, + selection_box = sbox, + collision_box = cbox, + +}) +end +--Glass +minetest.register_node("pacmine:glass", { + description = "glass", + tiles = {"pacmine_glass.png"}, + drawtype = "glasslike", + paramtype = "light", + paramtype2 = "facedir", + pointable = false, + groups = {immortal=1,not_in_creative_inventory = 1}, + selection_box = cbox, + collision_box = cbox, + +}) +minetest.register_node("pacmine:glassw", { + description = "glassw", + tiles = {"pacmine_glass.png"}, + drawtype = "glasslike", + paramtype = "light", + paramtype2 = "facedir", + walkable = false, + pointable = false, + groups = {immortal=1,not_in_creative_inventory = 1}, + selection_box = cbox, + colision_box = cbox, + +}) diff --git a/mods/z_remove/myArcade/pacmine/depends.txt b/mods/z_remove/myArcade/pacmine/depends.txt new file mode 100644 index 00000000..01e0fb06 --- /dev/null +++ b/mods/z_remove/myArcade/pacmine/depends.txt @@ -0,0 +1 @@ +myhighscore diff --git a/mods/z_remove/myArcade/pacmine/fruit.lua b/mods/z_remove/myArcade/pacmine/fruit.lua new file mode 100644 index 00000000..5e413135 --- /dev/null +++ b/mods/z_remove/myArcade/pacmine/fruit.lua @@ -0,0 +1,43 @@ +local cbox = { + type = "fixed", + fixed = {{-0.875, 0.125, -0.0625, -0.125, 0.875, 0.0625}} + } +local sbox = { + type = "fixed", + fixed = {{0, 0, 0, 0, 0, 0}} + } + +local pelletitems = { + {"cherrys", "Cherrys","100"}, + {"strawberry", "Strawberry","300"}, + {"orange", "Orange","500"}, + {"apple", "Apple","700"}, + } +for i in ipairs (pelletitems) do + local itm = pelletitems[i][1] + local desc = pelletitems[i][2] + local points = pelletitems[i][3] + +minetest.register_node("pacmine:"..itm,{ + description = desc, + inventory_image = "pacmine_"..itm..".png", + tiles = {"pacmine_"..itm..".png",}, + drawtype = "mesh", + mesh = "pacmine_"..itm..".obj", + paramtype = "light", + paramtype2 = "facedir", + walkable = false, + light_source = 14, + groups = {immortal=1,not_in_creative_inventory = 1}, + --node_box = cbox, + selection_box = sbox, + collision_box = cbox, + on_timer = function(pos, dtime) + minetest.remove_node(pos) + end, + on_player_collision = function(pos, player, gameid) + minetest.remove_node(pos) + pacmine.on_player_got_fruit(player, points) + end +}) +end diff --git a/mods/z_remove/myArcade/pacmine/gamestate.lua b/mods/z_remove/myArcade/pacmine/gamestate.lua new file mode 100644 index 00000000..b58cd78b --- /dev/null +++ b/mods/z_remove/myArcade/pacmine/gamestate.lua @@ -0,0 +1,328 @@ + +-- Array to hold all the running game states +pacmine.games = {} + +-- Store all the currently playing players +pacmine.players = {} + +-- Duration of the power pellet effect (in seconds) +local power_pellet_duration = 10 + +-- Amount of points that will award a life +local score_for_life_award = 5000 + +--------------------------------------------------------- +-- Public functions (these can be called from any other place) + +-- Start the game from the spawn block at position "pos" activated by "player" +function pacmine.game_start(pos, player, gamedef) + -- create an id unique for the given position + local id = minetest.pos_to_string(pos) + local player_name = player:get_player_name() + + -- make sure any previous game with the same id has ended + local gamestate = pacmine.games[id] + if gamestate then + minetest.chat_send_player(player_name, "A game is already in progress for player " .. gamestate.player_name) + return + end + + -- Create a new game state with that id and add it to the game list + gamedef = gamedef or {} + gamestate = { + id = id, + player_name = player_name, + pos = pos, + player_start = vector.add(pos, (gamedef.player_start or {x=14,y=0.5,z=16})), + ghost_start = vector.add(pos, (gamedef.ghost_start or {x=13,y=0.5,z=19})), + ghost_amount = gamedef.ghost_amount or 4, + pellet_total = gamedef.pellet_total or 252, + speed = gamedef.speed or 2, + lives = gamedef.lives or 3, + scorename = gamedef.scorename, + schematic = gamedef.schematic, + level = 1, + score = 0, + awarded_lives = 0, + pellet_count = 0, + } + pacmine.games[id] = gamestate + pacmine.players[id] = player + + -- store previous priviledges, disable fly whilöe the game is running + gamestate.player_privs = minetest.get_player_privs(player_name) + local new_privs = table.copy(gamestate.player_privs) + new_privs.fly = nil + new_privs.noclip = nil + new_privs.fast = nil + minetest.set_player_privs(player_name, new_privs) + + minetest.log("action","New pacmine game started at " .. id .. " by " .. gamestate.player_name) + + -- place schematic + minetest.place_schematic({x=pos.x,y=pos.y-1,z=pos.z-2},gamedef.schematic,0, "air", true) + + -- Set start positions + pacmine.game_reset(id, player) + pacmine.update_hud(id, player) + minetest.sound_play("pacmine_beginning", {pos = pos,max_hear_distance = 6,gain = 1.0,}) +end + +-- Finish the game with the given id +function pacmine.game_end(id) + pacmine.remove_ghosts(id) + local gamestate = pacmine.games[id] + local player = pacmine.players[id] or minetest.get_player_by_name(gamestate.player_name) + if player then + pacmine.remove_hud(player, gamestate.player_name) + player:moveto(vector.add(gamestate.pos,{x=0.5,y=0.5,z=-1.5})) + end + -- Restore player priviledges + minetest.set_player_privs(gamestate.player_name, gamestate.player_privs) + -- Save score + if gamestate.scorename then + local ranking = myhighscore.save_score(gamestate.scorename, { + player = gamestate.player_name, + score = gamestate.score + }) + if ranking then + minetest.chat_send_player(gamestate.player_name, "You made it to the highscores! Your Ranking: " .. ranking) + end + end + -- Clear the data + pacmine.games[id] = nil + pacmine.players[id] = nil +end + +-- Resets the game to the start positions +function pacmine.game_reset(id, player) + local gamestate = pacmine.games[id] + minetest.log("action", "resetting game " .. id) + + -- Save the time when the game was last resetted (to solve timing issues) + local last_reset = os.time() + + gamestate.power_pellet = false + gamestate.last_reset = last_reset + + -- Position the player + local player = player or minetest.get_player_by_name(gamestate.player_name) + player:setpos(gamestate.player_start) + + -- Spawn the ghosts and assign the game id to each ghost + minetest.after(2, function() + if pacmine.games[id] and last_reset == pacmine.games[id].last_reset then + local ghost = minetest.add_entity(gamestate.ghost_start, "pacmine:inky") + ghost:get_luaentity().gameid = id + end + end) + if gamestate.ghost_amount >= 2 then + minetest.after(12, function() + if pacmine.games[id] and last_reset == pacmine.games[id].last_reset then + local ghost = minetest.add_entity(gamestate.ghost_start, "pacmine:pinky") + ghost:get_luaentity().gameid = id + end + end) + end + if gamestate.ghost_amount >= 3 then + minetest.after(22, function() + if pacmine.games[id] and last_reset == pacmine.games[id].last_reset then + local ghost = minetest.add_entity(gamestate.ghost_start, "pacmine:blinky") + ghost:get_luaentity().gameid = id + end + end) + end + if gamestate.ghost_amount >= 4 then + minetest.after(32, function() + if pacmine.games[id] and last_reset == pacmine.games[id].last_reset then + local ghost = minetest.add_entity(gamestate.ghost_start, "pacmine:clyde") + ghost:get_luaentity().gameid = id + end + end) + end +end + +-- Remove all the ghosts from the board with the given id +function pacmine.remove_ghosts(id) + local gamestate = pacmine.games[id] + if not gamestate then return end + + -- Remove all non-players (ghosts!) + local boardcenter = vector.add(gamestate.pos, {x=13,y=0.5,z=15}) + for index, object in ipairs(minetest.get_objects_inside_radius(boardcenter,20)) do + if object:is_player() ~= true then + object:remove() + end + end +end + +-- Add a fruit to the game board +function pacmine.add_fruit(id) + local gamestate = pacmine.games[id] + if not gamestate then return end + local node = {} + -- Different fruit will be used depending on the level + if gamestate.level == 1 then + node.name = "pacmine:cherrys" + elseif gamestate.level == 2 then + node.name = "pacmine:strawberry" + elseif gamestate.level < 5 then + node.name = "pacmine:orange" + else + node.name = "pacmine:apple" + end + local pos = vector.add(gamestate.player_start,{x=0,y=-1,z=0}) + minetest.set_node(pos, node) + -- Set the timer for the fruit to disappear + minetest.get_node_timer(pos):start(math.random(20, 30)) +end + +-- A player got a pellet, update the state +function pacmine.on_player_got_pellet(player) + local name = player:get_player_name() + local gamestate = pacmine.get_game_by_player(name) + if not gamestate then return end + + gamestate.pellet_count = gamestate.pellet_count + 1 + gamestate.score = gamestate.score + 10 + pacmine.update_hud(gamestate.id, player) + minetest.sound_play("pacmine_chomp", {object = player, max_hear_distance = 6}) + + if gamestate.pellet_count == 70 or gamestate.pellet_count == 180 then + pacmine.add_fruit(gamestate.id) + elseif gamestate.pellet_count >= gamestate.pellet_total then + minetest.chat_send_player(name, "You cleared the board!") + + pacmine.remove_ghosts(gamestate.id) + gamestate.pellet_count = 0 + gamestate.level = gamestate.level + 1 + gamestate.speed = gamestate.level + 1 + + minetest.after(3.0, function() + minetest.chat_send_player(name, "Starting Level "..gamestate.level) + -- place schematic + minetest.place_schematic(vector.add(gamestate.pos, {x=0,y=-1,z=-2}),gamestate.schematic,0, "air", true) + + -- Set start positions + pacmine.game_reset(gamestate.id, player) + minetest.sound_play("pacmine_beginning", {pos = pos,max_hear_distance = 6,gain = 1.0,}) + end) + end + + if gamestate.score / score_for_life_award >= 1 + gamestate.awarded_lives then + minetest.chat_send_player(name, "You reached " .. gamestate.score .. " points and earned an extra life!") + gamestate.lives = gamestate.lives + 1 + gamestate.awarded_lives = gamestate.awarded_lives + 1 + end +end + +-- A player got a power pellet, update the state +function pacmine.on_player_got_power_pellet(player) + local name = player:get_player_name() + local gamestate = pacmine.get_game_by_player(name) + if not gamestate then return end + + minetest.chat_send_player(name, "You got a POWER PELLET") + gamestate.power_pellet = os.time() + power_pellet_duration + gamestate.score = gamestate.score + 50 + pacmine.update_hud(gamestate.id, player) + + local boardcenter = vector.add(gamestate.pos, {x=13,y=0.5,z=15}) + local powersound = minetest.sound_play("pacmine_powerup", {pos = boardcenter,max_hear_distance = 6, object=player, loop=true}) + + minetest.after(power_pellet_duration, function() + minetest.sound_stop(powersound) + if os.time() >= (gamestate.power_pellet or 0) then + gamestate.power_pellet = false + minetest.chat_send_player(name, "POWER PELLET wore off") + end + end) +end + +-- A player got a fruit, update the state +function pacmine.on_player_got_fruit(player, points) + local name = player:get_player_name() + local gamestate = pacmine.get_game_by_player(name) + if not gamestate then return end + gamestate.score = gamestate.score + points + minetest.chat_send_player(name, points .. " bonus points!") + minetest.sound_play("pacmine_eatfruit", {pos = pos, max_hear_distance = 6}) +end + +-- Get the game that the given player is playing +function pacmine.get_game_by_player(player_name) + for _,gamestate in pairs(pacmine.games) do + if gamestate.player_name == player_name then + return gamestate + end + end +end + +--------------------------------------------------------- +--- Private functions (only can be used inside this file) + + +-- Called every 0.5 seconds for each player that is currently playing +local function on_player_gamestep(player, gameid) + local player_pos = player:getpos() + local positions = { + {x=0.5,y=0.5,z=0.5}, + {x=-0.5,y=0.5,z=-0.5}, + } + for _,pos in pairs(positions) do + pos = vector.round(vector.add(player_pos, pos)) + local node = minetest.get_node(pos) + local nodedef = minetest.registered_nodes[node.name] + + if nodedef and nodedef.on_player_collision then + nodedef.on_player_collision(pos, player, gameid) + end + end +end + +------------------- +--- Execution code + + +-- Time counters +local tmr_gamestep = 0 +minetest.register_globalstep(function(dtime) + tmr_gamestep = tmr_gamestep + dtime; + if tmr_gamestep > 0.2 then + for id,player in pairs(pacmine.players) do + on_player_gamestep(player, id) + end + tmr_gamestep = 0 + end +end) + +minetest.register_on_leaveplayer(function(player) + local name = player:get_player_name() + for id,game in pairs(pacmine.games) do + if game.player_name == name then + pacmine.game_end(id) + end + end +end) + +minetest.register_on_shutdown(function() + minetest.log("action", "Server shuts down. Ending all pacmine games") + for id,game in pairs(pacmine.games) do + pacmine.game_end(id) + end +end) + +-- Chatcommand to end the game for the current player +minetest.register_chatcommand("pacmine_exit", { + params = "", + description = "Loads and saves all rooms", + func = function(name, param) + local gamestate = pacmine.get_game_by_player(name) + if gamestate then + pacmine.game_end(gamestate.id) + minetest.chat_send_player(name, "You are no longer playing pacmine") + else + minetest.chat_send_player(name, "You are not currently in a pacmine game") + end + end +}) diff --git a/mods/z_remove/myArcade/pacmine/ghost.lua b/mods/z_remove/myArcade/pacmine/ghost.lua new file mode 100644 index 00000000..ca9febda --- /dev/null +++ b/mods/z_remove/myArcade/pacmine/ghost.lua @@ -0,0 +1,148 @@ + +local ghosts_death_delay = 5 + + +local ghosts = { + {"pinky","Pinky"}, + {"inky","Inky"}, + {"blinky","Blinky"}, + {"clyde","Clyde"}, + } +for i in ipairs(ghosts) do + local itm = ghosts[i][1] + local desc = ghosts[i][2] + + minetest.register_entity("pacmine:"..itm, { + hp_max = 1, + physical = true, + collide_with_objects = true, + visual = "cube", + visual_size = {x = 0.6, y = 1}, + textures = { + "pacmine_"..itm.."s.png", + "pacmine_"..itm.."s.png", + "pacmine_"..itm.."s.png", + "pacmine_"..itm.."s.png", + "pacmine_"..itm.."f.png", + "pacmine_"..itm.."s.png", + }, + velocity = {x=math.random(-1,1), y=0, z=math.random(-1,1)}, + collisionbox = {-0.25, -1.0, -0.25, 0.25, 0.48, 0.25}, + is_visible = true, + automatic_rotate = true, + automatic_face_movement_dir = -90, -- set yaw direction in degrees, false to disable + makes_footstep_sound = false, + + set_velocity = function(self, v) + if not v then v = 0 end + local yaw = self.object:getyaw() + self.object:setvelocity({x=math.sin(yaw) * -v, y=self.object:getvelocity().y, z=math.cos(yaw) * v}) + end, + + on_step = function(self, dtime) + -- every 1 second + self.timer = (self.timer or 0) + dtime + if self.timer < 1 then return end + self.timer = 0 + + -- Do we have game state? if not just die + local gamestate = pacmine.games[self.gameid] + if not gamestate then + minetest.log("action", "Removing pacman ghost without game assigned") + self.object:remove() + return + end + -- Make sure we are in the right state by keeping track of the reset time + -- if the reset time changed it's likely the game got resetted while the entity wasn't loaded + if self.last_reset then + if self.last_reset ~= gamestate.last_reset then + minetest.log("action", "Removing pacman ghost remaining after reset ") + self.object:remove() + end + else + self.last_reset = gamestate.last_reset + end + + -- Make sure we have a targetted player + if not self.target then + self.target = minetest.get_player_by_name(gamestate.player_name) + end + local player = self.target + + -- If there's no player just stop + if not player then + self.set_velocity(self, 0) + return + end + + local s = self.object:getpos() -- ghost + local p = player:getpos() -- player + + -- find distance from ghost to player + local distance = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5 + if distance < 1.6 then + -- player touches ghost!! + + if gamestate.power_pellet then + -- Player eats ghost! move it to spawn + local ghost_spawn = gamestate.ghost_start + self.object:setpos(ghost_spawn) + -- set the timer negative so it'll have to wait extra time + self.timer = -ghosts_death_delay + -- play sound and reward player + minetest.sound_play("pacmine_eatghost", {pos = boardcenter,max_hear_distance = 6, object=player, loop=false}) + gamestate.score = gamestate.score + 200 + pacmine.update_hud(gamestate.id, player) + minetest.chat_send_player(gamestate.player_name,"You ate a ghost!") + else + -- Ghost catches the player! + gamestate.lives = gamestate.lives - 1 + if gamestate.lives < 1 then + minetest.chat_send_player(gamestate.player_name,"Game Over") + pacmine.game_end(self.gameid) + minetest.sound_play("pacmine_death", {pos = boardcenter,max_hear_distance = 20, object=player, loop=false}) + + elseif gamestate.lives == 1 then + minetest.chat_send_player(gamestate.player_name,"This is your last life") + pacmine.game_reset(self.gameid, player) + else + minetest.chat_send_player(gamestate.player_name,"You have ".. gamestate.lives .." lives left") + pacmine.game_reset(self.gameid, player) + end + end + pacmine.update_hud(self.gameid, player) + + else + local vec = {x=p.x-s.x, y=p.y-s.y, z=p.z-s.z} + local yaw = (math.atan(vec.z/vec.x)+math.pi/2) + if p.x > s.x then + yaw = yaw + math.pi + end + -- face player and move backwards/forwards + self.object:setyaw(yaw) + if gamestate.power_pellet then + self.set_velocity(self, -gamestate.speed) --negative velocity + else + self.set_velocity(self, gamestate.speed) + end + end + end, + + -- This function should return the saved state of the entity in a string + get_staticdata = function(self) + return (self.gameid or "") .. ";" .. (self.last_reset or "") + end, + + -- This function should load the saved state of the entity from a string + on_activate = function(self, staticdata) + self.object:set_armor_groups({immortal=1}) + if staticdata and staticdata ~= "" then + local data = string.split(staticdata, ";") + if #data == 2 then + self.gameid = data[1] + self.last_reset = tonumber(data[2]) + end + end + end + }) +end diff --git a/mods/z_remove/myArcade/pacmine/hud.lua b/mods/z_remove/myArcade/pacmine/hud.lua new file mode 100644 index 00000000..8fb9e0ce --- /dev/null +++ b/mods/z_remove/myArcade/pacmine/hud.lua @@ -0,0 +1,44 @@ + + +local hud_table = {} + +function pacmine.update_hud(id, player) + local game = pacmine.games[id] + player = player or minetest.get_player_by_name(game.player_name) + if not player then + return + elseif not game then + pacmine.remove_hud(player) + return + end + local pellets_left = game.pellet_total - game.pellet_count + local hudtext = "Score " .. game.score + .. "\nLevel " .. game.level + .. "\nLives " .. game.lives + .. "\nPellets " .. pellets_left + + local hud = hud_table[game.player_name] + if not hud then + hud = player:hud_add({ + hud_elem_type = "text", + position = {x = 0, y = 1}, + offset = {x=100, y = -100}, + scale = {x = 100, y = 100}, + number = 0xfff227, --color + text = hudtext + }) + hud_table[game.player_name] = hud + else + player:hud_change(hud, "text", hudtext) + end +end + + +function pacmine.remove_hud(player, playername) + local name = playername or player:get_player_name() + local hud = hud_table[name] + if hud then + player:hud_remove(hud) + hud_table[name] = nil + end +end diff --git a/mods/z_remove/myArcade/pacmine/init.lua b/mods/z_remove/myArcade/pacmine/init.lua new file mode 100644 index 00000000..5e8823b4 --- /dev/null +++ b/mods/z_remove/myArcade/pacmine/init.lua @@ -0,0 +1,148 @@ + +-- This variable will be exported to other mods when they "depend" on this mod +pacmine = {} + +dofile(minetest.get_modpath("pacmine").."/fruit.lua") +dofile(minetest.get_modpath("pacmine").."/ghost.lua") +dofile(minetest.get_modpath("pacmine").."/blocks.lua") +dofile(minetest.get_modpath("pacmine").."/portals.lua") +dofile(minetest.get_modpath("pacmine").."/gamestate.lua") +dofile(minetest.get_modpath("pacmine").."/hud.lua") +--dofile(minetest.get_modpath("pacmine").."/aliases.lua") + + + +--Yellow Pellets +minetest.register_node("pacmine:pellet_1", { + description = "Pellet 1", + tiles = {"wool_yellow.png"}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + walkable = false, + light_source = 11, + drop = "", + groups = {immortal = 1, not_in_creative_inventory = 1}, + node_box = { + type = "fixed", + fixed = { + {-0.625, 0.25, -0.125, -0.375, 0.5, 0.125}, + } + }, + selection_box = { + type = "fixed", + fixed = { + {0, 0, 0, 0, 0, 0}, + } + }, + on_player_collision = function(pos, player, gameid) + minetest.remove_node(pos) + pacmine.on_player_got_pellet(player) + end +}) + +--Power Pellets. Need to make these do something +minetest.register_node("pacmine:pellet_2", { + description = "Pellet 2", + tiles = {{name="pacmine_powerpellet.png", animation={type="vertical_frames",aspect_w=16, aspect_h=16, length=0.8}},}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + walkable = false, + light_source = 11, + drop = {max_items = 1,items = { + {items = {"pacmine:cherrys"},rarity = 4,}, + {items = {"pacmine:apple"},rarity = 4,}, + {items = {"pacmine:peach"},rarity = 4,}, + {items = {"pacmine:strawberry"},rarity = 4,},}, + }, + groups = {immortal = 1, not_in_creative_inventory = 1}, + node_box = { + type = "fixed", + fixed = { + {-0.625, -0.125, -0.25, -0.375, 0.125, 0.25}, + {-0.75, -0.125, -0.125, -0.25, 0.125, 0.125}, + {-0.625, -0.25, -0.125, -0.375, 0.25, 0.125}, + {-0.6875, -0.1875, -0.1875, -0.3125, 0.1875, 0.1875}, + } + }, + selection_box = { + type = "fixed", + fixed = { + {0, 0, 0, 0, 0, 0}, + } + }, + on_player_collision = function(pos, player, gameid) + minetest.remove_node(pos) + pacmine.on_player_got_power_pellet(player) + end +}) + +--The placer block for pacmine +minetest.register_node("pacmine:classic_board",{ + description = "Pacman", + inventory_image = "pacmine_1.png", + tiles = { + "pacmine_wallc.png", + "pacmine_1.png", + "pacmine_1.png", + "pacmine_1.png", + "pacmine_1.png", + "pacmine_1.png", + }, + drawtype = "normal", + paramtype = "light", + paramtype2 = "facedir", + light_source = 8, + groups = {cracky = 1}, + on_rightclick = function(pos, node, player, itemstack, pointed_thing) + pacmine.game_start(pos, player, { + schematic = minetest.get_modpath("pacmine").."/schems/pacmine.mts", + scorename = "pacmine:classic_board", + }) + end, +}) +--The placer block for pacmine mini +minetest.register_node("pacmine:mini_board",{ + description = "Pacman Mini", + inventory_image = "pacmine_1.png^pacmine_mini.png", + tiles = { + "pacmine_wallc.png", + "pacmine_1.png", + "pacmine_1.png", + "pacmine_1.png", + "pacmine_1.png", + "pacmine_1.png^pacmine_mini.png", + }, + drawtype = "normal", + paramtype = "light", + paramtype2 = "facedir", + light_source = 8, + groups = {cracky = 1}, + on_rightclick = function(pos, node, player, itemstack, pointed_thing) + pacmine.game_start(pos, player, { + schematic = minetest.get_modpath("pacmine").."/schems/pacmini.mts", + player_start = {x=13,y=0.5,z=2}, + ghost_start = {x=13,y=0.5,z=10}, + ghost_amount = 2, + speed = 1, + pellet_total = 91, + scorename = "pacmine:mini_board", + }) + end, +}) + +minetest.register_alias("pacmine:block", "pacmine:mini_board") +minetest.register_alias("pacmine:block2", "pacmine:normal_board") + +-- Register with the myhighscore mod +myhighscore.register_game("pacmine:classic_board", { + description = "Pacmine", + icon = "pacmine_1.png", +}) + +-- Register with the myhighscore mod +myhighscore.register_game("pacmine:mini_board", { + description = "Pacmine Mini", + icon = "pacmine_1.png^pacmine_mini.png", +}) diff --git a/mods/z_remove/myArcade/pacmine/models/mypacman_strawberry.obj b/mods/z_remove/myArcade/pacmine/models/mypacman_strawberry.obj new file mode 100644 index 00000000..e30ac5c8 --- /dev/null +++ b/mods/z_remove/myArcade/pacmine/models/mypacman_strawberry.obj @@ -0,0 +1,251 @@ +# Blender v2.76 (sub 2) OBJ File: '' +# www.blender.org +o Strawberry_Plane.004 +v 0.812500 0.375000 -0.050000 +v 0.812500 0.437500 -0.050000 +v 0.812500 0.437500 0.050000 +v 0.812500 0.375000 0.050000 +v 0.187500 0.562500 -0.050000 +v 0.187500 0.500000 -0.050000 +v 0.187500 0.500000 0.050000 +v 0.187500 0.562500 0.050000 +v 0.500000 0.125000 -0.050000 +v 0.562500 0.125000 -0.050000 +v 0.562500 0.125000 0.050000 +v 0.500000 0.125000 0.050000 +v 0.437500 0.187500 -0.050000 +v 0.500000 0.187500 -0.050000 +v 0.500000 0.187500 0.050000 +v 0.437500 0.187500 0.050000 +v 0.687500 0.187500 -0.050000 +v 0.687500 0.250000 -0.050000 +v 0.687500 0.250000 0.050000 +v 0.687500 0.187500 0.050000 +v 0.750000 0.250000 -0.050000 +v 0.750000 0.250000 0.050000 +v 0.250000 0.750000 -0.050000 +v 0.250000 0.687500 -0.050000 +v 0.250000 0.687500 0.050000 +v 0.250000 0.750000 0.050000 +v 0.562500 0.187500 -0.050000 +v 0.625000 0.187500 -0.050000 +v 0.625000 0.187500 0.050000 +v 0.562500 0.187500 0.050000 +v 0.750000 0.750000 -0.050000 +v 0.750000 0.812500 -0.050000 +v 0.750000 0.812500 0.050000 +v 0.750000 0.750000 0.050000 +v 0.875000 0.437500 -0.050000 +v 0.875000 0.437500 0.050000 +v 0.750000 0.312500 -0.050000 +v 0.812500 0.312500 -0.050000 +v 0.812500 0.312500 0.050000 +v 0.750000 0.312500 0.050000 +v 0.187500 0.687500 -0.050000 +v 0.187500 0.625000 -0.050000 +v 0.187500 0.625000 0.050000 +v 0.187500 0.687500 0.050000 +v 0.437500 0.812500 -0.050000 +v 0.375000 0.812500 -0.050000 +v 0.375000 0.812500 0.050000 +v 0.437500 0.812500 0.050000 +v 0.500000 0.875000 -0.050000 +v 0.500000 0.812500 -0.050000 +v 0.500000 0.812500 0.050000 +v 0.500000 0.875000 0.050000 +v 0.687500 0.812500 -0.050000 +v 0.687500 0.812500 0.050000 +v 0.625000 0.812500 -0.050000 +v 0.562500 0.812500 -0.050000 +v 0.562500 0.812500 0.050000 +v 0.625000 0.812500 0.050000 +v 0.375000 0.187500 -0.050000 +v 0.375000 0.187500 0.050000 +v 0.375000 0.250000 -0.050000 +v 0.375000 0.250000 0.050000 +v 0.312500 0.250000 -0.050000 +v 0.312500 0.250000 0.050000 +v 0.312500 0.750000 -0.050000 +v 0.312500 0.750000 0.050000 +v 0.875000 0.500000 -0.050000 +v 0.875000 0.562500 -0.050000 +v 0.875000 0.562500 0.050000 +v 0.875000 0.500000 0.050000 +v 0.250000 0.437500 -0.050000 +v 0.250000 0.375000 -0.050000 +v 0.250000 0.375000 0.050000 +v 0.250000 0.437500 0.050000 +v 0.187500 0.437500 -0.050000 +v 0.187500 0.437500 0.050000 +v 0.562500 0.875000 -0.050000 +v 0.562500 0.875000 0.050000 +v 0.312500 0.812500 -0.050000 +v 0.312500 0.812500 0.050000 +v 0.250000 0.312500 0.050000 +v 0.312500 0.312500 0.050000 +v 0.875000 0.625000 0.050000 +v 0.875000 0.687500 0.050000 +v 0.812500 0.687500 0.050000 +v 0.812500 0.750000 0.050000 +v 0.875000 0.625000 -0.050000 +v 0.875000 0.687500 -0.050000 +v 0.812500 0.750000 -0.050000 +v 0.312500 0.312500 -0.050000 +v 0.812500 0.687500 -0.050000 +v 0.250000 0.312500 -0.050000 +vt 0.802161 0.377298 +vt 0.802161 0.451280 +vt 0.200136 0.557905 +vt 0.200136 0.497702 +vt 0.508590 0.136488 +vt 0.555150 0.136488 +vt 0.440946 0.196690 +vt 0.508590 0.196690 +vt 0.681756 0.196690 +vt 0.681756 0.256893 +vt 0.741959 0.256893 +vt 0.334558 0.665856 +vt 0.334558 0.605654 +vt 0.555150 0.196690 +vt 0.621554 0.196690 +vt 0.618165 0.766021 +vt 0.618165 0.790573 +vt 0.750000 0.812500 +vt 0.750000 0.750000 +vt 0.862364 0.451280 +vt 0.741959 0.317095 +vt 0.802161 0.317095 +vt 0.200136 0.678310 +vt 0.200136 0.618107 +vt 0.485676 0.790573 +vt 0.470855 0.790573 +vt 0.375000 0.812500 +vt 0.437500 0.812500 +vt 0.524034 0.850966 +vt 0.524034 0.836534 +vt 0.500000 0.812500 +vt 0.500000 0.875000 +vt 0.593614 0.790573 +vt 0.687500 0.812500 +vt 0.578792 0.790573 +vt 0.570200 0.790573 +vt 0.571780 0.812500 +vt 0.625000 0.812500 +vt 0.380744 0.196690 +vt 0.380744 0.256893 +vt 0.320541 0.256893 +vt 0.320541 0.738512 +vt 0.260339 0.738512 +vt 0.862364 0.497702 +vt 0.862364 0.557905 +vt 0.260339 0.451280 +vt 0.260339 0.377298 +vt 0.200136 0.451280 +vt 0.538466 0.836534 +vt 0.538466 0.850966 +vt 0.562500 0.875000 +vt 0.562500 0.812500 +vt 0.446303 0.790573 +vt 0.312500 0.812500 +vt 0.312500 0.750000 +vt 0.250000 0.750000 +vt 0.250000 0.687500 +vt 0.187500 0.687500 +vt 0.187500 0.625000 +vt 0.187500 0.562500 +vt 0.187500 0.500000 +vt 0.187500 0.437500 +vt 0.250000 0.437500 +vt 0.250000 0.375000 +vt 0.250000 0.312500 +vt 0.312500 0.312500 +vt 0.312500 0.250000 +vt 0.375000 0.250000 +vt 0.375000 0.187500 +vt 0.437500 0.187500 +vt 0.500000 0.187500 +vt 0.500000 0.125000 +vt 0.562500 0.125000 +vt 0.562500 0.187500 +vt 0.625000 0.187500 +vt 0.687500 0.187500 +vt 0.687500 0.250000 +vt 0.750000 0.250000 +vt 0.750000 0.312500 +vt 0.812500 0.312500 +vt 0.812500 0.375000 +vt 0.812500 0.437500 +vt 0.875000 0.437500 +vt 0.875000 0.500000 +vt 0.875000 0.562500 +vt 0.875000 0.625000 +vt 0.875000 0.687500 +vt 0.812500 0.687500 +vt 0.812500 0.750000 +vt 0.862364 0.618107 +vt 0.862364 0.678310 +vt 0.802161 0.738512 +vt 0.741959 0.738512 +vt 0.320541 0.317095 +vt 0.494269 0.790573 +vt 0.490720 0.812500 +vt 0.802161 0.678310 +vt 0.260339 0.317095 +vt 0.446303 0.766021 +vt 0.274355 0.605654 +vn 1.000000 0.000000 0.000000 +vn -1.000000 -0.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 -0.000000 1.000000 +vn -0.000000 0.000000 -1.000000 +g Strawberry_Plane.004_Strawberry_Plane.004_None +s 1 +f 1/1/1 2/2/1 3/2/1 4/1/1 +f 5/3/2 6/4/2 7/4/2 8/3/2 +f 9/5/3 10/6/3 11/6/3 12/5/3 +f 13/7/3 14/8/3 15/8/3 16/7/3 +f 17/9/1 18/10/1 19/10/1 20/9/1 +f 18/10/3 21/11/3 22/11/3 19/10/3 +f 23/12/2 24/13/2 25/13/2 26/12/2 +f 27/14/3 28/15/3 29/15/3 30/14/3 +f 31/16/1 32/17/1 33/18/1 34/19/1 +f 2/2/3 35/20/3 36/20/3 3/2/3 +f 37/21/3 38/22/3 39/22/3 40/21/3 +f 41/23/2 42/24/2 43/24/2 44/23/2 +f 45/25/4 46/26/4 47/27/4 48/28/4 +f 49/29/2 50/30/2 51/31/2 52/32/2 +f 32/17/4 53/33/4 54/34/4 33/18/4 +f 55/35/4 56/36/4 57/37/4 58/38/4 +f 59/39/3 13/7/3 16/7/3 60/39/3 +f 14/8/2 9/5/2 12/5/2 15/8/2 +f 61/40/2 59/39/2 60/39/2 62/40/2 +f 63/41/3 61/40/3 62/40/3 64/41/3 +f 65/42/4 23/43/4 26/43/4 66/42/4 +f 67/44/1 68/45/1 69/45/1 70/44/1 +f 38/22/1 1/1/1 4/1/1 39/22/1 +f 71/46/2 72/47/2 73/47/2 74/46/2 +f 6/4/2 75/48/2 76/48/2 7/4/2 +f 56/49/1 77/50/1 78/51/1 57/52/1 +f 46/26/4 79/53/4 80/54/4 47/27/4 +f 57/52/5 78/51/5 52/32/5 51/31/5 48/28/5 47/27/5 80/54/5 66/55/5 26/56/5 25/57/5 44/58/5 43/59/5 8/60/5 7/61/5 76/62/5 74/63/5 73/64/5 81/65/5 82/66/5 64/67/5 62/68/5 60/69/5 16/70/5 15/71/5 12/72/5 11/73/5 30/74/5 29/75/5 20/76/5 19/77/5 22/78/5 40/79/5 39/80/5 4/81/5 3/82/5 36/83/5 70/84/5 69/85/5 83/86/5 84/87/5 85/88/5 86/89/5 34/19/5 33/18/5 54/34/5 58/38/5 +f 87/90/1 88/91/1 84/91/1 83/90/1 +f 42/24/2 5/3/2 8/3/2 43/24/2 +f 21/11/1 37/21/1 40/21/1 22/11/1 +f 10/6/1 27/14/1 30/14/1 11/6/1 +f 53/33/4 55/35/4 58/38/4 54/34/4 +f 89/92/4 31/93/4 34/93/4 86/92/4 +f 90/94/2 63/41/2 64/41/2 82/94/2 +f 50/95/4 45/25/4 48/28/4 51/96/4 +f 91/97/1 89/92/1 86/92/1 85/97/1 +f 92/98/3 90/94/3 82/94/3 81/98/3 +f 35/20/1 67/44/1 70/44/1 36/20/1 +f 28/15/3 17/9/3 20/9/3 29/15/3 +f 75/48/3 71/46/3 74/46/3 76/48/3 +f 79/53/2 65/99/2 66/55/2 80/54/2 +f 77/50/4 49/29/4 52/32/4 78/51/4 +f 72/47/2 92/98/2 81/98/2 73/47/2 +f 88/91/4 91/97/4 85/97/4 84/91/4 +f 68/45/1 87/90/1 83/90/1 69/45/1 +f 24/13/4 41/100/4 44/100/4 25/13/4 +f 56/52/6 55/38/6 53/34/6 32/18/6 31/19/6 89/89/6 91/88/6 88/87/6 87/86/6 68/85/6 67/84/6 35/83/6 2/82/6 1/81/6 38/80/6 37/79/6 21/78/6 18/77/6 17/76/6 28/75/6 27/74/6 10/73/6 9/72/6 14/71/6 13/70/6 59/69/6 61/68/6 63/67/6 90/66/6 92/65/6 72/64/6 71/63/6 75/62/6 6/61/6 5/60/6 42/59/6 41/58/6 24/57/6 23/56/6 65/55/6 79/54/6 46/27/6 45/28/6 50/31/6 49/32/6 77/51/6 diff --git a/mods/z_remove/myArcade/pacmine/models/pacmine_apple.obj b/mods/z_remove/myArcade/pacmine/models/pacmine_apple.obj new file mode 100644 index 00000000..505c7f5a --- /dev/null +++ b/mods/z_remove/myArcade/pacmine/models/pacmine_apple.obj @@ -0,0 +1,295 @@ +# Blender v2.76 (sub 2) OBJ File: '' +# www.blender.org +o Apple_Plane.002 +v 0.562500 0.750000 -0.050000 +v 0.500000 0.750000 -0.050000 +v 0.500000 0.750000 0.050000 +v 0.562500 0.750000 0.050000 +v 0.125000 0.687500 -0.050000 +v 0.125000 0.625000 -0.050000 +v 0.125000 0.625000 0.050000 +v 0.125000 0.687500 0.050000 +v 0.125000 0.562500 -0.050000 +v 0.125000 0.562500 0.050000 +v 0.750000 0.187500 -0.050000 +v 0.750000 0.250000 -0.050000 +v 0.750000 0.250000 0.050000 +v 0.750000 0.187500 0.050000 +v 0.125000 0.500000 -0.050000 +v 0.125000 0.500000 0.050000 +v 0.562500 0.875000 -0.050000 +v 0.500000 0.875000 -0.050000 +v 0.500000 0.875000 0.050000 +v 0.562500 0.875000 0.050000 +v 0.312500 0.125000 -0.050000 +v 0.375000 0.125000 -0.050000 +v 0.375000 0.125000 0.050000 +v 0.312500 0.125000 0.050000 +v 0.187500 0.250000 -0.050000 +v 0.250000 0.250000 -0.050000 +v 0.250000 0.250000 0.050000 +v 0.187500 0.250000 0.050000 +v 0.500000 0.812500 -0.050000 +v 0.562500 0.812500 -0.050000 +v 0.437500 0.750000 -0.050000 +v 0.375000 0.750000 -0.050000 +v 0.375000 0.750000 0.050000 +v 0.437500 0.750000 0.050000 +v 0.500000 0.187500 -0.050000 +v 0.500000 0.125000 -0.050000 +v 0.500000 0.125000 0.050000 +v 0.500000 0.187500 0.050000 +v 0.562500 0.812500 0.050000 +v 0.312500 0.187500 -0.050000 +v 0.312500 0.187500 0.050000 +v 0.250000 0.187500 -0.050000 +v 0.250000 0.187500 0.050000 +v 0.625000 0.125000 -0.050000 +v 0.687500 0.125000 -0.050000 +v 0.687500 0.125000 0.050000 +v 0.625000 0.125000 0.050000 +v 0.125000 0.750000 -0.050000 +v 0.125000 0.750000 0.050000 +v 0.500000 0.812500 0.050000 +v 0.437500 0.812500 -0.050000 +v 0.437500 0.812500 0.050000 +v 0.812500 0.250000 -0.050000 +v 0.812500 0.250000 0.050000 +v 0.312500 0.812500 -0.050000 +v 0.250000 0.812500 -0.050000 +v 0.250000 0.812500 0.050000 +v 0.312500 0.812500 0.050000 +v 0.562500 0.125000 -0.050000 +v 0.562500 0.125000 0.050000 +v 0.625000 0.812500 -0.050000 +v 0.625000 0.812500 0.050000 +v 0.875000 0.625000 -0.050000 +v 0.875000 0.687500 -0.050000 +v 0.875000 0.687500 0.050000 +v 0.875000 0.625000 0.050000 +v 0.812500 0.687500 -0.050000 +v 0.812500 0.687500 0.050000 +v 0.125000 0.437500 -0.050000 +v 0.125000 0.437500 0.050000 +v 0.125000 0.375000 -0.050000 +v 0.125000 0.375000 0.050000 +v 0.812500 0.375000 -0.050000 +v 0.875000 0.375000 -0.050000 +v 0.875000 0.375000 0.050000 +v 0.812500 0.375000 0.050000 +v 0.375000 0.812500 -0.050000 +v 0.375000 0.812500 0.050000 +v 0.812500 0.750000 -0.050000 +v 0.812500 0.750000 0.050000 +v 0.812500 0.312500 -0.050000 +v 0.812500 0.312500 0.050000 +v 0.687500 0.812500 -0.050000 +v 0.687500 0.812500 0.050000 +v 0.687500 0.187500 -0.050000 +v 0.687500 0.187500 0.050000 +v 0.875000 0.437500 -0.050000 +v 0.875000 0.500000 -0.050000 +v 0.875000 0.500000 0.050000 +v 0.875000 0.437500 0.050000 +v 0.750000 0.812500 -0.050000 +v 0.750000 0.812500 0.050000 +v 0.437500 0.125000 -0.050000 +v 0.437500 0.187500 -0.050000 +v 0.437500 0.187500 0.050000 +v 0.437500 0.125000 0.050000 +v 0.875000 0.562500 -0.050000 +v 0.875000 0.562500 0.050000 +v 0.750000 0.750000 -0.050000 +v 0.750000 0.750000 0.050000 +v 0.187500 0.375000 -0.050000 +v 0.187500 0.312500 -0.050000 +v 0.187500 0.312500 0.050000 +v 0.187500 0.375000 0.050000 +v 0.187500 0.812500 -0.050000 +v 0.187500 0.750000 -0.050000 +v 0.187500 0.750000 0.050000 +v 0.187500 0.812500 0.050000 +vt 0.575144 0.723188 +vt 0.512796 0.723188 +vt 0.160749 0.666646 +vt 0.160749 0.610104 +vt 0.160749 0.553563 +vt 0.726167 0.214312 +vt 0.726167 0.270854 +vt 0.160749 0.497021 +vt 0.554940 0.866589 +vt 0.515960 0.863925 +vt 0.515569 0.863925 +vt 0.330375 0.157770 +vt 0.386916 0.157770 +vt 0.217291 0.270854 +vt 0.273833 0.270854 +vt 0.500000 0.812500 +vt 0.500000 0.875000 +vt 0.562500 0.875000 +vt 0.562500 0.812500 +vt 0.430662 0.723188 +vt 0.367074 0.723188 +vt 0.522323 0.214312 +vt 0.522323 0.157770 +vt 0.554940 0.812500 +vt 0.330375 0.214312 +vt 0.273833 0.214312 +vt 0.613084 0.157770 +vt 0.669625 0.157770 +vt 0.575144 0.779730 +vt 0.160749 0.723188 +vt 0.471150 0.724512 +vt 0.469868 0.794272 +vt 0.475270 0.791034 +vt 0.476552 0.721273 +vt 0.445028 0.799923 +vt 0.442075 0.755677 +vt 0.782709 0.270854 +vt 0.330375 0.779730 +vt 0.273833 0.779730 +vt 0.556542 0.157770 +vt 0.500203 0.812717 +vt 0.613084 0.779730 +vt 0.839251 0.610104 +vt 0.839251 0.666646 +vt 0.782709 0.666646 +vt 0.160749 0.440479 +vt 0.160749 0.383937 +vt 0.782709 0.383937 +vt 0.839251 0.383937 +vt 0.367074 0.779730 +vt 0.782709 0.723188 +vt 0.782709 0.327396 +vt 0.669625 0.779730 +vt 0.669625 0.214312 +vt 0.839251 0.440479 +vt 0.839251 0.497021 +vt 0.726167 0.779730 +vt 0.427336 0.157770 +vt 0.427336 0.214312 +vt 0.839251 0.553563 +vt 0.485336 0.758138 +vt 0.726167 0.723188 +vt 0.217291 0.383937 +vt 0.217291 0.327396 +vt 0.217291 0.779730 +vt 0.217291 0.723188 +vt 0.812500 0.375000 +vt 0.875000 0.375000 +vt 0.875000 0.437500 +vt 0.875000 0.500000 +vt 0.875000 0.562500 +vt 0.875000 0.625000 +vt 0.875000 0.687500 +vt 0.812500 0.687500 +vt 0.812500 0.750000 +vt 0.750000 0.750000 +vt 0.750000 0.812500 +vt 0.687500 0.812500 +vt 0.625000 0.812500 +vt 0.562500 0.750000 +vt 0.500000 0.750000 +vt 0.437500 0.812500 +vt 0.437500 0.750000 +vt 0.375000 0.750000 +vt 0.375000 0.812500 +vt 0.312500 0.812500 +vt 0.250000 0.812500 +vt 0.187500 0.812500 +vt 0.187500 0.750000 +vt 0.125000 0.750000 +vt 0.125000 0.687500 +vt 0.125000 0.625000 +vt 0.125000 0.562500 +vt 0.125000 0.500000 +vt 0.125000 0.437500 +vt 0.125000 0.375000 +vt 0.187500 0.375000 +vt 0.187500 0.312500 +vt 0.187500 0.250000 +vt 0.250000 0.250000 +vt 0.250000 0.187500 +vt 0.312500 0.187500 +vt 0.312500 0.125000 +vt 0.375000 0.125000 +vt 0.437500 0.125000 +vt 0.437500 0.187500 +vt 0.500000 0.187500 +vt 0.500000 0.125000 +vt 0.562500 0.125000 +vt 0.625000 0.125000 +vt 0.687500 0.125000 +vt 0.687500 0.187500 +vt 0.750000 0.187500 +vt 0.750000 0.250000 +vt 0.812500 0.250000 +vt 0.812500 0.312500 +vn 0.000000 1.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 0.000000 -1.000000 +vn -0.000000 -0.000000 1.000000 +g Apple_Plane.002_Apple_Plane.002_None +s 1 +f 1/1/1 2/2/1 3/2/1 4/1/1 +f 5/3/2 6/4/2 7/4/2 8/3/2 +f 6/4/2 9/5/2 10/5/2 7/4/2 +f 11/6/3 12/7/3 13/7/3 14/6/3 +f 9/5/2 15/8/2 16/8/2 10/5/2 +f 17/9/1 18/10/1 19/11/1 20/9/1 +f 21/12/4 22/13/4 23/13/4 24/12/4 +f 25/14/4 26/15/4 27/15/4 28/14/4 +f 29/16/5 18/17/5 17/18/5 30/19/5 +f 31/20/1 32/21/1 33/21/1 34/20/1 +f 35/22/2 36/23/2 37/23/2 38/22/2 +f 30/24/3 17/9/3 20/9/3 39/24/3 +f 40/25/2 21/12/2 24/12/2 41/25/2 +f 42/26/4 40/25/4 41/25/4 43/26/4 +f 44/27/4 45/28/4 46/28/4 47/27/4 +f 30/29/2 1/1/2 4/1/2 39/29/2 +f 48/30/2 5/3/2 8/3/2 49/30/2 +f 29/31/4 30/32/4 39/33/4 50/34/4 +f 51/35/2 31/36/2 34/36/2 52/35/2 +f 12/7/4 53/37/4 54/37/4 13/7/4 +f 55/38/1 56/39/1 57/39/1 58/38/1 +f 36/23/4 59/40/4 60/40/4 37/23/4 +f 18/10/2 29/41/2 50/41/2 19/11/2 +f 26/15/2 42/26/2 43/26/2 27/15/2 +f 61/42/1 30/29/1 39/29/1 62/42/1 +f 63/43/3 64/44/3 65/44/3 66/43/3 +f 64/44/1 67/45/1 68/45/1 65/44/1 +f 15/8/2 69/46/2 70/46/2 16/8/2 +f 69/46/2 71/47/2 72/47/2 70/46/2 +f 73/48/4 74/49/4 75/49/4 76/48/4 +f 32/21/3 77/50/3 78/50/3 33/21/3 +f 67/45/3 79/51/3 80/51/3 68/45/3 +f 81/52/3 73/48/3 76/48/3 82/52/3 +f 83/53/1 61/42/1 62/42/1 84/53/1 +f 45/28/3 85/54/3 86/54/3 46/28/3 +f 87/55/3 88/56/3 89/56/3 90/55/3 +f 91/57/1 83/53/1 84/53/1 92/57/1 +f 93/58/3 94/59/3 95/59/3 96/58/3 +f 97/60/3 63/43/3 66/43/3 98/60/3 +f 88/56/3 97/60/3 98/60/3 89/56/3 +f 2/61/3 29/41/3 50/41/3 3/61/3 +f 79/51/1 99/62/1 100/62/1 80/51/1 +f 99/62/3 91/57/3 92/57/3 100/62/3 +f 101/63/2 102/64/2 103/64/2 104/63/2 +f 105/65/2 106/66/2 107/66/2 108/65/2 +f 22/13/4 93/58/4 96/58/4 23/13/4 +f 74/49/3 87/55/3 90/55/3 75/49/3 +f 29/41/1 51/35/1 52/35/1 50/41/1 +f 106/66/1 48/30/1 49/30/1 107/66/1 +f 53/37/3 81/52/3 82/52/3 54/37/3 +f 56/39/1 105/65/1 108/65/1 57/39/1 +f 94/59/4 35/22/4 38/22/4 95/59/4 +f 76/67/6 75/68/6 90/69/6 89/70/6 98/71/6 66/72/6 65/73/6 68/74/6 80/75/6 100/76/6 92/77/6 84/78/6 62/79/6 39/19/6 4/80/6 3/81/6 50/16/6 52/82/6 34/83/6 33/84/6 78/85/6 58/86/6 57/87/6 108/88/6 107/89/6 49/90/6 8/91/6 7/92/6 10/93/6 16/94/6 70/95/6 72/96/6 104/97/6 103/98/6 28/99/6 27/100/6 43/101/6 41/102/6 24/103/6 23/104/6 96/105/6 95/106/6 38/107/6 37/108/6 60/109/6 47/110/6 46/111/6 86/112/6 14/113/6 13/114/6 54/115/6 82/116/6 +f 77/50/1 55/38/1 58/38/1 78/50/1 +f 85/54/4 11/6/4 14/6/4 86/54/4 +f 71/47/4 101/63/4 104/63/4 72/47/4 +f 59/40/4 44/27/4 47/27/4 60/40/4 +f 102/64/2 25/14/2 28/14/2 103/64/2 +f 50/16/6 39/19/6 20/18/6 19/17/6 +f 73/67/5 81/116/5 53/115/5 12/114/5 11/113/5 85/112/5 45/111/5 44/110/5 59/109/5 36/108/5 35/107/5 94/106/5 93/105/5 22/104/5 21/103/5 40/102/5 42/101/5 26/100/5 25/99/5 102/98/5 101/97/5 71/96/5 69/95/5 15/94/5 9/93/5 6/92/5 5/91/5 48/90/5 106/89/5 105/88/5 56/87/5 55/86/5 77/85/5 32/84/5 31/83/5 51/82/5 29/16/5 2/81/5 1/80/5 30/19/5 61/79/5 83/78/5 91/77/5 99/76/5 79/75/5 67/74/5 64/73/5 63/72/5 97/71/5 88/70/5 87/69/5 74/68/5 diff --git a/mods/z_remove/myArcade/pacmine/models/pacmine_cherrys.obj b/mods/z_remove/myArcade/pacmine/models/pacmine_cherrys.obj new file mode 100644 index 00000000..bf1a1cb4 --- /dev/null +++ b/mods/z_remove/myArcade/pacmine/models/pacmine_cherrys.obj @@ -0,0 +1,400 @@ +# Blender v2.76 (sub 2) OBJ File: '' +# www.blender.org +o Cherry_Plane.003 +v 0.375000 0.687500 -0.050000 +v 0.375000 0.750000 -0.050000 +v 0.437500 0.750000 -0.050000 +v 0.500000 0.750000 -0.050000 +v 0.500000 0.687500 -0.050000 +v 0.437500 0.687500 -0.050000 +v 0.312500 0.562500 0.050000 +v 0.375000 0.562500 0.050000 +v 0.375000 0.625000 0.050000 +v 0.312500 0.625000 0.050000 +v 0.187500 0.875000 0.050000 +v 0.125000 0.875000 0.050000 +v 0.125000 0.812500 0.050000 +v 0.125000 0.750000 0.050000 +v 0.187500 0.750000 0.050000 +v 0.250000 0.750000 0.050000 +v 0.250000 0.687500 0.050000 +v 0.250000 0.625000 0.050000 +v 0.312500 0.687500 0.050000 +v 0.312500 0.750000 0.050000 +v 0.375000 0.750000 0.050000 +v 0.375000 0.812500 0.050000 +v 0.312500 0.812500 0.050000 +v 0.250000 0.812500 0.050000 +v 0.250000 0.875000 0.050000 +v 0.875000 0.500000 -0.050000 +v 0.875000 0.562500 -0.050000 +v 0.875000 0.562500 0.050000 +v 0.875000 0.500000 0.050000 +v 0.625000 0.437500 -0.050000 +v 0.625000 0.375000 -0.050000 +v 0.625000 0.375000 0.050000 +v 0.625000 0.437500 0.050000 +v 0.437500 0.500000 0.050000 +v 0.437500 0.562500 0.050000 +v 0.375000 0.500000 0.050000 +v 0.312500 0.500000 0.050000 +v 0.250000 0.500000 0.050000 +v 0.250000 0.437500 0.050000 +v 0.187500 0.437500 0.050000 +v 0.187500 0.375000 0.050000 +v 0.187500 0.312500 0.050000 +v 0.187500 0.250000 0.050000 +v 0.187500 0.187500 0.050000 +v 0.250000 0.187500 0.050000 +v 0.250000 0.125000 0.050000 +v 0.312500 0.125000 0.050000 +v 0.375000 0.125000 0.050000 +v 0.437500 0.125000 0.050000 +v 0.500000 0.125000 0.050000 +v 0.500000 0.187500 0.050000 +v 0.562500 0.187500 0.050000 +v 0.562500 0.250000 0.050000 +v 0.562500 0.312500 0.050000 +v 0.562500 0.375000 0.050000 +v 0.562500 0.437500 0.050000 +v 0.500000 0.437500 0.050000 +v 0.500000 0.500000 0.050000 +v 0.375000 0.687500 0.050000 +v 0.500000 0.625000 0.050000 +v 0.562500 0.625000 0.050000 +v 0.562500 0.687500 0.050000 +v 0.500000 0.687500 0.050000 +v 0.437500 0.687500 0.050000 +v 0.500000 0.750000 0.050000 +v 0.437500 0.750000 0.050000 +v 0.625000 0.625000 0.050000 +v 0.562500 0.562500 0.050000 +v 0.500000 0.562500 0.050000 +v 0.562500 0.500000 0.050000 +v 0.625000 0.312500 0.050000 +v 0.625000 0.250000 0.050000 +v 0.687500 0.250000 0.050000 +v 0.750000 0.250000 0.050000 +v 0.812500 0.250000 0.050000 +v 0.812500 0.312500 0.050000 +v 0.875000 0.312500 0.050000 +v 0.875000 0.375000 0.050000 +v 0.875000 0.437500 0.050000 +v 0.812500 0.562500 0.050000 +v 0.812500 0.625000 0.050000 +v 0.750000 0.625000 0.050000 +v 0.687500 0.625000 0.050000 +v 0.500000 0.625000 -0.050000 +v 0.562500 0.687500 -0.050000 +v 0.562500 0.625000 -0.050000 +v 0.312500 0.562500 -0.050000 +v 0.312500 0.625000 -0.050000 +v 0.375000 0.625000 -0.050000 +v 0.375000 0.562500 -0.050000 +v 0.812500 0.250000 -0.050000 +v 0.812500 0.312500 -0.050000 +v 0.125000 0.812500 -0.050000 +v 0.125000 0.750000 -0.050000 +v 0.250000 0.500000 -0.050000 +v 0.250000 0.437500 -0.050000 +v 0.562500 0.437500 -0.050000 +v 0.875000 0.312500 -0.050000 +v 0.875000 0.375000 -0.050000 +v 0.750000 0.250000 -0.050000 +v 0.187500 0.375000 -0.050000 +v 0.187500 0.312500 -0.050000 +v 0.187500 0.750000 -0.050000 +v 0.500000 0.125000 -0.050000 +v 0.500000 0.187500 -0.050000 +v 0.312500 0.750000 -0.050000 +v 0.187500 0.187500 -0.050000 +v 0.250000 0.187500 -0.050000 +v 0.312500 0.687500 -0.050000 +v 0.187500 0.437500 -0.050000 +v 0.562500 0.187500 -0.050000 +v 0.562500 0.250000 -0.050000 +v 0.250000 0.750000 -0.050000 +v 0.562500 0.562500 -0.050000 +v 0.500000 0.437500 -0.050000 +v 0.625000 0.312500 -0.050000 +v 0.625000 0.250000 -0.050000 +v 0.812500 0.562500 -0.050000 +v 0.812500 0.625000 -0.050000 +v 0.562500 0.312500 -0.050000 +v 0.562500 0.375000 -0.050000 +v 0.375000 0.500000 -0.050000 +v 0.125000 0.875000 -0.050000 +v 0.875000 0.437500 -0.050000 +v 0.250000 0.125000 -0.050000 +v 0.687500 0.250000 -0.050000 +v 0.187500 0.250000 -0.050000 +v 0.312500 0.125000 -0.050000 +v 0.250000 0.625000 -0.050000 +v 0.187500 0.875000 -0.050000 +v 0.250000 0.875000 -0.050000 +v 0.250000 0.812500 -0.050000 +v 0.312500 0.812500 -0.050000 +v 0.375000 0.812500 -0.050000 +v 0.250000 0.687500 -0.050000 +v 0.500000 0.500000 -0.050000 +v 0.375000 0.125000 -0.050000 +v 0.437500 0.125000 -0.050000 +v 0.437500 0.562500 -0.050000 +v 0.625000 0.625000 -0.050000 +v 0.687500 0.625000 -0.050000 +v 0.750000 0.625000 -0.050000 +v 0.562500 0.500000 -0.050000 +v 0.500000 0.562500 -0.050000 +v 0.312500 0.500000 -0.050000 +v 0.437500 0.500000 -0.050000 +vt 0.375000 0.687500 +vt 0.375000 0.750000 +vt 0.437500 0.750000 +vt 0.500000 0.750000 +vt 0.500000 0.687500 +vt 0.437500 0.687500 +vt 0.312500 0.562500 +vt 0.375000 0.562500 +vt 0.375000 0.625000 +vt 0.312500 0.625000 +vt 0.187500 0.875000 +vt 0.125000 0.875000 +vt 0.125000 0.812500 +vt 0.125000 0.750000 +vt 0.187500 0.750000 +vt 0.250000 0.750000 +vt 0.250000 0.687500 +vt 0.250000 0.625000 +vt 0.312500 0.687500 +vt 0.312500 0.750000 +vt 0.375000 0.812500 +vt 0.312500 0.812500 +vt 0.250000 0.812500 +vt 0.250000 0.875000 +vt 0.850971 0.500671 +vt 0.850971 0.553922 +vt 0.637970 0.447421 +vt 0.637970 0.394171 +vt 0.437500 0.500000 +vt 0.437500 0.562500 +vt 0.375000 0.500000 +vt 0.312500 0.500000 +vt 0.250000 0.500000 +vt 0.250000 0.437500 +vt 0.187500 0.437500 +vt 0.187500 0.375000 +vt 0.187500 0.312500 +vt 0.187500 0.250000 +vt 0.187500 0.187500 +vt 0.250000 0.187500 +vt 0.250000 0.125000 +vt 0.312500 0.125000 +vt 0.375000 0.125000 +vt 0.437500 0.125000 +vt 0.500000 0.125000 +vt 0.500000 0.187500 +vt 0.562500 0.187500 +vt 0.562500 0.250000 +vt 0.562500 0.312500 +vt 0.562500 0.375000 +vt 0.562500 0.437500 +vt 0.500000 0.437500 +vt 0.500000 0.500000 +vt 0.224806 0.819180 +vt 0.224806 0.799114 +vt 0.500000 0.625000 +vt 0.562500 0.625000 +vt 0.562500 0.687500 +vt 0.625000 0.625000 +vt 0.562500 0.562500 +vt 0.500000 0.562500 +vt 0.562500 0.500000 +vt 0.625000 0.437500 +vt 0.625000 0.375000 +vt 0.625000 0.312500 +vt 0.625000 0.250000 +vt 0.687500 0.250000 +vt 0.750000 0.250000 +vt 0.812500 0.250000 +vt 0.812500 0.312500 +vt 0.875000 0.312500 +vt 0.875000 0.375000 +vt 0.875000 0.437500 +vt 0.875000 0.500000 +vt 0.875000 0.562500 +vt 0.812500 0.562500 +vt 0.812500 0.625000 +vt 0.750000 0.625000 +vt 0.687500 0.625000 +vt 0.797721 0.287671 +vt 0.797721 0.340921 +vt 0.144544 0.839245 +vt 0.144544 0.819180 +vt 0.266910 0.474635 +vt 0.266910 0.420590 +vt 0.584720 0.447421 +vt 0.850971 0.340921 +vt 0.850971 0.394171 +vt 0.744471 0.287671 +vt 0.212865 0.366545 +vt 0.212865 0.312500 +vt 0.164610 0.819180 +vt 0.483090 0.150365 +vt 0.483090 0.204410 +vt 0.204741 0.819180 +vt 0.212865 0.204410 +vt 0.266910 0.204410 +vt 0.204741 0.789384 +vt 0.204741 0.799114 +vt 0.248204 0.799114 +vt 0.248204 0.779049 +vt 0.212865 0.420590 +vt 0.537135 0.204410 +vt 0.537135 0.258455 +vt 0.184675 0.819180 +vt 0.584720 0.607172 +vt 0.584720 0.553922 +vt 0.537135 0.420590 +vt 0.483090 0.420590 +vt 0.637970 0.340921 +vt 0.637970 0.287671 +vt 0.248204 0.819180 +vt 0.235029 0.819180 +vt 0.797721 0.553922 +vt 0.797721 0.607172 +vt 0.537135 0.312500 +vt 0.537135 0.366545 +vt 0.268270 0.779049 +vt 0.268270 0.799114 +vt 0.224806 0.775224 +vt 0.224806 0.755158 +vt 0.144544 0.859311 +vt 0.204741 0.775224 +vt 0.850971 0.447421 +vt 0.266910 0.150365 +vt 0.691220 0.287671 +vt 0.212865 0.258455 +vt 0.235029 0.799114 +vt 0.320955 0.150365 +vt 0.224806 0.789384 +vt 0.184675 0.789384 +vt 0.483090 0.474635 +vt 0.375000 0.150365 +vt 0.429045 0.150365 +vt 0.184675 0.799114 +vt 0.244872 0.775224 +vt 0.224806 0.839245 +vt 0.164610 0.859311 +vt 0.531470 0.553922 +vt 0.184675 0.859311 +vt 0.584720 0.508112 +vt 0.320955 0.474635 +vt 0.375000 0.474635 +vt 0.637970 0.607172 +vt 0.691220 0.607172 +vt 0.429045 0.474635 +vt 0.744471 0.607172 +vt 0.204741 0.839245 +vt 0.184675 0.839245 +vt 0.531470 0.508112 +vt 0.244872 0.755158 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 1.000000 +vn 1.000000 0.000000 0.000000 +vn -1.000000 -0.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +g Cherry_Plane.003_Cherry_Plane.003_None +s 1 +f 1/1/1 2/2/1 3/3/1 4/4/1 5/5/1 6/6/1 +f 7/7/2 8/8/2 9/9/2 10/10/2 +f 11/11/2 12/12/2 13/13/2 14/14/2 15/15/2 16/16/2 17/17/2 18/18/2 10/10/2 19/19/2 20/20/2 21/2/2 22/21/2 23/22/2 24/23/2 25/24/2 +f 26/25/3 27/26/3 28/26/3 29/25/3 +f 30/27/4 31/28/4 32/28/4 33/27/4 +f 34/29/2 35/30/2 8/8/2 36/31/2 37/32/2 38/33/2 39/34/2 40/35/2 41/36/2 42/37/2 43/38/2 44/39/2 45/40/2 46/41/2 47/42/2 48/43/2 49/44/2 50/45/2 51/46/2 52/47/2 53/48/2 54/49/2 55/50/2 56/51/2 57/52/2 58/53/2 +f 2/54/4 1/55/4 59/55/4 21/54/4 +f 60/56/2 61/57/2 62/58/2 63/5/2 +f 59/1/2 64/6/2 63/5/2 65/4/2 66/3/2 21/2/2 +f 67/59/2 61/57/2 68/60/2 69/61/2 58/53/2 70/62/2 56/51/2 33/63/2 32/64/2 71/65/2 72/66/2 73/67/2 74/68/2 75/69/2 76/70/2 77/71/2 78/72/2 79/73/2 29/74/2 28/75/2 80/76/2 81/77/2 82/78/2 83/79/2 +f 84/56/1 5/5/1 85/58/1 86/57/1 +f 87/7/1 88/10/1 89/9/1 90/8/1 +f 91/80/3 92/81/3 76/81/3 75/80/3 +f 93/82/4 94/83/4 14/83/4 13/82/4 +f 95/84/4 96/85/4 39/85/4 38/84/4 +f 97/86/5 30/27/5 33/27/5 56/86/5 +f 98/87/3 99/88/3 78/88/3 77/87/3 +f 100/89/5 91/80/5 75/80/5 74/89/5 +f 101/90/4 102/91/4 42/91/4 41/90/4 +f 94/83/5 103/92/5 15/92/5 14/83/5 +f 104/93/3 105/94/3 51/94/3 50/93/3 +f 106/95/5 2/54/5 21/54/5 20/95/5 +f 107/96/5 108/97/5 45/97/5 44/96/5 +f 88/98/3 109/99/3 19/99/3 10/98/3 +f 5/100/4 84/101/4 60/101/4 63/100/4 +f 110/102/4 101/90/4 41/90/4 40/102/4 +f 111/103/3 112/104/3 53/104/3 52/103/3 +f 103/92/5 113/105/5 16/105/5 15/92/5 +f 86/106/4 114/107/4 68/107/4 61/106/4 +f 97/108/6 115/109/6 57/109/6 56/108/6 +f 116/110/4 117/111/4 72/111/4 71/110/4 +f 4/112/6 3/113/6 66/113/6 65/112/6 +f 118/114/3 119/115/3 81/115/3 80/114/3 +f 120/116/3 121/117/3 55/117/3 54/116/3 +f 86/118/3 85/119/3 62/119/3 61/118/3 +f 90/120/4 122/121/4 36/121/4 8/120/4 +f 123/122/4 93/82/4 13/82/4 12/122/4 +f 87/123/5 90/120/5 8/120/5 7/123/5 +f 99/88/3 124/124/3 79/124/3 78/88/3 +f 27/26/6 118/114/6 80/114/6 28/26/6 +f 112/104/3 120/116/3 54/116/3 53/104/3 +f 108/97/4 125/125/4 46/125/4 45/97/4 +f 117/111/5 126/126/5 73/126/5 72/111/5 +f 127/127/4 107/96/4 44/96/4 43/127/4 +f 1/55/5 6/128/5 64/128/5 59/55/5 +f 124/124/3 26/25/3 29/25/3 79/124/3 +f 31/28/4 116/110/4 71/110/4 32/28/4 +f 125/125/5 128/129/5 47/129/5 46/125/5 +f 3/113/6 2/54/6 21/54/6 66/113/6 +f 90/120/3 89/130/3 9/130/3 8/120/3 +f 129/131/5 88/98/5 10/98/5 18/131/5 +f 130/11/1 131/24/1 132/23/1 133/22/1 134/21/1 2/2/1 106/20/1 109/19/1 88/10/1 129/18/1 135/17/1 113/16/1 103/15/1 94/14/1 93/13/1 123/12/1 +f 115/109/3 136/132/3 58/132/3 57/109/3 +f 137/133/5 138/134/5 49/134/5 48/133/5 +f 85/119/6 5/100/6 63/100/6 62/119/6 +f 6/128/5 5/100/5 63/100/5 64/128/5 +f 135/135/4 129/131/4 18/131/4 17/135/4 +f 139/136/6 90/120/6 8/120/6 35/136/6 +f 88/98/4 87/123/4 7/123/4 10/98/4 +f 5/100/3 4/112/3 65/112/3 63/100/3 +f 89/130/6 88/98/6 10/98/6 9/130/6 +f 140/59/1 141/79/1 142/78/1 119/77/1 118/76/1 27/75/1 26/74/1 124/73/1 99/72/1 98/71/1 92/70/1 91/69/1 100/68/1 126/67/1 117/66/1 116/65/1 31/64/1 30/63/1 97/51/1 143/62/1 136/53/1 144/61/1 114/60/1 86/57/1 +f 126/126/5 100/89/5 74/89/5 73/126/5 +f 2/54/3 134/137/3 22/137/3 21/54/3 +f 128/129/5 137/133/5 48/133/5 47/129/5 +f 130/138/6 123/122/6 12/122/6 11/138/6 +f 138/134/5 104/93/5 50/93/5 49/134/5 +f 114/107/6 144/139/6 69/139/6 68/107/6 +f 96/85/6 110/102/6 40/102/6 39/85/6 +f 131/140/6 130/138/6 11/138/6 25/140/6 +f 143/141/4 97/86/4 56/86/4 70/141/4 +f 121/117/3 97/108/3 56/108/3 55/117/3 +f 109/99/3 106/95/3 20/95/3 19/99/3 +f 145/142/6 95/84/6 38/84/6 37/142/6 +f 113/105/4 135/135/4 17/135/4 16/105/4 +f 84/101/5 86/118/5 61/118/5 60/101/5 +f 105/94/5 111/103/5 52/103/5 51/94/5 +f 122/143/6 145/142/6 37/142/6 36/143/6 +f 102/91/4 127/127/4 43/127/4 42/91/4 +f 140/144/6 86/106/6 61/106/6 67/144/6 +f 92/81/5 98/87/5 77/87/5 76/81/5 +f 141/145/6 140/144/6 67/144/6 83/145/6 +f 136/132/6 146/146/6 34/146/6 58/132/6 +f 142/147/6 141/145/6 83/145/6 82/147/6 +f 133/148/6 132/149/6 24/149/6 23/148/6 +f 144/139/4 136/150/4 58/150/4 69/139/4 +f 132/149/3 131/140/3 25/140/3 24/149/3 +f 136/150/5 143/141/5 70/141/5 58/150/5 +f 119/115/6 142/147/6 82/147/6 81/115/6 +f 134/137/6 133/148/6 23/148/6 22/137/6 +f 146/151/3 139/136/3 35/136/3 34/151/3 +f 146/29/1 136/53/1 115/52/1 97/51/1 121/50/1 120/49/1 112/48/1 111/47/1 105/46/1 104/45/1 138/44/1 137/43/1 128/42/1 125/41/1 108/40/1 107/39/1 127/38/1 102/37/1 101/36/1 110/35/1 96/34/1 95/33/1 145/32/1 122/31/1 90/8/1 139/30/1 diff --git a/mods/z_remove/myArcade/pacmine/models/pacmine_orange.obj b/mods/z_remove/myArcade/pacmine/models/pacmine_orange.obj new file mode 100644 index 00000000..2453987d --- /dev/null +++ b/mods/z_remove/myArcade/pacmine/models/pacmine_orange.obj @@ -0,0 +1,385 @@ +# Blender v2.76 (sub 2) OBJ File: '' +# www.blender.org +o Peach_Plane.001_Material +v 0.187500 0.625000 -0.050000 +v 0.187500 0.562500 -0.050000 +v 0.187500 0.500000 -0.050000 +v 0.187500 0.437500 -0.050000 +v 0.187500 0.375000 -0.050000 +v 0.187500 0.312500 -0.050000 +v 0.187500 0.250000 -0.050000 +v 0.250000 0.250000 -0.050000 +v 0.312500 0.250000 -0.050000 +v 0.375000 0.250000 -0.050000 +v 0.437500 0.250000 -0.050000 +v 0.500000 0.250000 -0.050000 +v 0.562500 0.250000 -0.050000 +v 0.625000 0.250000 -0.050000 +v 0.687500 0.250000 -0.050000 +v 0.750000 0.250000 -0.050000 +v 0.812500 0.250000 -0.050000 +v 0.812500 0.312500 -0.050000 +v 0.812500 0.375000 -0.050000 +v 0.812500 0.437500 -0.050000 +v 0.812500 0.500000 -0.050000 +v 0.812500 0.562500 -0.050000 +v 0.812500 0.625000 -0.050000 +v 0.812500 0.687500 -0.050000 +v 0.750000 0.687500 -0.050000 +v 0.687500 0.687500 -0.050000 +v 0.625000 0.687500 -0.050000 +v 0.562500 0.687500 -0.050000 +v 0.500000 0.687500 -0.050000 +v 0.437500 0.687500 -0.050000 +v 0.375000 0.687500 -0.050000 +v 0.312500 0.687500 -0.050000 +v 0.250000 0.687500 -0.050000 +v 0.187500 0.687500 -0.050000 +v 0.125000 0.375000 0.050000 +v 0.125000 0.437500 0.050000 +v 0.125000 0.500000 0.050000 +v 0.125000 0.562500 0.050000 +v 0.125000 0.625000 0.050000 +v 0.187500 0.625000 0.050000 +v 0.187500 0.562500 0.050000 +v 0.187500 0.500000 0.050000 +v 0.187500 0.437500 0.050000 +v 0.187500 0.375000 0.050000 +v 0.687500 0.187500 0.050000 +v 0.687500 0.125000 0.050000 +v 0.625000 0.125000 0.050000 +v 0.562500 0.125000 0.050000 +v 0.500000 0.125000 0.050000 +v 0.500000 0.187500 0.050000 +v 0.437500 0.187500 0.050000 +v 0.437500 0.125000 0.050000 +v 0.375000 0.125000 0.050000 +v 0.312500 0.125000 0.050000 +v 0.312500 0.187500 0.050000 +v 0.250000 0.187500 0.050000 +v 0.250000 0.250000 0.050000 +v 0.312500 0.250000 0.050000 +v 0.375000 0.250000 0.050000 +v 0.437500 0.250000 0.050000 +v 0.500000 0.250000 0.050000 +v 0.562500 0.250000 0.050000 +v 0.625000 0.250000 0.050000 +v 0.687500 0.250000 0.050000 +v 0.750000 0.250000 0.050000 +v 0.750000 0.187500 0.050000 +v 0.375000 0.125000 -0.050000 +v 0.312500 0.125000 -0.050000 +v 0.562500 0.937500 -0.050000 +v 0.625000 0.937500 -0.050000 +v 0.625000 0.937500 0.050000 +v 0.562500 0.937500 0.050000 +v 0.687500 0.937500 -0.050000 +v 0.687500 0.937500 0.050000 +v 0.687500 0.750000 -0.050000 +v 0.625000 0.750000 -0.050000 +v 0.562500 0.750000 -0.050000 +v 0.500000 0.750000 -0.050000 +v 0.437500 0.750000 -0.050000 +v 0.375000 0.750000 -0.050000 +v 0.312500 0.750000 -0.050000 +v 0.250000 0.750000 -0.050000 +v 0.750000 0.750000 -0.050000 +v 0.437500 0.125000 -0.050000 +v 0.312500 0.187500 -0.050000 +v 0.250000 0.187500 -0.050000 +v 0.187500 0.687500 0.050000 +v 0.500000 0.187500 -0.050000 +v 0.437500 0.187500 -0.050000 +v 0.750000 0.687500 0.050000 +v 0.750000 0.750000 0.050000 +v 0.250000 0.750000 0.050000 +v 0.250000 0.687500 0.050000 +v 0.750000 0.812500 -0.050000 +v 0.750000 0.812500 0.050000 +v 0.750000 0.187500 -0.050000 +v 0.687500 0.187500 -0.050000 +v 0.875000 0.375000 -0.050000 +v 0.875000 0.437500 -0.050000 +v 0.875000 0.500000 -0.050000 +v 0.875000 0.562500 -0.050000 +v 0.875000 0.625000 -0.050000 +v 0.687500 0.875000 -0.050000 +v 0.687500 0.875000 0.050000 +v 0.562500 0.125000 -0.050000 +v 0.500000 0.125000 -0.050000 +v 0.437500 0.812500 -0.050000 +v 0.437500 0.812500 0.050000 +v 0.437500 0.750000 0.050000 +v 0.562500 0.875000 -0.050000 +v 0.562500 0.875000 0.050000 +v 0.625000 0.125000 -0.050000 +v 0.812500 0.875000 -0.050000 +v 0.812500 0.812500 -0.050000 +v 0.812500 0.812500 0.050000 +v 0.812500 0.875000 0.050000 +v 0.500000 0.875000 -0.050000 +v 0.437500 0.875000 -0.050000 +v 0.500000 0.812500 -0.050000 +v 0.562500 0.812500 -0.050000 +v 0.750000 0.875000 -0.050000 +v 0.312500 0.687500 0.050000 +v 0.375000 0.687500 0.050000 +v 0.437500 0.687500 0.050000 +v 0.500000 0.687500 0.050000 +v 0.562500 0.687500 0.050000 +v 0.625000 0.687500 0.050000 +v 0.687500 0.687500 0.050000 +v 0.812500 0.687500 0.050000 +v 0.812500 0.625000 0.050000 +v 0.812500 0.562500 0.050000 +v 0.812500 0.500000 0.050000 +v 0.812500 0.437500 0.050000 +v 0.812500 0.375000 0.050000 +v 0.812500 0.312500 0.050000 +v 0.812500 0.250000 0.050000 +v 0.187500 0.250000 0.050000 +v 0.187500 0.312500 0.050000 +v 0.875000 0.625000 0.050000 +v 0.875000 0.562500 0.050000 +v 0.875000 0.500000 0.050000 +v 0.875000 0.437500 0.050000 +v 0.875000 0.375000 0.050000 +v 0.500000 0.875000 0.050000 +v 0.437500 0.875000 0.050000 +v 0.750000 0.875000 0.050000 +v 0.687500 0.750000 0.050000 +v 0.625000 0.750000 0.050000 +v 0.562500 0.750000 0.050000 +v 0.562500 0.812500 0.050000 +v 0.500000 0.812500 0.050000 +v 0.500000 0.750000 0.050000 +v 0.687500 0.125000 -0.050000 +v 0.312500 0.750000 0.050000 +v 0.375000 0.750000 0.050000 +v 0.125000 0.375000 -0.050000 +v 0.125000 0.625000 -0.050000 +v 0.125000 0.562500 -0.050000 +v 0.125000 0.500000 -0.050000 +v 0.125000 0.437500 -0.050000 +vt 0.187500 0.625000 +vt 0.187500 0.562500 +vt 0.187500 0.500000 +vt 0.187500 0.437500 +vt 0.187500 0.375000 +vt 0.187500 0.312500 +vt 0.187500 0.250000 +vt 0.250000 0.250000 +vt 0.312500 0.250000 +vt 0.375000 0.250000 +vt 0.437500 0.250000 +vt 0.500000 0.250000 +vt 0.562500 0.250000 +vt 0.625000 0.250000 +vt 0.687500 0.250000 +vt 0.750000 0.250000 +vt 0.812500 0.250000 +vt 0.812500 0.312500 +vt 0.812500 0.375000 +vt 0.812500 0.437500 +vt 0.812500 0.500000 +vt 0.812500 0.562500 +vt 0.812500 0.625000 +vt 0.812500 0.687500 +vt 0.750000 0.687500 +vt 0.687500 0.687500 +vt 0.625000 0.687500 +vt 0.562500 0.687500 +vt 0.500000 0.687500 +vt 0.437500 0.687500 +vt 0.375000 0.687500 +vt 0.312500 0.687500 +vt 0.250000 0.687500 +vt 0.187500 0.687500 +vt 0.125000 0.375000 +vt 0.125000 0.437500 +vt 0.125000 0.500000 +vt 0.125000 0.562500 +vt 0.125000 0.625000 +vt 0.687500 0.187500 +vt 0.687500 0.125000 +vt 0.625000 0.125000 +vt 0.562500 0.125000 +vt 0.500000 0.125000 +vt 0.500000 0.187500 +vt 0.437500 0.187500 +vt 0.437500 0.125000 +vt 0.375000 0.125000 +vt 0.312500 0.125000 +vt 0.312500 0.187500 +vt 0.250000 0.187500 +vt 0.750000 0.187500 +vt 0.382340 0.143351 +vt 0.323511 0.143351 +vt 0.585586 0.914414 +vt 0.632695 0.914414 +vt 0.679805 0.914414 +vt 0.687500 0.750000 +vt 0.625000 0.750000 +vt 0.562500 0.750000 +vt 0.500000 0.750000 +vt 0.437500 0.750000 +vt 0.375000 0.750000 +vt 0.312500 0.750000 +vt 0.250000 0.750000 +vt 0.750000 0.750000 +vt 0.429358 0.143351 +vt 0.323511 0.202181 +vt 0.264681 0.202181 +vt 0.205851 0.613989 +vt 0.205851 0.672819 +vt 0.511812 0.202181 +vt 0.429358 0.202181 +vt 0.735319 0.731649 +vt 0.735319 0.672819 +vt 0.264681 0.672819 +vt 0.264681 0.731649 +vt 0.726914 0.820195 +vt 0.726914 0.773086 +vt 0.735319 0.202181 +vt 0.676489 0.202181 +vt 0.875000 0.375000 +vt 0.875000 0.437500 +vt 0.875000 0.500000 +vt 0.875000 0.562500 +vt 0.875000 0.625000 +vt 0.679805 0.867305 +vt 0.558830 0.143351 +vt 0.511812 0.143351 +vt 0.449971 0.719162 +vt 0.449971 0.763284 +vt 0.585586 0.867305 +vt 0.617660 0.143351 +vt 0.774023 0.867305 +vt 0.774023 0.820195 +vt 0.562500 0.875000 +vt 0.500000 0.875000 +vt 0.437500 0.875000 +vt 0.437500 0.812500 +vt 0.500000 0.812500 +vt 0.562500 0.812500 +vt 0.750000 0.812500 +vt 0.812500 0.812500 +vt 0.812500 0.875000 +vt 0.750000 0.875000 +vt 0.687500 0.875000 +vt 0.687500 0.937500 +vt 0.625000 0.937500 +vt 0.562500 0.937500 +vt 0.449971 0.807407 +vt 0.494094 0.807407 +vt 0.676489 0.143351 +vt 0.494094 0.763284 +vt 0.494094 0.719162 +vt 0.585586 0.773086 +vt 0.585586 0.820195 +vt 0.794149 0.261011 +vt 0.735319 0.261011 +vt 0.794149 0.672819 +vt 0.794149 0.613989 +vt 0.264681 0.261011 +vt 0.205851 0.261011 +vt 0.147021 0.555160 +vt 0.147021 0.613989 +vt 0.852979 0.378670 +vt 0.794149 0.378670 +vt 0.852979 0.613989 +vt 0.852979 0.555160 +vt 0.205851 0.378670 +vt 0.147021 0.378670 +vt 0.147021 0.496330 +vt 0.852979 0.496330 +vt 0.147021 0.437500 +vt 0.852979 0.437500 +vt 0.538217 0.719162 +vt 0.388780 0.720471 +vt 0.451280 0.720471 +vt 0.205851 0.319840 +vt 0.323511 0.731649 +vt 0.368560 0.731649 +vt 0.794149 0.319840 +vt 0.538477 0.820195 +vt 0.726914 0.867305 +vt 0.538477 0.867305 +vn 0.000000 -0.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn -1.000000 -0.000000 0.000000 +g Peach_Plane.001_Material_Peach_Plane.001_Material_None +s 1 +f 1/1/1 2/2/1 3/3/1 4/4/1 5/5/1 6/6/1 7/7/1 8/8/1 9/9/1 10/10/1 11/11/1 12/12/1 13/13/1 14/14/1 15/15/1 16/16/1 17/17/1 18/18/1 19/19/1 20/20/1 21/21/1 22/22/1 23/23/1 24/24/1 25/25/1 26/26/1 27/27/1 28/28/1 29/29/1 30/30/1 31/31/1 32/32/1 33/33/1 34/34/1 +f 35/35/2 36/36/2 37/37/2 38/38/2 39/39/2 40/1/2 41/2/2 42/3/2 43/4/2 44/5/2 +f 45/40/2 46/41/2 47/42/2 48/43/2 49/44/2 50/45/2 51/46/2 52/47/2 53/48/2 54/49/2 55/50/2 56/51/2 57/8/2 58/9/2 59/10/2 60/11/2 61/12/2 62/13/2 63/14/2 64/15/2 65/16/2 66/52/2 +f 67/53/3 68/54/3 54/54/3 53/53/3 +f 69/55/4 70/56/4 71/56/4 72/55/4 +f 70/56/4 73/57/4 74/57/4 71/56/4 +f 75/58/1 76/59/1 77/60/1 78/61/1 79/62/1 80/63/1 81/64/1 82/65/1 33/33/1 32/32/1 31/31/1 30/30/1 29/29/1 28/28/1 27/27/1 26/26/1 25/25/1 83/66/1 +f 84/67/3 67/53/3 53/53/3 52/67/3 +f 85/68/3 86/69/3 56/69/3 55/68/3 +f 1/70/5 34/71/5 87/71/5 40/70/5 +f 88/72/3 89/73/3 51/73/3 50/72/3 +f 83/74/6 25/75/6 90/75/6 91/74/6 +f 33/76/5 82/77/5 92/77/5 93/76/5 +f 94/78/6 83/79/6 91/79/6 95/78/6 +f 96/80/3 97/81/3 45/81/3 66/80/3 +f 19/19/1 98/82/1 99/83/1 100/84/1 101/85/1 102/86/1 23/23/1 22/22/1 21/21/1 20/20/1 +f 73/57/6 103/87/6 104/87/6 74/57/6 +f 105/88/3 106/89/3 49/89/3 48/88/3 +f 79/90/5 107/91/5 108/91/5 109/90/5 +f 110/92/5 69/55/5 72/55/5 111/92/5 +f 112/93/3 105/88/3 48/88/3 47/93/3 +f 113/94/6 114/95/6 115/95/6 116/94/6 +f 110/96/1 117/97/1 118/98/1 107/99/1 79/62/1 78/61/1 119/100/1 120/101/1 77/60/1 76/59/1 75/58/1 83/66/1 94/102/1 114/103/1 113/104/1 121/105/1 103/106/1 73/107/1 70/108/1 69/109/1 +f 40/1/2 87/34/2 93/33/2 122/32/2 123/31/2 124/30/2 125/29/2 126/28/2 127/27/2 128/26/2 90/25/2 129/24/2 130/23/2 131/22/2 132/21/2 133/20/2 134/19/2 135/18/2 136/17/2 65/16/2 64/15/2 63/14/2 62/13/2 61/12/2 60/11/2 59/10/2 58/9/2 57/8/2 137/7/2 138/6/2 44/5/2 43/4/2 42/3/2 41/2/2 +f 134/19/2 133/20/2 132/21/2 131/22/2 130/23/2 139/86/2 140/85/2 141/84/2 142/83/2 143/82/2 +f 89/73/6 84/67/6 52/67/6 51/73/6 +f 118/110/4 117/111/4 144/111/4 145/110/4 +f 106/89/5 88/72/5 50/72/5 49/89/5 +f 111/96/2 72/109/2 71/108/2 74/107/2 104/106/2 146/105/2 116/104/2 115/103/2 95/102/2 91/66/2 147/58/2 148/59/2 149/60/2 150/101/2 151/100/2 152/61/2 109/62/2 108/99/2 145/98/2 144/97/2 +f 153/112/3 112/93/3 47/93/3 46/112/3 +f 97/81/6 153/112/6 46/112/6 45/81/6 +f 107/91/5 118/110/5 145/110/5 108/91/5 +f 147/58/2 91/66/2 90/25/2 128/26/2 127/27/2 126/28/2 125/29/2 124/30/2 123/31/2 122/32/2 93/33/2 92/65/2 154/64/2 155/63/2 109/62/2 152/61/2 149/60/2 148/59/2 +f 119/113/6 78/114/6 152/114/6 151/113/6 +f 77/115/5 120/116/5 150/116/5 149/115/5 +f 156/35/1 5/5/1 4/4/1 3/3/1 2/2/1 1/1/1 157/39/1 158/38/1 159/37/1 160/36/1 +f 97/40/1 96/52/1 16/16/1 15/15/1 14/14/1 13/13/1 12/12/1 11/11/1 10/10/1 9/9/1 8/8/1 86/51/1 85/50/1 68/49/1 67/48/1 84/47/1 89/46/1 88/45/1 106/44/1 105/43/1 112/42/1 153/41/1 +f 17/117/3 16/118/3 65/118/3 136/117/3 +f 24/119/6 23/120/6 130/120/6 129/119/6 +f 8/121/3 7/122/3 137/122/3 57/121/3 +f 158/123/5 157/124/5 39/124/5 38/123/5 +f 98/125/3 19/126/3 134/126/3 143/125/3 +f 102/127/6 101/128/6 140/128/6 139/127/6 +f 5/129/3 156/130/3 35/130/3 44/129/3 +f 159/131/5 158/123/5 38/123/5 37/131/5 +f 23/120/4 102/127/4 139/127/4 130/120/4 +f 101/128/6 100/132/6 141/132/6 140/128/6 +f 157/124/4 1/70/4 40/70/4 39/124/4 +f 160/133/5 159/131/5 37/131/5 36/133/5 +f 25/75/4 24/119/4 129/119/4 90/75/4 +f 100/132/6 99/134/6 142/134/6 141/132/6 +f 34/71/4 33/76/4 93/76/4 87/71/4 +f 156/130/5 160/133/5 36/133/5 35/130/5 +f 78/114/4 77/135/4 149/135/4 152/114/4 +f 99/134/6 98/125/6 143/125/6 142/134/6 +f 80/136/4 79/137/4 109/137/4 155/136/4 +f 6/138/5 5/129/5 44/129/5 138/138/5 +f 81/139/4 80/140/4 155/140/4 154/139/4 +f 19/126/6 18/141/6 135/141/6 134/126/6 +f 82/77/4 81/139/4 154/139/4 92/77/4 +f 7/122/5 6/138/5 138/138/5 137/122/5 +f 114/95/3 94/78/3 95/78/3 115/95/3 +f 18/141/6 17/117/6 136/117/6 135/141/6 +f 120/116/3 119/142/3 151/142/3 150/116/3 +f 86/69/5 8/121/5 57/121/5 56/69/5 +f 121/143/4 113/94/4 116/94/4 146/143/4 +f 16/118/6 96/80/6 66/80/6 65/118/6 +f 103/87/4 121/143/4 146/143/4 104/87/4 +f 68/54/5 85/68/5 55/68/5 54/54/5 +f 117/144/4 110/92/4 111/92/4 144/144/4 diff --git a/mods/z_remove/myArcade/pacmine/models/pacmine_strawberry.obj b/mods/z_remove/myArcade/pacmine/models/pacmine_strawberry.obj new file mode 100644 index 00000000..47b18ee4 --- /dev/null +++ b/mods/z_remove/myArcade/pacmine/models/pacmine_strawberry.obj @@ -0,0 +1,247 @@ +# Blender v2.76 (sub 2) OBJ File: '' +# www.blender.org +o Strawberry_Plane.000 +v 0.812500 0.375000 -0.050000 +v 0.812500 0.437500 -0.050000 +v 0.812500 0.437500 0.050000 +v 0.812500 0.375000 0.050000 +v 0.187500 0.562500 -0.050000 +v 0.187500 0.500000 -0.050000 +v 0.187500 0.500000 0.050000 +v 0.187500 0.562500 0.050000 +v 0.500000 0.125000 -0.050000 +v 0.562500 0.125000 -0.050000 +v 0.562500 0.125000 0.050000 +v 0.500000 0.125000 0.050000 +v 0.437500 0.187500 -0.050000 +v 0.500000 0.187500 -0.050000 +v 0.500000 0.187500 0.050000 +v 0.437500 0.187500 0.050000 +v 0.687500 0.187500 -0.050000 +v 0.687500 0.250000 -0.050000 +v 0.687500 0.250000 0.050000 +v 0.687500 0.187500 0.050000 +v 0.750000 0.250000 -0.050000 +v 0.750000 0.250000 0.050000 +v 0.250000 0.750000 -0.050000 +v 0.250000 0.687500 -0.050000 +v 0.250000 0.687500 0.050000 +v 0.250000 0.750000 0.050000 +v 0.562500 0.187500 -0.050000 +v 0.625000 0.187500 -0.050000 +v 0.625000 0.187500 0.050000 +v 0.562500 0.187500 0.050000 +v 0.750000 0.750000 -0.050000 +v 0.750000 0.812500 -0.050000 +v 0.750000 0.812500 0.050000 +v 0.750000 0.750000 0.050000 +v 0.875000 0.437500 -0.050000 +v 0.875000 0.437500 0.050000 +v 0.750000 0.312500 -0.050000 +v 0.812500 0.312500 -0.050000 +v 0.812500 0.312500 0.050000 +v 0.750000 0.312500 0.050000 +v 0.187500 0.687500 -0.050000 +v 0.187500 0.625000 -0.050000 +v 0.187500 0.625000 0.050000 +v 0.187500 0.687500 0.050000 +v 0.437500 0.812500 -0.050000 +v 0.375000 0.812500 -0.050000 +v 0.375000 0.812500 0.050000 +v 0.437500 0.812500 0.050000 +v 0.500000 0.875000 -0.050000 +v 0.500000 0.812500 -0.050000 +v 0.500000 0.812500 0.050000 +v 0.500000 0.875000 0.050000 +v 0.687500 0.812500 -0.050000 +v 0.687500 0.812500 0.050000 +v 0.625000 0.812500 -0.050000 +v 0.562500 0.812500 -0.050000 +v 0.562500 0.812500 0.050000 +v 0.625000 0.812500 0.050000 +v 0.375000 0.187500 -0.050000 +v 0.375000 0.187500 0.050000 +v 0.375000 0.250000 -0.050000 +v 0.375000 0.250000 0.050000 +v 0.312500 0.250000 -0.050000 +v 0.312500 0.250000 0.050000 +v 0.312500 0.750000 -0.050000 +v 0.312500 0.750000 0.050000 +v 0.875000 0.500000 -0.050000 +v 0.875000 0.562500 -0.050000 +v 0.875000 0.562500 0.050000 +v 0.875000 0.500000 0.050000 +v 0.250000 0.437500 -0.050000 +v 0.250000 0.375000 -0.050000 +v 0.250000 0.375000 0.050000 +v 0.250000 0.437500 0.050000 +v 0.187500 0.437500 -0.050000 +v 0.187500 0.437500 0.050000 +v 0.562500 0.875000 -0.050000 +v 0.562500 0.875000 0.050000 +v 0.312500 0.812500 -0.050000 +v 0.312500 0.812500 0.050000 +v 0.250000 0.312500 0.050000 +v 0.312500 0.312500 0.050000 +v 0.875000 0.625000 0.050000 +v 0.875000 0.687500 0.050000 +v 0.812500 0.687500 0.050000 +v 0.812500 0.750000 0.050000 +v 0.875000 0.625000 -0.050000 +v 0.875000 0.687500 -0.050000 +v 0.812500 0.750000 -0.050000 +v 0.312500 0.312500 -0.050000 +v 0.812500 0.687500 -0.050000 +v 0.250000 0.312500 -0.050000 +vt 0.790637 0.379858 +vt 0.790637 0.441016 +vt 0.214221 0.552783 +vt 0.214221 0.495142 +vt 0.507790 0.149292 +vt 0.554710 0.149292 +vt 0.444788 0.206933 +vt 0.507790 0.206933 +vt 0.675354 0.206933 +vt 0.675354 0.264575 +vt 0.732996 0.264575 +vt 0.328894 0.667896 +vt 0.328894 0.610254 +vt 0.554710 0.206933 +vt 0.617712 0.206933 +vt 0.713414 0.753664 +vt 0.713414 0.805711 +vt 0.848279 0.441016 +vt 0.732996 0.322217 +vt 0.790637 0.322217 +vt 0.271252 0.610254 +vt 0.214221 0.610425 +vt 0.453180 0.805711 +vt 0.401133 0.805711 +vt 0.506227 0.868773 +vt 0.506227 0.818727 +vt 0.661367 0.805711 +vt 0.609320 0.805711 +vt 0.569661 0.805711 +vt 0.445433 0.264601 +vt 0.445433 0.322242 +vt 0.387792 0.322242 +vt 0.329504 0.725708 +vt 0.848279 0.495142 +vt 0.848279 0.552783 +vt 0.271863 0.444941 +vt 0.271863 0.379858 +vt 0.214221 0.444941 +vt 0.556273 0.818727 +vt 0.556273 0.868773 +vt 0.349086 0.805711 +vt 0.562500 0.812500 +vt 0.562500 0.875000 +vt 0.500000 0.875000 +vt 0.500000 0.812500 +vt 0.437500 0.812500 +vt 0.375000 0.812500 +vt 0.312500 0.812500 +vt 0.312500 0.750000 +vt 0.250000 0.750000 +vt 0.250000 0.687500 +vt 0.187500 0.687500 +vt 0.187500 0.625000 +vt 0.187500 0.562500 +vt 0.187500 0.500000 +vt 0.187500 0.437500 +vt 0.250000 0.437500 +vt 0.250000 0.375000 +vt 0.250000 0.312500 +vt 0.312500 0.312500 +vt 0.312500 0.250000 +vt 0.375000 0.250000 +vt 0.375000 0.187500 +vt 0.437500 0.187500 +vt 0.500000 0.187500 +vt 0.500000 0.125000 +vt 0.562500 0.125000 +vt 0.562500 0.187500 +vt 0.625000 0.187500 +vt 0.687500 0.187500 +vt 0.687500 0.250000 +vt 0.750000 0.250000 +vt 0.750000 0.312500 +vt 0.812500 0.312500 +vt 0.812500 0.375000 +vt 0.812500 0.437500 +vt 0.875000 0.437500 +vt 0.875000 0.500000 +vt 0.875000 0.562500 +vt 0.875000 0.625000 +vt 0.875000 0.687500 +vt 0.812500 0.687500 +vt 0.812500 0.750000 +vt 0.750000 0.750000 +vt 0.750000 0.812500 +vt 0.687500 0.812500 +vt 0.625000 0.812500 +vt 0.848279 0.610425 +vt 0.848279 0.668067 +vt 0.790637 0.725708 +vt 0.732996 0.725708 +vt 0.329504 0.322217 +vt 0.492839 0.805711 +vt 0.790637 0.668067 +vt 0.271863 0.322217 +vt 0.349086 0.753664 +vn 1.000000 0.000000 0.000000 +vn -1.000000 -0.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 -0.000000 1.000000 +vn -0.000000 0.000000 -1.000000 +g Strawberry_Plane.000_Strawberry_Plane.000_None +s 1 +f 1/1/1 2/2/1 3/2/1 4/1/1 +f 5/3/2 6/4/2 7/4/2 8/3/2 +f 9/5/3 10/6/3 11/6/3 12/5/3 +f 13/7/3 14/8/3 15/8/3 16/7/3 +f 17/9/1 18/10/1 19/10/1 20/9/1 +f 18/10/3 21/11/3 22/11/3 19/10/3 +f 23/12/2 24/13/2 25/13/2 26/12/2 +f 27/14/3 28/15/3 29/15/3 30/14/3 +f 31/16/1 32/17/1 33/17/1 34/16/1 +f 2/2/3 35/18/3 36/18/3 3/2/3 +f 37/19/3 38/20/3 39/20/3 40/19/3 +f 41/21/2 42/22/2 43/22/2 44/21/2 +f 45/23/4 46/24/4 47/24/4 48/23/4 +f 49/25/2 50/26/2 51/26/2 52/25/2 +f 32/17/4 53/27/4 54/27/4 33/17/4 +f 55/28/4 56/29/4 57/29/4 58/28/4 +f 59/30/3 13/7/3 16/7/3 60/30/3 +f 14/8/2 9/5/2 12/5/2 15/8/2 +f 61/31/2 59/30/2 60/30/2 62/31/2 +f 63/32/3 61/31/3 62/31/3 64/32/3 +f 65/33/4 23/12/4 26/12/4 66/33/4 +f 67/34/1 68/35/1 69/35/1 70/34/1 +f 38/20/1 1/1/1 4/1/1 39/20/1 +f 71/36/2 72/37/2 73/37/2 74/36/2 +f 6/4/2 75/38/2 76/38/2 7/4/2 +f 56/39/1 77/40/1 78/40/1 57/39/1 +f 46/24/4 79/41/4 80/41/4 47/24/4 +f 57/42/5 78/43/5 52/44/5 51/45/5 48/46/5 47/47/5 80/48/5 66/49/5 26/50/5 25/51/5 44/52/5 43/53/5 8/54/5 7/55/5 76/56/5 74/57/5 73/58/5 81/59/5 82/60/5 64/61/5 62/62/5 60/63/5 16/64/5 15/65/5 12/66/5 11/67/5 30/68/5 29/69/5 20/70/5 19/71/5 22/72/5 40/73/5 39/74/5 4/75/5 3/76/5 36/77/5 70/78/5 69/79/5 83/80/5 84/81/5 85/82/5 86/83/5 34/84/5 33/85/5 54/86/5 58/87/5 +f 87/88/1 88/89/1 84/89/1 83/88/1 +f 42/22/2 5/3/2 8/3/2 43/22/2 +f 21/11/1 37/19/1 40/19/1 22/11/1 +f 10/6/1 27/14/1 30/14/1 11/6/1 +f 53/27/4 55/28/4 58/28/4 54/27/4 +f 89/90/4 31/91/4 34/91/4 86/90/4 +f 90/92/2 63/32/2 64/32/2 82/92/2 +f 50/93/4 45/23/4 48/23/4 51/93/4 +f 91/94/1 89/90/1 86/90/1 85/94/1 +f 92/95/3 90/92/3 82/92/3 81/95/3 +f 35/18/1 67/34/1 70/34/1 36/18/1 +f 28/15/3 17/9/3 20/9/3 29/15/3 +f 75/38/3 71/36/3 74/36/3 76/38/3 +f 79/41/2 65/96/2 66/96/2 80/41/2 +f 77/40/4 49/25/4 52/25/4 78/40/4 +f 72/37/2 92/95/2 81/95/2 73/37/2 +f 88/89/4 91/94/4 85/94/4 84/89/4 +f 68/35/1 87/88/1 83/88/1 69/35/1 +f 24/13/4 41/21/4 44/21/4 25/13/4 +f 56/42/6 55/87/6 53/86/6 32/85/6 31/84/6 89/83/6 91/82/6 88/81/6 87/80/6 68/79/6 67/78/6 35/77/6 2/76/6 1/75/6 38/74/6 37/73/6 21/72/6 18/71/6 17/70/6 28/69/6 27/68/6 10/67/6 9/66/6 14/65/6 13/64/6 59/63/6 61/62/6 63/61/6 90/60/6 92/59/6 72/58/6 71/57/6 75/56/6 6/55/6 5/54/6 42/53/6 41/52/6 24/51/6 23/50/6 65/49/6 79/48/6 46/47/6 45/46/6 50/45/6 49/44/6 77/43/6 diff --git a/mods/z_remove/myArcade/pacmine/models/xmypacman_orange.obj b/mods/z_remove/myArcade/pacmine/models/xmypacman_orange.obj new file mode 100644 index 00000000..4a06d4c7 --- /dev/null +++ b/mods/z_remove/myArcade/pacmine/models/xmypacman_orange.obj @@ -0,0 +1,358 @@ +# Blender v2.75 (sub 0) OBJ File: '' +# www.blender.org +mtllib peach-orange.mtl +o Plane.001 +v 0.687500 0.125000 -0.050000 +v 0.625000 0.125000 -0.050000 +v 0.562500 0.125000 -0.050000 +v 0.500000 0.125000 -0.050000 +v 0.437500 0.125000 -0.050000 +v 0.375000 0.125000 -0.050000 +v 0.312500 0.125000 -0.050000 +v 0.750000 0.187500 -0.050000 +v 0.687500 0.187500 -0.050000 +v 0.500000 0.187500 -0.050000 +v 0.437500 0.187500 -0.050000 +v 0.312500 0.187500 -0.050000 +v 0.250000 0.187500 -0.050000 +v 0.812500 0.250000 -0.050000 +v 0.750000 0.250000 -0.050000 +v 0.250000 0.250000 -0.050000 +v 0.187500 0.250000 -0.050000 +v 0.812500 0.312500 -0.050000 +v 0.187500 0.312500 -0.050000 +v 0.875000 0.375000 -0.050000 +v 0.812500 0.375000 -0.050000 +v 0.187500 0.375000 -0.050000 +v 0.125000 0.375000 -0.050000 +v 0.875000 0.437500 -0.050000 +v 0.125000 0.437500 -0.050000 +v 0.875000 0.500000 -0.050000 +v 0.125000 0.500000 -0.050000 +v 0.875000 0.562500 -0.050000 +v 0.125000 0.562500 -0.050000 +v 0.875000 0.625000 -0.050000 +v 0.812500 0.625000 -0.050000 +v 0.187500 0.625000 -0.050000 +v 0.125000 0.625000 -0.050000 +v 0.812500 0.687500 -0.050000 +v 0.750000 0.687500 -0.050000 +v 0.250000 0.687500 -0.050000 +v 0.187500 0.687500 -0.050000 +v 0.750000 0.750000 -0.050000 +v 0.562500 0.750000 -0.050000 +v 0.500000 0.750000 -0.050000 +v 0.437500 0.750000 -0.050000 +v 0.375000 0.750000 -0.050000 +v 0.312500 0.750000 -0.050000 +v 0.250000 0.750000 -0.050000 +v 0.812500 0.812500 -0.050000 +v 0.750000 0.812500 -0.050000 +v 0.562500 0.812500 -0.050000 +v 0.500000 0.812500 -0.050000 +v 0.437500 0.812500 -0.050000 +v 0.812500 0.875000 -0.050000 +v 0.750000 0.875000 -0.050000 +v 0.687500 0.875000 -0.050000 +v 0.562500 0.875000 -0.050000 +v 0.500000 0.875000 -0.050000 +v 0.437500 0.875000 -0.050000 +v 0.562500 0.937500 -0.050000 +v 0.625000 0.937500 -0.050000 +v 0.687500 0.937500 -0.050000 +v 0.375000 0.125000 0.050000 +v 0.437500 0.125000 0.050000 +v 0.500000 0.125000 0.050000 +v 0.687500 0.250000 -0.050000 +v 0.625000 0.250000 -0.050000 +v 0.562500 0.250000 -0.050000 +v 0.500000 0.250000 -0.050000 +v 0.437500 0.250000 -0.050000 +v 0.375000 0.250000 -0.050000 +v 0.312500 0.250000 -0.050000 +v 0.812500 0.437500 -0.050000 +v 0.187500 0.437500 -0.050000 +v 0.812500 0.500000 -0.050000 +v 0.187500 0.500000 -0.050000 +v 0.812500 0.562500 -0.050000 +v 0.187500 0.562500 -0.050000 +v 0.687500 0.687500 -0.050000 +v 0.625000 0.687500 -0.050000 +v 0.562500 0.687500 -0.050000 +v 0.500000 0.687500 -0.050000 +v 0.437500 0.687500 -0.050000 +v 0.375000 0.687500 -0.050000 +v 0.312500 0.687500 -0.050000 +v 0.687500 0.750000 -0.050000 +v 0.625000 0.750000 -0.050000 +v 0.687500 0.125000 0.050000 +v 0.625000 0.125000 0.050000 +v 0.562500 0.125000 0.050000 +v 0.312500 0.125000 0.050000 +v 0.750000 0.187500 0.050000 +v 0.687500 0.187500 0.050000 +v 0.500000 0.187500 0.050000 +v 0.437500 0.187500 0.050000 +v 0.312500 0.187500 0.050000 +v 0.250000 0.187500 0.050000 +v 0.812500 0.250000 0.050000 +v 0.750000 0.250000 0.050000 +v 0.250000 0.250000 0.050000 +v 0.187500 0.250000 0.050000 +v 0.875000 0.375000 0.050000 +v 0.812500 0.375000 0.050000 +v 0.187500 0.375000 0.050000 +v 0.125000 0.375000 0.050000 +v 0.875000 0.625000 0.050000 +v 0.812500 0.625000 0.050000 +v 0.187500 0.625000 0.050000 +v 0.125000 0.625000 0.050000 +v 0.812500 0.687500 0.050000 +v 0.750000 0.687500 0.050000 +v 0.250000 0.687500 0.050000 +v 0.187500 0.687500 0.050000 +v 0.562500 0.750000 0.050000 +v 0.500000 0.750000 0.050000 +v 0.437500 0.750000 0.050000 +v 0.375000 0.750000 0.050000 +v 0.312500 0.750000 0.050000 +v 0.250000 0.750000 0.050000 +v 0.812500 0.812500 0.050000 +v 0.750000 0.812500 0.050000 +v 0.562500 0.812500 0.050000 +v 0.500000 0.812500 0.050000 +v 0.812500 0.875000 0.050000 +v 0.750000 0.875000 0.050000 +v 0.687500 0.875000 0.050000 +v 0.562500 0.875000 0.050000 +v 0.500000 0.875000 0.050000 +v 0.437500 0.875000 0.050000 +v 0.437500 0.812500 0.050000 +v 0.750000 0.750000 0.050000 +v 0.125000 0.562500 0.050000 +v 0.875000 0.562500 0.050000 +v 0.125000 0.500000 0.050000 +v 0.875000 0.500000 0.050000 +v 0.125000 0.437500 0.050000 +v 0.875000 0.437500 0.050000 +v 0.187500 0.312500 0.050000 +v 0.812500 0.312500 0.050000 +v 0.562500 0.937500 0.050000 +v 0.687500 0.937500 0.050000 +v 0.625000 0.937500 0.050000 +v 0.812500 0.437500 0.050000 +v 0.187500 0.437500 0.050000 +v 0.812500 0.562500 0.050000 +v 0.187500 0.562500 0.050000 +v 0.625000 0.750000 0.050000 +v 0.687500 0.750000 0.050000 +v 0.312500 0.687500 0.050000 +v 0.687500 0.687500 0.050000 +v 0.312500 0.250000 0.050000 +v 0.687500 0.250000 0.050000 +v 0.625000 0.250000 0.050000 +v 0.562500 0.250000 0.050000 +v 0.500000 0.250000 0.050000 +v 0.437500 0.250000 0.050000 +v 0.375000 0.250000 0.050000 +v 0.625000 0.687500 0.050000 +v 0.562500 0.687500 0.050000 +v 0.500000 0.687500 0.050000 +v 0.437500 0.687500 0.050000 +v 0.375000 0.687500 0.050000 +v 0.187500 0.500000 0.050000 +v 0.812500 0.500000 0.050000 +vt 0.187500 0.625000 +vt 0.187500 0.562500 +vt 0.187500 0.500000 +vt 0.187500 0.437500 +vt 0.187500 0.375000 +vt 0.187500 0.312500 +vt 0.187500 0.250000 +vt 0.250000 0.250000 +vt 0.312500 0.250000 +vt 0.375000 0.250000 +vt 0.437500 0.250000 +vt 0.500000 0.250000 +vt 0.562500 0.250000 +vt 0.625000 0.250000 +vt 0.687500 0.250000 +vt 0.750000 0.250000 +vt 0.812500 0.250000 +vt 0.812500 0.312500 +vt 0.812500 0.375000 +vt 0.812500 0.437500 +vt 0.812500 0.500000 +vt 0.812500 0.562500 +vt 0.812500 0.625000 +vt 0.812500 0.687500 +vt 0.750000 0.687500 +vt 0.687500 0.687500 +vt 0.625000 0.687500 +vt 0.562500 0.687500 +vt 0.500000 0.687500 +vt 0.437500 0.687500 +vt 0.375000 0.687500 +vt 0.312500 0.687500 +vt 0.250000 0.687500 +vt 0.187500 0.687500 +vt 0.125000 0.375000 +vt 0.125000 0.437500 +vt 0.125000 0.500000 +vt 0.125000 0.562500 +vt 0.125000 0.625000 +vt 0.687500 0.187500 +vt 0.687500 0.125000 +vt 0.625000 0.125000 +vt 0.562500 0.125000 +vt 0.500000 0.125000 +vt 0.500000 0.187500 +vt 0.437500 0.187500 +vt 0.437500 0.125000 +vt 0.375000 0.125000 +vt 0.312500 0.125000 +vt 0.312500 0.187500 +vt 0.250000 0.187500 +vt 0.750000 0.187500 +vt 0.562500 0.937500 +vt 0.625000 0.937500 +vt 0.687500 0.937500 +vt 0.687500 0.750000 +vt 0.625000 0.750000 +vt 0.562500 0.750000 +vt 0.500000 0.750000 +vt 0.437500 0.750000 +vt 0.375000 0.750000 +vt 0.312500 0.750000 +vt 0.250000 0.750000 +vt 0.750000 0.750000 +vt 0.750000 0.812500 +vt 0.875000 0.375000 +vt 0.875000 0.437500 +vt 0.875000 0.500000 +vt 0.875000 0.562500 +vt 0.875000 0.625000 +vt 0.687500 0.875000 +vt 0.437500 0.812500 +vt 0.562500 0.875000 +vt 0.812500 0.875000 +vt 0.812500 0.812500 +vt 0.500000 0.875000 +vt 0.437500 0.875000 +vt 0.500000 0.812500 +vt 0.562500 0.812500 +vt 0.750000 0.875000 +vn -0.000000 0.000000 1.000000 +vn 0.000000 -0.000000 -1.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 1.000000 -0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +usemtl None +s off +f 32/1/1 74/2/1 72/3/1 70/4/1 22/5/1 19/6/1 17/7/1 16/8/1 68/9/1 67/10/1 66/11/1 65/12/1 64/13/1 63/14/1 62/15/1 15/16/1 14/17/1 18/18/1 21/19/1 69/20/1 71/21/1 73/22/1 31/23/1 34/24/1 35/25/1 75/26/1 76/27/1 77/28/1 78/29/1 79/30/1 80/31/1 81/32/1 36/33/1 37/34/1 +f 101/35/2 132/36/2 130/37/2 128/38/2 105/39/2 104/1/2 142/2/2 159/3/2 140/4/2 100/5/2 +f 89/40/2 84/41/2 85/42/2 86/43/2 61/44/2 90/45/2 91/46/2 60/47/2 59/48/2 87/49/2 92/50/2 93/51/2 96/8/2 147/9/2 153/10/2 152/11/2 151/12/2 150/13/2 149/14/2 148/15/2 95/16/2 88/52/2 +f 6/48/3 7/49/3 87/49/3 59/48/3 +f 56/53/4 57/54/4 138/54/4 136/53/4 +f 57/54/4 58/55/4 137/55/4 138/54/4 +f 82/56/1 83/57/1 39/58/1 40/59/1 41/60/1 42/61/1 43/62/1 44/63/1 36/33/1 81/32/1 80/31/1 79/30/1 78/29/1 77/28/1 76/27/1 75/26/1 35/25/1 38/64/1 +f 5/47/3 6/48/3 59/48/3 60/47/3 +f 12/50/3 13/51/3 93/51/3 92/50/3 +f 32/1/5 37/34/5 109/34/5 104/1/5 +f 10/45/3 11/46/3 91/46/3 90/45/3 +f 38/64/6 35/25/6 107/25/6 127/64/6 +f 36/33/5 44/63/5 115/63/5 108/33/5 +f 46/65/6 38/64/6 127/64/6 117/65/6 +f 8/52/3 9/40/3 89/40/3 88/52/3 +f 21/19/1 20/66/1 24/67/1 26/68/1 28/69/1 30/70/1 31/23/1 73/22/1 71/21/1 69/20/1 +f 58/55/6 52/71/6 122/71/6 137/55/6 +f 3/43/3 4/44/3 61/44/3 86/43/3 +f 41/60/5 49/72/5 126/72/5 112/60/5 +f 53/73/5 56/53/5 136/53/5 123/73/5 +f 2/42/3 3/43/3 86/43/3 85/42/3 +f 50/74/6 45/75/6 116/75/6 120/74/6 +f 53/73/1 54/76/1 55/77/1 49/72/1 41/60/1 40/59/1 48/78/1 47/79/1 39/58/1 83/57/1 82/56/1 38/64/1 46/65/1 45/75/1 50/74/1 51/80/1 52/71/1 58/55/1 57/54/1 56/53/1 +f 104/1/2 109/34/2 108/33/2 145/32/2 158/31/2 157/30/2 156/29/2 155/28/2 154/27/2 146/26/2 107/25/2 106/24/2 103/23/2 141/22/2 160/21/2 139/20/2 99/19/2 135/18/2 94/17/2 95/16/2 148/15/2 149/14/2 150/13/2 151/12/2 152/11/2 153/10/2 147/9/2 96/8/2 97/7/2 134/6/2 100/5/2 140/4/2 159/3/2 142/2/2 +f 99/19/2 139/20/2 160/21/2 141/22/2 103/23/2 102/70/2 129/69/2 131/68/2 133/67/2 98/66/2 +f 11/46/6 5/47/6 60/47/6 91/46/6 +f 55/77/4 54/76/4 124/76/4 125/77/4 +f 4/44/5 10/45/5 90/45/5 61/44/5 +f 123/73/2 136/53/2 138/54/2 137/55/2 122/71/2 121/80/2 120/74/2 116/75/2 117/65/2 127/64/2 144/56/2 143/57/2 110/58/2 118/79/2 119/78/2 111/59/2 112/60/2 126/72/2 125/77/2 124/76/2 +f 1/41/3 2/42/3 85/42/3 84/41/3 +f 9/40/6 1/41/6 84/41/6 89/40/6 +f 49/72/5 55/77/5 125/77/5 126/72/5 +f 144/56/2 127/64/2 107/25/2 146/26/2 154/27/2 155/28/2 156/29/2 157/30/2 158/31/2 145/32/2 108/33/2 115/63/2 114/62/2 113/61/2 112/60/2 111/59/2 110/58/2 143/57/2 +f 48/78/6 40/59/6 111/59/6 119/78/6 +f 39/58/5 47/79/5 118/79/5 110/58/5 +f 23/35/1 22/5/1 70/4/1 72/3/1 74/2/1 32/1/1 33/39/1 29/38/1 27/37/1 25/36/1 +f 9/40/1 8/52/1 15/16/1 62/15/1 63/14/1 64/13/1 65/12/1 66/11/1 67/10/1 68/9/1 16/8/1 13/51/1 12/50/1 7/49/1 6/48/1 5/47/1 11/46/1 10/45/1 4/44/1 3/43/1 2/42/1 1/41/1 +f 14/17/3 15/16/3 95/16/3 94/17/3 +f 34/24/6 31/23/6 103/23/6 106/24/6 +f 16/8/3 17/7/3 97/7/3 96/8/3 +f 29/38/5 33/39/5 105/39/5 128/38/5 +f 20/66/3 21/19/3 99/19/3 98/66/3 +f 30/70/6 28/69/6 129/69/6 102/70/6 +f 22/5/3 23/35/3 101/35/3 100/5/3 +f 27/37/5 29/38/5 128/38/5 130/37/5 +f 31/23/4 30/70/4 102/70/4 103/23/4 +f 28/69/6 26/68/6 131/68/6 129/69/6 +f 33/39/4 32/1/4 104/1/4 105/39/4 +f 25/36/5 27/37/5 130/37/5 132/36/5 +f 35/25/4 34/24/4 106/24/4 107/25/4 +f 26/68/6 24/67/6 133/67/6 131/68/6 +f 37/34/4 36/33/4 108/33/4 109/34/4 +f 23/35/5 25/36/5 132/36/5 101/35/5 +f 40/59/4 39/58/4 110/58/4 111/59/4 +f 24/67/6 20/66/6 98/66/6 133/67/6 +f 42/61/4 41/60/4 112/60/4 113/61/4 +f 19/6/5 22/5/5 100/5/5 134/6/5 +f 43/62/4 42/61/4 113/61/4 114/62/4 +f 21/19/6 18/18/6 135/18/6 99/19/6 +f 44/63/4 43/62/4 114/62/4 115/63/4 +f 17/7/5 19/6/5 134/6/5 97/7/5 +f 45/75/3 46/65/3 117/65/3 116/75/3 +f 18/18/6 14/17/6 94/17/6 135/18/6 +f 47/79/3 48/78/3 119/78/3 118/79/3 +f 13/51/5 16/8/5 96/8/5 93/51/5 +f 51/80/4 50/74/4 120/74/4 121/80/4 +f 15/16/6 8/52/6 88/52/6 95/16/6 +f 52/71/4 51/80/4 121/80/4 122/71/4 +f 7/49/5 12/50/5 92/50/5 87/49/5 +f 54/76/4 53/73/4 123/73/4 124/76/4 +o Plane +v -0.500000 -0.500000 0.121855 +v 0.500000 -0.500000 0.121855 +v -0.500000 0.500000 0.121855 +v 0.500000 0.500000 0.121855 +vt 0.000100 0.000100 +vt 0.999900 0.000100 +vt 0.999900 0.999900 +vt 0.000100 0.999900 +vn 0.000000 0.000000 1.000000 +usemtl None +s off +f 161/81/7 162/82/7 164/83/7 163/84/7 +o Cube +v 0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 -0.500000 +v 0.500000 0.500000 -0.500000 +v 0.500000 0.500000 0.500000 +v -0.500000 0.500000 0.500000 +v -0.500000 0.500000 -0.500000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn -0.000000 -0.000000 1.000000 +vn -1.000000 -0.000000 -0.000000 +vn 0.000000 0.000000 -1.000000 +usemtl Material +s off +f 165//8 166//8 167//8 168//8 +f 169//9 172//9 171//9 170//9 +f 165//10 169//10 170//10 166//10 +f 166//11 170//11 171//11 167//11 +f 167//12 171//12 172//12 168//12 +f 169//13 165//13 168//13 172//13 diff --git a/mods/z_remove/myArcade/pacmine/portals.lua b/mods/z_remove/myArcade/pacmine/portals.lua new file mode 100644 index 00000000..e0867048 --- /dev/null +++ b/mods/z_remove/myArcade/pacmine/portals.lua @@ -0,0 +1,75 @@ +local sbox = { + type = "fixed", + fixed = { + {0, 0, 0, 0, 0, 0} + } + } +local cbox = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5} + } + } + +--Portals +minetest.register_alias("pacmine:portalr", "pacmine:portalr") +minetest.register_node("pacmine:portalr", { + description = "Portalr ", + drawtype = "glasslike", + tiles = {"pacmine_portal.png"}, + paramtype = "light", + sunlight_propagates = true, + light_source = 14, + alpha = 150, + paramtype2 = "facedir", + walkable = false, + is_ground_content = false, + groups = {snappy = 2, cracky = 2, dig_immediate = 3,not_in_creative_inventory=1}, + selection_box = sbox, + +}) +minetest.register_alias("pacmine:portall", "pacmine:portall") +minetest.register_node("pacmine:portall", { + description = "Portall ", + drawtype = "glasslike", + tiles = {"pacmine_portal.png"}, + paramtype = "light", + sunlight_propagates = true, + light_source = 14, + alpha = 150, + paramtype2 = "facedir", + walkable = false, + is_ground_content = false, + groups = {snappy = 2, cracky = 2, dig_immediate = 3,not_in_creative_inventory=1}, + selection_box = sbox, + +}) + +minetest.register_abm({ + nodenames = {"pacmine:portall"}, + interval = 0.5, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local objs = minetest.env:get_objects_inside_radius(pos, 1) + for k, player in pairs(objs) do + if player:get_player_name() then + + player:setpos({x=pos.x-23,y=pos.y+0.5,z=pos.z}) + end + end + end +}) +minetest.register_abm({ + nodenames = {"pacmine:portalr"}, + interval = 0.5, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local objs = minetest.env:get_objects_inside_radius(pos, 1) + for k, player in pairs(objs) do + if player:get_player_name() then + + player:setpos({x=pos.x+23,y=pos.y+0.5,z=pos.z}) + end + end + end +}) diff --git a/mods/z_remove/myArcade/pacmine/schems/pacmine.mts b/mods/z_remove/myArcade/pacmine/schems/pacmine.mts new file mode 100644 index 0000000000000000000000000000000000000000..d85cb1828c0b549509c02b53971737ce79a8adf4 GIT binary patch literal 1151 zcmeYb3HD`RVUPu4wR#|6;AP+~NKDSn%uBT@Pt3_lX5c~QGB77*79mum<>coVF^Ixc zBy=r65$LgM=9bV5$mIb8=Ek;tdfBKo+H9C@^B+hil0%DoM;KLKnzk z5QM1!8j&3jGKYZ=CIq&&ykgGVsK#xx6?jy4TraEs{rvB*5Drg;giwnN`NZY^2c+_f zgq2nsu0HTCt!HoOZ%vEkhu>ajd~Ly9Tbgma@Q~x_Lu>vAtjwLWW50sGteOFa>Zg167F@dJUER~0Q)E9!e}B1x z`{mlBAFs98KA-wVyF~VL$o|#y?dP7i$lv)t$!_}VmQOM7e{2zac7^TzHRtPxPu?&3 z@y_YzwYM5aqWAXo-<&0FeZBATl$a~u{Gac&;LrSb`&Rh5>MeGD=dRRRY)@ZzBzk7! zw+~^*Z_eJHP_z zpZsL&-xdoesn~}esBk^9l#OvP4pTo|tu(7i|_jj$j z-&C$7fk@Lu)7Z`7N7ETo_lZC>PbtF$L#&%99X3u znzcIN{MJv-F(K2!tS&C={?V{?U$Rb>=-E@&%S)nSzDu#5X5Ra6lHZD)=+~jMHq1)- zRkP-Yy=PI@vdb3TN$*-+)h(~FYaQjX+FZ0IWk=*ISz-1Q7PnVbu9)SwacSVM!n&;v zZV@_MHj=W}HNUK{65?=NzP#wF#?1LInL;kVT-xP#z(+vN%K2-joPuJ6=$(-z*R!?SPcTlct%@7xdYL= zJYU%4NAs|+X}=b4xntvjg`LlTEZDQG<@m&N1~IP7r#|hJVDkAJ9N{>1@0ne)#cO@1 zUFUlIc|vc=rLbV<<=c3kCwV;gx_^7&W#_=G$z@ixkxo}VUirTkwk_PfC|A`y)@;TH zabuC?Q%g2wz>% literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/schems/pacmini.mts b/mods/z_remove/myArcade/pacmine/schems/pacmini.mts new file mode 100644 index 0000000000000000000000000000000000000000..7a30261e37e647de629c26e501d9c43fe9ed07ea GIT binary patch literal 539 zcmeYb3HD`RVUPx5{(2x_;AG$}NKDSn%uBT@Pt3_lX5c~QGB77*79mum<>coVF$lp_ z0Ci=?C*>y=r681~=Oh*vGYG(x6r|?lq?W`RA{2mZNySiLR59mm7~`bF3LGqZRQ{Ik zk6Uc2BpAH6=Ud*9l^d1v!~~chu&kD1sIC3IeveP^@0DL#z8|}^aqGuJZ2XH{S8soH zKKra$?Z5XQZk>Pn%x&R!N%iLn51$tP)u=7DH1E1z=EB~+*!M%%#vO9K500Mit6%4H z_Gfj?Q^3s(eKI+N7dAUv>sQ*G{>wb+0}B z$=9Ekii=tF*MWBQE&f69Vsr6n-`#IN zuNl0|XQt6pwVU~Nt`G7Yom^ks`r&qwW4jllm%7`E)oWbt&+wOZofBcC7ZJE=|HF>d zHFtaSI@-C{sO~l0W2FGX9~e`20tq&8{zd`dWp$wKl8~XPIWIcp_T%in32Hf3tSq h**(55YfL|{y0+yQ_titou4P~G-Wj@=Az$B?8vr_p`ZE9k literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/sounds/pacmine_beginning.ogg b/mods/z_remove/myArcade/pacmine/sounds/pacmine_beginning.ogg new file mode 100644 index 0000000000000000000000000000000000000000..2188e55e15ffec4c12c2379eb9d83632ff23ae1e GIT binary patch literal 17153 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 literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/sounds/pacmine_chomp.ogg b/mods/z_remove/myArcade/pacmine/sounds/pacmine_chomp.ogg new file mode 100644 index 0000000000000000000000000000000000000000..1d14e93fa35c7357631707023d328b8680cb6962 GIT binary patch literal 7014 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 literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/sounds/pacmine_death.ogg b/mods/z_remove/myArcade/pacmine/sounds/pacmine_death.ogg new file mode 100644 index 0000000000000000000000000000000000000000..277acb2bf041dd943222f5f79fb34d9465614326 GIT binary patch literal 7619 zcmcIpc{r5c+dnh5vCEcyD>6hV6)ko#_CXlg2H8fI2@#q?)+Ae@Cd-Uv>_i!B$r9x& zYgq~{WKD$%<9(*Szu$Ge*Y*DUKG!v8&V4@5xzByh{kiXR=8T1xmof7R)zqZqZ9;+r-TXR9!JQ;uAD>G|x@s8H-|oD+ zdgmeSFu;N4mzEW_M!6%h&}bx+xVxp}IdS(94MS-U9_s{SVe(ZAg)Dni?>@9W(m>qW z)Y>=;oekC8`K^tlt;bY73-J6VH;q|kab{JQ1x*%m+_O~;#oY%ms0Z$2s?d9Av~dAm zNb{ns2fwCa*8(T#{o_>$r&Zl2WXYiO*An8-Ar>bPDC$CFGu> z+TAs0Eq`M$&6aK_&}M}Fv6&5kXOD-yn#;CrIpE`oVtqpI5X2-2w8c zv-0T&jMF_FvOOKLi^H=^nKm>8NW=kPBWH6+P>64 z6l`#5eB$>QLU-T8rdSQ6S#zi|sooq!#_^1pYmhl)5PC)rJO-pp&MeGe=TGv8)X9JZ zXtWfa6zT3XJO_$dIylw1S4w|C1Nk7+6eVBzDBGA-DQiq-{(h!8N{;+U5ZzD89Me@~ z0)X)(^sz_8-K;=>LI8MT($Gf8=b2b@)%Z+wDzYaH{ZgarUT}))f|Sim)n2h!BV?Bl z-dy9elm~~xXR%lgHM$SEppT$#fwUr=a1sV$4*KMheG0vOa^)k6ODTo&6w0UY;x9SH zl!(GIN->36RYs}8g%f?~C=p4aK%yUovXn&e?Jq8$X#7HHT<)v8)Ld6FNu=~OmQm|2 zQL6l#>u^g|hbO5Y!zqh7#Y+*zU#OI&iMmB<-3lZoQ4}YOm-_0K`Wh?y>Z<%8w6J`l z3hKMkNAFv)UA(l|xY$Rn>Z@CwY^>U@t7LCppf*vhEj8jMbzgk989iz? zzF|5XVmsd8KN{li2#M-WcG(7_A)cdIAxUqyZ2?QvpcF`?9Nwlb_R+I=>9yFUY$wrk~+MNs4EtbiHGM3I9f&dSQf?^pwDDSe& zL6kh1Y>6@{$Q(oaDix1lI0_!|qkJkehcLd##t}3QQl&Oef_li4ADu_}An~TC?tBuL zt^%1fgfg!5958;7Uo@m)R7M&?8<#a$qWmCLC{!(Z2<2bdC4%x%A`M|6U6! z4W6R&;(i7iWn2c0@%erxm!?8aOgai#mX(gKxR)`cBQG11f-)vIq@xu7s)|En{3=K9 zp-t2?(;-z|&={2sBG!uPah7OyC}JRU8_xUrDm7Z_`W27_O%zlc1l^&*g&=^$>xeAt z5_G&(*Jvv#n+a7PyFq(-;h5!>q^==`*OX{D{ z0CW%-fHr~EGk-8G3uyBL;L72iqT|gU{89sX3q7E5NEXkfi$Hn~=pdxY0~!eOqY(|3 zg3L@^B$CYUC@)JM!yE=6zXJxOI+)E8yI^db4y-^Q61(NQgkrm;$U-rLLPh+Lv&lk` zDl)(OfKIOven1B)4Ali~&+V}a04zfWEqCb3AM=m} zX)HjSZozk&YeEn1{%yJAWU~ql+krfeLcw5H#sn zH0lc-K$0)hflM@%y%hohK-5@y;BVZ?htf41ghLcpML~;2Hbizyk@y|y6Gr=1VmWjn zKiNap!gQ&srLqe31h4nU^U0Z60+bP+1@W76ogL7fG*Sv zwLx?Lza}wDpF}1ag(O2oY0Sb@NsVK&&OkW2c zXsZzF6pBruFZNAU1o^T#%2-xCMMs{D=Y{&m3}Sqts7IrOV>7Yr(pi}pHYg|fA^h*BZS7HHK8_36f1qj>0Y995RGD$hH6lF zK(m8t|GI)6H-Fpy4W2)1_usZm-alOZ^YULUf1D>zr}Lj0tL%ThD*fLY8DanfJyRc8 zI9SvtgF80+jDZI_a=`)I6kLbhxM78W$L>SWPhkK7ega^`Mo38T{>;I}!^LO~9&!+1|Y2i>zeXAMyXrdnEhr?hkp^mKLf4RpHQh78HZX0lRcDBNrUld>26>6|_cILO7{bDmAhJUG` zpx{iXrc{aS)up)y!XEzP<=E;(&b4;rd%sHM_9=(geULg?slaE)@B^XUCQNu}-v4p+ zckOJ*VefU^=bMmGo$-!qUeJlQ+4hhflZtKNa{Z@tebS*Iq9YuO%xRwGZn1X{tGoxQo?O>UB(Q!H~e3s;Yn%VkX1 z{$lLIau(eV8kVhs!avxf5-M;(_wjZ+IX`3ZeC-=606y+U9})oClI>IB8wp6xDVEhs z=bnn*XEKl8dS)Hn1`4q*V-iNJ&S9{s0p{#y_PKc%ZM-K8?Tz;CZtfI7r^{cz$wvVp zw^|sf)pjyn)KuU}DQui2rA4*6-~L1)R!jLNny2FuE9g}Of}`ab(`(l(hzkj-r{X2m zpy^*z8&-y_0M2ZHV0YzfkFBURKOi)4v=4?YW%+BfAUf4mf*sHI%|FCA_%ppzgqZnzp4r z3?ndUpSipXA58xs-0S*ocxn9#99ohp&P2z9Pon`r5YChF&&?^mkPSju(iK|p&Z6E$ zW?Vn&ER}u z$8BVXiby>9sI|t*CU*|z8+mmM;)mrw!^JP5-!jt{+zZR6EmYpZy!CwezbU)U2%Hph z7A++CD09a$w)1xk%KtPd4@^&KzMroj?bs}^QsDk@27vckG&qRe60P1{(1aV+{0<|0 zA3uy^6ty%moV{{$WuLU;|$>a(H8Fu>y+9dU;P^iKP6w{OV7!3BnKU#6;?+E6HOrVHe05ep+8Ng`mK*C^Lj z*@O^1zMDtKJOW+@2RGvtsh)PwZtR3BRt5QQw#68Joz3Y;l#*J2GB#~2h+zo8< zK26TUEwyQW?UOG+zGUjO)27o4#Tl7KDZ%n+WupdG&0~TGf5oGSCC8j3L1P3ACm=s% zSPIYJeNg-UEv7&8sITE$6DI&fqN?`Z!@M0&LD5t&jKBiNz z_NYM>t>|Gg*15^_+kV z>XXEN04BbFb%9+lJ{ol-2Ms#D|Mp;B*j0Tkc=v_Ihjm8CT1||kQO#Znqm8AdC?fSj zNVJSU{Hg%+`oza_2L_N3wA&X8EZZd_{neW*Pw>Ct%-aIoH~V z8YQ>(X!!9W0_HkvPOI3_PgjCA-vn5Y-M>1Ln;Beq{wdvNd4(3&47RdDoGUs;P z(qpRe8SJ>7bQC;F^c$JDwJsesN7@IJ@p;vatdJuI&#!dvZTB%Oe7j^;`1x>PKSys* zvWB*2%Cz#+vChU>6LbwuEOG?45p_(A+lc+T^p}E%C%M=tST*q8^LouA*(u0uQM+5GDN~_ zNTId2e5{||nP%5x2hWE$8KK_}VCF|(5ABTNenMXzny@I@^3g2+z1cw2UggM;n9Z$j zII-9*=`8rBRepU%yNPkIuy3&RrNZkCmnoNPEsWs#i{ThM(T<&mE?!HVfK*sB%biVV zo-KK|Swk=a5IM6Y5UhO6La}q_Y#?@894$&X{kigjU{`@00Mwv89WW?79bH{A3~d%Q z^=%v<4|VC+TU@>R@E|B8Yf`ugZM0Sb;f4~EShzx4x|&PUZyC%wicHR9Lb%D8o-LId z@ok-y&@!u>MDRbk>ccRou1Q18YcSWmHv=cd(Kl|~s7OI)z3iGuCaQ`b7>cx8t}2hzW;g|fIAu?C zaAbu@Jr>`mS3l{(md%*!w*F885t#$uCWwiVQdqphY}$D}k0*7-PYYewoBWN9Isiqx zwo}W_cHeSQM$nVTCsIGWFb?2Mj;IfIGJld>+`{JCtU)}js98@dkIv;Kx~ZFT&*Zui zc7;AZ5s?QKlqO$=(2E1q)Fs#qY5q3{bWhY#zLizPH=!V_9Ad?~(o0a2Q}my5a! z<$qZIfJ^wybq7{kp!Qs7vPI(2`0>5_h01QJxTScda3y&$wP?G@rJ*GNsWXMHIbRaQ zmd_`oFn~breBZ5MX?EyvOi-&H2|MCtySpm7z{OXn;^1nel@?5kL zm}ni#UhzoQ{VFTv92Y<&VMbW;_q-W#iryV;S1B7;0(*PMWbmJ=g@NlDYRU-)2ynuh z>_hUqMfKxu#CqNl=Wojd=;*e6U`45l<#I^Xdc1cr@uI3RH-T2dU@!9qiqcZ$3wOjr zQESENF5>2vV1(R%C?4K1E9|xByr!USE6jGq?1^=U&!%<2cghm;83w5PSB5|iK2h9` zI*vj}&N?%XiakP`tCZcPygS_IH~(||D&LwOth|Pbf43CJPJrKfcb84_=eL$P8?Pfi zZ1-0V7^=tb*aMJ_-RR|Zy{7sUl*fwwxMPVYP;+MWpPKDvT7ww}L z*s&tp1ktwEHdgw22F51ZdJfh`I!0zXCbs6e*dXE&!UGi`3xaX&!u+nLRTGK2%Lhdt z>~?bUb$knZzXk`;ZRxzlc-S&F{YD>G@FqpQqHQ?*!Uo#B>%nJCOFBBL(Ol=dJN)7P`P+xk!4Px5W)dY&7mVV*n4pi1|O5x@Rh=()YSk zE8xXyWaKeqky^4s=j7+&+VbY{9|gxS#f;~!ruImtz3OkBpf<=!N2d!q3-Yp*rd;%%MjNaEV7=ra{EVO<&;GB5j@t`)4O2uB4Fjo zZb_J67jm5K^TRSZmlC!*Ih2Wh-kaMW&}T@dYXzvgYy}mjnH%9+g5{6$;8a)E^G_4r z-{5hK$sHYSc~`V2NoDoo}RNZIGr7-cIN;-om8Q+U8VN;#Daj8vZp!I zJP$4G20vq9q~3Sbw7~0Aj_}*}9>e=tL#AFuQj}UOWC6*TQ!b5s{ zLOtrsRPGZA*NpAX=b8Sqb3UJogUpFDYI))ZUF~dYIOURZB%2eblSlQZs}kiZ`PkFmGXge(7#?)d}!3=hJ58&{<3mS`W>4{|rgZA!Ljumf zN~%53C&B}x=qiJbtL#4ojxwH75?^y4VWqg;bE)<3VAAGpddLL8b;h{|Wks1>@C!+hh&UWrEs@%Vt-S|uw`V&|8~gf*g^o{oTstn6a)OV2 z3}dvltL@)H`lGM&_s*~Scy0@GIro&;uNS(_4;J)?^k@*e z7hYCTa-G6nX@5&fyzrgzK+hRioZ>2@LYq_Pj6x@`w8#|-ci!y017Mgu$25A0;ueL_F8uII9f8iAx2sh4mmUpK_ zNO9Wj#}^m96~tVTzkHkYNF;!_2~X=&^o!VN-&k#zi_b^*QmK>g*M5|8y?9T{?jHIu zY*9+tm*2ZRbJ48(`Jux>yLq>GVb3et}<0T{*&k9pzDfInuia{dP<6^k-Orj{chUzC#D@26PSsTcB_X) z$}?xKho^?O@m&=wVo(Wg2$wi@N?^#O?T%yU^XHgncelQ7lOLyTdJi^*RhmGzOx_`` zW^w!-&y9}m%JK|OAHJ=bm?zRUd*L>ffotJ0eNViXOY5IMRl@S1t^Rn)z|CJC=lb%F zT$YRPpM14(_uK@2?bzr&6?aiF>A3rc`ImYkt{ND2ue15&u|);$&kFMi60QIAe0668 zUM%KiCcX%ZGpKE*Mh6HM_E(YZS`5OH5{8h!z9j!(MOMG@4=mMR|M|3nXRpRtMz<;VC2N`f>{X0F@6T5CXRm@H2(Y}E#=&h4W(zOL z322k$_sFyp?Z?-Ou9k=YQ-{xf6StuiaB8iHd&+U~V~+Ds&^pOCQsDS;!_Cdy`SmDg z{`}+ZN2`o4%IfaT?LJ1nSZ4LTwfz9Ud;CYVABbSPeY04Vi?uh)o$4;h{dr*8=Ghdx T$MO-4&75MI@iJt!fAv;Jk literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/sounds/pacmine_eatfruit.ogg b/mods/z_remove/myArcade/pacmine/sounds/pacmine_eatfruit.ogg new file mode 100644 index 0000000000000000000000000000000000000000..212782f3ba23183d007641698e328ac1afc5ed8b GIT binary patch literal 4343 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 literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/sounds/pacmine_powerup.ogg b/mods/z_remove/myArcade/pacmine/sounds/pacmine_powerup.ogg new file mode 100644 index 0000000000000000000000000000000000000000..23b2854fc16104a023892efd7185b881a862e517 GIT binary patch literal 20591 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 C3?r}r literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/textures/.pacmine_glass.png b/mods/z_remove/myArcade/pacmine/textures/.pacmine_glass.png new file mode 100644 index 0000000000000000000000000000000000000000..2c6dee993e3f3895910928e0c4b0a3df28e0157e GIT binary patch literal 431 zcmV;g0Z{&lP)472y1>emfp#IHXA zD3(iJHXEFCEJMHx5El#TrlCs-TR-p~s^7N&T-`qdz2&xTk<5E5ih@6@72OBqe<8*9 z(^^%Px~@MYUtB-^S3A0tVOVgE=J}qfI6Am2OFS@{Jhq-^8KT+?oP#ePan2#YBFji- zm>E@7;fp*!D-iRXYPZ7xM5vqQl!0$kIxFz{bbY$QGDf6NpOg}ES(dihZa)>G7eUwC zE#q#S0$V>2oTD{E4+D9e@DvBC+Bed%=tL%o`0^2e_H=NJwyr8N?`gXZ72)vCpIChP zfeihBNC~fsir~}m3Lyk+zh~dJcvZgLt*GAK*wr-vGv_#rvI?^qSqS_E@RyqVb?}n; P00000NkvXXu0mjf_QuQF literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/textures/pacmine_apple.png b/mods/z_remove/myArcade/pacmine/textures/pacmine_apple.png new file mode 100644 index 0000000000000000000000000000000000000000..22e060fceaf82c896bc317511809b97b34839755 GIT binary patch literal 313 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#J{JoEt6Z*_Qx{O^hNp{Th{fsTDZ!CP8u-N4hoszyNIHK22sS+X$kZlqlcmkH zUwpxe$`bXyMi6-V@OUK8r$3oI{zcvsmRvXT;SgxtEbyRpZ9<767^%2_}_g?;q!mx)1t3se&4S?+9enpGtZv)9jh7}8(W*R^{tDh z%AXC7$k)wjy~_Gu(u1LAeZRq>SO?C8NzeTkpJ7P(FTiwR!=iQE5`j(OSDxA1-F|DM z705I}g?YnKhBn3{5>0C)vrQIhCLCE_S-`+B_qO-S$EJO+fqrE0boFyt=akR{0EG;6 Am;e9( literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/textures/pacmine_blinkyf.png b/mods/z_remove/myArcade/pacmine/textures/pacmine_blinkyf.png new file mode 100644 index 0000000000000000000000000000000000000000..fb1a17de75d60804685b58d8083748affb9aa76f GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#J{Pm7vE<(n`8uGGm8Xkih{fsTKl)jp=QlDPIO3qV;0A*j&&2R{!5qWrrbk!4 xH#uAsWNTcc%yXnG_zlysh4Q_N*?8EP8Fc^hUN1cT#2IJ`gQu&X%Q~loCIAZUEPnt1 literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/textures/pacmine_blinkys.png b/mods/z_remove/myArcade/pacmine/textures/pacmine_blinkys.png new file mode 100644 index 0000000000000000000000000000000000000000..79bb09d4abf761c0898100aa17605edd7d1a273e GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#J{L1Dx4DW&OcPK@*3-o?#Nu@FAN{P)^Bb8C9C1*TFip795Xj8d&B(A|9aH`- S$*Y_|g$$mqelF{r5}E)O1|9VP literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/textures/pacmine_cherrys.png b/mods/z_remove/myArcade/pacmine/textures/pacmine_cherrys.png new file mode 100644 index 0000000000000000000000000000000000000000..0009e275d96e62b0b07106bac3c6378167f5a2af GIT binary patch literal 296 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP~ml%t@>`v`_%0Qv5o-U3d7N^fnG88(bAmIAn>RZSy z#opr=q64f$WV*DH=SCk%zLBsiqL3-*AV;HTn@QeLhTr!#amTLn-*V*nUj_!54aQ0i zMNd`3_eoyh>T0NavqIjQ>-E|NS^P`|yiQ9sJ=WE%U}IQg%;{p_ds1YL@rH9M-xAJE z{%recd34>r4O11q)CR6(H;u00Tc()1D50t}{XE z)7O>#J{Pm7f$C2&11q4Aji-xah{fq-o7kh@<~K4OIO3qV;0A+O3FG8z^9#Ps%qnYo zbme=K!$m>1#zo3JN4kRFFdbVc-@BNNhmDybT#Nr~fQQmQpg9blu6{1-oD!M{XE z)7O>#J{L1DpTM6`*)>2RSx*{XE z)7O>#J{L2Oyk5S(rvgw&*3-o?#Nu@FpZ}hJ?U`8{Ivbq~vJR|ZT+GHJ#>{Z~0kb)O S;{XE z)7O>#J{L2ijJWW9#vMSRR8JSj5RLP9C!ORxV8Fvt?pjqi^H}PxS!WMVIAQeh5#S;glwa%HHH+sfMCYxw(G*eY!6nY!JP{?QJUaOuR{D+OA3^&ujZq rUz+@q&3tE5vibP0l+XkKCKf`g literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/textures/pacmine_floor.png b/mods/z_remove/myArcade/pacmine/textures/pacmine_floor.png new file mode 100644 index 0000000000000000000000000000000000000000..8e4adc8b50c8bd8db6d6f1b9b8225df28c06ae65 GIT binary patch literal 556 zcmV+{0@MA8P){4+kYhD7a@PS65ijf8?S=p;C2qB10t~e>%`%2ZGvv5f+=&S8_dE91_YA|p=hqhi>$(!aye#Nx zsXO;^eAq3*G|!g?wzbCJ&(8}QKoVh(Ae%9-E8DiQA33-U0|Kb(L(rNt?cfWrM^JLc zQ@T7qFAET@ai1psjU)3sLw7{-oJk~1HB9w##LZrme~I$?)E%JK%GMgKHR9x%5&{gR zT#-ISx1YREIwFFr;yJS}3vmd13b>t(&)1gCB8gma?n}8|o*V(H?$^GlhNl$Pj`+Ge uu`DdxhN&{t3cxr`#1X7#y54nUcm4zN(E{L8iqdlc0000) x^mS#w$05VRVlF-9Z5dFA%hSa%ghMtt0mx=zU_5`q^eK?V;OXk;vd$@?2>{_36?Xst literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/textures/pacmine_glass.png b/mods/z_remove/myArcade/pacmine/textures/pacmine_glass.png new file mode 100644 index 0000000000000000000000000000000000000000..2c6dee993e3f3895910928e0c4b0a3df28e0157e GIT binary patch literal 431 zcmV;g0Z{&lP){XE z)7O>#J{Pm7k?zsox4M8rww^AIAr_~TrvyiSncv8C;E03bf*TBCC5`RdlON_(UOmck zbme>2#zo3JOs?({9iq!`u=Y6HOS$t(@BnSQ_<--f-=$SMfd(;ny85}Sb4q9e0RM0< AQvd(} literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/textures/pacmine_inkys.png b/mods/z_remove/myArcade/pacmine/textures/pacmine_inkys.png new file mode 100644 index 0000000000000000000000000000000000000000..c94a44c42d5f2204b67c619745091a43186623f9 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#J{L1DkH)ja;~RiNvYsxEAr_~TrvyiSncv8C;E02wglWQ+hCpVvZbpWeiA>Db TbK)a_3K=|I{an^LB{Ts5Sau%Z literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/textures/pacmine_inv.png b/mods/z_remove/myArcade/pacmine/textures/pacmine_inv.png new file mode 100644 index 0000000000000000000000000000000000000000..244894ab22e7b68b72213d583d117a5ae5007c9c GIT binary patch literal 274 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzwj^(N7ltc^y@G)H8bHPM^`oFZ-+p^jA zD6DOs&2Z@H1-HksMi;D3tk-|oa9%^Yp~d^Imf+j3=jtw9-}Y_&W6tSTZu$zFbaN{< z9kXrv{Al;td1evSHuh<3TMl~&ulcEwJzwu(wB%y{W;-5;PJdx@v7EBk#eNoGaeX6et0Kp}fi7sn8b)5!@Etcw#aFz7vH|G#sJ z{Ga2;+?H+ZG+Zd%a$YFsQ33P5yP*j#%Q{V2j{XE z)7O>#J{JoEm(<(Gvtk$+7$rPi978NlCr=5EJkr1?wmu}~Mnuy213<9h*+-@}ftxIC zrv2gzR#cX#_cemR$NejKn{Dc)4o|)#wBt$L?5#X~?oAJC_Wj=f&)C4g;6v`rBOQqi zb51F>wacd)0!0iAuHSLmxb*qO`~Q9G|0nI3kbhdmZ3d%{!C4+4c>h-P!H@iIDVLm; ze9D{BO6(rj2THd&Ti=r8nbDn?^j}g!LgJa;KJM@-GOK$QwV$8b+xYRTU<)Hi@BFg= zP1$XYJG!;I3=F;O(G>@{H+=&J O8-u5-pUXO@geCwdb(fg{ literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/textures/pacmine_pinkyf.png b/mods/z_remove/myArcade/pacmine/textures/pacmine_pinkyf.png new file mode 100644 index 0000000000000000000000000000000000000000..e31a81b76cd66294fcb24d703236a98dc81f151f GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#J{Pm7F*3-o?#Nu@FADjC3^=w=W!pyA=Nz4%!SSy6)Jb0te{Y_A0 y`95)$u08_}5!pnAusKQM27G@rWK0tbfF`bq61?hhe|;O!AO=rYKbLh*2~7Zew{XE z)7O>#J{L1DoA|01Ozc1*IZqeI5R22ve{AaC*Rydk2s5`PTxkeocH@=M0UEc;pE+;p S6h|+hN(N6?KbLh*2~7a?2pi7; literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/textures/pacmine_portal.png b/mods/z_remove/myArcade/pacmine/textures/pacmine_portal.png new file mode 100644 index 0000000000000000000000000000000000000000..04bdc13a818739577b216cfe4e5f6a4f8c1ec37c GIT binary patch literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE(~uNZZpit&JO@da29w( z7Bet#3xP1>rMq>1fP(BLp1!W^_qil^1y!amHkSkn$$GjthFF|VPI=TZ^P~e~Lec_( j9w~#Y11lJtk1{a$Zeo<5aKiZ#P$7e-tDnm{r-UW|{4gb5 literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/textures/pacmine_powerpellet.png b/mods/z_remove/myArcade/pacmine/textures/pacmine_powerpellet.png new file mode 100644 index 0000000000000000000000000000000000000000..880b6283fc5a1bd8cdc1e5afcb2af457e32a3014 GIT binary patch literal 238 zcmeAS@N?(olHy`uVBq!ia0vp^0zmA*!3HFSYrjteQfx`y?k+$Y2!1;6t_M<_1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP~mpDJ8#iaJV_CTR(PZ!6Kh{JEMY~*cF5NLfkfA!tA z%sCS>WgNJdFF4+GIHU4{-70sz{tvA!S8m;1aOt|6$!#x5t!+VU8>VjJQ0n-gEOX#x zb48icH%FW0|CG;8RpdYPN7qHbv1NL}&t(Ra=LY<_GB;z}RHG>$xr(2j*X~eg;`kNf eD&WX+p8wg$Szih-J?aHIgTd3)&t;ucLK6U`jaGU9 literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/textures/pacmine_strawberry.png b/mods/z_remove/myArcade/pacmine/textures/pacmine_strawberry.png new file mode 100644 index 0000000000000000000000000000000000000000..dcedbe62130098283fa8676902aca765111d2718 GIT binary patch literal 386 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP~ml%tjp8SKp5(WlFeoq(25R21iC+OxKb`WUY?|I5M z>)Mf3B40(q3L-oUL{h@Sgfuq08Lo;Q*&OwMMNy>v zqpxpfo9DYP+ic5l`lM9D77vL-Pxmk-T-g`lckNmZ$2A3AA!}P*q3kaoEA#7&cf8cD zv$dUVp2t|R=Kt4s@BW5<(qglBImL5PR-;l>y5ZxuD~A8-Dj5_$DD9jRE@8h%?ZoN` z(`OYo4C8awRP3?6x!Kyqfx*qsnBntLwuZ-v*JrHC*t_|NS+4Tmtk{V!bM99(b=^KB z=W^=JET9og`c1!L^EOLIo^KTQRBqfXGdt|Z@ofrTB literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/textures/pacmine_wall.png b/mods/z_remove/myArcade/pacmine/textures/pacmine_wall.png new file mode 100644 index 0000000000000000000000000000000000000000..4f6d2c07618a18f0316af54f8575652a19bb5b0b GIT binary patch literal 498 zcmV(QI@#dH+y-|4;?= z&p0Ze&KMnIQ~`aPCIxhgQ316g3g~mra46~BIY+o$08rIaf4g4ydjM`f7(;ChfHfrm zh8S6vg^MwiQUJJg;Aia&T5F^}_^f4JDXLg&Nwos-_wy5d2>|5I0AL6K1+L>r2!Z26 z<`qEn9w)Nzw{F|6%h&C;4|wlsuK-Y`sN&s2mf9)b=lQhO`p=p>fH9Aw7=v^t07L{U zf_Dx9#t?|!zhKZS=ZpedN|+8bjU%Xn)mNivUxM zd!&D8@Z7s~`$Pn93_b*MN@y2&J!p0Q3)VudE=dSKy>3DcBF orQnQV8it2E>x%YZ<<9O{-{@S(w!XHOiU0rr07*qoM6N<$f{<;|SO5S3 literal 0 HcmV?d00001 diff --git a/mods/z_remove/myArcade/pacmine/textures/pacmine_wallc.png b/mods/z_remove/myArcade/pacmine/textures/pacmine_wallc.png new file mode 100644 index 0000000000000000000000000000000000000000..548b32f2f6d84e20dc5d9da97e5a59ebf595b0f4 GIT binary patch literal 500 zcmVjcOl}As_4M8o+ZF&x59ibQeB=T6w zf)&9#hX7*;MDHIcXxO$51=f@>jc6K2N-4MSL=Gx?jo0QGz=}{*3C^)@8#!l6+k^8o z9roaxf}%jV){kdLc^**<)NFnI=^(qIo?oSEqIJfQT58q+{xw|t>69rgHIgxcKA>h*Y zq?As7DdpsCbysW}FnwcjqofC29Q5VT8)QuzYx5;-Me z)6ll<={qW_6vk=d-~G-!&(PKeIaXt);I80){zwerN%`aF0Qvf@IzZQTY^6|2K?l#K z!GIxWRM8xwhyQsWbj*zCPE3h)Sx^=D5OAw;;r-*KVSIfWzW_6W#o(yBVsQWf002ov JPDHLkV1mjy&OrbG literal 0 HcmV?d00001 diff --git a/mods/z_remove/travelnet/README.md b/mods/z_remove/travelnet/README.md new file mode 100644 index 00000000..d9bd7758 --- /dev/null +++ b/mods/z_remove/travelnet/README.md @@ -0,0 +1,11 @@ + +How this works: + +- craft it by filling the right and left row with glass; place in the middle row (from top to bottom): steel, mese, steel +- place the travelnet box somewhere +- right-click on it; enter name of the station (e.g. "my house", "center of desert city") and name of the network (e.g. "intresting towns","my buildings") +- punch it to update the list of stations on that network +- right-click to use the travelbox + +An unconfigured travelnet box can be configured by anyone. If it is misconfigured, just dig it and place it anew. +All stations that have the same network name set and are owned by the same user connect to the same network. diff --git a/mods/z_remove/travelnet/config.lua b/mods/z_remove/travelnet/config.lua new file mode 100644 index 00000000..ec6037b9 --- /dev/null +++ b/mods/z_remove/travelnet/config.lua @@ -0,0 +1,80 @@ + +travelnet.MAX_STATIONS_PER_NETWORK = 24; + +-- set this to true if you want a simulated beam effect +travelnet.travelnet_effect_enabled = true; +-- set this to true if you want a sound to be played when the travelnet is used +travelnet.travelnet_sound_enabled = false; + +-- if you set this to false, travelnets cannot be created +-- (this may be useful if you want nothing but the elevators on your server) +travelnet.travelnet_enabled = false; +-- if you set travelnet.elevator_enabled to false, you will not be able to +-- craft, place or use elevators +travelnet.elevator_enabled = true; +-- if you set this to false, doors will be disabled +travelnet.doors_enabled = true; + +-- starts an abm which re-adds travelnet stations to networks in case the savefile got lost +travelnet.abm_enabled = false; + +-- change these if you want other receipes for travelnet or elevator +travelnet.travelnet_recipe = { + {"default:glass", "es:infinium_ingot", "default:glass", }, + {"default:glass", "es:emeraldblock", "default:glass", }, + {"default:glass", "es:infinium_ingot", "default:glass", } +} +travelnet.elevator_recipe = { + {"default:steel_ingot", "es:rubyblock", "default:steel_ingot", }, + {"default:steel_ingot", "", "default:steel_ingot", }, + {"default:steel_ingot", "default:glass", "default:steel_ingot", } +} + +-- if this function returns true, the player with the name player_name is +-- allowed to add a box to the network named network_name, which is owned +-- by the player owner_name; +-- if you want to allow *everybody* to attach stations to all nets, let the +-- function always return true; +-- if the function returns false, players with the travelnet_attach priv +-- can still add stations to that network + +travelnet.allow_attach = function( player_name, owner_name, network_name ) + return true; +end + + +-- if this returns true, a player named player_name can remove a travelnet station +-- from network_name (owned by owner_name) even though he is neither the owner nor +-- has the travelnet_remove priv +travelnet.allow_dig = function( player_name, owner_name, network_name ) + return false; +end + + +-- if this function returns false, then player player_name will not be allowed to use +-- the travelnet station_name_start on networ network_name owned by owner_name to travel to +-- the station station_name_target on the same network; +-- if this function returns true, the player will be transfered to the target station; +-- you can use this code to i.e. charge the player money for the transfer or to limit +-- usage of stations to players in the same fraction on PvP servers +travelnet.allow_travel = function( player_name, owner_name, network_name, station_name_start, station_name_target ) + + --minetest.chat_send_player( player_name, "Player "..tostring( player_name ).." tries to use station "..tostring( station_name_start ).. + -- " on network "..tostring( network_name ).." owned by "..tostring( owner_name ).." in order to travel to ".. + -- tostring( station_name_target ).."."); + + return true; +end +travelnet.allow_travel = function( player_name, owner_name, network_name, station_name_start, station_name_target ) + + --minetest.chat_send_player( player_name, "Player "..tostring( player_name ).." tries to use station "..tostring( station_name_start ).. + -- " on network "..tostring( network_name ).." owned by "..tostring( owner_name ).." in order to travel to ".. + -- tostring( station_name_target ).."."); + if( player_name ~= owner_name ) then + --minetest.chat_send_player( player_name, 'Only '..tostring( owner_name )..' may use this elevator. Build your own!'); + minetest.chat_send_player( player_name, 'Howdy! '..tostring( owner_name )..' Thanks you for traveling!'); + return true;--turn off other players + end + + return true; +end diff --git a/mods/z_remove/travelnet/doors.lua b/mods/z_remove/travelnet/doors.lua new file mode 100644 index 00000000..a45a9f68 --- /dev/null +++ b/mods/z_remove/travelnet/doors.lua @@ -0,0 +1,142 @@ +-- Doors that are especially useful for travelnet elevators but can also be used in other situations. +-- All doors (not only these here) in front of a travelnet or elevator are opened automaticly when a player arrives +-- and are closed when a player departs from the travelnet or elevator. +-- Autor: Sokomine + +minetest.register_node("travelnet:elevator_door_steel_open", { + description = "elevator door (open)", + drawtype = "nodebox", + -- top, bottom, side1, side2, inner, outer + tiles = {"default_stone.png"}, + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = true, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, + -- larger than one node but slightly smaller than a half node so that wallmounted torches pose no problem + node_box = { + type = "fixed", + fixed = { + {-0.90, -0.5, 0.4, -0.49, 1.5, 0.5}, + { 0.49, -0.5, 0.4, 0.9, 1.5, 0.5}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.9, -0.5, 0.4, 0.9, 1.5, 0.5}, + }, + }, + drop = "travelnet:elevator_door_steel_closed", + on_rightclick = function(pos, node, puncher) + minetest.add_node(pos, {name = "travelnet:elevator_door_steel_closed", param2 = node.param2}) + end, +}) + +minetest.register_node("travelnet:elevator_door_steel_closed", { + description = "elevator door (closed)", + drawtype = "nodebox", + -- top, bottom, side1, side2, inner, outer + tiles = {"default_stone.png"}, + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = true, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, 0.4, -0.01, 1.5, 0.5}, + { 0.01, -0.5, 0.4, 0.5, 1.5, 0.5}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, 0.4, 0.5, 1.5, 0.5}, + }, + }, + on_rightclick = function(pos, node, puncher) + minetest.add_node(pos, {name = "travelnet:elevator_door_steel_open", param2 = node.param2}) + end, +}) + + + + +minetest.register_node("travelnet:elevator_door_glass_open", { + description = "elevator door (open)", + drawtype = "nodebox", + -- top, bottom, side1, side2, inner, outer + tiles = {"travelnet_elevator_door_glass.png"}, + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = true, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, + -- larger than one node but slightly smaller than a half node so that wallmounted torches pose no problem + node_box = { + type = "fixed", + fixed = { + {-0.99, -0.5, 0.4, -0.49, 1.5, 0.5}, + { 0.49, -0.5, 0.4, 0.99, 1.5, 0.5}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.9, -0.5, 0.4, 0.9, 1.5, 0.5}, + }, + }, + drop = "travelnet:elevator_door_glass_closed", + on_rightclick = function(pos, node, puncher) + minetest.add_node(pos, {name = "travelnet:elevator_door_glass_closed", param2 = node.param2}) + end, +}) + +minetest.register_node("travelnet:elevator_door_glass_closed", { + description = "elevator door (closed)", + drawtype = "nodebox", + -- top, bottom, side1, side2, inner, outer + tiles = {"travelnet_elevator_door_glass.png"}, + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = true, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, 0.4, -0.01, 1.5, 0.5}, + { 0.01, -0.5, 0.4, 0.5, 1.5, 0.5}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, 0.4, 0.5, 1.5, 0.5}, + }, + }, + on_rightclick = function(pos, node, puncher) + minetest.add_node(pos, {name = "travelnet:elevator_door_glass_open", param2 = node.param2}) + end, +}) + +minetest.register_craft({ + output = "travelnet:elevator_door_glass_closed", + recipe = { + {"default:glass", "", "default:glass", }, + {"default:glass", "", "default:glass", }, + {"default:glass", "", "default:glass", } + } + }) + +minetest.register_craft({ + output = "travelnet:elevator_door_steel_closed", + recipe = { + {"default:steel_ingot", "", "default:steel_ingot", }, + {"default:steel_ingot", "", "default:steel_ingot", }, + {"default:steel_ingot", "", "default:steel_ingot", } + } + }) +-- local old_node = minetest.get_node( pos ); +-- minetest.add_node(pos, {name = "travelnet:elevator_door_glass_closed", param2 = old_node.param2}) + + + diff --git a/mods/z_remove/travelnet/elevator.lua b/mods/z_remove/travelnet/elevator.lua new file mode 100644 index 00000000..a407d33a --- /dev/null +++ b/mods/z_remove/travelnet/elevator.lua @@ -0,0 +1,112 @@ +-- This version of the travelnet box allows to move up or down only. +-- The network name is determined automaticly from the position (x/z coordinates). +-- >utor: Sokomine + +minetest.register_node("travelnet:elevator", { + description = "Elevator", + drawtype = "mesh", + mesh = "travelnet_elevator.obj", + sunlight_propagates = true, + paramtype = 'light', + paramtype2 = "facedir", + wield_scale = {x=0.6, y=0.6, z=0.6}, + + selection_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 } + }, + + collision_box = { + type = "fixed", + fixed = { + + { 0.48, -0.5,-0.5, 0.5, 0.5, 0.5}, + {-0.5 , -0.5, 0.48, 0.48, 0.5, 0.5}, + {-0.5, -0.5,-0.5 ,-0.48, 0.5, 0.5}, + + --groundplate to stand on + { -0.5,-0.5,-0.5,0.5,-0.48, 0.5}, + }, + }, + + tiles = { + "travelnet_elevator_front.png", + "travelnet_elevator_inside_controls.png", + "travelnet_elevator_sides_outside.png", + "travelnet_elevator_inside_ceiling.png", + "travelnet_elevator_inside_floor.png", + "default_steel_block.png" + }, + inventory_image = "travelnet_elevator_inv.png", + groups = {cracky=1,choppy=1,snappy=1}, + + light_source = 10, + + after_place_node = function(pos, placer, itemstack) + local meta = minetest.get_meta(pos); + meta:set_string("infotext", "Elevator (unconfigured)"); + meta:set_string("station_name", ""); + meta:set_string("station_network",""); + meta:set_string("owner", placer:get_player_name() ); + -- request initinal data + meta:set_string("formspec", + "size[12,10]".. + "field[0.3,5.6;6,0.7;station_name;Name of this station:;]".. +-- "field[0.3,6.6;6,0.7;station_network;Assign to Network:;]".. +-- "field[0.3,7.6;6,0.7;owner_name;(optional) owned by:;]".. + "button_exit[6.3,6.2;1.7,0.7;station_set;Store]" ); + + local p = {x=pos.x, y=pos.y+1, z=pos.z} + local p2 = minetest.dir_to_facedir(placer:get_look_dir()) + minetest.add_node(p, {name="travelnet:elevator_top", paramtype2="facedir", param2=p2}) + end, + + on_receive_fields = travelnet.on_receive_fields, + on_punch = function(pos, node, puncher) + travelnet.update_formspec(pos, puncher:get_player_name()) + end, + + can_dig = function( pos, player ) + return travelnet.can_dig( pos, player, 'elevator' ) + end, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + travelnet.remove_box( pos, oldnode, oldmetadata, digger ) + end, + + -- taken from VanessaEs homedecor fridge + on_place = function(itemstack, placer, pointed_thing) + local pos = pointed_thing.above; + local node = minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}); + -- leftover elevator_top nodes can be removed by placing a new elevator underneath + if( node ~= nil and node.name ~= "air" and node.name ~= 'travelnet:elevator_top') then + minetest.chat_send_player( placer:get_player_name(), 'Not enough vertical space to place the travelnet box!' ) + return; + end + return minetest.item_place(itemstack, placer, pointed_thing); + end, + + on_destruct = function(pos) + local p = {x=pos.x, y=pos.y+1, z=pos.z} + minetest.remove_node(p) + end +}) + +minetest.register_alias("travelnet:elevator_top", "air") + +--if( minetest.get_modpath("technic") ~= nil ) then +-- minetest.register_craft({ +-- output = "travelnet:elevator", +-- recipe = { +-- {"default:steel_ingot", "technic:motor", "default:steel_ingot", }, +-- {"default:steel_ingot", "technic:control_logic_unit", "default:steel_ingot", }, +-- {"default:steel_ingot", "moreores:copper_ingot", "default:steel_ingot", } +-- } +-- }) +--else + minetest.register_craft({ + output = "travelnet:elevator", + recipe = travelnet.elevator_recipe, + }) +--end + diff --git a/mods/z_remove/travelnet/init.lua b/mods/z_remove/travelnet/init.lua new file mode 100644 index 00000000..76562aef --- /dev/null +++ b/mods/z_remove/travelnet/init.lua @@ -0,0 +1,683 @@ + + +--[[ + Teleporter networks that allow players to choose a destination out of a list + Copyright (C) 2013 Sokomine + + 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 . + + Version: 2.2 (with optional abm for self-healing) + + Please configure this mod in config.lua + + Changelog: + 05.10.14 - Added an optional abm so that the travelnet network can heal itshelf in case of loss of the savefile. + If you want to use this, set + travelnet.enable_abm = true + in config.lua and edit the interval in the abm to suit your needs. + 19.11.13 - moved doors and travelnet definition into an extra file + - moved configuration to config.lua + 05.08.13 - fixed possible crash when the node in front of the travelnet is unknown + 26.06.13 - added inventory image for elevator (created by VanessaE) + 21.06.13 - bugfix: wielding an elevator while digging a door caused the elevator_top to be placed + - leftover floating elevator_top nodes can be removed by placing a new travelnet:elevator underneath them and removing that afterwards + - homedecor-doors are now opened and closed correctly as well + - removed nodes that are not intended for manual use from creative inventory + - improved naming of station levels for the elevator + 21.06.13 - elevator stations are sorted by height instead of date of creation as is the case with travelnet boxes + - elevator stations are named automaticly + 20.06.13 - doors can be opened and closed from inside the travelnet box/elevator + - the elevator can only move vertically; the network name is defined by its x and z coordinate + 13.06.13 - bugfix + - elevator added (written by kpoppel) and placed into extra file + - elevator doors added + - groups changed to avoid accidental dig/drop on dig of node beneath + - added new priv travelnet_remove for digging of boxes owned by other players + - only the owner of a box or players with the travelnet_remove priv can now dig it + - entering your own name as owner_name does no longer abort setup + 22.03.13 - added automatic detection if yaw can be set + - beam effect is disabled by default + 20.03.13 - added inventory image provided by VanessaE + - fixed bug that made it impossible to remove stations from the net + - if the station a player beamed to no longer exists, the station will be removed automaticly + - with the travelnet_attach priv, you can now attach your box to the nets of other players + - in newer versions of Minetest, the players yaw is set so that he/she looks out of the receiving box + - target list is now centered if there are less than 9 targets +--]] + + +minetest.register_privilege("travelnet_attach", { description = "allows to attach travelnet boxes to travelnets of other players", give_to_singleplayer = false}); +minetest.register_privilege("travelnet_remove", { description = "allows to dig travelnet boxes which belog to nets of other players", give_to_singleplayer = false}); + +travelnet = {}; + +travelnet.targets = {}; + + +-- read the configuration +dofile(minetest.get_modpath("travelnet").."/config.lua"); -- the normal, default travelnet + + + +-- TODO: save and restore ought to be library functions and not implemented in each individual mod! +-- called whenever a station is added or removed +travelnet.save_data = function() + + local data = minetest.serialize( travelnet.targets ); + local path = minetest.get_worldpath().."/mod_travelnet.data"; + + local file = io.open( path, "w" ); + if( file ) then + file:write( data ); + file:close(); + else + print("[Mod travelnet] Error: Savefile '"..tostring( path ).."' could not be written."); + end +end + + +travelnet.restore_data = function() + + local path = minetest.get_worldpath().."/mod_travelnet.data"; + + local file = io.open( path, "r" ); + if( file ) then + local data = file:read("*all"); + travelnet.targets = minetest.deserialize( data ); + file:close(); + else + print("[Mod travelnet] Error: Savefile '"..tostring( path ).."' not found."); + end +end + + + + +travelnet.update_formspec = function( pos, puncher_name ) + + local meta = minetest.get_meta(pos); + + local this_node = minetest.get_node( pos ); + local is_elevator = false; + + if( this_node ~= nil and this_node.name == 'travelnet:elevator' ) then + is_elevator = true; + end + + if( not( meta )) then + return; + end + + local owner_name = meta:get_string( "owner" ); + local station_name = meta:get_string( "station_name" ); + local station_network = meta:get_string( "station_network" ); + + if( not( owner_name ) + or not( station_name ) or station_network == '' + or not( station_network )) then + + + if( is_elevator == true ) then + travelnet.add_target( nil, nil, pos, puncher_name, meta, owner_name ); + return; + end + +-- minetest.chat_send_player(puncher_name, "DEBUG DATA: owner: "..(owner_name or "?").. +-- " station_name: "..(station_name or "?").. +-- " station_network: "..(station_network or "?").."."); +-- minetest.chat_send_player(puncher_name, "data: "..minetest.serialize( travelnet.targets )); + + + meta:set_string("infotext", "Travelnet-box (unconfigured)"); + meta:set_string("station_name", ""); + meta:set_string("station_network",""); + meta:set_string("owner", ""); + -- request initinal data + meta:set_string("formspec", + "size[12,10]".. + "field[0.3,7.6;9,0.9;station_name;Name of this station:;"..(station_name or "?").."]".. + "field[0.3,8.6;9,0.9;station_network;Assign to Network:;"..(station_network or "?").."]".. + "field[0.3,9.6;9,0.9;owner;Owned by:;"..(owner_name or "?").."]".. + "button_exit[6.3,8.2;1.7,0.7;station_set;Store]" ); + + minetest.chat_send_player(puncher_name, "Error: Update failed! Resetting this box on the travelnet."); + return; + end + + -- if the station got lost from the network for some reason (savefile corrupted?) then add it again + if( not( travelnet.targets[ owner_name ] ) + or not( travelnet.targets[ owner_name ][ station_network ] ) + or not( travelnet.targets[ owner_name ][ station_network ][ station_name ] )) then + + -- first one by this player? + if( not( travelnet.targets[ owner_name ] )) then + travelnet.targets[ owner_name ] = {}; + end + + -- first station on this network? + if( not( travelnet.targets[ owner_name ][ station_network ] )) then + travelnet.targets[ owner_name ][ station_network ] = {}; + end + + + local zeit = meta:get_int("timestamp"); + if( not( zeit) or zeit<100000 ) then + zeit = os.time(); + end + + -- add this station + travelnet.targets[ owner_name ][ station_network ][ station_name ] = {pos=pos, timestamp=zeit }; + + minetest.chat_send_player(owner_name, "Station '"..station_name.."' has been reattached to the network '"..station_network.."'."); + + end + + + -- add name of station + network + owner + update-button + local formspec = "size[12,10]".. + "label[3.3,0.0;Travelnet-Box:]".."label[6.3,0.0;Punch box to update target list.]".. + "label[0.3,0.4;Name of this station:]".."label[6.3,0.4;"..(station_name or "?").."]".. + "label[0.3,0.8;Assigned to Network:]" .."label[6.3,0.8;"..(station_network or "?").."]".. + "label[0.3,1.2;Owned by:]" .."label[6.3,1.2;"..(owner_name or "?").."]".. + "label[3.3,1.6;Click on target to travel there:]"; +-- "button_exit[5.3,0.3;8,0.8;do_update;Punch box to update destination list. Click on target to travel there.]".. + local x = 0; + local y = 0; + local i = 0; + + + -- collect all station names in a table + local stations = {}; + + for k,v in pairs( travelnet.targets[ owner_name ][ station_network ] ) do + table.insert( stations, k ); + end + -- minetest.chat_send_player(puncher_name, "stations: "..minetest.serialize( stations )); + + local ground_level = 1; + if( is_elevator ) then + table.sort( stations, function(a,b) return travelnet.targets[ owner_name ][ station_network ][ a ].pos.y > + travelnet.targets[ owner_name ][ station_network ][ b ].pos.y end); + -- find ground level + local vgl_timestamp = 999999999999; + for index,k in ipairs( stations ) do + if( travelnet.targets[ owner_name ][ station_network ][ k ].timestamp < vgl_timestamp ) then + vgl_timestamp = travelnet.targets[ owner_name ][ station_network ][ k ].timestamp; + ground_level = index; + end + end + for index,k in ipairs( stations ) do + if( index == ground_level ) then + travelnet.targets[ owner_name ][ station_network ][ k ].nr = 'G'; + else + travelnet.targets[ owner_name ][ station_network ][ k ].nr = tostring( ground_level - index ); + end + end + + else + -- sort the table according to the timestamp (=time the station was configured) + table.sort( stations, function(a,b) return travelnet.targets[ owner_name ][ station_network ][ a ].timestamp < + travelnet.targets[ owner_name ][ station_network ][ b ].timestamp end); + end + + -- if there are only 8 stations (plus this one), center them in the formspec + if( #stations < 10 ) then + x = 4; + end + + for index,k in ipairs( stations ) do + + -- check if there is an elevator door in front that needs to be opened + local open_door_cmd = false; + if( k==station_name ) then + open_door_cmd = true; + end + + if( k ~= station_name or open_door_cmd) then + i = i+1; + + -- new column + if( y==8 ) then + x = x+4; + y = 0; + end + + if( open_door_cmd ) then + formspec = formspec .."button_exit["..(x)..","..(y+2.5)..";1,0.5;open_door;<>]".. + "label["..(x+0.9)..","..(y+2.35)..";"..tostring( k ).."]"; + elseif( is_elevator ) then + formspec = formspec .."button_exit["..(x)..","..(y+2.5)..";1,0.5;target;"..tostring( travelnet.targets[ owner_name ][ station_network ][ k ].nr ).."]".. + "label["..(x+0.9)..","..(y+2.35)..";"..tostring( k ).."]"; + else + formspec = formspec .."button_exit["..(x)..","..(y+2.5)..";4,0.5;target;"..k.."]"; + end + +-- if( is_elevator ) then +-- formspec = formspec ..' ('..tostring( travelnet.targets[ owner_name ][ station_network ][ k ].pos.y )..'m)'; +-- end +-- formspec = formspec .. ']'; + + y = y+1; + --x = x+4; + end + end + + meta:set_string( "formspec", formspec ); + + meta:set_string( "infotext", "Station '"..tostring( station_name ).."' on travelnet '"..tostring( station_network ).. + "' (owned by "..tostring( owner_name )..") ready for usage. Right-click to travel, punch to update."); + + minetest.chat_send_player(puncher_name, "The target list of this box on the travelnet has been updated."); +end + + + +-- add a new target; meta is optional +travelnet.add_target = function( station_name, network_name, pos, player_name, meta, owner_name ) + + -- if it is an elevator, determine the network name through x and z coordinates + local this_node = minetest.get_node( pos ); + local is_elevator = false; + + if( this_node.name == 'travelnet:elevator' ) then +-- owner_name = '*'; -- the owner name is not relevant here + is_elevator = true; + network_name = tostring( pos.x )..','..tostring( pos.z ); + if( not( station_name ) or station_name == '' ) then + station_name = 'at '..tostring( pos.y )..'m'; + end + end + + if( station_name == "" or not(station_name )) then + minetest.chat_send_player(player_name, "Please provide a name for this station."); + return; + end + + if( network_name == "" or not( network_name )) then + minetest.chat_send_player(player_name, "Please provide the name of the network this station ought to be connected to."); + return; + end + + if( owner_name == nil or owner_name == '' or owner_name == player_name) then + owner_name = player_name; + + elseif( is_elevator ) then -- elevator networks + owner_name = player_name; + + elseif( not( travelnet.targets[ owner_name ] ) + or not( travelnet.targets[ owner_name ][ network_name ] )) then + + minetest.chat_send_player(player_name, "There is no network named "..tostring( network_name ).." owned by "..tostring( owner_name )..". Aborting."); + return; + + elseif( not( minetest.check_player_privs(player_name, {travelnet_attach=true})) + and not( travelnet.allow_attach( player_name, owner_name, network_name ))) then + + minetest.chat_send_player(player_name, "You do not have the travelnet_attach priv which is required to attach your box to the network of someone else. Aborting."); + return; + end + + -- first one by this player? + if( not( travelnet.targets[ owner_name ] )) then + travelnet.targets[ owner_name ] = {}; + end + + -- first station on this network? + if( not( travelnet.targets[ owner_name ][ network_name ] )) then + travelnet.targets[ owner_name ][ network_name ] = {}; + end + + -- lua doesn't allow efficient counting here + local anz = 0; + for k,v in pairs( travelnet.targets[ owner_name ][ network_name ] ) do + + if( k == station_name ) then + minetest.chat_send_player(player_name, "Error: A station named '"..station_name.."' already exists on this network. Please choose a diffrent name!"); + return; + end + + anz = anz + 1; + end + + -- we don't want too many stations in the same network because that would get confusing when displaying the targets + if( anz+1 > travelnet.MAX_STATIONS_PER_NETWORK ) then + minetest.chat_send_player(player_name, "Error: Network '"..network_name.."' already contains the maximum number (=" + ..(travelnet.MAX_STATIONS_PER_NETWORK)..") of allowed stations per network. Please choose a diffrent/new network name."); + return; + end + + -- add this station + travelnet.targets[ owner_name ][ network_name ][ station_name ] = {pos=pos, timestamp=os.time() }; + + -- do we have a new node to set up? (and are not just reading from a safefile?) + if( meta ) then + + minetest.chat_send_player(player_name, "Station '"..station_name.."' has been added to the network '" + ..network_name.."', which now consists of "..( anz+1 ).." station(s)."); + + meta:set_string( "station_name", station_name ); + meta:set_string( "station_network", network_name ); + meta:set_string( "owner", owner_name ); + meta:set_int( "timestamp", travelnet.targets[ owner_name ][ network_name ][ station_name ].timestamp); + + meta:set_string("formspec", + "size[12,10]".. + "field[0.3,0.6;6,0.7;station_name;Station:;".. meta:get_string("station_name").."]".. + "field[0.3,3.6;6,0.7;station_network;Network:;"..meta:get_string("station_network").."]" ); + + -- display a list of all stations that can be reached from here + travelnet.update_formspec( pos, player_name ); + + -- save the updated network data in a savefile over server restart + travelnet.save_data(); + end +end + + + +-- allow doors to open +travelnet.open_close_door = function( pos, player, mode ) + + local this_node = minetest.get_node( pos ); + local pos2 = {x=pos.x,y=pos.y,z=pos.z}; + + if( this_node.param2 == 0 ) then pos2 = {x=pos.x,y=pos.y,z=(pos.z-1)}; + elseif( this_node.param2 == 1 ) then pos2 = {x=(pos.x-1),y=pos.y,z=pos.z}; + elseif( this_node.param2 == 2 ) then pos2 = {x=pos.x,y=pos.y,z=(pos.z+1)}; + elseif( this_node.param2 == 3 ) then pos2 = {x=(pos.x+1),y=pos.y,z=pos.z}; + end + + local door_node = minetest.get_node( pos2 ); + if( door_node ~= nil and door_node.name ~= 'ignore' and door_node.name ~= 'air' and minetest.registered_nodes[ door_node.name ] ~= nil and minetest.registered_nodes[ door_node.name ].on_rightclick ~= nil) then + + -- at least for homedecor, same facedir would mean "door closed" + + -- do not close the elevator door if it is already closed + if( mode==1 and ( door_node.name == 'travelnet:elevator_door_glass_closed' + or door_node.name == 'travelnet:elevator_door_steel_closed' + -- handle doors that change their facedir + or ( door_node.param2 == this_node.param2 + and door_node.name ~= 'travelnet:elevator_door_glass_open' + and door_node.name ~= 'travelnet:elevator_door_steel_open'))) then + return; + end + -- do not open the doors if they are already open (works only on elevator-doors; not on doors in general) + if( mode==2 and ( door_node.name == 'travelnet:elevator_door_glass_open' + or door_node.name == 'travelnet:elevator_door_steel_open' + -- handle doors that change their facedir + or ( door_node.param2 ~= this_node.param2 + and door_node.name ~= 'travelnet:elevator_door_glass_closed' + and door_node.name ~= 'travelnet:elevator_door_steel_closed'))) then + return; + end + + if( mode==2 ) then + minetest.after( 1, minetest.registered_nodes[ door_node.name ].on_rightclick, pos2, door_node, player ); + else + minetest.registered_nodes[ door_node.name ].on_rightclick(pos2, door_node, player); + end + end +end + + +travelnet.on_receive_fields = function(pos, formname, fields, player) + local meta = minetest.get_meta(pos); + + local name = player:get_player_name(); + + -- if the box has not been configured yet + if( meta:get_string("station_network")=="" ) then + + travelnet.add_target( fields.station_name, fields.station_network, pos, name, meta, fields.owner_name ); + return; + end + + if( fields.open_door ) then + travelnet.open_close_door( pos, player, 0 ); + return; + end + + + if( not( fields.target )) then + minetest.chat_send_player(name, "Please click on the target you want to travel to."); + return; + end + + + -- if there is something wrong with the data + local owner_name = meta:get_string( "owner" ); + local station_name = meta:get_string( "station_name" ); + local station_network = meta:get_string( "station_network" ); + + if( not( owner_name ) + or not( station_name ) + or not( station_network ) + or not( travelnet.targets[ owner_name ] ) + or not( travelnet.targets[ owner_name ][ station_network ] )) then + + + if( owner_name + and station_name + and station_network ) then + travelnet.add_target( station_name, station_network, pos, owner_name, meta, owner_name ); + else + minetest.chat_send_player(name, "Error: There is something wrong with the configuration of this station. ".. + " DEBUG DATA: owner: "..( owner_name or "?").. + " station_name: "..(station_name or "?").. + " station_network: "..(station_network or "?").."."); + return + end + end + + local this_node = minetest.get_node( pos ); + if( this_node ~= nil and this_node.name == 'travelnet:elevator' ) then + for k,v in pairs( travelnet.targets[ owner_name ][ station_network ] ) do + if( travelnet.targets[ owner_name ][ station_network ][ k ].nr --..' ('..tostring( travelnet.targets[ owner_name ][ station_network ][ k ].pos.y )..'m)' + == fields.target) then + fields.target = k; + end + end + end + + + -- if the target station is gone + if( not( travelnet.targets[ owner_name ][ station_network ][ fields.target ] )) then + + minetest.chat_send_player(name, "Station '"..( fields.target or "?").." does not exist (anymore?) on this network."); + travelnet.update_formspec( pos, name ); + return; + end + + + if( not( travelnet.allow_travel( name, owner_name, station_network, station_name, fields.target ))) then + return; + end + minetest.chat_send_player(name, "Initiating transfer to station '"..( fields.target or "?").."'.'"); + + + + if( travelnet.travelnet_sound_enabled ) then + minetest.sound_play("128590_7037-lq.mp3", {pos = pos, gain = 1.0, max_hear_distance = 10,}) + end + if( travelnet.travelnet_effect_enabled ) then + minetest.add_entity( {x=pos.x,y=pos.y+0.5,z=pos.z}, "travelnet:effect"); -- it self-destructs after 20 turns + end + + -- close the doors at the sending station + travelnet.open_close_door( pos, player, 1 ); + + -- transport the player to the target location + local target_pos = travelnet.targets[ owner_name ][ station_network ][ fields.target ].pos; + player:moveto( target_pos, false); + + if( travelnet.travelnet_sound_enabled ) then + minetest.sound_play("travelnet_travel.wav", {pos = target_pos, gain = 1.0, max_hear_distance = 10,}) + end + if( travelnet.travelnet_effect_enabled ) then + minetest.add_entity( {x=target_pos.x,y=target_pos.y+0.5,z=target_pos.z}, "travelnet:effect"); -- it self-destructs after 20 turns + end + + + -- check if the box has at the other end has been removed. + local node2 = minetest.get_node( target_pos ); + if( node2 ~= nil and node2.name ~= 'ignore' and node2.name ~= 'travelnet:travelnet' and node2.name ~= 'travelnet:elevator') then + + -- provide information necessary to identify the removed box + local oldmetadata = { fields = { owner = owner_name, + station_name = fields.target, + station_network = station_network }}; + + travelnet.remove_box( target_pos, nil, oldmetadata, player ); + + -- do this only on servers where the function exists + elseif( player.set_look_yaw ) then + + -- rotate the player so that he/she can walk straight out of the box + local yaw = 0; + local param2 = node2.param2; + if( param2==0 ) then + yaw = 180; + elseif( param2==1 ) then + yaw = 90; + elseif( param2==2 ) then + yaw = 0; + elseif( param2==3 ) then + yaw = 270; + end + + player:set_look_yaw( math.rad( yaw )); -- this is only supported in recent versions of MT + player:set_look_pitch( math.rad( 0 )); -- this is only supported in recent versions of MT + end + + travelnet.open_close_door( target_pos, player, 2 ); +end + + +travelnet.remove_box = function( pos, oldnode, oldmetadata, digger ) + + if( not( oldmetadata ) or oldmetadata=="nil" or not(oldmetadata.fields)) then + minetest.chat_send_player( digger:get_player_name(), "Error: Could not find information about the station that is to be removed."); + return; + end + + local owner_name = oldmetadata.fields[ "owner" ]; + local station_name = oldmetadata.fields[ "station_name" ]; + local station_network = oldmetadata.fields[ "station_network" ]; + + -- station is not known? then just remove it + if( not( owner_name ) + or not( station_name ) + or not( station_network ) + or not( travelnet.targets[ owner_name ] ) + or not( travelnet.targets[ owner_name ][ station_network ] )) then + + minetest.chat_send_player( digger:get_player_name(), "Error: Could not find the station that is to be removed."); + return; + end + + travelnet.targets[ owner_name ][ station_network ][ station_name ] = nil; + + -- inform the owner + minetest.chat_send_player( owner_name, "Station '"..station_name.."' has been REMOVED from the network '"..station_network.."'."); + if( digger ~= nil and owner_name ~= digger:get_player_name() ) then + minetest.chat_send_player( digger:get_player_name(), "Station '"..station_name.."' has been REMOVED from the network '"..station_network.."'."); + end + + -- save the updated network data in a savefile over server restart + travelnet.save_data(); +end + + + +travelnet.can_dig = function( pos, player, description ) + + if( not( player )) then + return false; + end + local name = player:get_player_name(); + + -- players with that priv can dig regardless of owner + if( minetest.check_player_privs(name, {travelnet_remove=true}) + or travelnet.allow_dig( player_name, owner_name, network_name )) then + return true; + end + + local meta = minetest.get_meta( pos ); + local owner = meta:get_string('owner'); + + if( not( meta ) or not( owner) or owner=='') then + minetest.chat_send_player(name, "This "..description.." has not been configured yet. Please set it up first to claim it. Afterwards you can remove it because you are then the owner."); + return false; + + elseif( owner ~= name ) then + minetest.chat_send_player(name, "This "..description.." belongs to "..tostring( meta:get_string('owner'))..". You can't remove it."); + return false; + end + return true; +end + + + + + +if( travelnet.travelnet_effect_enabled ) then + minetest.register_entity( 'travelnet:effect', { + + hp_max = 1, + physical = false, + weight = 5, + collisionbox = {-0.4,-0.5,-0.4, 0.4,1.5,0.4}, + visual = "upright_sprite", + visual_size = {x=1, y=2}, +-- mesh = "model", + textures = { "travelnet_flash.png" }, -- number of required textures depends on visual +-- colors = {}, -- number of required colors depends on visual + spritediv = {x=1, y=1}, + initial_sprite_basepos = {x=0, y=0}, + is_visible = true, + makes_footstep_sound = false, + automatic_rotate = true, + + anz_rotations = 0, + + on_step = function( self, dtime ) + -- this is supposed to be more flickering than smooth animation + self.object:setyaw( self.object:getyaw()+1); + self.anz_rotations = self.anz_rotations + 1; + -- eventually self-destruct + if( self.anz_rotations > 15 ) then + self.object:remove(); + end + end + }) +end + + +if( travelnet.travelnet_enabled ) then + dofile(minetest.get_modpath("travelnet").."/travelnet.lua"); -- the travelnet node definition +end +if( travelnet.elevator_enabled ) then + dofile(minetest.get_modpath("travelnet").."/elevator.lua"); -- allows up/down transfers only +end +if( travelnet.doors_enabled ) then + dofile(minetest.get_modpath("travelnet").."/doors.lua"); -- doors that open and close automaticly when the travelnet or elevator is used +end + +if( travelnet.abm_enabled ) then + dofile(minetest.get_modpath("travelnet").."/restore_network_via_abm.lua"); -- restore travelnet data when players pass by broken networks +end + +-- upon server start, read the savefile +travelnet.restore_data(); + diff --git a/mods/z_remove/travelnet/models/travelnet.obj b/mods/z_remove/travelnet/models/travelnet.obj new file mode 100644 index 00000000..50e5afd7 --- /dev/null +++ b/mods/z_remove/travelnet/models/travelnet.obj @@ -0,0 +1,63 @@ +# Blender v2.73 (sub 0) OBJ File: 'travelnet.blend' +# www.blender.org +o Cylinder +v -0.499016 -0.499034 0.499022 +v -0.499016 -0.499034 -0.498989 +v 0.499035 -0.499034 -0.498989 +v 0.499035 -0.499034 0.499022 +v -0.499016 1.498990 0.499022 +v -0.499016 1.498990 -0.498989 +v 0.499035 1.498990 -0.498989 +v 0.499035 1.498990 0.499022 +v 0.437500 -0.437500 0.437500 +v -0.499016 1.437500 -0.498989 +v 0.499035 1.437500 -0.498989 +v -0.437500 -0.437500 0.437500 +v 0.437500 1.437500 0.437500 +v -0.499016 -0.437500 -0.498989 +v 0.499035 -0.437500 -0.498989 +v -0.437500 1.437500 0.437500 +v -0.437500 -0.437500 -0.498989 +v 0.437500 -0.437500 -0.498989 +v -0.437500 1.437500 -0.498989 +v 0.437500 1.437500 -0.498989 +vt 0.000000 0.968750 +vt 1.000000 0.968750 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.062500 0.031250 +vt 0.062500 0.968750 +vt 0.000000 0.031250 +vt 0.937500 0.031250 +vt 1.000000 0.031250 +vt 0.937500 0.968750 +vt 1.000000 -0.000000 +vt 0.000000 -0.000000 +vt 0.062500 -0.000000 +vt 0.937500 -0.000000 +vt 0.937500 0.937500 +vt 0.062500 0.937500 +vt 0.062500 1.000000 +vt 0.062500 0.062500 +vt 0.937500 0.062500 +vt 0.937500 1.000000 +g Cylinder_Cylinder_front +s off +f 11/1 10/2 6/3 7/4 +f 18/5 20/6 11/1 15/7 +f 17/8 14/9 10/2 19/10 +f 13/6 9/5 12/8 16/10 +f 2/11 14/9 15/7 3/12 +g Cylinder_Cylinder_back +f 8/4 5/3 1/11 4/12 +g Cylinder_Cylinder_sides +f 18/7 9/8 13/10 20/1 +f 17/7 19/1 16/10 12/8 +f 8/3 4/11 3/12 7/4 +f 6/4 2/12 1/11 5/3 +g Cylinder_Cylinder_top +f 5/12 8/11 7/3 6/4 +f 19/13 20/14 13/15 16/16 +g Cylinder_Cylinder_bottom +f 17/17 12/18 9/19 18/20 +f 2/12 3/11 4/3 1/4 diff --git a/mods/z_remove/travelnet/models/travelnet_elevator.obj b/mods/z_remove/travelnet/models/travelnet_elevator.obj new file mode 100644 index 00000000..cc006e21 --- /dev/null +++ b/mods/z_remove/travelnet/models/travelnet_elevator.obj @@ -0,0 +1,64 @@ +# Blender v2.73 (sub 0) OBJ File: 'travelnet_elevator.blend' +# www.blender.org +o Cylinder +v -0.499016 -0.499034 0.499022 +v -0.499016 -0.499034 -0.498989 +v 0.499035 -0.499034 -0.498989 +v 0.499035 -0.499034 0.499022 +v -0.499016 1.498990 0.499022 +v -0.499016 1.498990 -0.498989 +v 0.499035 1.498990 -0.498989 +v 0.499035 1.498990 0.499022 +v 0.437500 -0.437500 0.437500 +v -0.499016 1.437500 -0.498989 +v 0.499035 1.437500 -0.498989 +v -0.437500 -0.437500 0.437500 +v 0.437500 1.437500 0.437500 +v -0.499016 -0.437500 -0.498989 +v 0.499035 -0.437500 -0.498989 +v -0.437500 1.437500 0.437500 +v -0.437500 -0.437500 -0.498989 +v 0.437500 -0.437500 -0.498989 +v -0.437500 1.437500 -0.498989 +v 0.437500 1.437500 -0.498989 +vt 0.000000 0.968750 +vt 1.000000 0.968750 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.062500 0.031250 +vt 0.062500 0.968750 +vt 0.000000 0.031250 +vt 0.937500 0.031250 +vt 1.000000 0.031250 +vt 0.937500 0.968750 +vt 1.000000 -0.000000 +vt 0.000000 -0.000000 +vt 0.062500 -0.000000 +vt 0.937500 -0.000000 +vt 0.937500 0.937500 +vt 0.062500 0.937500 +vt 0.062500 1.000000 +vt 0.062500 0.062500 +vt 0.937500 0.062500 +vt 0.937500 1.000000 +g Cylinder_Cylinder_front +s off +f 11/1 10/2 6/3 7/4 +f 18/5 20/6 11/1 15/7 +f 17/8 14/9 10/2 19/10 +f 13/6 9/5 12/8 16/10 +f 2/11 14/9 15/7 3/12 +f 17/7 19/1 16/10 12/8 +g Cylinder_Cylinder_controls +f 18/7 9/8 13/10 20/1 +g Cylinder_Cylinder_outside +f 8/3 4/11 3/12 7/4 +f 6/4 2/12 1/11 5/3 +f 8/4 5/3 1/11 4/12 +g Cylinder_Cylinder_ceiling +f 19/13 20/14 13/15 16/16 +g Cylinder_Cylinder_floor +f 17/17 12/18 9/19 18/20 +g Cylinder_Cylinder_top-bottom +f 5/12 8/11 7/3 6/4 +f 2/12 3/11 4/3 1/4 diff --git a/mods/z_remove/travelnet/restore_network_via_abm.lua b/mods/z_remove/travelnet/restore_network_via_abm.lua new file mode 100644 index 00000000..3bd1ddab --- /dev/null +++ b/mods/z_remove/travelnet/restore_network_via_abm.lua @@ -0,0 +1,24 @@ + +minetest.register_abm({ + nodenames = {"travelnet:travelnet"}, + interval = 20, + chance = 1, + action = function(pos, node) + local meta = minetest.get_meta( pos ); + + local owner_name = meta:get_string( "owner" ); + local station_name = meta:get_string( "station_name" ); + local station_network = meta:get_string( "station_network" ); + + if( owner_name and station_name and station_network + and ( not( travelnet.targets ) + or not( travelnet.targets[ owner_name ] ) + or not( travelnet.targets[ owner_name ][ station_network ] ) + or not( travelnet.targets[ owner_name ][ station_network ][ station_name ] ))) then + + travelnet.add_target( station_name, station_network, pos, owner_name, meta, owner_name ); + print( 'TRAVELNET: re-adding '..tostring( station_name )..' to '..tostring( station_network )..' owned by '..tostring( owner_name )); + end + end +}) + diff --git a/mods/z_remove/travelnet/textures/travelnet_elevator_door_glass.png b/mods/z_remove/travelnet/textures/travelnet_elevator_door_glass.png new file mode 100644 index 0000000000000000000000000000000000000000..ae775c4fdbf0b91443a11346e6bd8085d9c24b32 GIT binary patch literal 952 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl4nEnR%gt#tSa&p;{b1RpfT(RuT zsugD!FTS#9(bXl3udH2rYwOm#J9gaLwd?+Y1CNg!d3@~H(=%sYT)g<|`t>(=?!3Ey z|HH$FAD=$`^!oMJj~{=2{rda+_g_DL{Q33k@1H;a{{8z8v}hEJhQMGB0md&g=L6lx zSQ6wH%;50sMjD8d?NMQuIzW&c$v5@ zuIt!}1BFaHT^vIsE+-3!q%bhDxK3#hXi;qnIC!|hrSa+~XN|-~ysA0}m=ixLgnUSf h(B@fKabhzo!%;VO!6)DS<$(GbJYD@<);T3K0RSU4dy)VE literal 0 HcmV?d00001 diff --git a/mods/z_remove/travelnet/textures/travelnet_elevator_front.png b/mods/z_remove/travelnet/textures/travelnet_elevator_front.png new file mode 100644 index 0000000000000000000000000000000000000000..60ec49ea53225f3181e07b902ea8adaa05a0bf9e GIT binary patch literal 756 zcmVEW0uE|J zu91-V#OTcV&pH1Q*VotP{{EgQiU`AyFbsR&XJ==uRx6ZJ#Bq#Ls(YWFo{*1^kKEne zaeI5qXf(ogT~1F=Da(>9%P5M1vMjM}o5f;*<2YPgTo42S05Xaq=JPoZ4-W_-&{`ve z0O)u!nc(|=@Bj1jGf9#(0bJLmsw#vKSe8Xy*BE04*|u#iFE5d;&W{Ie+r}6($hK{B zb#>JQ&{~t{Ia10l6JyLEJB~vT1Xy7h;y4aKcY`tJOP^$+8R?$1#)1grX>rQc{*>PxEJ7RTbOq7O9lN zaU2$l1yxn`=3t1|>osLrVkxEmlU`ldU-EvxCyryRIF5OHd+T)7b=}=K#7UB%lxidd zLBP$;&CxYbN;Mg@2U?A7+lKh{^|i@hxm>bdue%9r4b%4hGftAEse$kNxUSnP*2lho z#-8U91VQ5k*L9Dc1JCn_qNuTRJKx95fs~Rk44VMw=jUB}ezXSD>GZG!E9T5IAsZp@UXDL`-keZ{NQ3eWSJ0K44|*LAx-w+Dw<2yxg4 zd7d9#gFMe0H~#(S@BB2k*nA%$5bt(1@P3Oi25mGLdfBAuKdirxkbnL08$W;Z8CfN| zt}%7v_quw&%@~Ysf|%N1jK&y9jpmnMM@<)uKI3(pBM@wpgzV5E(Hq#!Ax2C_rA3+ zG$b;aJbx@W5KdIY$i#o#(-gHNCSp?y*_w%#=v*R_34*X@RZ%Woj!guSg>22d9ieNs zv0*M1-8oX<(9n|#ZNpW=x+87j&1mBeL$Cie^hAB*jXR9>MFUeew#7;+Y7*~0j0{c9 q4dlYIrlh`l_mM{rUUa11b^QPoXnPW_0{(3P0000+6vUX9FiK2)&j+^)P z_7>~r=7!75OD--ha9tPIb@4ope!tIdx5F?DvMj^4Z9LDT*Xt36A$NCo09audGM~@6 zzP?5Xfl>+~1VF=+$%M&d()zEIVzb#)0nX0OkWwOqz%UHTvP5g$$(Cg?o6WF-Ai!~) z)!!QWL5NkS} zvfJ(6+=Jn8i0}ItNs{2YZj(VuN&R%OQi?Q9v7#uVCW6p`mSh!4Pf5R)dOQi`%HU*tT`iQ~9Z;QKx&gZK3NYx+HxJkMY4 z!G6Cdj^j$fcDrS{lq?pXuv!HurO;Y8HNV7JmQ@NCiv?0jzW!#85CS1YYwopijyXvZ zqA0=`kH-{6(aibdhIO%Nns}a9dBO8M@;vXX`IzgyV1;3b>$PZ!&^jqm$a04XI84-bvh z`sw2FcuW|E7}M#rnSDL~`pR~(VHnT*AWhRZ--Dtkp7%kTrf=@Sa=9dmqRLEJmI1W( z-)k(Te0F1+ri@0TX3q7&E?zE|RWIt5_SPOaj#DZ4^VgpUCt&>3MK*(3#7VY1q0C^6uVXv1oov)bnD_9eglwIVMq_WM1HIObnemlzyIp>UP}0000< KMNUMnLSTYY2%bm) literal 0 HcmV?d00001 diff --git a/mods/z_remove/travelnet/textures/travelnet_elevator_inside_floor.png b/mods/z_remove/travelnet/textures/travelnet_elevator_inside_floor.png new file mode 100644 index 0000000000000000000000000000000000000000..7874bac0a492f65aab4e68f1365da87940c46473 GIT binary patch literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHV5AX?b-4n0BD?)RdpVGN9+yDRn xHzk$514;>bx;Tb#Tu)ADVPZ?wNRS8+WJt>6WQ;ZF^asi^c)I$ztaD0e0stP*8?gWY literal 0 HcmV?d00001 diff --git a/mods/z_remove/travelnet/textures/travelnet_elevator_inv.png b/mods/z_remove/travelnet/textures/travelnet_elevator_inv.png new file mode 100644 index 0000000000000000000000000000000000000000..a390d759735c5c2ad025e80c0edeac54e58a793f GIT binary patch literal 4946 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 Q1poj507*qoM6N<$g3Q2C#sB~S literal 0 HcmV?d00001 diff --git a/mods/z_remove/travelnet/textures/travelnet_elevator_sides_outside.png b/mods/z_remove/travelnet/textures/travelnet_elevator_sides_outside.png new file mode 100644 index 0000000000000000000000000000000000000000..82c0a03eb7dd056ec0fc475bfe7bb0402085dd5f GIT binary patch literal 347 zcmV-h0i^zkP){O;qEPR;dU0X<>&K?uZg)5w z%uH2Pb%MoWal73BxI5l)xm@UYJf6?zl#+rgwZ|Rb?}4nkJ=` zQkuKnb|9n1kmYH*n|dLICYyVv^w zfV-~yPQ!A!tk`Z;u(4000F(Nkls|BSgQ5V@oEZrvF6%kS(1WQ5Gl^20GR)iD?Mh0ez zFDMbBE32y;=&UcZGw8g(&z$$Ci?h8v@bG-UJU@Q$?Mug=nQ{9`^v1eCZq)Yv>xTB+5J9c2a+ zA5j^jP^E#bCd&sb?l1my{_ylKw$aWYrPO@>@pm@+YPDL2LwY$i@IQQLnL{NeFEX@H z{6U^lYCrUohvetap9d$-og2Eq_$^F)%;X^B;|w4}W0KMmt=rhCPEIawM6A~6W)DC7 zu!yj;vNUmxxKg?K_QH(Yiy}~%grWoI5Y@hMDzdlt-DalewUVrQN<(ns_zTCC^ z{Qc77=3|}>#40%o2Pb!T7{9@zi@gmA|!~2S^PTqX7b0>GBe-srHv|m4YEF( zbvF0;c$5$Jc)QK(!_4KdKpf>GI;(uQuSlavWtZ|Ah2t~|wCAYKFgVH(29afuEiV^Z zyqCmFxQsgbt5l9tMtO(I=NTBGf0J@Q1HXFgvAhrwS_1=9I9w7#Te5*YMk)*im3fLa zvOU^$4hGq+vYD~`#anM(%=JdKgq%XYOEK&5(gzfeQrIK*DXmc|QL0jGQQRWW;VlX$ zDI%LD?^5`LLYKTmR-#a%aEt=o;*M;f;A(Z;OgV>>VW3$O*4m^UR=!U=%+nQ+91}5F``Kf6NoaAh`N;eIh=WYw$GV1U->BOM~4oYBXs*{ zqf?^2O{d%Ib^3eX*gl}!btVw3cd~7|g`VQH-=tCP;pV%v3N)`?;|sKIrcvg@7XRp2 zd@>pROE#R6XO@;42imPuIxV_w)NiC-rk?j!xjx>TjRRt(kC(cppLp$+SKiCu>r+!v zHaAM)#DVRoiv#S}*`H<)`&;Z|e^=VWddBK4XU`sF5mDr4M>zNn@7|NC&GhT+FSAqW zspsw9ld+AxV5^^Q#sgaI`;U=69c~=#^Xv$%#w6P-Y+-BQTD_)9J8NuRURl{e zH|J5s+^fw_=TD`=!P&0Um*-@=9cnkxLTb@0_Ac10i5*tkYik$UY4Tp_&5IYEJawwb z!gSNoJ4#IAP@D0*r$}j;W`T{i)=I8X7*jot7w}?s^3*A4{qp>87uIzzV-ZU^%UE7z zb(obgR!X+F$5hWmJpDc1`w>svl-`dp+q0cgXK(d}^?~uvmB@#wqP*AJiAI^NZ3hP< z%I6aI@aP<0{bB0%WU0v2>%z>B#opPZ@{H8{Cw=)gsoL{}jV5cI`roF@{r7$Yud(^G zjR+A-<%l>J@$zcK-y@=ZA>z&Z)*|lOkGN|s;>_iU&+IQOj5j0tBVsb*(m+I{yZ|QK zc$KS{;<4Ud#5=O*=S06nfmC33tMxuv%8<7yGFg?X45J49^bR@pBE!yEaKG@ t5wBI2dsf~b5tVE9XJKLSzjpth_%}#HoqCq5ogM%H002ovPDHLkV1maf<1qjL literal 0 HcmV?d00001 diff --git a/mods/z_remove/travelnet/textures/travelnet_inv.png b/mods/z_remove/travelnet/textures/travelnet_inv.png new file mode 100644 index 0000000000000000000000000000000000000000..6f7df2215457527e9f445e6d3c0ef6ef2196c17e GIT binary patch literal 5680 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 Wwy+WW%8lCq0000+(HR0u76!g z0KpIS-WR^(IE(cn48!@)c^t<=h{a+NMUhgTK@dE@_y}C~0A4)1%ivZ0 z{`UPHKCBQ`URrC6E6;OE01*TMuv{+9z_#rgq-l!AaU3&nUAG3+qu1-1!G6ETI)cOb zlswO?fCO-GwQB}p7&apO<>uzb43tvUM_pFiw#^{RvIaQN>2%CMYkgNBpmmD)*qY5| zs76_LyPX+~MkC}Av}w27X5jmNBSJ|ShGsCI&vB1^*rD<>dk{i2M#JWCIG8~cMfb`& z7!1r{wOUmv2>^@rdTj<}S>8JjWm%fRcDqF%&x3cqaZwaChHrl!6h%SN*mRO4X0Ti? zX&r%s5W)f4W<-@I3F!*SATMR8lDw z$MJMJ?RLAK=Ve(Y<>pD7(^WaJKMXFw0;`USq{3 literal 0 HcmV?d00001 diff --git a/mods/z_remove/travelnet/textures/travelnet_travelnet_front.png b/mods/z_remove/travelnet/textures/travelnet_travelnet_front.png new file mode 100644 index 0000000000000000000000000000000000000000..2b0c3a2c6fc687a82d12f1ea3da6756fb75d78c5 GIT binary patch literal 904 zcmV;319$w1P)|b(^{;>Z!RhHK|8ca|d7l64Qvr83 zo**Cu4<$q}1pyi~c*vj)jSbUGNwp@JOL0-gs63Z)bt zKxnNIj7B3YbRdEasK9`O761iN6kz~Fp67VNFr)?fBC7)d2^0{3B#z^zf&!2@=Ma4H z?9GO|Pd@yCDPKK%+gf{a@0^mNC{mU^7zTp@Q-UA>%Cck%p2=ilt;In^9LGe<3WD3O z-sU$>?w#WxgbHe+C<3UUMP1ixkidIS4IW~cfrXII-ua0(c$#)!pmjVR&xc(BFoP*b za8N>kwRR;90(!k(GbRG?Jo*0aY&Mfp8e<;a|AiLT+O-}W($j21_T74Ktcp17>GcUWf^iA;JCiN zo>O6=nt!9_{35Z|zQEGn-W~}AG*9f}wjqI%s;Y2nbI7tRH6Z!?+c$&|WmyJ6@c8}b zOrZqrX%Uv8pP9xpr;^OGs@dlSv~+V@z3=WmyU#s0qUm4-s9$*NXX{qCdG0NmhpJ}a>>d4b84s;0;zfU z-p@#wk)|nwH7(68akelEzcLsU#0&-l;$?tem_o2nhg#T&pQqU0-(Opx7NgPV&-~%h z(UA}$j^m4q3-yXhl0+#r91gqPZZ;h5tO9Bd)knMpzd}S+u-jVfG2D_cLqb0LaQyQ~Bo9st1u@H&02s!JrKiXDg@Y}g>NK#{np!lWrAwu9r- z#T;9SLLzsh$S3y9uQ~txGh^NV+Skm06xaj`U}l~^kN^&1uK7*O`%O@2Km!}V2QW3~ z4M3TI0GRffi`MEa0a5$_= ztMG-y(P&f~z;PVWM-GbVoYL0V<>h5n72o%T0~-{sWYFn!Rt8^OTi9LvsyL1-hx7Au zeROnWt>r+K8CU`^9*--Bb-@6G!2p7JDd+z;4?NGS#=Ihwu6liatqsuac11{ODWn3F zQndl{JeS4dfx?!0Zf|d|4Z6Czs;ct#_6D|G!6Ba;Q!6ZvW8Lj`D`H!%mPmP8wzCJ8 zWv#pO!pAgCVO&mSTlzZcN1U9T=w`D?qtU>1U9{H3aZC^dL{Y@!<0HLZPv)l?gVz1e zeT{E6@zg9)%Pi2DS*~THdUIz-zB`0-E8P%U_Bys%`{n!0JRK@2{{uz7>o!k^G%ElA N002ovPDHLkV1j#BRn7na literal 0 HcmV?d00001 diff --git a/mods/z_remove/travelnet/travelnet.lua b/mods/z_remove/travelnet/travelnet.lua new file mode 100644 index 00000000..11dd4b48 --- /dev/null +++ b/mods/z_remove/travelnet/travelnet.lua @@ -0,0 +1,100 @@ +-- contains the node definition for a general travelnet that can be used by anyone +-- further travelnets can only be installed by the owner or by people with the travelnet_attach priv +-- digging of such a travelnet is limited to the owner and to people with the travelnet_remove priv (useful for admins to clean up) +-- (this can be overrided in config.lua) +-- Autor: Sokomine +minetest.register_node("travelnet:travelnet", { + + description = "Travelnet box", + + drawtype = "mesh", + mesh = "travelnet.obj", + sunlight_propagates = true, + paramtype = 'light', + paramtype2 = "facedir", + wield_scale = {x=0.6, y=0.6, z=0.6}, + selection_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 } + }, + + collision_box = { + type = "fixed", + fixed = { + + { 0.45, -0.5,-0.5, 0.5, 1.45, 0.5}, + {-0.5 , -0.5, 0.45, 0.45, 1.45, 0.5}, + {-0.5, -0.5,-0.5 ,-0.45, 1.45, 0.5}, + + --groundplate to stand on + { -0.5,-0.5,-0.5,0.5,-0.45, 0.5}, + --roof + { -0.5, 1.45,-0.5,0.5, 1.5, 0.5}, + + -- control panel + -- { -0.2, 0.6, 0.3, 0.2, 1.1, 0.5}, + + }, + }, + + tiles = { + "travelnet_travelnet_front.png", -- backward view + "travelnet_travelnet_back.png", -- front view + "travelnet_travelnet_side.png", -- sides :) + "default_steel_block.png", -- view from top + "default_clay.png", -- view from bottom + }, + inventory_image = "travelnet_inv.png", + + groups = {cracky=1,choppy=1,snappy=1}, + + light_source = 10, + + after_place_node = function(pos, placer, itemstack) + local meta = minetest.get_meta(pos); + meta:set_string("infotext", "Travelnet-box (unconfigured)"); + meta:set_string("station_name", ""); + meta:set_string("station_network",""); + meta:set_string("owner", placer:get_player_name() ); + -- request initinal data + meta:set_string("formspec", + "size[12,10]".. + "field[0.3,5.6;6,0.7;station_name;Name of this station:;]".. + "field[0.3,6.6;6,0.7;station_network;Assign to Network:;]".. + "field[0.3,7.6;6,0.7;owner_name;(optional) owned by:;]".. + "button_exit[6.3,6.2;1.7,0.7;station_set;Store]" ); + end, + + on_receive_fields = travelnet.on_receive_fields, + on_punch = function(pos, node, puncher) + travelnet.update_formspec(pos, puncher:get_player_name()) + end, + + can_dig = function( pos, player ) + return travelnet.can_dig( pos, player, 'travelnet box' ) + end, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + travelnet.remove_box( pos, oldnode, oldmetadata, digger ) + end, + + -- taken from VanessaEs homedecor fridge + on_place = function(itemstack, placer, pointed_thing) + + local pos = pointed_thing.above; + if( minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name ~= "air" ) then + + minetest.chat_send_player( placer:get_player_name(), 'Not enough vertical space to place the travelnet box!' ) + return; + end + return minetest.item_place(itemstack, placer, pointed_thing); + end, + +}) + +--[[ +minetest.register_craft({ + output = "travelnet:travelnet", + recipe = travelnet.travelnet_recipe, +}) +]] \ No newline at end of file