aboutsummaryrefslogtreecommitdiff
path: root/games
diff options
context:
space:
mode:
Diffstat (limited to 'games')
-rw-r--r--games/devtest/.luacheckrc43
-rw-r--r--games/devtest/LICENSE.txt4
-rw-r--r--games/devtest/README.md51
-rw-r--r--games/devtest/game.conf2
-rw-r--r--games/devtest/menu/background.pngbin0 -> 160 bytes
-rw-r--r--games/devtest/menu/header.pngbin0 -> 404 bytes
-rw-r--r--games/devtest/menu/icon.pngbin0 -> 217 bytes
-rw-r--r--games/devtest/mods/basenodes/init.lua351
-rw-r--r--games/devtest/mods/basenodes/mod.conf2
-rw-r--r--games/devtest/mods/basenodes/textures/basenodes_dirt_with_grass_bottom.pngbin0 -> 187 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/basenodes_dirt_with_snow.pngbin0 -> 166 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/basenodes_dirt_with_snow_bottom.pngbin0 -> 177 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/basenodes_snow_sheet.pngbin0 -> 166 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_apple.pngbin0 -> 102 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_cobble.pngbin0 -> 340 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_desert_sand.pngbin0 -> 293 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_desert_stone.pngbin0 -> 584 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_dirt.pngbin0 -> 7303 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_grass.pngbin0 -> 697 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_gravel.pngbin0 -> 171 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_ice.pngbin0 -> 369 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_junglegrass.pngbin0 -> 201 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_jungleleaves.pngbin0 -> 399 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_jungletree.pngbin0 -> 730 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_jungletree_top.pngbin0 -> 714 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_lava.png (renamed from games/minimal/mods/default/textures/default_lava.png)bin172 -> 172 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_lava_flowing.pngbin0 -> 91 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_leaves.pngbin0 -> 883 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_mossycobble.pngbin0 -> 574 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_pine_needles.pngbin0 -> 648 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_pine_tree.pngbin0 -> 604 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_pine_tree_top.pngbin0 -> 174 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_river_water.pngbin0 -> 496 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_river_water_flowing.pngbin0 -> 99 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_sand.pngbin0 -> 554 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_snow.pngbin0 -> 166 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_snow_side.pngbin0 -> 152 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_stone.pngbin0 -> 313 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_tree.pngbin0 -> 659 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_tree_top.pngbin0 -> 175 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_water.png (renamed from games/minimal/mods/default/textures/default_water.png)bin302 -> 302 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/default_water_flowing.pngbin0 -> 115 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/dirt_with_grass/default_grass.pngbin0 -> 829 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/dirt_with_grass/default_grass_side.pngbin0 -> 796 bytes
-rw-r--r--games/devtest/mods/basenodes/textures/info.txt7
-rw-r--r--games/devtest/mods/basetools/init.lua449
-rw-r--r--games/devtest/mods/basetools/mod.conf2
-rw-r--r--games/devtest/mods/basetools/textures/basetools_bloodsword.pngbin0 -> 165 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_elementalsword.pngbin0 -> 177 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_firesword.pngbin0 -> 166 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_healdagger.pngbin0 -> 162 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_healsword.pngbin0 -> 170 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_icesword.pngbin0 -> 170 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_mesepick.pngbin0 -> 156 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_mesesword.pngbin0 -> 163 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_steelaxe.pngbin0 -> 131 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_steeldagger.pngbin0 -> 154 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_steelpick.pngbin0 -> 159 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_steelpick_l1.pngbin0 -> 190 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_steelpick_l2.pngbin0 -> 177 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_steelshears.pngbin0 -> 208 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_steelshovel.pngbin0 -> 140 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_steelsword.pngbin0 -> 163 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_stoneaxe.pngbin0 -> 130 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_stonepick.png (renamed from games/minimal/mods/default/textures/default_tool_stonepick.png)bin155 -> 155 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_stoneshears.pngbin0 -> 224 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_stoneshovel.pngbin0 -> 134 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_stonesword.pngbin0 -> 159 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_superhealsword.pngbin0 -> 192 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_titaniumsword.pngbin0 -> 160 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_usespick.pngbin0 -> 161 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_usessword.pngbin0 -> 133 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_woodaxe.pngbin0 -> 121 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_wooddagger.pngbin0 -> 139 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_woodpick.png (renamed from games/minimal/mods/default/textures/default_tool_woodpick.png)bin149 -> 149 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_woodshears.pngbin0 -> 212 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_woodshovel.pngbin0 -> 133 bytes
-rw-r--r--games/devtest/mods/basetools/textures/basetools_woodsword.pngbin0 -> 139 bytes
-rw-r--r--games/devtest/mods/broken/init.lua11
-rw-r--r--games/devtest/mods/broken/mod.conf2
-rw-r--r--games/devtest/mods/bucket/init.lua27
-rw-r--r--games/devtest/mods/bucket/mod.conf2
-rw-r--r--games/devtest/mods/bucket/textures/bucket.pngbin0 -> 163 bytes
-rw-r--r--games/devtest/mods/bucket/textures/bucket_lava.pngbin0 -> 168 bytes
-rw-r--r--games/devtest/mods/bucket/textures/bucket_water.pngbin0 -> 168 bytes
-rw-r--r--games/devtest/mods/chest/init.lua40
-rw-r--r--games/devtest/mods/chest/mod.conf2
-rw-r--r--games/devtest/mods/chest/textures/chest_chest.pngbin0 -> 163 bytes
-rw-r--r--games/devtest/mods/chest_of_everything/init.lua136
-rw-r--r--games/devtest/mods/chest_of_everything/mod.conf2
-rw-r--r--games/devtest/mods/chest_of_everything/textures/chest_of_everything_chest.pngbin0 -> 210 bytes
-rw-r--r--games/devtest/mods/dignodes/init.lua37
-rw-r--r--games/devtest/mods/dignodes/mod.conf2
-rw-r--r--games/devtest/mods/dignodes/textures/dignodes_choppy.pngbin0 -> 187 bytes
-rw-r--r--games/devtest/mods/dignodes/textures/dignodes_cracky.pngbin0 -> 193 bytes
-rw-r--r--games/devtest/mods/dignodes/textures/dignodes_crumbly.pngbin0 -> 172 bytes
-rw-r--r--games/devtest/mods/dignodes/textures/dignodes_dig_immediate.pngbin0 -> 170 bytes
-rw-r--r--games/devtest/mods/dignodes/textures/dignodes_none.pngbin0 -> 201 bytes
-rw-r--r--games/devtest/mods/dignodes/textures/dignodes_rating1.pngbin0 -> 94 bytes
-rw-r--r--games/devtest/mods/dignodes/textures/dignodes_rating2.pngbin0 -> 92 bytes
-rw-r--r--games/devtest/mods/dignodes/textures/dignodes_rating3.pngbin0 -> 93 bytes
-rw-r--r--games/devtest/mods/experimental/commands.lua221
-rw-r--r--games/devtest/mods/experimental/detached.lua29
-rw-r--r--games/devtest/mods/experimental/init.lua23
-rw-r--r--games/devtest/mods/experimental/items.lua105
-rw-r--r--games/devtest/mods/experimental/mod.conf2
-rw-r--r--games/devtest/mods/experimental/textures/experimental_callback_node.pngbin0 -> 139 bytes
-rw-r--r--games/devtest/mods/experimental/textures/experimental_particle_sheet.pngbin0 -> 208 bytes
-rw-r--r--games/devtest/mods/experimental/textures/experimental_particle_vertical.pngbin0 -> 308 bytes
-rw-r--r--games/devtest/mods/experimental/textures/experimental_tester_tool_1.pngbin0 -> 138 bytes
-rw-r--r--games/devtest/mods/give_initial_stuff/init.lua37
-rw-r--r--games/devtest/mods/give_initial_stuff/mod.conf3
-rw-r--r--games/devtest/mods/initial_message/init.lua9
-rw-r--r--games/devtest/mods/initial_message/mod.conf2
-rw-r--r--games/devtest/mods/mapgen/init.lua104
-rw-r--r--games/devtest/mods/mapgen/mod.conf3
-rw-r--r--games/devtest/mods/modchannels/init.lua14
-rw-r--r--games/devtest/mods/modchannels/mod.conf2
-rw-r--r--games/devtest/mods/soundstuff/init.lua174
-rw-r--r--games/devtest/mods/soundstuff/mod.conf2
-rw-r--r--games/devtest/mods/soundstuff/sounds/soundstuff_mono.oggbin0 -> 4362 bytes
-rw-r--r--games/devtest/mods/soundstuff/textures/soundstuff_eat.pngbin0 -> 113 bytes
-rw-r--r--games/devtest/mods/soundstuff/textures/soundstuff_node_blank.pngbin0 -> 83 bytes
-rw-r--r--games/devtest/mods/soundstuff/textures/soundstuff_node_climbable.pngbin0 -> 189 bytes
-rw-r--r--games/devtest/mods/soundstuff/textures/soundstuff_node_dig.pngbin0 -> 126 bytes
-rw-r--r--games/devtest/mods/soundstuff/textures/soundstuff_node_dug.pngbin0 -> 132 bytes
-rw-r--r--games/devtest/mods/soundstuff/textures/soundstuff_node_fall.pngbin0 -> 100 bytes
-rw-r--r--games/devtest/mods/soundstuff/textures/soundstuff_node_footstep.pngbin0 -> 120 bytes
-rw-r--r--games/devtest/mods/soundstuff/textures/soundstuff_node_place.pngbin0 -> 115 bytes
-rw-r--r--games/devtest/mods/soundstuff/textures/soundstuff_node_place_failed.pngbin0 -> 143 bytes
-rw-r--r--games/devtest/mods/soundstuff/textures/soundstuff_node_sound.pngbin0 -> 116 bytes
-rw-r--r--games/devtest/mods/stairs/init.lua (renamed from games/minimal/mods/stairs/init.lua)58
-rw-r--r--games/devtest/mods/stairs/mod.conf3
-rw-r--r--games/devtest/mods/testentities/armor.lua61
-rw-r--r--games/devtest/mods/testentities/callbacks.lua78
-rw-r--r--games/devtest/mods/testentities/init.lua3
-rw-r--r--games/devtest/mods/testentities/mod.conf2
-rw-r--r--games/devtest/mods/testentities/textures/testentities_armorball.pngbin0 -> 1385 bytes
-rw-r--r--games/devtest/mods/testentities/textures/testentities_callback.pngbin0 -> 156 bytes
-rw-r--r--games/devtest/mods/testentities/textures/testentities_callback_step.pngbin0 -> 166 bytes
-rw-r--r--games/devtest/mods/testentities/textures/testentities_cube1.pngbin0 -> 130 bytes
-rw-r--r--games/devtest/mods/testentities/textures/testentities_cube2.pngbin0 -> 128 bytes
-rw-r--r--games/devtest/mods/testentities/textures/testentities_cube3.pngbin0 -> 124 bytes
-rw-r--r--games/devtest/mods/testentities/textures/testentities_cube4.pngbin0 -> 126 bytes
-rw-r--r--games/devtest/mods/testentities/textures/testentities_cube5.pngbin0 -> 126 bytes
-rw-r--r--games/devtest/mods/testentities/textures/testentities_cube6.pngbin0 -> 126 bytes
-rw-r--r--games/devtest/mods/testentities/textures/testentities_dungeon_master.pngbin0 -> 2855 bytes
-rw-r--r--games/devtest/mods/testentities/textures/testentities_sprite.pngbin0 -> 120 bytes
-rw-r--r--games/devtest/mods/testentities/textures/testentities_upright_sprite1.pngbin0 -> 114 bytes
-rw-r--r--games/devtest/mods/testentities/textures/testentities_upright_sprite2.pngbin0 -> 119 bytes
-rw-r--r--games/devtest/mods/testentities/visuals.lua137
-rw-r--r--games/devtest/mods/testfood/init.lua31
-rw-r--r--games/devtest/mods/testfood/mod.conf2
-rw-r--r--games/devtest/mods/testfood/textures/testfood_bad.pngbin0 -> 126 bytes
-rw-r--r--games/devtest/mods/testfood/textures/testfood_bad2.pngbin0 -> 133 bytes
-rw-r--r--games/devtest/mods/testfood/textures/testfood_good.pngbin0 -> 129 bytes
-rw-r--r--games/devtest/mods/testfood/textures/testfood_good2.pngbin0 -> 145 bytes
-rw-r--r--games/devtest/mods/testfood/textures/testfood_replace.pngbin0 -> 135 bytes
-rw-r--r--games/devtest/mods/testformspec/LICENSE.txt14
-rw-r--r--games/devtest/mods/testformspec/callbacks.lua51
-rw-r--r--games/devtest/mods/testformspec/dummy_items.lua14
-rw-r--r--games/devtest/mods/testformspec/formspec.lua536
-rw-r--r--games/devtest/mods/testformspec/init.lua3
-rw-r--r--games/devtest/mods/testformspec/mod.conf2
-rw-r--r--games/devtest/mods/testformspec/models/testformspec_character.b3dbin0 -> 73433 bytes
-rw-r--r--games/devtest/mods/testformspec/models/testformspec_chest.obj79
-rw-r--r--games/devtest/mods/testformspec/textures/default_chest_front.pngbin0 -> 423 bytes
-rw-r--r--games/devtest/mods/testformspec/textures/default_chest_inside.pngbin0 -> 102 bytes
-rw-r--r--games/devtest/mods/testformspec/textures/default_chest_side.pngbin0 -> 375 bytes
-rw-r--r--games/devtest/mods/testformspec/textures/default_chest_top.pngbin0 -> 423 bytes
-rw-r--r--games/devtest/mods/testformspec/textures/testformspec_9slice.pngbin0 -> 5935 bytes
-rw-r--r--games/devtest/mods/testformspec/textures/testformspec_animation.jpgbin0 -> 4376 bytes
-rw-r--r--games/devtest/mods/testformspec/textures/testformspec_animation.pngbin0 -> 214 bytes
-rw-r--r--games/devtest/mods/testformspec/textures/testformspec_bg.pngbin0 -> 92 bytes
-rw-r--r--games/devtest/mods/testformspec/textures/testformspec_bg_9slice.pngbin0 -> 146 bytes
-rw-r--r--games/devtest/mods/testformspec/textures/testformspec_bg_9slice_hovered.pngbin0 -> 146 bytes
-rw-r--r--games/devtest/mods/testformspec/textures/testformspec_bg_9slice_pressed.pngbin0 -> 146 bytes
-rw-r--r--games/devtest/mods/testformspec/textures/testformspec_bg_hovered.pngbin0 -> 92 bytes
-rw-r--r--games/devtest/mods/testformspec/textures/testformspec_bg_pressed.pngbin0 -> 91 bytes
-rw-r--r--games/devtest/mods/testformspec/textures/testformspec_button_image.pngbin0 -> 146 bytes
-rw-r--r--games/devtest/mods/testformspec/textures/testformspec_character.pngbin0 -> 2754 bytes
-rw-r--r--games/devtest/mods/testformspec/textures/testformspec_hovered.pngbin0 -> 195 bytes
-rw-r--r--games/devtest/mods/testformspec/textures/testformspec_item.pngbin0 -> 182 bytes
-rw-r--r--games/devtest/mods/testformspec/textures/testformspec_node.pngbin0 -> 113 bytes
-rw-r--r--games/devtest/mods/testformspec/textures/testformspec_pressed.pngbin0 -> 165 bytes
-rw-r--r--games/devtest/mods/testhud/init.lua81
-rw-r--r--games/devtest/mods/testhud/mod.conf2
-rw-r--r--games/devtest/mods/testitems/init.lua55
-rw-r--r--games/devtest/mods/testitems/mod.conf2
-rw-r--r--games/devtest/mods/testitems/textures/testitems_overlay_base.pngbin0 -> 106 bytes
-rw-r--r--games/devtest/mods/testitems/textures/testitems_overlay_overlay.pngbin0 -> 220 bytes
-rw-r--r--games/devtest/mods/testnodes/README.md11
-rw-r--r--games/devtest/mods/testnodes/drawtypes.lua629
-rw-r--r--games/devtest/mods/testnodes/init.lua11
-rw-r--r--games/devtest/mods/testnodes/light.lua50
-rw-r--r--games/devtest/mods/testnodes/liquids.lua134
-rw-r--r--games/devtest/mods/testnodes/meshes.lua145
-rw-r--r--games/devtest/mods/testnodes/mod.conf3
-rw-r--r--games/devtest/mods/testnodes/models/testnodes_ocorner.obj23
-rw-r--r--games/devtest/mods/testnodes/models/testnodes_pyramid.obj24
-rw-r--r--games/devtest/mods/testnodes/nodeboxes.lua81
-rw-r--r--games/devtest/mods/testnodes/overlays.lua93
-rw-r--r--games/devtest/mods/testnodes/param2.lua168
-rw-r--r--games/devtest/mods/testnodes/properties.lua397
-rw-r--r--games/devtest/mods/testnodes/textures.lua290
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_1.pngbin0 -> 107 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_1g.pngbin0 -> 104 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_1w.pngbin0 -> 121 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_1wg.pngbin0 -> 122 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_2.pngbin0 -> 112 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_2g.pngbin0 -> 110 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_2w.pngbin0 -> 134 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_2wg.pngbin0 -> 135 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_3.pngbin0 -> 105 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_3g.pngbin0 -> 103 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_3w.pngbin0 -> 112 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_3wg.pngbin0 -> 112 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_4.pngbin0 -> 97 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_4g.pngbin0 -> 95 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_4w.pngbin0 -> 128 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_4wg.pngbin0 -> 128 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_5.pngbin0 -> 98 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_5g.pngbin0 -> 98 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_5w.pngbin0 -> 117 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_5wg.pngbin0 -> 117 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_6.pngbin0 -> 100 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_6g.pngbin0 -> 98 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_6w.pngbin0 -> 117 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_6wg.pngbin0 -> 117 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_airlike.pngbin0 -> 92 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_allfaces.pngbin0 -> 150 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_allfaces_optional.pngbin0 -> 150 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_alpha.pngbin0 -> 96 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_alpha128.pngbin0 -> 136 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_alpha191.pngbin0 -> 132 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_alpha64.pngbin0 -> 134 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_anim.pngbin0 -> 274 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_attached_bottom.pngbin0 -> 86 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_attached_side.pngbin0 -> 98 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_attached_top.pngbin0 -> 87 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_attachedw_bottom.pngbin0 -> 130 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_attachedw_side.pngbin0 -> 122 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_attachedw_top.pngbin0 -> 109 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_bouncy.pngbin0 -> 106 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_buildable_to.pngbin0 -> 89 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_climbable_nojump_side.pngbin0 -> 164 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_climbable_resistance_side.pngbin0 -> 295 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_climbable_side.pngbin0 -> 150 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_damage.pngbin0 -> 108 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_damage_neg.pngbin0 -> 121 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_drowning.pngbin0 -> 127 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_fall_damage_minus.pngbin0 -> 116 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_fall_damage_plus.pngbin0 -> 117 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_fencelike.pngbin0 -> 90 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_firelike.pngbin0 -> 149 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_glasslike.pngbin0 -> 117 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_glasslike_detail.pngbin0 -> 167 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_glasslike_framed.pngbin0 -> 88 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_glasslike_framed2.pngbin0 -> 118 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_glasslike_framed_optional.pngbin0 -> 128 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_glasslikeliquid.pngbin0 -> 122 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_light.pngbin0 -> 117 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_light_1.pngbin0 -> 158 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_light_10.pngbin0 -> 147 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_light_11.pngbin0 -> 149 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_light_12.pngbin0 -> 138 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_light_13.pngbin0 -> 137 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_light_14.pngbin0 -> 132 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_light_2.pngbin0 -> 152 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_light_3.pngbin0 -> 150 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_light_4.pngbin0 -> 157 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_light_5.pngbin0 -> 150 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_light_6.pngbin0 -> 154 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_light_7.pngbin0 -> 146 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_light_8.pngbin0 -> 139 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_light_9.pngbin0 -> 149 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_line_crossing.pngbin0 -> 130 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_line_curved.pngbin0 -> 123 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_line_straight.pngbin0 -> 115 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_line_t_junction.pngbin0 -> 128 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquid.pngbin0 -> 95 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquidflowing.pngbin0 -> 132 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r0.pngbin0 -> 162 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r1.pngbin0 -> 160 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r2.pngbin0 -> 154 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r3.pngbin0 -> 155 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r4.pngbin0 -> 154 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r5.pngbin0 -> 155 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r6.pngbin0 -> 155 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r7.pngbin0 -> 157 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r8.pngbin0 -> 152 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquidsource.pngbin0 -> 128 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquidsource_r0.pngbin0 -> 149 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquidsource_r1.pngbin0 -> 152 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquidsource_r2.pngbin0 -> 152 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquidsource_r3.pngbin0 -> 152 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquidsource_r4.pngbin0 -> 155 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquidsource_r5.pngbin0 -> 150 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquidsource_r6.pngbin0 -> 148 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquidsource_r7.pngbin0 -> 154 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_liquidsource_r8.pngbin0 -> 148 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_mesh_stripes.pngbin0 -> 150 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_mesh_stripes2.pngbin0 -> 144 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_mesh_stripes3.pngbin0 -> 85 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_mesh_stripes4.pngbin0 -> 93 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_move_resistance.pngbin0 -> 221 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_node.pngbin0 -> 89 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_node_falling.pngbin0 -> 112 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_nodebox.pngbin0 -> 112 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_nojump_side.pngbin0 -> 94 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_nojump_top.pngbin0 -> 121 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_normal.pngbin0 -> 92 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_normal1.pngbin0 -> 114 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_normal2.pngbin0 -> 122 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_normal3.pngbin0 -> 114 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_normal4.pngbin0 -> 106 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_normal5.pngbin0 -> 109 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_normal6.pngbin0 -> 111 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_overlay.pngbin0 -> 153 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_overlayable.pngbin0 -> 87 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_palette_facedir.pngbin0 -> 87 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_palette_full.pngbin0 -> 568 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_palette_wallmounted.pngbin0 -> 136 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_plantlike.pngbin0 -> 183 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_plantlike_degrotate.pngbin0 -> 176 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_plantlike_leveled.pngbin0 -> 163 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_plantlike_meshoptions.pngbin0 -> 164 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted.pngbin0 -> 182 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base.pngbin0 -> 101 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_degrotate.pngbin0 -> 145 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_leveled.pngbin0 -> 127 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_meshoptions.pngbin0 -> 128 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_wallmounted.pngbin0 -> 224 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_waving.pngbin0 -> 126 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_degrotate.pngbin0 -> 176 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_leveled.pngbin0 -> 162 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_meshoptions.pngbin0 -> 162 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_wallmounted.pngbin0 -> 268 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_waving.pngbin0 -> 125 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_plantlike_wallmounted.pngbin0 -> 268 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_plantlike_waving.pngbin0 -> 127 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_rail2_crossing.pngbin0 -> 246 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_rail2_curved.pngbin0 -> 253 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_rail2_straight.pngbin0 -> 246 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_rail2_t_junction.pngbin0 -> 254 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_rail_crossing.pngbin0 -> 151 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_rail_curved.pngbin0 -> 164 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_rail_straight.pngbin0 -> 133 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_rail_t_junction.pngbin0 -> 202 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_signlike.pngbin0 -> 150 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_slippery.pngbin0 -> 111 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_street_crossing.pngbin0 -> 137 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_street_curved.pngbin0 -> 115 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_street_straight.pngbin0 -> 101 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_street_t_junction.pngbin0 -> 126 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_sunlight_filter.pngbin0 -> 113 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_bt.tgabin0 -> 179 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_tb.tgabin0 -> 179 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_bt.tgabin0 -> 120 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_tb.tgabin0 -> 120 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_bt.tgabin0 -> 172 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_tb.tgabin0 -> 172 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_bt.tgabin0 -> 300 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_tb.tgabin0 -> 300 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_bt.tgabin0 -> 172 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_tb.tgabin0 -> 172 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_torchlike_ceiling.pngbin0 -> 157 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_torchlike_floor.pngbin0 -> 141 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_torchlike_wall.pngbin0 -> 158 bytes
-rw-r--r--games/devtest/mods/testpathfinder/README.md15
-rw-r--r--games/devtest/mods/testpathfinder/init.lua136
-rw-r--r--games/devtest/mods/testpathfinder/mod.conf2
-rw-r--r--games/devtest/mods/testpathfinder/textures/testpathfinder_testpathfinder.pngbin0 -> 159 bytes
-rw-r--r--games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint.pngbin0 -> 99 bytes
-rw-r--r--games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint_end.pngbin0 -> 147 bytes
-rw-r--r--games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint_start.pngbin0 -> 139 bytes
-rw-r--r--games/devtest/mods/testtools/README.md128
-rw-r--r--games/devtest/mods/testtools/init.lua951
-rw-r--r--games/devtest/mods/testtools/light.lua37
-rw-r--r--games/devtest/mods/testtools/mod.conf2
-rw-r--r--games/devtest/mods/testtools/textures/testtools_children_getter.pngbin0 -> 281 bytes
-rw-r--r--games/devtest/mods/testtools/textures/testtools_entity_rotator.pngbin0 -> 151 bytes
-rw-r--r--games/devtest/mods/testtools/textures/testtools_entity_scaler.pngbin0 -> 182 bytes
-rw-r--r--games/devtest/mods/testtools/textures/testtools_entity_spawner.pngbin0 -> 189 bytes
-rw-r--r--games/devtest/mods/testtools/textures/testtools_falling_node_tool.pngbin0 -> 140 bytes
-rw-r--r--games/devtest/mods/testtools/textures/testtools_item_meta_editor.pngbin0 -> 114 bytes
-rw-r--r--games/devtest/mods/testtools/textures/testtools_lighttool.pngbin0 -> 1659 bytes
-rw-r--r--games/devtest/mods/testtools/textures/testtools_node_meta_editor.pngbin0 -> 135 bytes
-rw-r--r--games/devtest/mods/testtools/textures/testtools_node_setter.pngbin0 -> 146 bytes
-rw-r--r--games/devtest/mods/testtools/textures/testtools_object_attacher.pngbin0 -> 173 bytes
-rw-r--r--games/devtest/mods/testtools/textures/testtools_object_editor.pngbin0 -> 180 bytes
-rw-r--r--games/devtest/mods/testtools/textures/testtools_object_mover.pngbin0 -> 175 bytes
-rw-r--r--games/devtest/mods/testtools/textures/testtools_param2tool.pngbin0 -> 127 bytes
-rw-r--r--games/devtest/mods/testtools/textures/testtools_remover.pngbin0 -> 129 bytes
-rw-r--r--games/devtest/mods/tiled/init.lua33
-rw-r--r--games/devtest/mods/tiled/mod.conf3
-rw-r--r--games/devtest/mods/tiled/textures/tiled_tiled.pngbin0 -> 410 bytes
-rw-r--r--games/devtest/mods/unittests/async_env.lua168
-rw-r--r--games/devtest/mods/unittests/crafting.lua112
-rw-r--r--games/devtest/mods/unittests/crafting_prepare.lua94
-rw-r--r--games/devtest/mods/unittests/entity.lua132
-rw-r--r--games/devtest/mods/unittests/init.lua202
-rw-r--r--games/devtest/mods/unittests/inside_async_env.lua25
-rw-r--r--games/devtest/mods/unittests/itemdescription.lua42
-rw-r--r--games/devtest/mods/unittests/misc.lua82
-rw-r--r--games/devtest/mods/unittests/mod.conf3
-rw-r--r--games/devtest/mods/unittests/player.lua70
-rw-r--r--games/devtest/mods/unittests/textures/default_dirt.pngbin0 -> 790 bytes
-rw-r--r--games/devtest/mods/unittests/textures/unittests_coal_lump.pngbin0 -> 160 bytes
-rw-r--r--games/devtest/mods/unittests/textures/unittests_description_test.pngbin0 -> 268 bytes
-rw-r--r--games/devtest/mods/unittests/textures/unittests_iron_lump.pngbin0 -> 154 bytes
-rw-r--r--games/devtest/mods/unittests/textures/unittests_repairable_tool.pngbin0 -> 160 bytes
-rw-r--r--games/devtest/mods/unittests/textures/unittests_steel_ingot.pngbin0 -> 159 bytes
-rw-r--r--games/devtest/mods/unittests/textures/unittests_stick.pngbin0 -> 147 bytes
-rw-r--r--games/devtest/mods/unittests/textures/unittests_torch.pngbin0 -> 155 bytes
-rw-r--r--games/devtest/mods/unittests/textures/unittests_unrepairable_tool.pngbin0 -> 157 bytes
-rw-r--r--games/devtest/mods/util_commands/init.lua309
-rw-r--r--games/devtest/mods/util_commands/mod.conf2
-rw-r--r--games/devtest/screenshot.pngbin0 -> 133364 bytes
-rw-r--r--games/devtest/settingtypes.txt32
-rw-r--r--games/minimal/game.conf2
-rw-r--r--games/minimal/menu/background.pngbin392 -> 0 bytes
-rw-r--r--games/minimal/menu/icon.pngbin218 -> 0 bytes
-rw-r--r--games/minimal/mods/bucket/depends.txt2
-rw-r--r--games/minimal/mods/bucket/init.lua95
-rw-r--r--games/minimal/mods/bucket/textures/bucket.pngbin182 -> 0 bytes
-rw-r--r--games/minimal/mods/bucket/textures/bucket_lava.pngbin183 -> 0 bytes
-rw-r--r--games/minimal/mods/bucket/textures/bucket_water.pngbin180 -> 0 bytes
-rw-r--r--games/minimal/mods/default/init.lua1797
-rw-r--r--games/minimal/mods/default/mapgen.lua136
-rw-r--r--games/minimal/mods/default/sounds/default_grass_footstep.1.oggbin7014 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/bubble.pngbin273 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/crack_anylength.pngbin255 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_apple.pngbin109 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_book.pngbin157 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_bookshelf.pngbin515 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_brick.pngbin457 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_cactus_side.pngbin144 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_cactus_top.pngbin121 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_chest_front.pngbin114 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_chest_lock.pngbin145 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_chest_side.pngbin98 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_chest_top.pngbin93 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_clay.pngbin318 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_clay_brick.pngbin173 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_clay_lump.pngbin140 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_cloud.pngbin83 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_coal_lump.pngbin138 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_cobble.pngbin374 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_dirt.pngbin1586 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_fence.pngbin480 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_furnace_fire_bg.pngbin220 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_furnace_fire_fg.pngbin719 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_furnace_front.pngbin159 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_furnace_front_active.pngbin283 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_furnace_side.pngbin125 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_glass.pngbin210 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_grass.pngbin782 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_grass_footsteps.pngbin771 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_grass_side.pngbin878 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_gravel.pngbin172 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_iron_lump.pngbin140 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_junglegrass.pngbin237 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_ladder.pngbin368 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_lava_flowing_animated.pngbin7818 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_lava_source_animated.pngbin2902 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_leaves.pngbin1683 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_mese.pngbin129 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_mineral_coal.pngbin142 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_mineral_iron.pngbin922 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_mossycobble.pngbin603 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_nc_back.pngbin186 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_nc_front.pngbin204 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_nc_rb.pngbin137 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_nc_side.pngbin148 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_paper.pngbin139 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_papyrus.pngbin165 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_rail.pngbin437 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_rail_crossing.pngbin388 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_rail_curved.pngbin375 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_rail_t_junction.pngbin374 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_sand.pngbin762 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_sandstone.pngbin744 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_sapling.pngbin328 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_scorched_stuff.pngbin164 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_sign_wall.pngbin416 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_steel_block.pngbin128 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_steel_ingot.pngbin144 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_stick.pngbin120 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_stone.pngbin389 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_tnt_bottom.pngbin98 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_tnt_side.pngbin129 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_tnt_top.pngbin146 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_tool_mesepick.pngbin155 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_tool_steelaxe.pngbin140 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_tool_steelpick.pngbin163 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_tool_steelshovel.pngbin144 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_tool_steelsword.pngbin169 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_tool_stoneaxe.pngbin141 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_tool_stoneshovel.pngbin144 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_tool_stonesword.pngbin168 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_tool_woodaxe.pngbin134 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_tool_woodshovel.pngbin135 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_tool_woodsword.pngbin147 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_torch.pngbin146 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_torch_on_ceiling.pngbin137 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_torch_on_floor.pngbin138 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_tree.pngbin1445 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_tree_top.pngbin177 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/default_wood.pngbin1400 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/heart.pngbin248 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/player.pngbin157 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/player_back.pngbin149 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/treeprop.pngbin757 -> 0 bytes
-rw-r--r--games/minimal/mods/default/textures/wieldhand.pngbin212 -> 0 bytes
-rw-r--r--games/minimal/mods/errorhandler_test/init.lua106
-rw-r--r--games/minimal/mods/experimental/depends.txt2
-rw-r--r--games/minimal/mods/experimental/init.lua601
-rw-r--r--games/minimal/mods/experimental/textures/experimental_dummyball.pngbin399 -> 0 bytes
-rw-r--r--games/minimal/mods/experimental/textures/experimental_tester_tool_1.pngbin160 -> 0 bytes
-rw-r--r--games/minimal/mods/give_initial_stuff/depends.txt2
-rw-r--r--games/minimal/mods/give_initial_stuff/init.lua16
-rw-r--r--games/minimal/mods/legacy/depends.txt2
-rw-r--r--games/minimal/mods/legacy/init.lua128
-rw-r--r--games/minimal/mods/legacy/textures/apple_iron.pngbin119 -> 0 bytes
-rw-r--r--games/minimal/mods/legacy/textures/cooked_rat.pngbin145 -> 0 bytes
-rw-r--r--games/minimal/mods/legacy/textures/dungeon_master.pngbin3007 -> 0 bytes
-rw-r--r--games/minimal/mods/legacy/textures/fireball.pngbin279 -> 0 bytes
-rw-r--r--games/minimal/mods/legacy/textures/firefly.pngbin99 -> 0 bytes
-rw-r--r--games/minimal/mods/legacy/textures/oerkki1.pngbin165 -> 0 bytes
-rw-r--r--games/minimal/mods/legacy/textures/oerkki1_damaged.pngbin210 -> 0 bytes
-rw-r--r--games/minimal/mods/legacy/textures/rat.pngbin141 -> 0 bytes
-rw-r--r--games/minimal/mods/stairs/depends.txt1
-rw-r--r--games/minimal/mods/test/init.lua11
534 files changed, 7712 insertions, 2944 deletions
diff --git a/games/devtest/.luacheckrc b/games/devtest/.luacheckrc
new file mode 100644
index 000000000..1c7d3994f
--- /dev/null
+++ b/games/devtest/.luacheckrc
@@ -0,0 +1,43 @@
+unused_args = false
+allow_defined_top = true
+max_string_line_length = false
+max_line_length = false
+
+ignore = {
+ "131", -- Unused global variable
+ "211", -- Unused local variable
+ "231", -- Local variable never accessed
+ "311", -- Value assigned to a local variable is unused
+ "412", -- Redefining an argument
+ "421", -- Shadowing a local variable
+ "431", -- Shadowing an upvalue
+ "432", -- Shadowing an upvalue argument
+ "611", -- Line contains only whitespace
+}
+
+read_globals = {
+ "ItemStack",
+ "INIT",
+ "DIR_DELIM",
+ "dump", "dump2",
+ "fgettext", "fgettext_ne",
+ "vector",
+ "VoxelArea",
+ "profiler",
+ "Settings",
+ "check",
+ "PseudoRandom",
+
+ string = {fields = {"split", "trim"}},
+ table = {fields = {"copy", "getn", "indexof", "insert_all"}},
+ math = {fields = {"hypot", "round"}},
+}
+
+globals = {
+ "aborted",
+ "minetest",
+ "core",
+ os = { fields = { "tempfolder" } },
+ "_",
+}
+
diff --git a/games/devtest/LICENSE.txt b/games/devtest/LICENSE.txt
new file mode 100644
index 000000000..71bd0e596
--- /dev/null
+++ b/games/devtest/LICENSE.txt
@@ -0,0 +1,4 @@
+License information for Development Test
+----------------------------------------
+
+The same license as for Minetest applies.
diff --git a/games/devtest/README.md b/games/devtest/README.md
new file mode 100644
index 000000000..77e722af7
--- /dev/null
+++ b/games/devtest/README.md
@@ -0,0 +1,51 @@
+# Development Test (devtest)
+
+This is a basic testing environment that contains a bunch of things to test the engine, but it could also be used as a minimal testbed for testing out mods.
+
+## Features
+
+* Basic nodes for mapgen
+* Basic, minimal map generator
+* Lots of example nodes for testing drawtypes, param2, light level, and many other node properties
+* Example entities
+* Other example items
+* Formspec test (via `/test_formspec` command)
+* Automated unit tests (disabled by default)
+* Tools for manipulating nodes and entities, like the "Param2 Tool"
+
+## Getting started
+
+Basically, just create a world and start. A few important things to note:
+
+* Items are gotten from the “Chest of Everything” (`chest_of_everything:chest`)
+* When you lost your initial items, type in `/stuff` command to get them back
+* By default, Creative Mode activates infinite node placement. This behavior can be changed with the `devtest_infplace` setting
+* Use the `/infplace` command to toggle infinite node placement in-game
+* Use the Param2 Tool to change the param2 of nodes; it's useful to experiment with the various drawtype test nodes
+* Check out the game settings and server commands for additional tests and features
+
+Confused by a certain node or item? Check out for inline code comments. The usages of most tools are explained in their tooltips.
+
+### Example tests
+
+* You can use this to test what happens if a player is simultaneously in 2 nodes with `damage_per_second` but with a different value.
+* Or use the Falling Node Tool on various test nodes to see how they behave when falling.
+* You could also use this as a testbed for dependency-free mods, e.g. to test out how your formspecs behave without theming.
+
+## Random notes
+
+* Experimental/strange/unstructured tests can be found in the `experimental` mod
+* Textures of drawtype test nodes have a red dot at the top left corner. This is to see whether the textures are oriented properly
+
+## Design philosophy
+
+This should loosely follow the following principles:
+
+* Engine testing: The main focus of this is to aid testing of *engine* features, such as mapgen or node drawtypes
+* Mod testing: The secondary focus is to help modders as well, either as a minimal testbed for mods or even as a code example
+* Minimal interference: Under default settings, it shall not interfere with APIs except on explicit user wish. Non-trivial tests and features need to be enabled by a setting first
+* Convenience: Have various tools to make usage easier and more convenient
+* Reproducing engine bugs: When an engine bug was found, consider creating a test case
+* Clarity: Textures and names need to be designed to keep different things clearly visually apart at a glance
+* Low loading time: It must load blazing-fast so stuff can be tested quickly
+
diff --git a/games/devtest/game.conf b/games/devtest/game.conf
new file mode 100644
index 000000000..0f5656c99
--- /dev/null
+++ b/games/devtest/game.conf
@@ -0,0 +1,2 @@
+title = Development Test
+description = Testing environment to help with testing the engine features of Minetest. It can also be helpful in mod development.
diff --git a/games/devtest/menu/background.png b/games/devtest/menu/background.png
new file mode 100644
index 000000000..89c45fcd5
--- /dev/null
+++ b/games/devtest/menu/background.png
Binary files differ
diff --git a/games/devtest/menu/header.png b/games/devtest/menu/header.png
new file mode 100644
index 000000000..c80ed71f1
--- /dev/null
+++ b/games/devtest/menu/header.png
Binary files differ
diff --git a/games/devtest/menu/icon.png b/games/devtest/menu/icon.png
new file mode 100644
index 000000000..f854b9c31
--- /dev/null
+++ b/games/devtest/menu/icon.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/init.lua b/games/devtest/mods/basenodes/init.lua
new file mode 100644
index 000000000..2c808c35e
--- /dev/null
+++ b/games/devtest/mods/basenodes/init.lua
@@ -0,0 +1,351 @@
+local WATER_ALPHA = "^[opacity:" .. 160
+local WATER_VISC = 1
+local LAVA_VISC = 7
+
+--
+-- Node definitions
+--
+
+-- Register nodes
+
+minetest.register_node("basenodes:stone", {
+ description = "Stone",
+ tiles = {"default_stone.png"},
+ groups = {cracky=3},
+})
+
+minetest.register_node("basenodes:desert_stone", {
+ description = "Desert Stone",
+ tiles = {"default_desert_stone.png"},
+ groups = {cracky=3},
+})
+
+minetest.register_node("basenodes:dirt_with_grass", {
+ description = "Dirt with Grass",
+ tiles ={"default_grass.png",
+ -- a little dot on the bottom to distinguish it from dirt
+ "default_dirt.png^basenodes_dirt_with_grass_bottom.png",
+ {name = "default_dirt.png^default_grass_side.png",
+ tileable_vertical = false}},
+ groups = {crumbly=3, soil=1},
+})
+
+minetest.register_node("basenodes:dirt_with_snow", {
+ description = "Dirt with Snow",
+ tiles ={"basenodes_dirt_with_snow.png",
+ -- a little dot on the bottom to distinguish it from dirt
+ "default_dirt.png^basenodes_dirt_with_snow_bottom.png",
+ {name = "default_dirt.png^default_snow_side.png",
+ tileable_vertical = false}},
+ groups = {crumbly=3, soil=1},
+})
+
+minetest.register_node("basenodes:dirt", {
+ description = "Dirt",
+ tiles ={"default_dirt.png"},
+ groups = {crumbly=3, soil=1},
+})
+
+minetest.register_node("basenodes:sand", {
+ description = "Sand",
+ tiles ={"default_sand.png"},
+ groups = {crumbly=3},
+})
+
+minetest.register_node("basenodes:desert_sand", {
+ description = "Desert Sand",
+ tiles ={"default_desert_sand.png"},
+ groups = {crumbly=3},
+})
+
+minetest.register_node("basenodes:gravel", {
+ description = "Gravel",
+ tiles ={"default_gravel.png"},
+ groups = {crumbly=2},
+})
+
+minetest.register_node("basenodes:junglegrass", {
+ description = "Jungle Grass",
+ drawtype = "plantlike",
+ tiles ={"default_junglegrass.png"},
+ inventory_image = "default_junglegrass.png",
+ wield_image = "default_junglegrass.png",
+ paramtype = "light",
+ walkable = false,
+ groups = {snappy=3},
+})
+
+minetest.register_node("basenodes:tree", {
+ description = "Normal Tree Trunk",
+ tiles = {"default_tree_top.png", "default_tree_top.png", "default_tree.png"},
+ is_ground_content = false,
+ groups = {choppy=2,oddly_breakable_by_hand=1},
+})
+
+minetest.register_node("basenodes:leaves", {
+ description = "Normal Leaves",
+ drawtype = "allfaces_optional",
+ tiles = {"default_leaves.png"},
+ paramtype = "light",
+ is_ground_content = false,
+ groups = {snappy=3},
+})
+
+minetest.register_node("basenodes:jungletree", {
+ description = "Jungle Tree Trunk",
+ tiles = {"default_jungletree_top.png", "default_jungletree_top.png", "default_jungletree.png"},
+ is_ground_content = false,
+ groups = {choppy=2,oddly_breakable_by_hand=1},
+})
+
+minetest.register_node("basenodes:jungleleaves", {
+ description = "Jungle Leaves",
+ drawtype = "allfaces_optional",
+ tiles = {"default_jungleleaves.png"},
+ paramtype = "light",
+ is_ground_content = false,
+ groups = {snappy=3},
+})
+
+minetest.register_node("basenodes:pine_tree", {
+ description = "Pine Tree Trunk",
+ tiles = {"default_pine_tree_top.png", "default_pine_tree_top.png", "default_pine_tree.png"},
+ is_ground_content = false,
+ groups = {choppy=2,oddly_breakable_by_hand=1},
+})
+
+minetest.register_node("basenodes:pine_needles", {
+ description = "Pine Needles",
+ drawtype = "allfaces_optional",
+ tiles = {"default_pine_needles.png"},
+ paramtype = "light",
+ is_ground_content = false,
+ groups = {snappy=3},
+})
+
+minetest.register_node("basenodes:water_source", {
+ description = "Water Source".."\n"..
+ "Drowning damage: 1",
+ drawtype = "liquid",
+ waving = 3,
+ tiles = {"default_water.png"..WATER_ALPHA},
+ special_tiles = {
+ {name = "default_water.png"..WATER_ALPHA, backface_culling = false},
+ {name = "default_water.png"..WATER_ALPHA, backface_culling = true},
+ },
+ use_texture_alpha = "blend",
+ paramtype = "light",
+ walkable = false,
+ pointable = false,
+ diggable = false,
+ buildable_to = true,
+ is_ground_content = false,
+ drowning = 1,
+ liquidtype = "source",
+ liquid_alternative_flowing = "basenodes:water_flowing",
+ liquid_alternative_source = "basenodes:water_source",
+ liquid_viscosity = WATER_VISC,
+ post_effect_color = {a = 64, r = 100, g = 100, b = 200},
+ groups = {water = 3, liquid = 3},
+})
+
+minetest.register_node("basenodes:water_flowing", {
+ description = "Flowing Water".."\n"..
+ "Drowning damage: 1",
+ drawtype = "flowingliquid",
+ waving = 3,
+ tiles = {"default_water_flowing.png"},
+ special_tiles = {
+ {name = "default_water_flowing.png"..WATER_ALPHA,
+ backface_culling = false},
+ {name = "default_water_flowing.png"..WATER_ALPHA,
+ backface_culling = false},
+ },
+ use_texture_alpha = "blend",
+ paramtype = "light",
+ paramtype2 = "flowingliquid",
+ walkable = false,
+ pointable = false,
+ diggable = false,
+ buildable_to = true,
+ is_ground_content = false,
+ drowning = 1,
+ liquidtype = "flowing",
+ liquid_alternative_flowing = "basenodes:water_flowing",
+ liquid_alternative_source = "basenodes:water_source",
+ liquid_viscosity = WATER_VISC,
+ post_effect_color = {a = 64, r = 100, g = 100, b = 200},
+ groups = {water = 3, liquid = 3},
+})
+
+minetest.register_node("basenodes:river_water_source", {
+ description = "River Water Source".."\n"..
+ "Drowning damage: 1",
+ drawtype = "liquid",
+ waving = 3,
+ tiles = { "default_river_water.png"..WATER_ALPHA },
+ special_tiles = {
+ {name = "default_river_water.png"..WATER_ALPHA, backface_culling = false},
+ {name = "default_river_water.png"..WATER_ALPHA, backface_culling = true},
+ },
+ use_texture_alpha = "blend",
+ paramtype = "light",
+ walkable = false,
+ pointable = false,
+ diggable = false,
+ buildable_to = true,
+ is_ground_content = false,
+ drowning = 1,
+ liquidtype = "source",
+ liquid_alternative_flowing = "basenodes:river_water_flowing",
+ liquid_alternative_source = "basenodes:river_water_source",
+ liquid_viscosity = 1,
+ liquid_renewable = false,
+ liquid_range = 2,
+ post_effect_color = {a = 103, r = 30, g = 76, b = 90},
+ groups = {water = 3, liquid = 3, },
+})
+
+minetest.register_node("basenodes:river_water_flowing", {
+ description = "Flowing River Water".."\n"..
+ "Drowning damage: 1",
+ drawtype = "flowingliquid",
+ waving = 3,
+ tiles = {"default_river_water_flowing.png"..WATER_ALPHA},
+ special_tiles = {
+ {name = "default_river_water_flowing.png"..WATER_ALPHA,
+ backface_culling = false},
+ {name = "default_river_water_flowing.png"..WATER_ALPHA,
+ backface_culling = false},
+ },
+ use_texture_alpha = "blend",
+ paramtype = "light",
+ paramtype2 = "flowingliquid",
+ walkable = false,
+ pointable = false,
+ diggable = false,
+ buildable_to = true,
+ is_ground_content = false,
+ drowning = 1,
+ liquidtype = "flowing",
+ liquid_alternative_flowing = "basenodes:river_water_flowing",
+ liquid_alternative_source = "basenodes:river_water_source",
+ liquid_viscosity = 1,
+ liquid_renewable = false,
+ liquid_range = 2,
+ post_effect_color = {a = 103, r = 30, g = 76, b = 90},
+ groups = {water = 3, liquid = 3, },
+})
+
+minetest.register_node("basenodes:lava_flowing", {
+ description = "Flowing Lava".."\n"..
+ "4 damage per second".."\n"..
+ "Drowning damage: 1",
+ drawtype = "flowingliquid",
+ tiles = {"default_lava_flowing.png"},
+ special_tiles = {
+ {name="default_lava_flowing.png", backface_culling = false},
+ {name="default_lava_flowing.png", backface_culling = false},
+ },
+ paramtype = "light",
+ light_source = minetest.LIGHT_MAX,
+ walkable = false,
+ pointable = false,
+ diggable = false,
+ buildable_to = true,
+ is_ground_content = false,
+ drowning = 1,
+ damage_per_second = 4,
+ liquidtype = "flowing",
+ liquid_alternative_flowing = "basenodes:lava_flowing",
+ liquid_alternative_source = "basenodes:lava_source",
+ liquid_viscosity = LAVA_VISC,
+ post_effect_color = {a=192, r=255, g=64, b=0},
+ groups = {lava=3, liquid=1},
+})
+
+minetest.register_node("basenodes:lava_source", {
+ description = "Lava Source".."\n"..
+ "4 damage per second".."\n"..
+ "Drowning damage: 1",
+ drawtype = "liquid",
+ tiles = { "default_lava.png" },
+ special_tiles = {
+ {name = "default_lava.png", backface_culling = false},
+ {name = "default_lava.png", backface_culling = true},
+ },
+ paramtype = "light",
+ light_source = minetest.LIGHT_MAX,
+ walkable = false,
+ pointable = false,
+ diggable = false,
+ buildable_to = true,
+ is_ground_content = false,
+ drowning = 1,
+ damage_per_second = 4,
+ liquidtype = "source",
+ liquid_alternative_flowing = "basenodes:lava_flowing",
+ liquid_alternative_source = "basenodes:lava_source",
+ liquid_viscosity = LAVA_VISC,
+ post_effect_color = {a=192, r=255, g=64, b=0},
+ groups = {lava=3, liquid=1},
+})
+
+minetest.register_node("basenodes:cobble", {
+ description = "Cobblestone",
+ tiles ={"default_cobble.png"},
+ is_ground_content = false,
+ groups = {cracky=3},
+})
+
+minetest.register_node("basenodes:mossycobble", {
+ description = "Mossy Cobblestone",
+ tiles ={"default_mossycobble.png"},
+ is_ground_content = false,
+ groups = {cracky=3},
+})
+
+minetest.register_node("basenodes:apple", {
+ description = "Apple".."\n"..
+ "Food (+2)",
+ drawtype = "plantlike",
+ tiles ={"default_apple.png"},
+ inventory_image = "default_apple.png",
+ paramtype = "light",
+ is_ground_content = false,
+ sunlight_propagates = true,
+ walkable = false,
+ groups = {dig_immediate=3},
+
+ -- Make eatable because why not?
+ on_use = minetest.item_eat(2),
+})
+
+minetest.register_node("basenodes:ice", {
+ description = "Ice",
+ tiles ={"default_ice.png"},
+ groups = {cracky=3},
+})
+
+-- The snow nodes intentionally have different tints to make them more
+-- distinguishable
+minetest.register_node("basenodes:snow", {
+ description = "Snow Sheet",
+ tiles = {"basenodes_snow_sheet.png"},
+ groups = {crumbly=3},
+ walkable = false,
+ paramtype = "light",
+ drawtype = "nodebox",
+ node_box = {
+ type = "fixed",
+ fixed = {-0.5, -0.5, -0.5, 0.5, -0.25, 0.5},
+ },
+})
+
+minetest.register_node("basenodes:snowblock", {
+ description = "Snow Block",
+ tiles ={"default_snow.png"},
+ groups = {crumbly=3},
+})
+
+
diff --git a/games/devtest/mods/basenodes/mod.conf b/games/devtest/mods/basenodes/mod.conf
new file mode 100644
index 000000000..25024dc63
--- /dev/null
+++ b/games/devtest/mods/basenodes/mod.conf
@@ -0,0 +1,2 @@
+name = basenodes
+description = Contains basic nodes for mapgen
diff --git a/games/devtest/mods/basenodes/textures/basenodes_dirt_with_grass_bottom.png b/games/devtest/mods/basenodes/textures/basenodes_dirt_with_grass_bottom.png
new file mode 100644
index 000000000..5e8fc41a9
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/basenodes_dirt_with_grass_bottom.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/basenodes_dirt_with_snow.png b/games/devtest/mods/basenodes/textures/basenodes_dirt_with_snow.png
new file mode 100644
index 000000000..7ea2d8d31
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/basenodes_dirt_with_snow.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/basenodes_dirt_with_snow_bottom.png b/games/devtest/mods/basenodes/textures/basenodes_dirt_with_snow_bottom.png
new file mode 100644
index 000000000..447c94e98
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/basenodes_dirt_with_snow_bottom.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/basenodes_snow_sheet.png b/games/devtest/mods/basenodes/textures/basenodes_snow_sheet.png
new file mode 100644
index 000000000..455332093
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/basenodes_snow_sheet.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_apple.png b/games/devtest/mods/basenodes/textures/default_apple.png
new file mode 100644
index 000000000..9c115dae4
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_apple.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_cobble.png b/games/devtest/mods/basenodes/textures/default_cobble.png
new file mode 100644
index 000000000..5b859e9c2
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_cobble.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_desert_sand.png b/games/devtest/mods/basenodes/textures/default_desert_sand.png
new file mode 100644
index 000000000..19ec87dc0
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_desert_sand.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_desert_stone.png b/games/devtest/mods/basenodes/textures/default_desert_stone.png
new file mode 100644
index 000000000..5126fb61c
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_desert_stone.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_dirt.png b/games/devtest/mods/basenodes/textures/default_dirt.png
new file mode 100644
index 000000000..aa75bffb6
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_dirt.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_grass.png b/games/devtest/mods/basenodes/textures/default_grass.png
new file mode 100644
index 000000000..3d6397186
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_grass.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_gravel.png b/games/devtest/mods/basenodes/textures/default_gravel.png
new file mode 100644
index 000000000..7e5ff616f
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_gravel.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_ice.png b/games/devtest/mods/basenodes/textures/default_ice.png
new file mode 100644
index 000000000..c4bddd223
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_ice.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_junglegrass.png b/games/devtest/mods/basenodes/textures/default_junglegrass.png
new file mode 100644
index 000000000..d64e33abc
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_junglegrass.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_jungleleaves.png b/games/devtest/mods/basenodes/textures/default_jungleleaves.png
new file mode 100644
index 000000000..1fa67e83a
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_jungleleaves.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_jungletree.png b/games/devtest/mods/basenodes/textures/default_jungletree.png
new file mode 100644
index 000000000..053850fa7
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_jungletree.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_jungletree_top.png b/games/devtest/mods/basenodes/textures/default_jungletree_top.png
new file mode 100644
index 000000000..e80de8a69
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_jungletree_top.png
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_lava.png b/games/devtest/mods/basenodes/textures/default_lava.png
index a4cf649f1..a4cf649f1 100644
--- a/games/minimal/mods/default/textures/default_lava.png
+++ b/games/devtest/mods/basenodes/textures/default_lava.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_lava_flowing.png b/games/devtest/mods/basenodes/textures/default_lava_flowing.png
new file mode 100644
index 000000000..07066a6e3
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_lava_flowing.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_leaves.png b/games/devtest/mods/basenodes/textures/default_leaves.png
new file mode 100644
index 000000000..c0475d4d2
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_leaves.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_mossycobble.png b/games/devtest/mods/basenodes/textures/default_mossycobble.png
new file mode 100644
index 000000000..69585e37b
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_mossycobble.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_pine_needles.png b/games/devtest/mods/basenodes/textures/default_pine_needles.png
new file mode 100644
index 000000000..137caa2a3
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_pine_needles.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_pine_tree.png b/games/devtest/mods/basenodes/textures/default_pine_tree.png
new file mode 100644
index 000000000..5743183c0
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_pine_tree.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_pine_tree_top.png b/games/devtest/mods/basenodes/textures/default_pine_tree_top.png
new file mode 100644
index 000000000..cc18f3462
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_pine_tree_top.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_river_water.png b/games/devtest/mods/basenodes/textures/default_river_water.png
new file mode 100644
index 000000000..e1074d2ef
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_river_water.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_river_water_flowing.png b/games/devtest/mods/basenodes/textures/default_river_water_flowing.png
new file mode 100644
index 000000000..4a756b2bd
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_river_water_flowing.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_sand.png b/games/devtest/mods/basenodes/textures/default_sand.png
new file mode 100644
index 000000000..0ed0e4ceb
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_sand.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_snow.png b/games/devtest/mods/basenodes/textures/default_snow.png
new file mode 100644
index 000000000..c42e0eecb
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_snow.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_snow_side.png b/games/devtest/mods/basenodes/textures/default_snow_side.png
new file mode 100644
index 000000000..f34d10991
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_snow_side.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_stone.png b/games/devtest/mods/basenodes/textures/default_stone.png
new file mode 100644
index 000000000..763b4396a
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_stone.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_tree.png b/games/devtest/mods/basenodes/textures/default_tree.png
new file mode 100644
index 000000000..189ec1593
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_tree.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_tree_top.png b/games/devtest/mods/basenodes/textures/default_tree_top.png
new file mode 100644
index 000000000..d1a4fa704
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_tree_top.png
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_water.png b/games/devtest/mods/basenodes/textures/default_water.png
index 3e385ae8b..3e385ae8b 100644
--- a/games/minimal/mods/default/textures/default_water.png
+++ b/games/devtest/mods/basenodes/textures/default_water.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/default_water_flowing.png b/games/devtest/mods/basenodes/textures/default_water_flowing.png
new file mode 100644
index 000000000..7cdafd51d
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/default_water_flowing.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/dirt_with_grass/default_grass.png b/games/devtest/mods/basenodes/textures/dirt_with_grass/default_grass.png
new file mode 100644
index 000000000..29fde6b26
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/dirt_with_grass/default_grass.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/dirt_with_grass/default_grass_side.png b/games/devtest/mods/basenodes/textures/dirt_with_grass/default_grass_side.png
new file mode 100644
index 000000000..04770b6f6
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/dirt_with_grass/default_grass_side.png
Binary files differ
diff --git a/games/devtest/mods/basenodes/textures/info.txt b/games/devtest/mods/basenodes/textures/info.txt
new file mode 100644
index 000000000..2d4ef7efa
--- /dev/null
+++ b/games/devtest/mods/basenodes/textures/info.txt
@@ -0,0 +1,7 @@
+
+The dirt_with_grass folder is for testing loading textures from subfolders.
+If it works correctly, the default_grass_side.png file in the folder is used but
+default_grass.png is not overwritten by the file in the folder.
+
+default_dirt.png should be overwritten by the default_dirt.png in the unittests
+mod which depends on basenodes.
diff --git a/games/devtest/mods/basetools/init.lua b/games/devtest/mods/basetools/init.lua
new file mode 100644
index 000000000..3ec69d39f
--- /dev/null
+++ b/games/devtest/mods/basetools/init.lua
@@ -0,0 +1,449 @@
+--
+-- Tool definitions
+--
+
+--[[ TOOLS SUMMARY:
+
+Tool types:
+
+* Hand: basic tool/weapon (special capabilities in creative mode)
+* Pickaxe: dig cracky
+* Axe: dig choppy
+* Shovel: dig crumbly
+* Shears: dig snappy
+* Sword: deal damage
+* Dagger: deal damage, but faster
+
+Tool materials:
+
+* Wood: dig nodes of rating 3
+* Stone: dig nodes of rating 3 or 2
+* Steel: dig nodes of rating 3, 2 or 1
+* Mese: dig "everything" instantly
+* n-Uses: can be used n times before breaking
+]]
+
+-- The hand
+if minetest.settings:get_bool("creative_mode") then
+ local digtime = 42
+ local caps = {times = {digtime, digtime, digtime}, uses = 0, maxlevel = 256}
+
+ minetest.register_item(":", {
+ type = "none",
+ wield_image = "wieldhand.png",
+ wield_scale = {x = 1, y = 1, z = 2.5},
+ range = 10,
+ tool_capabilities = {
+ full_punch_interval = 0.5,
+ max_drop_level = 3,
+ groupcaps = {
+ crumbly = caps,
+ cracky = caps,
+ snappy = caps,
+ choppy = caps,
+ oddly_breakable_by_hand = caps,
+ -- dig_immediate group doesn't use value 1. Value 3 is instant dig
+ dig_immediate =
+ {times = {[2] = digtime, [3] = 0}, uses = 0, maxlevel = 256},
+ },
+ damage_groups = {fleshy = 10},
+ }
+ })
+else
+ minetest.register_item(":", {
+ type = "none",
+ wield_image = "wieldhand.png",
+ wield_scale = {x = 1, y = 1, z = 2.5},
+ tool_capabilities = {
+ full_punch_interval = 0.9,
+ max_drop_level = 0,
+ groupcaps = {
+ crumbly = {times = {[2] = 3.00, [3] = 0.70}, uses = 0, maxlevel = 1},
+ snappy = {times = {[3] = 0.40}, uses = 0, maxlevel = 1},
+ oddly_breakable_by_hand =
+ {times = {[1] = 3.50, [2] = 2.00, [3] = 0.70}, uses = 0}
+ },
+ damage_groups = {fleshy = 1},
+ }
+ })
+end
+
+-- Mese Pickaxe: special tool that digs "everything" instantly
+minetest.register_tool("basetools:pick_mese", {
+ description = "Mese Pickaxe".."\n"..
+ "Digs diggable nodes instantly",
+ inventory_image = "basetools_mesepick.png",
+ tool_capabilities = {
+ full_punch_interval = 1.0,
+ max_drop_level=3,
+ groupcaps={
+ cracky={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255},
+ crumbly={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255},
+ snappy={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255},
+ choppy={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255},
+ dig_immediate={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255},
+ },
+ damage_groups = {fleshy=100},
+ },
+})
+
+
+--
+-- Pickaxes: Dig cracky
+--
+
+minetest.register_tool("basetools:pick_wood", {
+ description = "Wooden Pickaxe".."\n"..
+ "Digs cracky=3",
+ inventory_image = "basetools_woodpick.png",
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ cracky={times={[3]=2.00}, uses=30, maxlevel=0}
+ },
+ },
+})
+minetest.register_tool("basetools:pick_stone", {
+ description = "Stone Pickaxe".."\n"..
+ "Digs cracky=2..3",
+ inventory_image = "basetools_stonepick.png",
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ cracky={times={[2]=1.20, [3]=0.80}, uses=60, maxlevel=0}
+ },
+ },
+})
+minetest.register_tool("basetools:pick_steel", {
+ description = "Steel Pickaxe".."\n"..
+ "Digs cracky=1..3",
+ inventory_image = "basetools_steelpick.png",
+ tool_capabilities = {
+ max_drop_level=1,
+ groupcaps={
+ cracky={times={[1]=4.00, [2]=1.60, [3]=1.00}, uses=90, maxlevel=0}
+ },
+ },
+})
+minetest.register_tool("basetools:pick_steel_l1", {
+ description = "Steel Pickaxe Level 1".."\n"..
+ "Digs cracky=1..3".."\n"..
+ "maxlevel=1",
+ inventory_image = "basetools_steelpick_l1.png",
+ tool_capabilities = {
+ max_drop_level=1,
+ groupcaps={
+ cracky={times={[1]=4.00, [2]=1.60, [3]=1.00}, uses=90, maxlevel=1}
+ },
+ },
+})
+minetest.register_tool("basetools:pick_steel_l2", {
+ description = "Steel Pickaxe Level 2".."\n"..
+ "Digs cracky=1..3".."\n"..
+ "maxlevel=2",
+ inventory_image = "basetools_steelpick_l2.png",
+ tool_capabilities = {
+ max_drop_level=1,
+ groupcaps={
+ cracky={times={[1]=4.00, [2]=1.60, [3]=1.00}, uses=90, maxlevel=2}
+ },
+ },
+})
+
+--
+-- Shovels (dig crumbly)
+--
+
+minetest.register_tool("basetools:shovel_wood", {
+ description = "Wooden Shovel".."\n"..
+ "Digs crumbly=3",
+ inventory_image = "basetools_woodshovel.png",
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ crumbly={times={[3]=0.50}, uses=30, maxlevel=0}
+ },
+ },
+})
+minetest.register_tool("basetools:shovel_stone", {
+ description = "Stone Shovel".."\n"..
+ "Digs crumbly=2..3",
+ inventory_image = "basetools_stoneshovel.png",
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ crumbly={times={[2]=0.50, [3]=0.30}, uses=60, maxlevel=0}
+ },
+ },
+})
+minetest.register_tool("basetools:shovel_steel", {
+ description = "Steel Shovel".."\n"..
+ "Digs crumbly=1..3",
+ inventory_image = "basetools_steelshovel.png",
+ tool_capabilities = {
+ max_drop_level=1,
+ groupcaps={
+ crumbly={times={[1]=1.00, [2]=0.70, [3]=0.60}, uses=90, maxlevel=0}
+ },
+ },
+})
+
+--
+-- Axes (dig choppy)
+--
+
+minetest.register_tool("basetools:axe_wood", {
+ description = "Wooden Axe".."\n"..
+ "Digs choppy=3",
+ inventory_image = "basetools_woodaxe.png",
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ choppy={times={[3]=0.80}, uses=30, maxlevel=0},
+ },
+ },
+})
+minetest.register_tool("basetools:axe_stone", {
+ description = "Stone Axe".."\n"..
+ "Digs choppy=2..3",
+ inventory_image = "basetools_stoneaxe.png",
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ choppy={times={[2]=1.00, [3]=0.60}, uses=60, maxlevel=0},
+ },
+ },
+})
+minetest.register_tool("basetools:axe_steel", {
+ description = "Steel Axe".."\n"..
+ "Digs choppy=1..3",
+ inventory_image = "basetools_steelaxe.png",
+ tool_capabilities = {
+ max_drop_level=1,
+ groupcaps={
+ choppy={times={[1]=2.00, [2]=0.80, [3]=0.40}, uses=90, maxlevel=0},
+ },
+ },
+})
+
+--
+-- Shears (dig snappy)
+--
+
+minetest.register_tool("basetools:shears_wood", {
+ description = "Wooden Shears".."\n"..
+ "Digs snappy=3",
+ inventory_image = "basetools_woodshears.png",
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ snappy={times={[3]=1.00}, uses=30, maxlevel=0},
+ },
+ },
+})
+minetest.register_tool("basetools:shears_stone", {
+ description = "Stone Shears".."\n"..
+ "Digs snappy=2..3",
+ inventory_image = "basetools_stoneshears.png",
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ snappy={times={[2]=1.00, [3]=0.50}, uses=60, maxlevel=0},
+ },
+ },
+})
+minetest.register_tool("basetools:shears_steel", {
+ description = "Steel Shears".."\n"..
+ "Digs snappy=1..3",
+ inventory_image = "basetools_steelshears.png",
+ tool_capabilities = {
+ max_drop_level=1,
+ groupcaps={
+ snappy={times={[1]=1.00, [2]=0.50, [3]=0.25}, uses=90, maxlevel=0},
+ },
+ },
+})
+
+--
+-- Swords (deal damage)
+--
+
+minetest.register_tool("basetools:sword_wood", {
+ description = "Wooden Sword".."\n"..
+ "Damage: fleshy=2",
+ inventory_image = "basetools_woodsword.png",
+ tool_capabilities = {
+ full_punch_interval = 1.0,
+ damage_groups = {fleshy=2},
+ }
+})
+minetest.register_tool("basetools:sword_stone", {
+ description = "Stone Sword".."\n"..
+ "Damage: fleshy=5",
+ inventory_image = "basetools_stonesword.png",
+ tool_capabilities = {
+ full_punch_interval = 1.0,
+ max_drop_level=0,
+ damage_groups = {fleshy=5},
+ }
+})
+minetest.register_tool("basetools:sword_steel", {
+ description = "Steel Sword".."\n"..
+ "Damage: fleshy=10",
+ inventory_image = "basetools_steelsword.png",
+ tool_capabilities = {
+ full_punch_interval = 1.0,
+ max_drop_level=1,
+ damage_groups = {fleshy=10},
+ }
+})
+minetest.register_tool("basetools:sword_titanium", {
+ description = "Titanium Sword".."\n"..
+ "Damage: fleshy=100",
+ inventory_image = "basetools_titaniumsword.png",
+ tool_capabilities = {
+ full_punch_interval = 1.0,
+ max_drop_level=1,
+ damage_groups = {fleshy=100},
+ }
+})
+minetest.register_tool("basetools:sword_blood", {
+ description = "Blood Sword".."\n"..
+ "Damage: fleshy=1000",
+ inventory_image = "basetools_bloodsword.png",
+ tool_capabilities = {
+ full_punch_interval = 1.0,
+ max_drop_level=1,
+ damage_groups = {fleshy=1000},
+ }
+})
+
+-- Max. damage sword
+minetest.register_tool("basetools:sword_mese", {
+ description = "Mese Sword".."\n"..
+ "Damage: fleshy=32767, fiery=32767, icy=32767".."\n"..
+ "Full Punch Interval: 0.0s",
+ inventory_image = "basetools_mesesword.png",
+ tool_capabilities = {
+ full_punch_interval = 0.0,
+ max_drop_level=1,
+ damage_groups = {fleshy=32767, fiery=32767, icy=32767},
+ }
+})
+
+-- Fire/Ice sword: Deal damage to non-fleshy damage groups
+minetest.register_tool("basetools:sword_fire", {
+ description = "Fire Sword".."\n"..
+ "Damage: icy=10",
+ inventory_image = "basetools_firesword.png",
+ tool_capabilities = {
+ full_punch_interval = 1.0,
+ max_drop_level=0,
+ damage_groups = {icy=10},
+ }
+})
+minetest.register_tool("basetools:sword_ice", {
+ description = "Ice Sword".."\n"..
+ "Damage: fiery=10",
+ inventory_image = "basetools_icesword.png",
+ tool_capabilities = {
+ full_punch_interval = 1.0,
+ max_drop_level=0,
+ damage_groups = {fiery=10},
+ }
+})
+minetest.register_tool("basetools:sword_elemental", {
+ description = "Elemental Sword".."\n"..
+ "Damage: fiery=10, icy=10",
+ inventory_image = "basetools_elementalsword.png",
+ tool_capabilities = {
+ full_punch_interval = 1.0,
+ max_drop_level=0,
+ damage_groups = {fiery=10, icy=10},
+ }
+})
+
+-- Healing weapons: heal HP
+minetest.register_tool("basetools:dagger_heal", {
+ description = "Healing Dagger".."\n"..
+ "Heal: fleshy=1".."\n"..
+ "Full Punch Interval: 0.5s",
+ inventory_image = "basetools_healdagger.png",
+ tool_capabilities = {
+ full_punch_interval = 0.5,
+ damage_groups = {fleshy=-1},
+ }
+})
+minetest.register_tool("basetools:sword_heal", {
+ description = "Healing Sword".."\n"..
+ "Heal: fleshy=10",
+ inventory_image = "basetools_healsword.png",
+ tool_capabilities = {
+ full_punch_interval = 1.0,
+ damage_groups = {fleshy=-10},
+ }
+})
+minetest.register_tool("basetools:sword_heal_super", {
+ description = "Super Healing Sword".."\n"..
+ "Heal: fleshy=32768, fiery=32768, icy=32768",
+ inventory_image = "basetools_superhealsword.png",
+ tool_capabilities = {
+ full_punch_interval = 1.0,
+ damage_groups = {fleshy=-32768, fiery=-32768, icy=-32768},
+ }
+})
+
+
+--
+-- Dagger: Low damage, fast punch interval
+--
+minetest.register_tool("basetools:dagger_wood", {
+ description = "Wooden Dagger".."\n"..
+ "Damage: fleshy=1".."\n"..
+ "Full Punch Interval: 0.5s",
+ inventory_image = "basetools_wooddagger.png",
+ tool_capabilities = {
+ full_punch_interval = 0.5,
+ max_drop_level=0,
+ damage_groups = {fleshy=1},
+ }
+})
+minetest.register_tool("basetools:dagger_steel", {
+ description = "Steel Dagger".."\n"..
+ "Damage: fleshy=2".."\n"..
+ "Full Punch Interval: 0.5s",
+ inventory_image = "basetools_steeldagger.png",
+ tool_capabilities = {
+ full_punch_interval = 0.5,
+ max_drop_level=0,
+ damage_groups = {fleshy=2},
+ }
+})
+
+-- Test tool uses and punch_attack_uses
+local uses = { 1, 2, 3, 5, 10, 50, 100, 1000, 10000, 65535 }
+for i=1, #uses do
+ local u = uses[i]
+ local color = string.format("#FF00%02X", math.floor(((i-1)/#uses) * 255))
+ minetest.register_tool("basetools:pick_uses_"..string.format("%05d", u), {
+ description = u.."-Uses Pickaxe".."\n"..
+ "Digs cracky=3",
+ inventory_image = "basetools_usespick.png^[colorize:"..color..":127",
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ cracky={times={[3]=0.1, [2]=0.2, [1]=0.3}, uses=u, maxlevel=0}
+ },
+ },
+ })
+
+ minetest.register_tool("basetools:sword_uses_"..string.format("%05d", u), {
+ description = u.."-Uses Sword".."\n"..
+ "Damage: fleshy=1",
+ inventory_image = "basetools_usessword.png^[colorize:"..color..":127",
+ tool_capabilities = {
+ damage_groups = {fleshy=1},
+ punch_attack_uses = u,
+ },
+ })
+end
diff --git a/games/devtest/mods/basetools/mod.conf b/games/devtest/mods/basetools/mod.conf
new file mode 100644
index 000000000..f0d9f657d
--- /dev/null
+++ b/games/devtest/mods/basetools/mod.conf
@@ -0,0 +1,2 @@
+name = basetools
+description = Contains basic digging tools
diff --git a/games/devtest/mods/basetools/textures/basetools_bloodsword.png b/games/devtest/mods/basetools/textures/basetools_bloodsword.png
new file mode 100644
index 000000000..a521ba4a2
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_bloodsword.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_elementalsword.png b/games/devtest/mods/basetools/textures/basetools_elementalsword.png
new file mode 100644
index 000000000..d007217ee
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_elementalsword.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_firesword.png b/games/devtest/mods/basetools/textures/basetools_firesword.png
new file mode 100644
index 000000000..eca999ba1
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_firesword.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_healdagger.png b/games/devtest/mods/basetools/textures/basetools_healdagger.png
new file mode 100644
index 000000000..3e6eb9cd0
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_healdagger.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_healsword.png b/games/devtest/mods/basetools/textures/basetools_healsword.png
new file mode 100644
index 000000000..f93fddfb2
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_healsword.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_icesword.png b/games/devtest/mods/basetools/textures/basetools_icesword.png
new file mode 100644
index 000000000..55a8d609d
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_icesword.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_mesepick.png b/games/devtest/mods/basetools/textures/basetools_mesepick.png
new file mode 100644
index 000000000..2993b475b
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_mesepick.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_mesesword.png b/games/devtest/mods/basetools/textures/basetools_mesesword.png
new file mode 100644
index 000000000..bc82769bc
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_mesesword.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_steelaxe.png b/games/devtest/mods/basetools/textures/basetools_steelaxe.png
new file mode 100644
index 000000000..aac594d84
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_steelaxe.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_steeldagger.png b/games/devtest/mods/basetools/textures/basetools_steeldagger.png
new file mode 100644
index 000000000..4c9173094
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_steeldagger.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_steelpick.png b/games/devtest/mods/basetools/textures/basetools_steelpick.png
new file mode 100644
index 000000000..bc02aac3e
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_steelpick.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_steelpick_l1.png b/games/devtest/mods/basetools/textures/basetools_steelpick_l1.png
new file mode 100644
index 000000000..dc03f3f65
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_steelpick_l1.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_steelpick_l2.png b/games/devtest/mods/basetools/textures/basetools_steelpick_l2.png
new file mode 100644
index 000000000..011df4584
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_steelpick_l2.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_steelshears.png b/games/devtest/mods/basetools/textures/basetools_steelshears.png
new file mode 100644
index 000000000..04c86c370
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_steelshears.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_steelshovel.png b/games/devtest/mods/basetools/textures/basetools_steelshovel.png
new file mode 100644
index 000000000..8cab60784
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_steelshovel.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_steelsword.png b/games/devtest/mods/basetools/textures/basetools_steelsword.png
new file mode 100644
index 000000000..9909365c3
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_steelsword.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_stoneaxe.png b/games/devtest/mods/basetools/textures/basetools_stoneaxe.png
new file mode 100644
index 000000000..a374c547d
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_stoneaxe.png
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_tool_stonepick.png b/games/devtest/mods/basetools/textures/basetools_stonepick.png
index d9156ee3a..d9156ee3a 100644
--- a/games/minimal/mods/default/textures/default_tool_stonepick.png
+++ b/games/devtest/mods/basetools/textures/basetools_stonepick.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_stoneshears.png b/games/devtest/mods/basetools/textures/basetools_stoneshears.png
new file mode 100644
index 000000000..0b4bd3b74
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_stoneshears.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_stoneshovel.png b/games/devtest/mods/basetools/textures/basetools_stoneshovel.png
new file mode 100644
index 000000000..3c1bb48cb
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_stoneshovel.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_stonesword.png b/games/devtest/mods/basetools/textures/basetools_stonesword.png
new file mode 100644
index 000000000..6f3e94cda
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_stonesword.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_superhealsword.png b/games/devtest/mods/basetools/textures/basetools_superhealsword.png
new file mode 100644
index 000000000..4175a0917
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_superhealsword.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_titaniumsword.png b/games/devtest/mods/basetools/textures/basetools_titaniumsword.png
new file mode 100644
index 000000000..55e22c7d5
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_titaniumsword.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_usespick.png b/games/devtest/mods/basetools/textures/basetools_usespick.png
new file mode 100644
index 000000000..27850f961
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_usespick.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_usessword.png b/games/devtest/mods/basetools/textures/basetools_usessword.png
new file mode 100644
index 000000000..0eaf4cf38
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_usessword.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_woodaxe.png b/games/devtest/mods/basetools/textures/basetools_woodaxe.png
new file mode 100644
index 000000000..4015e910f
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_woodaxe.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_wooddagger.png b/games/devtest/mods/basetools/textures/basetools_wooddagger.png
new file mode 100644
index 000000000..6e5ab0fd6
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_wooddagger.png
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_tool_woodpick.png b/games/devtest/mods/basetools/textures/basetools_woodpick.png
index 15c61f408..15c61f408 100644
--- a/games/minimal/mods/default/textures/default_tool_woodpick.png
+++ b/games/devtest/mods/basetools/textures/basetools_woodpick.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_woodshears.png b/games/devtest/mods/basetools/textures/basetools_woodshears.png
new file mode 100644
index 000000000..4ff92fd7c
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_woodshears.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_woodshovel.png b/games/devtest/mods/basetools/textures/basetools_woodshovel.png
new file mode 100644
index 000000000..6cc52f8a1
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_woodshovel.png
Binary files differ
diff --git a/games/devtest/mods/basetools/textures/basetools_woodsword.png b/games/devtest/mods/basetools/textures/basetools_woodsword.png
new file mode 100644
index 000000000..364016ed6
--- /dev/null
+++ b/games/devtest/mods/basetools/textures/basetools_woodsword.png
Binary files differ
diff --git a/games/devtest/mods/broken/init.lua b/games/devtest/mods/broken/init.lua
new file mode 100644
index 000000000..04993ca16
--- /dev/null
+++ b/games/devtest/mods/broken/init.lua
@@ -0,0 +1,11 @@
+-- Register stuff with empty definitions to test if Minetest fallback options
+-- for these things work properly.
+
+-- The itemstrings are deliberately kept descriptive to keep them easy to
+-- recognize.
+
+minetest.register_node("broken:node_with_empty_definition", {})
+minetest.register_tool("broken:tool_with_empty_definition", {})
+minetest.register_craftitem("broken:craftitem_with_empty_definition", {})
+
+minetest.register_entity("broken:entity_with_empty_definition", {})
diff --git a/games/devtest/mods/broken/mod.conf b/games/devtest/mods/broken/mod.conf
new file mode 100644
index 000000000..a24378a34
--- /dev/null
+++ b/games/devtest/mods/broken/mod.conf
@@ -0,0 +1,2 @@
+name = broken
+description = Register items and an entity with empty definitions to test fallback
diff --git a/games/devtest/mods/bucket/init.lua b/games/devtest/mods/bucket/init.lua
new file mode 100644
index 000000000..ff58b0669
--- /dev/null
+++ b/games/devtest/mods/bucket/init.lua
@@ -0,0 +1,27 @@
+-- Bucket: Punch liquid source or flowing liquid to collect it
+
+minetest.register_tool("bucket:bucket", {
+ description = "Bucket".."\n"..
+ "Picks up liquid nodes",
+ inventory_image = "bucket.png",
+ stack_max = 1,
+ liquids_pointable = true,
+ groups = { disable_repair = 1 },
+ on_use = function(itemstack, user, pointed_thing)
+ -- Must be pointing to node
+ if pointed_thing.type ~= "node" then
+ return
+ end
+ -- Check if pointing to a liquid
+ local n = minetest.get_node(pointed_thing.under)
+ local def = minetest.registered_nodes[n.name]
+ if def ~= nil and (def.liquidtype == "source" or def.liquidtype == "flowing") then
+ minetest.add_node(pointed_thing.under, {name="air"})
+ local inv = user:get_inventory()
+ if inv then
+ inv:add_item("main", ItemStack(n.name))
+ end
+ end
+ end,
+})
+
diff --git a/games/devtest/mods/bucket/mod.conf b/games/devtest/mods/bucket/mod.conf
new file mode 100644
index 000000000..d14deb4ea
--- /dev/null
+++ b/games/devtest/mods/bucket/mod.conf
@@ -0,0 +1,2 @@
+name = bucket
+description = Minimal bucket to pick up liquids
diff --git a/games/devtest/mods/bucket/textures/bucket.png b/games/devtest/mods/bucket/textures/bucket.png
new file mode 100644
index 000000000..677952875
--- /dev/null
+++ b/games/devtest/mods/bucket/textures/bucket.png
Binary files differ
diff --git a/games/devtest/mods/bucket/textures/bucket_lava.png b/games/devtest/mods/bucket/textures/bucket_lava.png
new file mode 100644
index 000000000..dfcae65fb
--- /dev/null
+++ b/games/devtest/mods/bucket/textures/bucket_lava.png
Binary files differ
diff --git a/games/devtest/mods/bucket/textures/bucket_water.png b/games/devtest/mods/bucket/textures/bucket_water.png
new file mode 100644
index 000000000..e164b0a50
--- /dev/null
+++ b/games/devtest/mods/bucket/textures/bucket_water.png
Binary files differ
diff --git a/games/devtest/mods/chest/init.lua b/games/devtest/mods/chest/init.lua
new file mode 100644
index 000000000..5798c13e7
--- /dev/null
+++ b/games/devtest/mods/chest/init.lua
@@ -0,0 +1,40 @@
+minetest.register_node("chest:chest", {
+ description = "Chest" .. "\n" ..
+ "32 inventory slots",
+ tiles ={"chest_chest.png^[sheet:2x2:0,0", "chest_chest.png^[sheet:2x2:0,0",
+ "chest_chest.png^[sheet:2x2:1,0", "chest_chest.png^[sheet:2x2:1,0",
+ "chest_chest.png^[sheet:2x2:1,0", "chest_chest.png^[sheet:2x2:0,1"},
+ paramtype2 = "facedir",
+ groups = {dig_immediate=2,choppy=3},
+ is_ground_content = false,
+ on_construct = function(pos)
+ local meta = minetest.get_meta(pos)
+ meta:set_string("formspec",
+ "size[8,9]"..
+ "list[current_name;main;0,0;8,4;]"..
+ "list[current_player;main;0,5;8,4;]" ..
+ "listring[]")
+ meta:set_string("infotext", "Chest")
+ local inv = meta:get_inventory()
+ inv:set_size("main", 8*4)
+ end,
+ can_dig = function(pos,player)
+ local meta = minetest.get_meta(pos);
+ local inv = meta:get_inventory()
+ return inv:is_empty("main")
+ end,
+ allow_metadata_inventory_put = function(pos, listname, index, stack, player)
+ minetest.chat_send_player(player:get_player_name(), "Allow put: " .. stack:to_string())
+ return stack:get_count()
+ end,
+ allow_metadata_inventory_take = function(pos, listname, index, stack, player)
+ minetest.chat_send_player(player:get_player_name(), "Allow take: " .. stack:to_string())
+ return stack:get_count()
+ end,
+ on_metadata_inventory_put = function(pos, listname, index, stack, player)
+ minetest.chat_send_player(player:get_player_name(), "On put: " .. stack:to_string())
+ end,
+ on_metadata_inventory_take = function(pos, listname, index, stack, player)
+ minetest.chat_send_player(player:get_player_name(), "On take: " .. stack:to_string())
+ end,
+})
diff --git a/games/devtest/mods/chest/mod.conf b/games/devtest/mods/chest/mod.conf
new file mode 100644
index 000000000..0d7500164
--- /dev/null
+++ b/games/devtest/mods/chest/mod.conf
@@ -0,0 +1,2 @@
+name = chest
+description = A simple chest to store items
diff --git a/games/devtest/mods/chest/textures/chest_chest.png b/games/devtest/mods/chest/textures/chest_chest.png
new file mode 100644
index 000000000..824b4d502
--- /dev/null
+++ b/games/devtest/mods/chest/textures/chest_chest.png
Binary files differ
diff --git a/games/devtest/mods/chest_of_everything/init.lua b/games/devtest/mods/chest_of_everything/init.lua
new file mode 100644
index 000000000..3e9d2678a
--- /dev/null
+++ b/games/devtest/mods/chest_of_everything/init.lua
@@ -0,0 +1,136 @@
+local F = minetest.formspec_escape
+
+-- Create a detached inventory
+local inv_everything = minetest.create_detached_inventory("everything", {
+ allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
+ return 0
+ end,
+ allow_put = function(inv, listname, index, stack, player)
+ return 0
+ end,
+ allow_take = function(inv, listname, index, stack, player)
+ return -1
+ end,
+})
+local inv_trash = minetest.create_detached_inventory("trash", {
+ allow_take = function(inv, listname, index, stack, player)
+ return 0
+ end,
+ allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
+ return 0
+ end,
+ on_put = function(inv, listname, index, stack, player)
+ inv:set_list("main", {})
+ end,
+})
+inv_trash:set_size("main", 1)
+
+local max_page = 1
+
+local function get_chest_formspec(page)
+ local start = 0 + (page-1)*32
+ return "size[8,9]"..
+ "list[detached:everything;main;0,0;8,4;"..start.."]"..
+ "list[current_player;main;0,5;8,4;]" ..
+ "label[6,4;Trash:]" ..
+ "list[detached:trash;main;7,4;1,1]" ..
+ "button[0,4;1,1;chest_of_everything_prev;"..F("<").."]"..
+ "button[1,4;1,1;chest_of_everything_next;"..F(">").."]"..
+ "label[2,4;"..F("Page: "..page).."]"..
+ "listring[detached:everything;main]"..
+ "listring[current_player;main]"..
+ "listring[detached:trash;main]"
+end
+
+minetest.register_node("chest_of_everything:chest", {
+ description = "Chest of Everything" .. "\n" ..
+ "Grants access to all items",
+ tiles ={"chest_of_everything_chest.png^[sheet:2x2:0,0", "chest_of_everything_chest.png^[sheet:2x2:0,0",
+ "chest_of_everything_chest.png^[sheet:2x2:1,0", "chest_of_everything_chest.png^[sheet:2x2:1,0",
+ "chest_of_everything_chest.png^[sheet:2x2:1,0", "chest_of_everything_chest.png^[sheet:2x2:0,1"},
+ paramtype2 = "facedir",
+ groups = {dig_immediate=2,choppy=3},
+ is_ground_content = false,
+ on_construct = function(pos)
+ local meta = minetest.get_meta(pos)
+ meta:set_string("infotext", "Chest of Everything")
+ meta:set_int("page", 1)
+ meta:set_string("formspec", get_chest_formspec(1))
+ end,
+ on_receive_fields = function(pos, formname, fields, sender)
+ if formname == "" then
+ local meta = minetest.get_meta(pos)
+ local page = meta:get_int("page")
+ if fields.chest_of_everything_prev then
+ page = page - 1
+ elseif fields.chest_of_everything_next then
+ page = page + 1
+ end
+ if page < 1 then
+ page = 1
+ end
+ if page > max_page then
+ page = max_page
+ end
+ meta:set_int("page", page)
+ meta:set_string("formspec", get_chest_formspec(page))
+ end
+ end,
+})
+
+minetest.register_on_mods_loaded(function()
+ local items = {}
+ for itemstring,_ in pairs(minetest.registered_items) do
+ if itemstring ~= "" and itemstring ~= "unknown" and itemstring ~= "ignore" then
+ table.insert(items, itemstring)
+ end
+ end
+ --[[ Sort items in this order:
+ * Chest of Everything
+ * Test tools
+ * Other tools
+ * Craftitems
+ * Other items
+ * Dummy items ]]
+ local function compare(item1, item2)
+ local def1 = minetest.registered_items[item1]
+ local def2 = minetest.registered_items[item2]
+ local tool1 = def1.type == "tool"
+ local tool2 = def2.type == "tool"
+ local testtool1 = minetest.get_item_group(item1, "testtool") == 1
+ local testtool2 = minetest.get_item_group(item2, "testtool") == 1
+ local dummy1 = minetest.get_item_group(item1, "dummy") == 1
+ local dummy2 = minetest.get_item_group(item2, "dummy") == 1
+ local craftitem1 = def1.type == "craft"
+ local craftitem2 = def2.type == "craft"
+ if item1 == "chest_of_everything:chest" then
+ return true
+ elseif item2 == "chest_of_everything:chest" then
+ return false
+ elseif dummy1 and not dummy2 then
+ return false
+ elseif not dummy1 and dummy2 then
+ return true
+ elseif testtool1 and not testtool2 then
+ return true
+ elseif not testtool1 and testtool2 then
+ return false
+ elseif tool1 and not tool2 then
+ return true
+ elseif not tool1 and tool2 then
+ return false
+ elseif craftitem1 and not craftitem2 then
+ return true
+ elseif not craftitem1 and craftitem2 then
+ return false
+ else
+ return item1 < item2
+ end
+ end
+ table.sort(items, compare)
+ inv_everything:set_size("main", #items)
+ max_page = math.ceil(#items / 32)
+ for i=1, #items do
+ inv_everything:add_item("main", items[i])
+ end
+end)
diff --git a/games/devtest/mods/chest_of_everything/mod.conf b/games/devtest/mods/chest_of_everything/mod.conf
new file mode 100644
index 000000000..4a4425e05
--- /dev/null
+++ b/games/devtest/mods/chest_of_everything/mod.conf
@@ -0,0 +1,2 @@
+name = chest_of_everything
+description = Adds the chest of everything from which you can take all items
diff --git a/games/devtest/mods/chest_of_everything/textures/chest_of_everything_chest.png b/games/devtest/mods/chest_of_everything/textures/chest_of_everything_chest.png
new file mode 100644
index 000000000..6b2fd58d5
--- /dev/null
+++ b/games/devtest/mods/chest_of_everything/textures/chest_of_everything_chest.png
Binary files differ
diff --git a/games/devtest/mods/dignodes/init.lua b/games/devtest/mods/dignodes/init.lua
new file mode 100644
index 000000000..833150873
--- /dev/null
+++ b/games/devtest/mods/dignodes/init.lua
@@ -0,0 +1,37 @@
+local groups = {
+ "cracky", "dig_immediate"
+}
+
+-- Register dig nodes with 1 digging group, a rating between 1-3 and a level between 0-2
+for g=1, #groups do
+ local gr = groups[g]
+ for r=1, 3 do
+ for l=0, 2 do
+ if not (gr=="dig_immediate" and (l>0 or r==1)) then
+ local d
+ if l > 0 then
+ d = string.format("Dig Test Node: %s=%d, level=%d", gr, r, l)
+ else
+ d = string.format("Dig Test Node: %s=%d", gr, r)
+ end
+ local tile = "dignodes_"..gr..".png^dignodes_rating"..r..".png"
+ if l==1 then
+ tile = tile .. "^[colorize:#FFFF00:127"
+ elseif l==2 then
+ tile = tile .. "^[colorize:#FF0000:127"
+ end
+ minetest.register_node("dignodes:"..gr.."_"..r.."_"..l, {
+ description = d,
+ tiles = { tile },
+ groups = { [gr] = r, level = l },
+ })
+ end
+ end
+ end
+end
+
+-- Node without any digging groups
+minetest.register_node("dignodes:none", {
+ description = "Dig Test Node: groupless",
+ tiles = {"dignodes_none.png"},
+})
diff --git a/games/devtest/mods/dignodes/mod.conf b/games/devtest/mods/dignodes/mod.conf
new file mode 100644
index 000000000..52a80d66e
--- /dev/null
+++ b/games/devtest/mods/dignodes/mod.conf
@@ -0,0 +1,2 @@
+name = dignodes
+description = Nodes with different digging groups
diff --git a/games/devtest/mods/dignodes/textures/dignodes_choppy.png b/games/devtest/mods/dignodes/textures/dignodes_choppy.png
new file mode 100644
index 000000000..a73fc2424
--- /dev/null
+++ b/games/devtest/mods/dignodes/textures/dignodes_choppy.png
Binary files differ
diff --git a/games/devtest/mods/dignodes/textures/dignodes_cracky.png b/games/devtest/mods/dignodes/textures/dignodes_cracky.png
new file mode 100644
index 000000000..eb84e3079
--- /dev/null
+++ b/games/devtest/mods/dignodes/textures/dignodes_cracky.png
Binary files differ
diff --git a/games/devtest/mods/dignodes/textures/dignodes_crumbly.png b/games/devtest/mods/dignodes/textures/dignodes_crumbly.png
new file mode 100644
index 000000000..23f2f7c71
--- /dev/null
+++ b/games/devtest/mods/dignodes/textures/dignodes_crumbly.png
Binary files differ
diff --git a/games/devtest/mods/dignodes/textures/dignodes_dig_immediate.png b/games/devtest/mods/dignodes/textures/dignodes_dig_immediate.png
new file mode 100644
index 000000000..a532ad90b
--- /dev/null
+++ b/games/devtest/mods/dignodes/textures/dignodes_dig_immediate.png
Binary files differ
diff --git a/games/devtest/mods/dignodes/textures/dignodes_none.png b/games/devtest/mods/dignodes/textures/dignodes_none.png
new file mode 100644
index 000000000..60f13650b
--- /dev/null
+++ b/games/devtest/mods/dignodes/textures/dignodes_none.png
Binary files differ
diff --git a/games/devtest/mods/dignodes/textures/dignodes_rating1.png b/games/devtest/mods/dignodes/textures/dignodes_rating1.png
new file mode 100644
index 000000000..d2fee3a23
--- /dev/null
+++ b/games/devtest/mods/dignodes/textures/dignodes_rating1.png
Binary files differ
diff --git a/games/devtest/mods/dignodes/textures/dignodes_rating2.png b/games/devtest/mods/dignodes/textures/dignodes_rating2.png
new file mode 100644
index 000000000..15329b93f
--- /dev/null
+++ b/games/devtest/mods/dignodes/textures/dignodes_rating2.png
Binary files differ
diff --git a/games/devtest/mods/dignodes/textures/dignodes_rating3.png b/games/devtest/mods/dignodes/textures/dignodes_rating3.png
new file mode 100644
index 000000000..37216bfd1
--- /dev/null
+++ b/games/devtest/mods/dignodes/textures/dignodes_rating3.png
Binary files differ
diff --git a/games/devtest/mods/experimental/commands.lua b/games/devtest/mods/experimental/commands.lua
new file mode 100644
index 000000000..e42ae954d
--- /dev/null
+++ b/games/devtest/mods/experimental/commands.lua
@@ -0,0 +1,221 @@
+minetest.register_chatcommand("test_inv", {
+ params = "",
+ description = "Test: Modify player's inventory formspec",
+ func = function(name, param)
+ local player = minetest.get_player_by_name(name)
+ if not player then
+ return false, "No player."
+ end
+ player:set_inventory_formspec(
+ "size[13,7.5]"..
+ "image[6,0.6;1,2;player.png]"..
+ "list[current_player;main;5,3.5;8,4;]"..
+ "list[current_player;craft;8,0;3,3;]"..
+ "list[current_player;craftpreview;12,1;1,1;]"..
+ "list[detached:test_inventory;main;0,0;4,6;0]"..
+ "button[0.5,7;2,1;button1;Button 1]"..
+ "button_exit[2.5,7;2,1;button2;Exit Button]")
+ return true, "Done."
+ end,
+})
+
+minetest.register_chatcommand("test_bulk_set_node", {
+ params = "",
+ description = "Test: Bulk-set 9×9×9 stone nodes",
+ func = function(name, param)
+ local player = minetest.get_player_by_name(name)
+ if not player then
+ return false, "No player."
+ end
+ local pos_list = {}
+ local ppos = player:get_pos()
+ local i = 1
+ for x=2,10 do
+ for y=2,10 do
+ for z=2,10 do
+ pos_list[i] = {x=ppos.x + x,y = ppos.y + y,z = ppos.z + z}
+ i = i + 1
+ end
+ end
+ end
+ minetest.bulk_set_node(pos_list, {name = "mapgen_stone"})
+ return true, "Done."
+ end,
+})
+
+minetest.register_chatcommand("bench_bulk_set_node", {
+ params = "",
+ description = "Benchmark: Bulk-set 99×99×99 stone nodes",
+ func = function(name, param)
+ local player = minetest.get_player_by_name(name)
+ if not player then
+ return false, "No player."
+ end
+ local pos_list = {}
+ local ppos = player:get_pos()
+ local i = 1
+ for x=2,100 do
+ for y=2,100 do
+ for z=2,100 do
+ pos_list[i] = {x=ppos.x + x,y = ppos.y + y,z = ppos.z + z}
+ i = i + 1
+ end
+ end
+ end
+
+ minetest.chat_send_player(name, "Benchmarking minetest.bulk_set_node. Warming up ...");
+
+ -- warm up with stone to prevent having different callbacks
+ -- due to different node topology
+ minetest.bulk_set_node(pos_list, {name = "mapgen_stone"})
+
+ minetest.chat_send_player(name, "Warming up finished, now benchmarking ...");
+
+ local start_time = minetest.get_us_time()
+ for i=1,#pos_list do
+ minetest.set_node(pos_list[i], {name = "mapgen_stone"})
+ end
+ local middle_time = minetest.get_us_time()
+ minetest.bulk_set_node(pos_list, {name = "mapgen_stone"})
+ local end_time = minetest.get_us_time()
+ local msg = string.format("Benchmark results: minetest.set_node loop: %.2f ms; minetest.bulk_set_node: %.2f ms",
+ ((middle_time - start_time)) / 1000,
+ ((end_time - middle_time)) / 1000
+ )
+ return true, msg
+ end,
+})
+
+local function advance_pos(pos, start_pos, advance_z)
+ if advance_z then
+ pos.z = pos.z + 2
+ pos.x = start_pos.x
+ else
+ pos.x = pos.x + 2
+ end
+ if pos.x > 30900 or pos.x - start_pos.x > 46 then
+ pos.x = start_pos.x
+ pos.z = pos.z + 2
+ end
+ if pos.z > 30900 then
+ -- We ran out of space! Aborting
+ aborted = true
+ return false
+ end
+ return pos
+end
+
+local function place_nodes(param)
+ local nodes = param.nodes
+ local name = param.name
+ local pos = param.pos
+ local start_pos = param.start_pos
+ table.sort(nodes)
+ minetest.chat_send_player(name, "Placing nodes …")
+ local nodes_placed = 0
+ local aborted = false
+ for n=1, #nodes do
+ local itemstring = nodes[n]
+ local def = minetest.registered_nodes[itemstring]
+ local p2_max = 0
+ if param.param ~= "no_param2" then
+ -- Also test the param2 values of the nodes
+ -- ... but we only use permissible param2 values
+ if def.paramtype2 == "wallmounted" then
+ p2_max = 5
+ elseif def.paramtype2 == "facedir" then
+ p2_max = 23
+ elseif def.paramtype2 == "glasslikeliquidlevel" then
+ p2_max = 63
+ elseif def.paramtype2 == "meshoptions" and def.drawtype == "plantlike" then
+ p2_max = 63
+ elseif def.paramtype2 == "leveled" then
+ p2_max = 127
+ elseif def.paramtype2 == "degrotate" and (def.drawtype == "plantlike" or def.drawtype == "mesh") then
+ p2_max = 239
+ elseif def.paramtype2 == "colorfacedir" or
+ def.paramtype2 == "colorwallmounted" or
+ def.paramtype2 == "colordegrotate" or
+ def.paramtype2 == "color" then
+ p2_max = 255
+ end
+ end
+ for p2 = 0, p2_max do
+ -- Skip undefined param2 values
+ if not ((def.paramtype2 == "meshoptions" and p2 % 8 > 4) or
+ (def.paramtype2 == "colorwallmounted" and p2 % 8 > 5) or
+ ((def.paramtype2 == "colorfacedir" or def.paramtype2 == "colordegrotate")
+ and p2 % 32 > 23)) then
+
+ minetest.set_node(pos, { name = itemstring, param2 = p2 })
+ nodes_placed = nodes_placed + 1
+ pos = advance_pos(pos, start_pos)
+ if not pos then
+ aborted = true
+ break
+ end
+ end
+ end
+ if aborted then
+ break
+ end
+ end
+ if aborted then
+ minetest.chat_send_player(name, "Not all nodes could be placed, please move further away from the world boundary. Nodes placed: "..nodes_placed)
+ end
+ minetest.chat_send_player(name, "Nodes placed: "..nodes_placed..".")
+end
+
+local function after_emerge(blockpos, action, calls_remaining, param)
+ if calls_remaining == 0 then
+ place_nodes(param)
+ end
+end
+
+minetest.register_chatcommand("test_place_nodes", {
+ params = "[ no_param2 ]",
+ description = "Test: Place all non-experimental nodes and optionally their permissible param2 variants",
+ func = function(name, param)
+ local player = minetest.get_player_by_name(name)
+ if not player then
+ return false, "No player."
+ end
+ local pos = vector.floor(player:get_pos())
+ pos.x = math.ceil(pos.x + 3)
+ pos.z = math.ceil(pos.z + 3)
+ pos.y = math.ceil(pos.y + 1)
+ local start_pos = table.copy(pos)
+ if pos.x > 30800 then
+ return false, "Too close to world boundary (+X). Please move to X < 30800."
+ end
+ if pos.z > 30800 then
+ return false, "Too close to world boundary (+Z). Please move to Z < 30800."
+ end
+
+ local aborted = false
+ local nodes = {}
+ local emerge_estimate = 0
+ for itemstring, def in pairs(minetest.registered_nodes) do
+ if itemstring ~= "ignore" and string.sub(itemstring, 1, 13) ~= "experimental:" then
+ table.insert(nodes, itemstring)
+ if def.paramtype2 == 0 then
+ emerge_estimate = emerge_estimate + 1
+ else
+ emerge_estimate = emerge_estimate + 255
+ end
+ end
+ end
+ -- Emerge area to make sure that all nodes are being placed.
+ -- Note we will emerge much more than we need to (overestimation),
+ -- the estimation code could be improved performance-wise …
+ local length = 16 + math.ceil(emerge_estimate / 24) * 2
+ minetest.emerge_area(start_pos,
+ { x = start_pos.x + 46, y = start_pos.y, z = start_pos.z + length },
+ after_emerge, { nodes = nodes, name = name, pos = pos, start_pos = start_pos, param = param })
+ return true, "Emerging area …"
+ end,
+})
+
+core.register_on_chatcommand(function(name, command, params)
+ minetest.log("action", "caught command '"..command.."', issued by '"..name.."'. Parameters: '"..params.."'")
+end)
diff --git a/games/devtest/mods/experimental/detached.lua b/games/devtest/mods/experimental/detached.lua
new file mode 100644
index 000000000..673adfdd4
--- /dev/null
+++ b/games/devtest/mods/experimental/detached.lua
@@ -0,0 +1,29 @@
+-- Create a detached inventory
+local inv = minetest.create_detached_inventory("test_inventory", {
+ allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
+ experimental.print_to_everything("allow move asked")
+ return count -- Allow all
+ end,
+ allow_put = function(inv, listname, index, stack, player)
+ experimental.print_to_everything("allow put asked")
+ return 1 -- Allow only 1
+ end,
+ allow_take = function(inv, listname, index, stack, player)
+ experimental.print_to_everything("allow take asked")
+ return 4 -- Allow 4 at max
+ end,
+ on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
+ experimental.print_to_everything(player:get_player_name().." moved items")
+ end,
+ on_put = function(inv, listname, index, stack, player)
+ experimental.print_to_everything(player:get_player_name().." put items")
+ end,
+ on_take = function(inv, listname, index, stack, player)
+ experimental.print_to_everything(player:get_player_name().." took items")
+ end,
+})
+inv:set_size("main", 4*6)
+inv:add_item("main", "experimental:callback_node")
+inv:add_item("main", "experimental:particle_spawner")
+
+
diff --git a/games/devtest/mods/experimental/init.lua b/games/devtest/mods/experimental/init.lua
new file mode 100644
index 000000000..b292f792e
--- /dev/null
+++ b/games/devtest/mods/experimental/init.lua
@@ -0,0 +1,23 @@
+--
+-- Experimental things
+--
+
+experimental = {}
+
+dofile(minetest.get_modpath("experimental").."/detached.lua")
+dofile(minetest.get_modpath("experimental").."/items.lua")
+dofile(minetest.get_modpath("experimental").."/commands.lua")
+
+function experimental.print_to_everything(msg)
+ minetest.log("action", msg)
+ minetest.chat_send_all(msg)
+end
+
+minetest.log("info", "[experimental] modname="..dump(minetest.get_current_modname()))
+minetest.log("info", "[experimental] modpath="..dump(minetest.get_modpath("experimental")))
+minetest.log("info", "[experimental] worldpath="..dump(minetest.get_worldpath()))
+
+
+minetest.register_on_mods_loaded(function()
+ minetest.log("action", "[experimental] on_mods_loaded()")
+end)
diff --git a/games/devtest/mods/experimental/items.lua b/games/devtest/mods/experimental/items.lua
new file mode 100644
index 000000000..94be71cf7
--- /dev/null
+++ b/games/devtest/mods/experimental/items.lua
@@ -0,0 +1,105 @@
+minetest.register_node("experimental:callback_node", {
+ description = "Callback Test Node (construct/destruct/timer)",
+ tiles = {"experimental_callback_node.png"},
+ groups = {dig_immediate=3},
+ -- This was known to cause a bug in minetest.item_place_node() when used
+ -- via minetest.place_node(), causing a placer with no position
+ paramtype2 = "facedir",
+ drop = "",
+
+ on_construct = function(pos)
+ experimental.print_to_everything("experimental:callback_node:on_construct("..minetest.pos_to_string(pos)..")")
+ local meta = minetest.get_meta(pos)
+ meta:set_string("mine", "test")
+ local timer = minetest.get_node_timer(pos)
+ timer:start(4, 3)
+ end,
+
+ after_place_node = function(pos, placer)
+ experimental.print_to_everything("experimental:callback_node:after_place_node("..minetest.pos_to_string(pos)..")")
+ local meta = minetest.get_meta(pos)
+ if meta:get_string("mine") == "test" then
+ experimental.print_to_everything("correct metadata found")
+ else
+ experimental.print_to_everything("incorrect metadata found")
+ end
+ end,
+
+ on_destruct = function(pos)
+ experimental.print_to_everything("experimental:callback_node:on_destruct("..minetest.pos_to_string(pos)..")")
+ end,
+
+ after_destruct = function(pos)
+ experimental.print_to_everything("experimental:callback_node:after_destruct("..minetest.pos_to_string(pos)..")")
+ end,
+
+ after_dig_node = function(pos, oldnode, oldmetadata, digger)
+ experimental.print_to_everything("experimental:callback_node:after_dig_node("..minetest.pos_to_string(pos)..")")
+ end,
+
+ on_timer = function(pos, elapsed)
+ experimental.print_to_everything("on_timer(): elapsed="..dump(elapsed))
+ return true
+ end,
+})
+
+minetest.register_tool("experimental:privatizer", {
+ description = "Node Meta Privatizer".."\n"..
+ "Punch: Marks 'infotext' and 'formspec' meta fields of chest as private",
+ inventory_image = "experimental_tester_tool_1.png",
+ groups = { testtool = 1, disable_repair = 1 },
+ on_use = function(itemstack, user, pointed_thing)
+ if pointed_thing.type == "node" then
+ local node = minetest.get_node(pointed_thing.under)
+ if node.name == "chest:chest" then
+ local p = pointed_thing.under
+ minetest.log("action", "Privatizer used at "..minetest.pos_to_string(p))
+ minetest.get_meta(p):mark_as_private({"infotext", "formspec"})
+ if user and user:is_player() then
+ minetest.chat_send_player(user:get_player_name(), "Chest metadata (infotext, formspec) set private!")
+ end
+ return
+ end
+ end
+ if user and user:is_player() then
+ minetest.chat_send_player(user:get_player_name(), "Privatizer can only be used on chest!")
+ end
+ end,
+})
+
+minetest.register_tool("experimental:particle_spawner", {
+ description = "Particle Spawner".."\n"..
+ "Punch: Spawn random test particle",
+ inventory_image = "experimental_tester_tool_1.png^[invert:g",
+ groups = { testtool = 1, disable_repair = 1 },
+ on_use = function(itemstack, user, pointed_thing)
+ local pos = minetest.get_pointed_thing_position(pointed_thing, true)
+ if pos == nil then
+ if user then
+ pos = user:get_pos()
+ end
+ end
+ pos = vector.add(pos, {x=0, y=0.5, z=0})
+ local tex, anim
+ if math.random(0, 1) == 0 then
+ tex = "experimental_particle_sheet.png"
+ anim = {type="sheet_2d", frames_w=3, frames_h=2, frame_length=0.5}
+ else
+ tex = "experimental_particle_vertical.png"
+ anim = {type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
+ end
+
+ minetest.add_particle({
+ pos = pos,
+ velocity = {x=0, y=0, z=0},
+ acceleration = {x=0, y=0.04, z=0},
+ expirationtime = 6,
+ collisiondetection = true,
+ texture = tex,
+ animation = anim,
+ size = 4,
+ glow = math.random(0, 5),
+ })
+ end,
+})
+
diff --git a/games/devtest/mods/experimental/mod.conf b/games/devtest/mods/experimental/mod.conf
new file mode 100644
index 000000000..cf0f9cb42
--- /dev/null
+++ b/games/devtest/mods/experimental/mod.conf
@@ -0,0 +1,2 @@
+name = experimental
+description = Chaotic mod containing unstructured tests for testing out engine features. The features in this mod should be moved to other mods.
diff --git a/games/devtest/mods/experimental/textures/experimental_callback_node.png b/games/devtest/mods/experimental/textures/experimental_callback_node.png
new file mode 100644
index 000000000..e9d87434c
--- /dev/null
+++ b/games/devtest/mods/experimental/textures/experimental_callback_node.png
Binary files differ
diff --git a/games/devtest/mods/experimental/textures/experimental_particle_sheet.png b/games/devtest/mods/experimental/textures/experimental_particle_sheet.png
new file mode 100644
index 000000000..6d70394e4
--- /dev/null
+++ b/games/devtest/mods/experimental/textures/experimental_particle_sheet.png
Binary files differ
diff --git a/games/devtest/mods/experimental/textures/experimental_particle_vertical.png b/games/devtest/mods/experimental/textures/experimental_particle_vertical.png
new file mode 100644
index 000000000..0320b7545
--- /dev/null
+++ b/games/devtest/mods/experimental/textures/experimental_particle_vertical.png
Binary files differ
diff --git a/games/devtest/mods/experimental/textures/experimental_tester_tool_1.png b/games/devtest/mods/experimental/textures/experimental_tester_tool_1.png
new file mode 100644
index 000000000..5df416a58
--- /dev/null
+++ b/games/devtest/mods/experimental/textures/experimental_tester_tool_1.png
Binary files differ
diff --git a/games/devtest/mods/give_initial_stuff/init.lua b/games/devtest/mods/give_initial_stuff/init.lua
new file mode 100644
index 000000000..491a531e4
--- /dev/null
+++ b/games/devtest/mods/give_initial_stuff/init.lua
@@ -0,0 +1,37 @@
+local give_if_not_gotten_already = function(inv, list, item)
+ if not inv:contains_item(list, item) then
+ inv:add_item(list, item)
+ end
+end
+
+local give_initial_stuff = function(player)
+ local inv = player:get_inventory()
+ give_if_not_gotten_already(inv, "main", "basetools:pick_mese")
+ give_if_not_gotten_already(inv, "main", "basetools:axe_steel")
+ give_if_not_gotten_already(inv, "main", "basetools:shovel_steel")
+ give_if_not_gotten_already(inv, "main", "bucket:bucket")
+ give_if_not_gotten_already(inv, "main", "testnodes:light14")
+ give_if_not_gotten_already(inv, "main", "chest_of_everything:chest")
+ minetest.log("action", "[give_initial_stuff] Giving initial stuff to "..player:get_player_name())
+end
+
+minetest.register_on_newplayer(function(player)
+ if minetest.settings:get_bool("give_initial_stuff", true) then
+ give_initial_stuff(player)
+ end
+end)
+
+minetest.register_chatcommand("stuff", {
+ params = "",
+ privs = { give = true },
+ description = "Give yourself initial items",
+ func = function(name, param)
+ local player = minetest.get_player_by_name(name)
+ if not player or not player:is_player() then
+ return false, "No player."
+ end
+ give_initial_stuff(player)
+ return true
+ end,
+})
+
diff --git a/games/devtest/mods/give_initial_stuff/mod.conf b/games/devtest/mods/give_initial_stuff/mod.conf
new file mode 100644
index 000000000..1ba49f52a
--- /dev/null
+++ b/games/devtest/mods/give_initial_stuff/mod.conf
@@ -0,0 +1,3 @@
+name = give_initial_stuff
+description = Gives items to players on join
+depends = basetools, bucket, chest_of_everything, testnodes
diff --git a/games/devtest/mods/initial_message/init.lua b/games/devtest/mods/initial_message/init.lua
new file mode 100644
index 000000000..59e9f5f4b
--- /dev/null
+++ b/games/devtest/mods/initial_message/init.lua
@@ -0,0 +1,9 @@
+minetest.register_on_joinplayer(function(player)
+ local cb = function(player)
+ if not player or not player:is_player() then
+ return
+ end
+ minetest.chat_send_player(player:get_player_name(), "This is the \"Development Test\" [devtest], meant only for testing and development. Use Minetest Game for the real thing.")
+ end
+ minetest.after(2.0, cb, player)
+end)
diff --git a/games/devtest/mods/initial_message/mod.conf b/games/devtest/mods/initial_message/mod.conf
new file mode 100644
index 000000000..32aa2ac4e
--- /dev/null
+++ b/games/devtest/mods/initial_message/mod.conf
@@ -0,0 +1,2 @@
+name = initial_message
+description = Show message to joining players explaining what this testing game is about
diff --git a/games/devtest/mods/mapgen/init.lua b/games/devtest/mods/mapgen/init.lua
new file mode 100644
index 000000000..a5f9128fb
--- /dev/null
+++ b/games/devtest/mods/mapgen/init.lua
@@ -0,0 +1,104 @@
+--
+-- Aliases for map generator outputs
+--
+
+-- ESSENTIAL node aliases
+-- Basic nodes
+minetest.register_alias("mapgen_stone", "basenodes:stone")
+minetest.register_alias("mapgen_water_source", "basenodes:water_source")
+minetest.register_alias("mapgen_river_water_source", "basenodes:river_water_source")
+
+-- Additional essential aliases for v6
+minetest.register_alias("mapgen_lava_source", "basenodes:lava_source")
+minetest.register_alias("mapgen_dirt", "basenodes:dirt")
+minetest.register_alias("mapgen_dirt_with_grass", "basenodes:dirt_with_grass")
+minetest.register_alias("mapgen_sand", "basenodes:sand")
+minetest.register_alias("mapgen_tree", "basenodes:tree")
+minetest.register_alias("mapgen_leaves", "basenodes:leaves")
+minetest.register_alias("mapgen_apple", "basenodes:apple")
+
+-- Essential alias for dungeons
+minetest.register_alias("mapgen_cobble", "basenodes:cobble")
+
+-- Optional aliases for v6 (they all have fallback values in the engine)
+if minetest.settings:get_bool("devtest_v6_mapgen_aliases", false) then
+ minetest.register_alias("mapgen_gravel", "basenodes:gravel")
+ minetest.register_alias("mapgen_desert_stone", "basenodes:desert_stone")
+ minetest.register_alias("mapgen_desert_sand", "basenodes:desert_sand")
+ minetest.register_alias("mapgen_dirt_with_snow", "basenodes:dirt_with_snow")
+ minetest.register_alias("mapgen_snowblock", "basenodes:snowblock")
+ minetest.register_alias("mapgen_snow", "basenodes:snow")
+ minetest.register_alias("mapgen_ice", "basenodes:ice")
+ minetest.register_alias("mapgen_junglegrass", "basenodes:junglegrass")
+ minetest.register_alias("mapgen_jungletree", "basenodes:jungletree")
+ minetest.register_alias("mapgen_jungleleaves", "basenodes:jungleleaves")
+ minetest.register_alias("mapgen_pine_tree", "basenodes:pine_tree")
+ minetest.register_alias("mapgen_pine_needles", "basenodes:pine_needles")
+end
+-- Optional alias for mossycobble (should fall back to cobble)
+if minetest.settings:get_bool("devtest_dungeon_mossycobble", false) then
+ minetest.register_alias("mapgen_mossycobble", "basenodes:mossycobble")
+end
+-- Optional aliases for dungeon stairs (should fall back to full nodes)
+if minetest.settings:get_bool("devtest_dungeon_stairs", false) then
+ minetest.register_alias("mapgen_stair_cobble", "stairs:stair_cobble")
+ if minetest.settings:get_bool("devtest_v6_mapgen_aliases", false) then
+ minetest.register_alias("mapgen_stair_desert_stone", "stairs:stair_desert_stone")
+ end
+end
+
+--
+-- Register biomes for biome API
+--
+
+minetest.clear_registered_biomes()
+minetest.clear_registered_decorations()
+
+if minetest.settings:get_bool("devtest_register_biomes", true) then
+ minetest.register_biome({
+ name = "mapgen:grassland",
+ node_top = "basenodes:dirt_with_grass",
+ depth_top = 1,
+ node_filler = "basenodes:dirt",
+ depth_filler = 1,
+ node_riverbed = "basenodes:sand",
+ depth_riverbed = 2,
+ node_dungeon = "basenodes:cobble",
+ node_dungeon_alt = "basenodes:mossycobble",
+ node_dungeon_stair = "stairs:stair_cobble",
+ y_max = 31000,
+ y_min = 4,
+ heat_point = 50,
+ humidity_point = 50,
+ })
+
+ minetest.register_biome({
+ name = "mapgen:grassland_ocean",
+ node_top = "basenodes:sand",
+ depth_top = 1,
+ node_filler = "basenodes:sand",
+ depth_filler = 3,
+ node_riverbed = "basenodes:sand",
+ depth_riverbed = 2,
+ node_cave_liquid = "basenodes:water_source",
+ node_dungeon = "basenodes:cobble",
+ node_dungeon_alt = "basenodes:mossycobble",
+ node_dungeon_stair = "stairs:stair_cobble",
+ y_max = 3,
+ y_min = -255,
+ heat_point = 50,
+ humidity_point = 50,
+ })
+
+ minetest.register_biome({
+ name = "mapgen:grassland_under",
+ node_cave_liquid = {"basenodes:water_source", "basenodes:lava_source"},
+ node_dungeon = "basenodes:cobble",
+ node_dungeon_alt = "basenodes:mossycobble",
+ node_dungeon_stair = "stairs:stair_cobble",
+ y_max = -256,
+ y_min = -31000,
+ heat_point = 50,
+ humidity_point = 50,
+ })
+end
diff --git a/games/devtest/mods/mapgen/mod.conf b/games/devtest/mods/mapgen/mod.conf
new file mode 100644
index 000000000..15750ccbe
--- /dev/null
+++ b/games/devtest/mods/mapgen/mod.conf
@@ -0,0 +1,3 @@
+name = mapgen
+description = Minimal map generator
+depends = basenodes
diff --git a/games/devtest/mods/modchannels/init.lua b/games/devtest/mods/modchannels/init.lua
new file mode 100644
index 000000000..ee925f09b
--- /dev/null
+++ b/games/devtest/mods/modchannels/init.lua
@@ -0,0 +1,14 @@
+--
+-- Mod channels experimental handlers
+--
+local mod_channel = minetest.mod_channel_join("experimental_preview")
+
+minetest.register_on_modchannel_message(function(channel, sender, message)
+ minetest.log("action", "[modchannels] Server received message `" .. message
+ .. "` on channel `" .. channel .. "` from sender `" .. sender .. "`")
+
+ if mod_channel:is_writeable() then
+ mod_channel:send_all("experimental answers to preview")
+ mod_channel:leave()
+ end
+end)
diff --git a/games/devtest/mods/modchannels/mod.conf b/games/devtest/mods/modchannels/mod.conf
new file mode 100644
index 000000000..7c13aadfb
--- /dev/null
+++ b/games/devtest/mods/modchannels/mod.conf
@@ -0,0 +1,2 @@
+name = modchannels
+description = Add experimental mod channel handlers
diff --git a/games/devtest/mods/soundstuff/init.lua b/games/devtest/mods/soundstuff/init.lua
new file mode 100644
index 000000000..b263a3f35
--- /dev/null
+++ b/games/devtest/mods/soundstuff/init.lua
@@ -0,0 +1,174 @@
+local simple_nodes = {
+ footstep = { "Footstep Sound Node", "soundstuff_node_footstep.png" },
+ dig = { "Dig Sound Node", "soundstuff_node_dig.png" },
+ dug = { "Dug Sound Node", "soundstuff_node_dug.png" },
+ place = { "Place Sound Node", "soundstuff_node_place.png" },
+ place_failed = { "Place Failed Sound Node", "soundstuff_node_place_failed.png" },
+}
+
+for k,v in pairs(simple_nodes) do
+ minetest.register_node("soundstuff:"..k, {
+ description = v[1],
+ tiles = {"soundstuff_node_sound.png","soundstuff_node_sound.png",v[2]},
+ groups = {dig_immediate=2},
+ sounds = {
+ [k] = { name = "soundstuff_mono", gain = 1.0 },
+ }
+ })
+end
+
+minetest.register_node("soundstuff:place_failed_attached", {
+ description = "Attached Place Failed Sound Node",
+ tiles = {"soundstuff_node_sound.png", "soundstuff_node_sound.png", "soundstuff_node_place_failed.png"},
+ groups = {dig_immediate=2, attached_node=1},
+ drawtype = "nodebox",
+ paramtype = "light",
+ node_box = { type = "fixed", fixed = {
+ { -7/16, -7/16, -7/16, 7/16, 7/16, 7/16 },
+ { -0.5, -0.5, -0.5, 0.5, -7/16, 0.5 },
+ }},
+ sounds = {
+ place_failed = { name = "soundstuff_mono", gain = 1.0 },
+ },
+})
+
+minetest.register_node("soundstuff:fall", {
+ description = "Fall Sound Node",
+ tiles = {"soundstuff_node_sound.png", "soundstuff_node_sound.png", "soundstuff_node_fall.png"},
+ groups = {dig_immediate=2, falling_node=1},
+ sounds = {
+ fall = { name = "soundstuff_mono", gain = 1.0 },
+ }
+})
+
+minetest.register_node("soundstuff:fall_attached", {
+ description = "Attached Fall Sound Node",
+ tiles = {"soundstuff_node_sound.png", "soundstuff_node_sound.png", "soundstuff_node_fall.png"},
+ groups = {dig_immediate=2, attached_node=1},
+ drawtype = "nodebox",
+ paramtype = "light",
+ node_box = { type = "fixed", fixed = {
+ { -7/16, -7/16, -7/16, 7/16, 7/16, 7/16 },
+ { -0.5, -0.5, -0.5, 0.5, -7/16, 0.5 },
+ }},
+ sounds = {
+ fall = { name = "soundstuff_mono", gain = 1.0 },
+ }
+})
+
+minetest.register_node("soundstuff:footstep_liquid", {
+ description = "Liquid Footstep Sound Node",
+ drawtype = "liquid",
+ tiles = {
+ "soundstuff_node_sound.png^[colorize:#0000FF:127^[opacity:190",
+ },
+ special_tiles = {
+ {name = "soundstuff_node_sound.png^[colorize:#0000FF:127^[opacity:190",
+ backface_culling = false},
+ {name = "soundstuff_node_sound.png^[colorize:#0000FF:127^[opacity:190",
+ backface_culling = true},
+ },
+ liquids_pointable = true,
+ liquidtype = "source",
+ liquid_alternative_flowing = "soundstuff:footstep_liquid",
+ liquid_alternative_source = "soundstuff:footstep_liquid",
+ liquid_renewable = false,
+ liquid_range = 0,
+ liquid_viscosity = 0,
+ use_texture_alpha = "blend",
+ paramtype = "light",
+ walkable = false,
+ pointable = false,
+ diggable = false,
+ buildable_to = true,
+ is_ground_content = false,
+ post_effect_color = {a = 64, r = 0, g = 0, b = 200},
+ sounds = {
+ footstep = { name = "soundstuff_mono", gain = 1.0 },
+ }
+})
+
+minetest.register_node("soundstuff:footstep_climbable", {
+ description = "Climbable Footstep Sound Node",
+ drawtype = "allfaces",
+ tiles = {
+ "soundstuff_node_climbable.png",
+ },
+ paramtype = "light",
+ sunlight_propagates = true,
+ walkable = false,
+ climbable = true,
+ is_ground_content = false,
+ groups = { dig_immediate = 2 },
+ sounds = {
+ footstep = { name = "soundstuff_mono", gain = 1.0 },
+ }
+})
+
+
+
+minetest.register_craftitem("soundstuff:eat", {
+ description = "Eat Sound Item".."\n"..
+ "Makes a sound when 'eaten' (with punch key)",
+ inventory_image = "soundstuff_eat.png",
+ on_use = minetest.item_eat(0),
+ sound = {
+ eat = { name = "soundstuff_mono", gain = 1.0 },
+ }
+})
+
+minetest.register_tool("soundstuff:breaks", {
+ description = "Break Sound Tool".."\n"..
+ "Digs cracky=3 and more".."\n"..
+ "Makes a sound when it breaks",
+ inventory_image = "soundstuff_node_dug.png",
+ sound = {
+ breaks = { name = "soundstuff_mono", gain = 1.0 },
+ },
+ tool_capabilities = {
+ max_drop_level=0,
+ groupcaps={
+ cracky={times={[2]=2.00, [3]=1.20}, uses=1, maxlevel=0},
+ choppy={times={[2]=2.00, [3]=1.20}, uses=1, maxlevel=0},
+ snappy={times={[2]=2.00, [3]=1.20}, uses=1, maxlevel=0},
+ crumbly={times={[2]=2.00, [3]=1.20}, uses=1, maxlevel=0},
+ },
+ },
+})
+
+-- Plays sound repeatedly
+minetest.register_node("soundstuff:positional", {
+ description = "Positional Sound Node",
+ on_construct = function(pos)
+ local timer = minetest.get_node_timer(pos)
+ timer:start(0)
+ end,
+ on_timer = function(pos, elapsed)
+ local node = minetest.get_node(pos)
+ local dist = node.param2
+ if dist == 0 then
+ dist = nil
+ end
+ minetest.sound_play("soundstuff_mono", { pos = pos, max_hear_distance = dist })
+ local timer = minetest.get_node_timer(pos)
+ timer:start(0.7)
+ end,
+ on_rightclick = function(pos, node, clicker)
+ node.param2 = (node.param2 + 1) % 64
+ minetest.set_node(pos, node)
+ if clicker and clicker:is_player() then
+ local dist = node.param2
+ local diststr
+ if dist == 0 then
+ diststr = "<default>"
+ else
+ diststr = tostring(dist)
+ end
+ minetest.chat_send_player(clicker:get_player_name(), "max_hear_distance = " .. diststr)
+ end
+ end,
+
+ groups = { dig_immediate = 2 },
+ tiles = { "soundstuff_node_sound.png" },
+})
+
diff --git a/games/devtest/mods/soundstuff/mod.conf b/games/devtest/mods/soundstuff/mod.conf
new file mode 100644
index 000000000..2c631e2da
--- /dev/null
+++ b/games/devtest/mods/soundstuff/mod.conf
@@ -0,0 +1,2 @@
+name = soundstuff
+description = Example items and nodes for testing sound effects
diff --git a/games/devtest/mods/soundstuff/sounds/soundstuff_mono.ogg b/games/devtest/mods/soundstuff/sounds/soundstuff_mono.ogg
new file mode 100644
index 000000000..43428d566
--- /dev/null
+++ b/games/devtest/mods/soundstuff/sounds/soundstuff_mono.ogg
Binary files differ
diff --git a/games/devtest/mods/soundstuff/textures/soundstuff_eat.png b/games/devtest/mods/soundstuff/textures/soundstuff_eat.png
new file mode 100644
index 000000000..aed205422
--- /dev/null
+++ b/games/devtest/mods/soundstuff/textures/soundstuff_eat.png
Binary files differ
diff --git a/games/devtest/mods/soundstuff/textures/soundstuff_node_blank.png b/games/devtest/mods/soundstuff/textures/soundstuff_node_blank.png
new file mode 100644
index 000000000..4dffacc4c
--- /dev/null
+++ b/games/devtest/mods/soundstuff/textures/soundstuff_node_blank.png
Binary files differ
diff --git a/games/devtest/mods/soundstuff/textures/soundstuff_node_climbable.png b/games/devtest/mods/soundstuff/textures/soundstuff_node_climbable.png
new file mode 100644
index 000000000..3888f793c
--- /dev/null
+++ b/games/devtest/mods/soundstuff/textures/soundstuff_node_climbable.png
Binary files differ
diff --git a/games/devtest/mods/soundstuff/textures/soundstuff_node_dig.png b/games/devtest/mods/soundstuff/textures/soundstuff_node_dig.png
new file mode 100644
index 000000000..67ba111d8
--- /dev/null
+++ b/games/devtest/mods/soundstuff/textures/soundstuff_node_dig.png
Binary files differ
diff --git a/games/devtest/mods/soundstuff/textures/soundstuff_node_dug.png b/games/devtest/mods/soundstuff/textures/soundstuff_node_dug.png
new file mode 100644
index 000000000..bab5fbe51
--- /dev/null
+++ b/games/devtest/mods/soundstuff/textures/soundstuff_node_dug.png
Binary files differ
diff --git a/games/devtest/mods/soundstuff/textures/soundstuff_node_fall.png b/games/devtest/mods/soundstuff/textures/soundstuff_node_fall.png
new file mode 100644
index 000000000..17b14f1e4
--- /dev/null
+++ b/games/devtest/mods/soundstuff/textures/soundstuff_node_fall.png
Binary files differ
diff --git a/games/devtest/mods/soundstuff/textures/soundstuff_node_footstep.png b/games/devtest/mods/soundstuff/textures/soundstuff_node_footstep.png
new file mode 100644
index 000000000..6367ae909
--- /dev/null
+++ b/games/devtest/mods/soundstuff/textures/soundstuff_node_footstep.png
Binary files differ
diff --git a/games/devtest/mods/soundstuff/textures/soundstuff_node_place.png b/games/devtest/mods/soundstuff/textures/soundstuff_node_place.png
new file mode 100644
index 000000000..d159ad533
--- /dev/null
+++ b/games/devtest/mods/soundstuff/textures/soundstuff_node_place.png
Binary files differ
diff --git a/games/devtest/mods/soundstuff/textures/soundstuff_node_place_failed.png b/games/devtest/mods/soundstuff/textures/soundstuff_node_place_failed.png
new file mode 100644
index 000000000..780ba946d
--- /dev/null
+++ b/games/devtest/mods/soundstuff/textures/soundstuff_node_place_failed.png
Binary files differ
diff --git a/games/devtest/mods/soundstuff/textures/soundstuff_node_sound.png b/games/devtest/mods/soundstuff/textures/soundstuff_node_sound.png
new file mode 100644
index 000000000..0592a0299
--- /dev/null
+++ b/games/devtest/mods/soundstuff/textures/soundstuff_node_sound.png
Binary files differ
diff --git a/games/minimal/mods/stairs/init.lua b/games/devtest/mods/stairs/init.lua
index 4929d1370..2701cabab 100644
--- a/games/minimal/mods/stairs/init.lua
+++ b/games/devtest/mods/stairs/init.lua
@@ -2,10 +2,10 @@ stairs = {}
-- Node will be called stairs:stair_<subname>
function stairs.register_stair(subname, recipeitem, groups, images, description)
- minetest.register_node("stairs:stair_" .. subname, {
+ minetest.register_node(":stairs:stair_" .. subname, {
description = description,
drawtype = "nodebox",
- tile_images = images,
+ tiles = images,
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = true,
@@ -18,23 +18,14 @@ function stairs.register_stair(subname, recipeitem, groups, images, description)
},
},
})
-
- minetest.register_craft({
- output = 'stairs:stair_' .. subname .. ' 4',
- recipe = {
- {recipeitem, "", ""},
- {recipeitem, recipeitem, ""},
- {recipeitem, recipeitem, recipeitem},
- },
- })
end
-- Node will be called stairs:slab_<subname>
function stairs.register_slab(subname, recipeitem, groups, images, description)
- minetest.register_node("stairs:slab_" .. subname, {
+ minetest.register_node(":stairs:slab_" .. subname, {
description = description,
drawtype = "nodebox",
- tile_images = images,
+ tiles = images,
paramtype = "light",
is_ground_content = true,
groups = groups,
@@ -47,13 +38,6 @@ function stairs.register_slab(subname, recipeitem, groups, images, description)
fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
},
})
-
- minetest.register_craft({
- output = 'stairs:slab_' .. subname .. ' 3',
- recipe = {
- {recipeitem, recipeitem, recipeitem},
- },
- })
end
-- Nodes will be called stairs:{stair,slab}_<subname>
@@ -62,32 +46,20 @@ function stairs.register_stair_and_slab(subname, recipeitem, groups, images, des
stairs.register_slab(subname, recipeitem, groups, images, desc_slab)
end
-stairs.register_stair_and_slab("wood", "default:wood",
- {snappy=2,choppy=2,oddly_breakable_by_hand=2},
- {"default_wood.png"},
- "Wooden stair",
- "Wooden slab")
-
-stairs.register_stair_and_slab("stone", "default:stone",
+stairs.register_stair_and_slab("stone", "basenodes:stone",
{cracky=3},
{"default_stone.png"},
- "Stone stair",
- "Stone slab")
+ "Stone Stair",
+ "Stone Slab")
-stairs.register_stair_and_slab("cobble", "default:cobble",
+stairs.register_stair_and_slab("desert_stone", "basenodes:desert_stone",
{cracky=3},
- {"default_cobble.png"},
- "Cobble stair",
- "Cobble slab")
+ {"default_desert_stone.png"},
+ "Desert Stone Stair",
+ "Desert Stone Slab")
-stairs.register_stair_and_slab("brick", "default:brick",
+stairs.register_stair_and_slab("cobble", "basenodes:cobble",
{cracky=3},
- {"default_brick.png"},
- "Brick stair",
- "Brick slab")
-
-stairs.register_stair_and_slab("sandstone", "default:sandstone",
- {crumbly=2,cracky=2},
- {"default_sandstone.png"},
- "Sandstone stair",
- "Sandstone slab")
+ {"default_cobble.png"},
+ "Cobblestone Stair",
+ "Cobblestone Slab")
diff --git a/games/devtest/mods/stairs/mod.conf b/games/devtest/mods/stairs/mod.conf
new file mode 100644
index 000000000..724bff881
--- /dev/null
+++ b/games/devtest/mods/stairs/mod.conf
@@ -0,0 +1,3 @@
+name = stairs
+description = Adds stairs and slabs
+depends = basenodes
diff --git a/games/devtest/mods/testentities/armor.lua b/games/devtest/mods/testentities/armor.lua
new file mode 100644
index 000000000..415e5bd19
--- /dev/null
+++ b/games/devtest/mods/testentities/armor.lua
@@ -0,0 +1,61 @@
+-- Armorball: Test entity for testing armor groups
+-- Rightclick to change armor group
+
+local phasearmor = {
+ [0]={icy=100},
+ [1]={fiery=100},
+ [2]={icy=100, fiery=100},
+ [3]={fleshy=-100},
+ [4]={fleshy=1},
+ [5]={fleshy=10},
+ [6]={fleshy=50},
+ [7]={fleshy=100},
+ [8]={fleshy=200},
+ [9]={fleshy=1000},
+ [10]={fleshy=32767},
+ [11]={immortal=1},
+ [12]={punch_operable=1},
+}
+local max_phase = 12
+
+minetest.register_entity("testentities:armorball", {
+ initial_properties = {
+ hp_max = 20,
+ physical = false,
+ collisionbox = {-0.4,-0.4,-0.4, 0.4,0.4,0.4},
+ visual = "sprite",
+ visual_size = {x=1, y=1},
+ textures = {"testentities_armorball.png"},
+ spritediv = {x=1, y=max_phase+1},
+ initial_sprite_basepos = {x=0, y=0},
+ },
+
+ _phase = 7,
+
+ on_activate = function(self, staticdata)
+ minetest.log("action", "[testentities] armorball.on_activate")
+ self.object:set_armor_groups(phasearmor[self._phase])
+ self.object:set_sprite({x=0, y=self._phase})
+ end,
+
+ on_rightclick = function(self, clicker)
+ -- Change armor group and sprite
+ self._phase = self._phase + 1
+ if self._phase >= max_phase + 1 then
+ self._phase = 0
+ end
+ self.object:set_sprite({x=0, y=self._phase})
+ self.object:set_armor_groups(phasearmor[self._phase])
+ end,
+
+ on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
+ if not puncher then
+ return
+ end
+ local name = puncher:get_player_name()
+ if not name then
+ return
+ end
+ minetest.chat_send_player(name, "time_from_last_punch="..string.format("%.3f", time_from_last_punch).."; damage="..tostring(damage))
+ end,
+})
diff --git a/games/devtest/mods/testentities/callbacks.lua b/games/devtest/mods/testentities/callbacks.lua
new file mode 100644
index 000000000..a212fbfbe
--- /dev/null
+++ b/games/devtest/mods/testentities/callbacks.lua
@@ -0,0 +1,78 @@
+-- Entities that test their callbacks
+
+local message = function(msg)
+ minetest.log("action", msg)
+ minetest.chat_send_all(msg)
+end
+
+local get_object_name = function(obj)
+ local name = "<nil>"
+ if obj then
+ if obj:is_player() then
+ name = obj:get_player_name()
+ else
+ name = "<entity>"
+ end
+ end
+ return name
+end
+
+local spos = function(self)
+ return minetest.pos_to_string(vector.round(self.object:get_pos()))
+end
+
+-- Callback test entity (all callbacks except on_step)
+minetest.register_entity("testentities:callback", {
+ initial_properties = {
+ visual = "upright_sprite",
+ textures = { "testentities_callback.png" },
+ },
+
+ on_activate = function(self, staticdata, dtime_s)
+ message("Callback entity: on_activate! pos="..spos(self).."; dtime_s="..dtime_s)
+ end,
+ on_deactivate = function(self, removal)
+ message("Callback entity: on_deactivate! pos="..spos(self) .. "; removal=" .. tostring(removal))
+ end,
+ on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
+ local name = get_object_name(puncher)
+ message(
+ "Callback entity: on_punch! "..
+ "pos="..spos(self).."; puncher="..name.."; "..
+ "time_from_last_punch="..time_from_last_punch.."; "..
+ "tool_capabilities="..tostring(dump(tool_capabilities)).."; "..
+ "dir="..tostring(dump(dir)).."; damage="..damage)
+ end,
+ on_rightclick = function(self, clicker)
+ local name = get_object_name(clicker)
+ message("Callback entity: on_rightclick! pos="..spos(self).."; clicker="..name)
+ end,
+ on_death = function(self, killer)
+ local name = get_object_name(killer)
+ message("Callback entity: on_death! pos="..spos(self).."; killer="..name)
+ end,
+ on_attach_child = function(self, child)
+ local name = get_object_name(child)
+ message("Callback entity: on_attach_child! pos="..spos(self).."; child="..name)
+ end,
+ on_detach_child = function(self, child)
+ local name = get_object_name(child)
+ message("Callback entity: on_detach_child! pos="..spos(self).."; child="..name)
+ end,
+ on_detach = function(self, parent)
+ local name = get_object_name(parent)
+ message("Callback entity: on_detach! pos="..spos(self).."; parent="..name)
+ end,
+ get_staticdata = function(self)
+ message("Callback entity: get_staticdata! pos="..spos(self))
+ end,
+})
+
+-- Only test on_step callback
+minetest.register_entity("testentities:callback_step", {
+ visual = "upright_sprite",
+ textures = { "testentities_callback_step.png" },
+ on_step = function(self, dtime)
+ message("on_step callback entity: on_step! pos="..spos(self).."; dtime="..dtime)
+ end,
+})
diff --git a/games/devtest/mods/testentities/init.lua b/games/devtest/mods/testentities/init.lua
new file mode 100644
index 000000000..df8c72ea7
--- /dev/null
+++ b/games/devtest/mods/testentities/init.lua
@@ -0,0 +1,3 @@
+dofile(minetest.get_modpath("testentities").."/visuals.lua")
+dofile(minetest.get_modpath("testentities").."/armor.lua")
+dofile(minetest.get_modpath("testentities").."/callbacks.lua")
diff --git a/games/devtest/mods/testentities/mod.conf b/games/devtest/mods/testentities/mod.conf
new file mode 100644
index 000000000..7a8cb5a3e
--- /dev/null
+++ b/games/devtest/mods/testentities/mod.conf
@@ -0,0 +1,2 @@
+name = testentities
+description = Example entities for testing
diff --git a/games/devtest/mods/testentities/textures/testentities_armorball.png b/games/devtest/mods/testentities/textures/testentities_armorball.png
new file mode 100644
index 000000000..708c7b36d
--- /dev/null
+++ b/games/devtest/mods/testentities/textures/testentities_armorball.png
Binary files differ
diff --git a/games/devtest/mods/testentities/textures/testentities_callback.png b/games/devtest/mods/testentities/textures/testentities_callback.png
new file mode 100644
index 000000000..c4c9066d1
--- /dev/null
+++ b/games/devtest/mods/testentities/textures/testentities_callback.png
Binary files differ
diff --git a/games/devtest/mods/testentities/textures/testentities_callback_step.png b/games/devtest/mods/testentities/textures/testentities_callback_step.png
new file mode 100644
index 000000000..b67506a97
--- /dev/null
+++ b/games/devtest/mods/testentities/textures/testentities_callback_step.png
Binary files differ
diff --git a/games/devtest/mods/testentities/textures/testentities_cube1.png b/games/devtest/mods/testentities/textures/testentities_cube1.png
new file mode 100644
index 000000000..c667e425f
--- /dev/null
+++ b/games/devtest/mods/testentities/textures/testentities_cube1.png
Binary files differ
diff --git a/games/devtest/mods/testentities/textures/testentities_cube2.png b/games/devtest/mods/testentities/textures/testentities_cube2.png
new file mode 100644
index 000000000..481823420
--- /dev/null
+++ b/games/devtest/mods/testentities/textures/testentities_cube2.png
Binary files differ
diff --git a/games/devtest/mods/testentities/textures/testentities_cube3.png b/games/devtest/mods/testentities/textures/testentities_cube3.png
new file mode 100644
index 000000000..03b5daa15
--- /dev/null
+++ b/games/devtest/mods/testentities/textures/testentities_cube3.png
Binary files differ
diff --git a/games/devtest/mods/testentities/textures/testentities_cube4.png b/games/devtest/mods/testentities/textures/testentities_cube4.png
new file mode 100644
index 000000000..639204896
--- /dev/null
+++ b/games/devtest/mods/testentities/textures/testentities_cube4.png
Binary files differ
diff --git a/games/devtest/mods/testentities/textures/testentities_cube5.png b/games/devtest/mods/testentities/textures/testentities_cube5.png
new file mode 100644
index 000000000..d8acdf0b6
--- /dev/null
+++ b/games/devtest/mods/testentities/textures/testentities_cube5.png
Binary files differ
diff --git a/games/devtest/mods/testentities/textures/testentities_cube6.png b/games/devtest/mods/testentities/textures/testentities_cube6.png
new file mode 100644
index 000000000..5f81a64d9
--- /dev/null
+++ b/games/devtest/mods/testentities/textures/testentities_cube6.png
Binary files differ
diff --git a/games/devtest/mods/testentities/textures/testentities_dungeon_master.png b/games/devtest/mods/testentities/textures/testentities_dungeon_master.png
new file mode 100644
index 000000000..1e3107746
--- /dev/null
+++ b/games/devtest/mods/testentities/textures/testentities_dungeon_master.png
Binary files differ
diff --git a/games/devtest/mods/testentities/textures/testentities_sprite.png b/games/devtest/mods/testentities/textures/testentities_sprite.png
new file mode 100644
index 000000000..a4b019699
--- /dev/null
+++ b/games/devtest/mods/testentities/textures/testentities_sprite.png
Binary files differ
diff --git a/games/devtest/mods/testentities/textures/testentities_upright_sprite1.png b/games/devtest/mods/testentities/textures/testentities_upright_sprite1.png
new file mode 100644
index 000000000..6242511df
--- /dev/null
+++ b/games/devtest/mods/testentities/textures/testentities_upright_sprite1.png
Binary files differ
diff --git a/games/devtest/mods/testentities/textures/testentities_upright_sprite2.png b/games/devtest/mods/testentities/textures/testentities_upright_sprite2.png
new file mode 100644
index 000000000..a79a760e3
--- /dev/null
+++ b/games/devtest/mods/testentities/textures/testentities_upright_sprite2.png
Binary files differ
diff --git a/games/devtest/mods/testentities/visuals.lua b/games/devtest/mods/testentities/visuals.lua
new file mode 100644
index 000000000..e382ec44c
--- /dev/null
+++ b/games/devtest/mods/testentities/visuals.lua
@@ -0,0 +1,137 @@
+-- Minimal test entities to test visuals
+
+minetest.register_entity("testentities:sprite", {
+ initial_properties = {
+ visual = "sprite",
+ textures = { "testentities_sprite.png" },
+ },
+})
+
+minetest.register_entity("testentities:upright_sprite", {
+ initial_properties = {
+ visual = "upright_sprite",
+ textures = {
+ "testentities_upright_sprite1.png",
+ "testentities_upright_sprite2.png",
+ },
+ },
+})
+
+minetest.register_entity("testentities:cube", {
+ initial_properties = {
+ visual = "cube",
+ textures = {
+ "testentities_cube1.png",
+ "testentities_cube2.png",
+ "testentities_cube3.png",
+ "testentities_cube4.png",
+ "testentities_cube5.png",
+ "testentities_cube6.png",
+ },
+ },
+})
+
+minetest.register_entity("testentities:item", {
+ initial_properties = {
+ visual = "item",
+ wield_item = "testnodes:normal",
+ },
+})
+
+minetest.register_entity("testentities:wielditem", {
+ initial_properties = {
+ visual = "wielditem",
+ wield_item = "testnodes:normal",
+ },
+})
+
+minetest.register_entity("testentities:mesh", {
+ initial_properties = {
+ visual = "mesh",
+ mesh = "testnodes_pyramid.obj",
+ textures = {
+ "testnodes_mesh_stripes2.png"
+ },
+ },
+})
+
+minetest.register_entity("testentities:mesh_unshaded", {
+ initial_properties = {
+ visual = "mesh",
+ mesh = "testnodes_pyramid.obj",
+ textures = {
+ "testnodes_mesh_stripes2.png"
+ },
+ shaded = false,
+ },
+})
+
+-- Advanced visual tests
+
+-- An entity for testing animated and yaw-modulated sprites
+minetest.register_entity("testentities:yawsprite", {
+ initial_properties = {
+ selectionbox = {-0.3, -0.5, -0.3, 0.3, 0.3, 0.3},
+ visual = "sprite",
+ visual_size = {x=0.6666, y=1},
+ textures = {"testentities_dungeon_master.png^[makealpha:128,0,0^[makealpha:128,128,0"},
+ spritediv = {x=6, y=5},
+ initial_sprite_basepos = {x=0, y=0},
+ },
+ on_activate = function(self, staticdata)
+ self.object:set_sprite({x=0, y=0}, 3, 0.5, true)
+ end,
+})
+
+-- An entity for testing animated upright sprites
+minetest.register_entity("testentities:upright_animated", {
+ initial_properties = {
+ visual = "upright_sprite",
+ textures = {"testnodes_anim.png"},
+ spritediv = {x = 1, y = 4},
+ },
+ on_activate = function(self)
+ self.object:set_sprite({x=0, y=0}, 4, 1.0, false)
+ end,
+})
+
+minetest.register_entity("testentities:nametag", {
+ initial_properties = {
+ visual = "sprite",
+ textures = { "testentities_sprite.png" },
+ },
+
+ on_activate = function(self, staticdata)
+ if staticdata ~= "" then
+ local data = minetest.deserialize(staticdata)
+ self.color = data.color
+ self.bgcolor = data.bgcolor
+ else
+ self.color = {
+ r = math.random(0, 255),
+ g = math.random(0, 255),
+ b = math.random(0, 255),
+ }
+
+ if math.random(0, 10) > 5 then
+ self.bgcolor = {
+ r = math.random(0, 255),
+ g = math.random(0, 255),
+ b = math.random(0, 255),
+ a = math.random(0, 255),
+ }
+ end
+ end
+
+ assert(self.color)
+ self.object:set_properties({
+ nametag = tostring(math.random(1000, 10000)),
+ nametag_color = self.color,
+ nametag_bgcolor = self.bgcolor,
+ })
+ end,
+
+ get_staticdata = function(self)
+ return minetest.serialize({ color = self.color, bgcolor = self.bgcolor })
+ end,
+})
diff --git a/games/devtest/mods/testfood/init.lua b/games/devtest/mods/testfood/init.lua
new file mode 100644
index 000000000..39b121306
--- /dev/null
+++ b/games/devtest/mods/testfood/init.lua
@@ -0,0 +1,31 @@
+local S = minetest.get_translator("testfood")
+
+minetest.register_craftitem("testfood:good1", {
+ description = S("Good Food (+1)"),
+ inventory_image = "testfood_good.png",
+ on_use = minetest.item_eat(1),
+})
+minetest.register_craftitem("testfood:good5", {
+ description = S("Good Food (+5)"),
+ inventory_image = "testfood_good2.png",
+ on_use = minetest.item_eat(5),
+})
+
+minetest.register_craftitem("testfood:bad1", {
+ description = S("Bad Food (-1)"),
+ inventory_image = "testfood_bad.png",
+ on_use = minetest.item_eat(-1),
+})
+minetest.register_craftitem("testfood:bad5", {
+ description = S("Bad Food (-5)"),
+ inventory_image = "testfood_bad2.png",
+ on_use = minetest.item_eat(-5),
+})
+
+minetest.register_craftitem("testfood:replace1", {
+ description = S("Replacing Food (+1)").."\n"..
+ S("Replaced with 'Good Food (+1)' when eaten"),
+ inventory_image = "testfood_replace.png",
+ on_use = minetest.item_eat(1, "testfood:good1"),
+})
+
diff --git a/games/devtest/mods/testfood/mod.conf b/games/devtest/mods/testfood/mod.conf
new file mode 100644
index 000000000..7bff21b6e
--- /dev/null
+++ b/games/devtest/mods/testfood/mod.conf
@@ -0,0 +1,2 @@
+name = testfood
+description = For testing food items
diff --git a/games/devtest/mods/testfood/textures/testfood_bad.png b/games/devtest/mods/testfood/textures/testfood_bad.png
new file mode 100644
index 000000000..6e9251440
--- /dev/null
+++ b/games/devtest/mods/testfood/textures/testfood_bad.png
Binary files differ
diff --git a/games/devtest/mods/testfood/textures/testfood_bad2.png b/games/devtest/mods/testfood/textures/testfood_bad2.png
new file mode 100644
index 000000000..22b567890
--- /dev/null
+++ b/games/devtest/mods/testfood/textures/testfood_bad2.png
Binary files differ
diff --git a/games/devtest/mods/testfood/textures/testfood_good.png b/games/devtest/mods/testfood/textures/testfood_good.png
new file mode 100644
index 000000000..31df7f5dd
--- /dev/null
+++ b/games/devtest/mods/testfood/textures/testfood_good.png
Binary files differ
diff --git a/games/devtest/mods/testfood/textures/testfood_good2.png b/games/devtest/mods/testfood/textures/testfood_good2.png
new file mode 100644
index 000000000..e43dda209
--- /dev/null
+++ b/games/devtest/mods/testfood/textures/testfood_good2.png
Binary files differ
diff --git a/games/devtest/mods/testfood/textures/testfood_replace.png b/games/devtest/mods/testfood/textures/testfood_replace.png
new file mode 100644
index 000000000..1ef6876e5
--- /dev/null
+++ b/games/devtest/mods/testfood/textures/testfood_replace.png
Binary files differ
diff --git a/games/devtest/mods/testformspec/LICENSE.txt b/games/devtest/mods/testformspec/LICENSE.txt
new file mode 100644
index 000000000..07696cc30
--- /dev/null
+++ b/games/devtest/mods/testformspec/LICENSE.txt
@@ -0,0 +1,14 @@
+License of media files
+----------------------
+Content imported from minetest_game.
+
+
+BlockMen (CC BY-SA 3.0)
+ default_chest_front.png
+ default_chest_lock.png
+ default_chest_side.png
+ default_chest_top.png
+
+stujones11 (CC BY-SA 3.0)
+An0n3m0us (CC BY-SA 3.0)
+ testformspec_character.b3d
diff --git a/games/devtest/mods/testformspec/callbacks.lua b/games/devtest/mods/testformspec/callbacks.lua
new file mode 100644
index 000000000..559380580
--- /dev/null
+++ b/games/devtest/mods/testformspec/callbacks.lua
@@ -0,0 +1,51 @@
+local callback_test = 0
+
+local out = function(player, formname, fields, number)
+ local snum = ""
+ if number then
+ snum = " "..number
+ end
+ local msg = "Formspec callback"..snum..": player="..player:get_player_name()..", formname=\""..tostring(formname).."\", fields="..dump(fields)
+ minetest.chat_send_player(player:get_player_name(), msg)
+ minetest.log("action", msg)
+end
+
+minetest.register_on_player_receive_fields(function(player, formname, fields)
+ if callback_test == 1 then
+ out(player, formname, fields)
+ elseif callback_test == 2 then
+ out(player, formname, fields, 1)
+ end
+end)
+minetest.register_on_player_receive_fields(function(player, formname, fields)
+ if callback_test == 2 then
+ out(player, formname, fields, 2)
+ return true -- Disable the first callback
+ end
+end)
+minetest.register_on_player_receive_fields(function(player, formname, fields)
+ if callback_test == 2 then
+ out(player, formname, fields, 3)
+ end
+end)
+
+minetest.register_chatcommand("test_formspec_callbacks", {
+ params = "[ 0 | 1 | 2 ]",
+ description = "Test: Change formspec callbacks testing mode",
+ func = function(name, param)
+ local mode = tonumber(param)
+ if not mode then
+ callback_test = (callback_test + 1 % 3)
+ else
+ callback_test = mode
+ end
+ if callback_test == 1 then
+ minetest.chat_send_player(name, "Formspec callback test mode 1 enabled: Logging only")
+ elseif callback_test == 2 then
+ minetest.chat_send_player(name, "Formspec callback test mode 2 enabled: Three callbacks, disable pre-registered callbacks")
+ else
+ callback_test = 0
+ minetest.chat_send_player(name, "Formspec callback test disabled!")
+ end
+ end
+})
diff --git a/games/devtest/mods/testformspec/dummy_items.lua b/games/devtest/mods/testformspec/dummy_items.lua
new file mode 100644
index 000000000..2037ae9cf
--- /dev/null
+++ b/games/devtest/mods/testformspec/dummy_items.lua
@@ -0,0 +1,14 @@
+-- This code adds dummy items that are supposed to be used in formspecs
+-- for testing item_image formspec elements.
+
+minetest.register_node("testformspec:node", {
+ description = "Formspec Test Node",
+ tiles = { "testformspec_node.png" },
+ groups = { dig_immediate = 3, dummy = 1 },
+})
+
+minetest.register_craftitem("testformspec:item", {
+ description = "Formspec Test Item",
+ inventory_image = "testformspec_item.png",
+ groups = { dummy = 1 },
+})
diff --git a/games/devtest/mods/testformspec/formspec.lua b/games/devtest/mods/testformspec/formspec.lua
new file mode 100644
index 000000000..5f1f8970e
--- /dev/null
+++ b/games/devtest/mods/testformspec/formspec.lua
@@ -0,0 +1,536 @@
+local color = minetest.colorize
+
+local clip_fs = [[
+ style_type[label,button,image_button,item_image_button,
+ tabheader,scrollbar,table,animated_image
+ ,field,textarea,checkbox,dropdown;noclip=%c]
+
+ label[0,0;A clipping test]
+ button[0,1;3,0.8;clip_button;A clipping test]
+ image_button[0,2;3,0.8;testformspec_button_image.png;clip_image_button;A clipping test]
+ item_image_button[0,3;3,0.8;testformspec:item;clip_item_image_button;A clipping test]
+ tabheader[0,4.7;3,0.63;clip_tabheader;Clip,Test,Text,Tabs;1;false;false]
+ field[0,5;3,0.8;clip_field;Title;]
+ textarea[0,6;3,1;clip_textarea;Title;]
+ checkbox[0,7.5;clip_checkbox;This is a test;true]
+ dropdown[0,8;3,0.8;clip_dropdown;Select An Item,One,Two,Three,Four,Five;1]
+ scrollbar[0,9;3,0.8;horizontal;clip_scrollbar;3]
+ tablecolumns[text;text]
+ table[0,10;3,1;clip_table;one,two,three,four;1]
+ animated_image[-0.5,11;4.5,1;clip_animated_image;testformspec_animation.png;4;100]
+]]
+
+local tabheaders_fs = [[
+ tabheader[0,0;10,0.63;tabs_opaque;Opaque,Without,Border;1;false;false]
+ tabheader[0,1;10,0.63;tabs_opaque_border;Opaque,With,Border;1;false;true]
+ tabheader[0,2;10,0.63;tabs_transparent;Transparent,Without,Border;1;true;false]
+ tabheader[0,3;10,0.63;tabs_transparent_border;Transparent,With,Border;1;true;true]
+ tabheader[0,4;tabs_default;Default,Tabs;1]
+ tabheader[0,6;10,0.5;tabs_size1;Height=0.5;1;false;false]
+ tabheader[2,6;10,0.75;tabs_size1;Height=0.75;1;false;false]
+ tabheader[4,6;10,1;tabs_size2;Height=1;1;false;false]
+ tabheader[6,6;10,1.25;tabs_size2;Height=1.25;1;false;false]
+ tabheader[8,6;10,1.5;tabs_size2;Height=1.5;1;false;false]
+]]
+
+local inv_style_fs = [[
+ style_type[list;noclip=true]
+ list[current_player;main;-0.75,0.75;2,2]
+
+ real_coordinates[false]
+ list[current_player;main;1.5,0;3,2]
+ real_coordinates[true]
+
+ real_coordinates[false]
+ style_type[list;size=1.1;spacing=0.1]
+ list[current_player;main;5,0;3,2]
+ real_coordinates[true]
+
+ style_type[list;size=.001;spacing=0]
+ list[current_player;main;7,3.5;8,4]
+
+ box[3,3.5;1,1;#000000]
+ box[5,3.5;1,1;#000000]
+ box[4,4.5;1,1;#000000]
+ box[3,5.5;1,1;#000000]
+ box[5,5.5;1,1;#000000]
+ style_type[list;spacing=.25,.125;size=.75,.875]
+ list[current_player;main;3,3.5;3,3]
+
+ style_type[list;spacing=0;size=1.1]
+ list[current_player;main;.5,7;8,4]
+]]
+
+local hypertext_basic = [[
+<bigger>Normal test</bigger>
+This is a normal text.
+
+<bigger><mono>style</mono> test</bigger>
+<style color=#FFFF00>Yellow text.</style> <style color=#FF0000>Red text.</style>
+<style size=24>Size 24.</style> <style size=16>Size 16</style>. <style size=12>Size 12.</style>
+<style font=normal>Normal font.</style> <style font=mono>Mono font.</style>
+
+<bigger>Tag test</bigger>
+<normal>normal</normal>
+<mono>mono</mono>
+<b>bold</b>
+<i>italic</i>
+<u>underlined</u>
+<big>big</big>
+<bigger>bigger</bigger>
+<left>left</left>
+<center>center</center>
+<right>right</right>
+<justify>justify. Here comes a blind text: Lorem testum dolor sit amet consecutor celeron fiftifahivus e shadoninia e smalus jokus anrus relsocutoti rubenwardus. Erasputinus hara holisti dominus wusi. Grumarinsti erltusmuate ol fortitusti fla flo, blani burki e sfani fahif. Ultae ratii, e megus gigae don anonimus. Grinus dimondus krockus e nore. Endus finalus nowus comus endus o blindus tekstus.</justify>
+
+<bigger>Custom tag test</bigger>
+<tag name=t_green color=green>
+<tag name=t_hover hovercolor=yellow>
+<tag name=t_size size=24>
+<tag name=t_mono font=mono>
+<tag name=t_multi color=green font=mono size=24>
+<t_green>color=green</t_green>
+Action: <action name=color><t_green>color=green</t_green></action>
+Action: <action name=hovercolor><t_hover>hovercolor=yellow</t_hover></action>
+<t_size>size=24</t_size>
+<t_mono>font=mono</t_mono>
+<t_multi>color=green font=mono size=24</t_multi>
+
+<bigger><mono>action</mono> test</bigger>
+<action name=action_test>action</action>
+
+<bigger><mono>img</mono> test</bigger>
+Normal:
+<img name=testformspec_item.png>
+<mono>width=48 height=48</mono>:
+<img name=testformspec_item.png width=48 height=48>
+<mono>float=left</mono>:
+<img name=testformspec_item.png float=left>
+<mono>float=right</mono>:
+<img name=testformspec_item.png float=right>
+
+<bigger><mono>item</mono> test</bigger>
+Normal:
+<item name=testformspec:node>
+<mono>width=48 height=48</mono>
+<item name=testformspec:node width=48 height=48>
+<mono>angle=30,0,0</mono>:
+<item name=testformspec:node angle=30,0,0>
+<mono>angle=0,30,0</mono>:
+<item name=testformspec:node angle=0,30,0>
+<mono>angle=0,0,30</mono>:
+<item name=testformspec:node angle=0,0,30>
+<mono>rotate=yes</mono>:
+<item name=testformspec:node rotate=yes>
+<mono>rotate=100,0,0</mono>:
+<item name=testformspec:node rotate=100,0,0>
+<mono>rotate=0,100,0</mono>:
+<item name=testformspec:node rotate=0,100,0>
+<mono>rotate=0,0,100</mono>:
+<item name=testformspec:node rotate=0,0,100>
+<mono>rotate=50,75,100</mono>:
+<item name=testformspec:node rotate=50,75,100>
+<mono>angle=-30,-45,90 rotate=100,150,-50</mono>:
+<item name=testformspec:node angle=-30,-45,90 rotate=100,150,-50>]]
+
+local hypertext_global = [[
+<global background=gray margin=20 valign=bottom halign=right color=pink hovercolor=purple size=12 font=mono>
+This is a test of the global tag. The parameters are:
+background=gray margin=20 valign=bottom halign=right color=pink hovercolor=purple size=12 font=mono
+<action name=global>action</action>]]
+
+local hypertext_fs = "hypertext[0,0;11,9;hypertext;"..minetest.formspec_escape(hypertext_basic).."]"..
+ "hypertext[0,9.5;11,2.5;hypertext;"..minetest.formspec_escape(hypertext_global).."]"
+
+local style_fs = [[
+ style[one_btn1;bgcolor=red;textcolor=yellow;bgcolor_hovered=orange;
+ bgcolor_pressed=purple]
+ button[0,0;2.5,0.8;one_btn1;Button]
+
+ style[one_btn2;border=false;textcolor=cyan] ]]..
+ "button[0,1.05;2.5,0.8;one_btn2;Text " .. color("#FF0", "Yellow") .. [[]
+
+ style[one_btn3;bgimg=testformspec_button_image.png;bgimg_hovered=testformspec_hovered.png;
+ bgimg_pressed=testformspec_pressed.png]
+ button[0,2.1;1,1;one_btn3;Border]
+
+ style[one_btn4;bgimg=testformspec_button_image.png;bgimg_hovered=testformspec_hovered.png;
+ bgimg_pressed=testformspec_pressed.png;border=false]
+ button[1.25,2.1;1,1;one_btn4;NoBor]
+
+ style[one_btn5;bgimg=testformspec_button_image.png;bgimg_hovered=testformspec_hovered.png;
+ bgimg_pressed=testformspec_pressed.png;border=false;alpha=false]
+ button[0,3.35;1,1;one_btn5;Alph]
+
+ style[one_btn6;border=true]
+ image_button[0,4.6;1,1;testformspec_button_image.png;one_btn6;Border]
+
+ style[one_btn7;border=false]
+ image_button[1.25,4.6;1,1;testformspec_button_image.png;one_btn7;NoBor]
+
+ style[one_btn8;border=false]
+ image_button[0,5.85;1,1;testformspec_button_image.png;one_btn8;Border;false;true;testformspec_pressed.png]
+
+ style[one_btn9;border=true]
+ image_button[1.25,5.85;1,1;testformspec_button_image.png;one_btn9;NoBor;false;false;testformspec_pressed.png]
+
+ style[one_btn10;alpha=false]
+ image_button[0,7.1;1,1;testformspec_button_image.png;one_btn10;NoAlpha]
+
+ style[one_btn11;alpha=true]
+ image_button[1.25,7.1;1,1;testformspec_button_image.png;one_btn11;Alpha]
+
+ style[one_btn12;border=true]
+ item_image_button[0,8.35;1,1;testformspec:item;one_btn12;Border]
+
+ style[one_btn13;border=false]
+ item_image_button[1.25,8.35;1,1;testformspec:item;one_btn13;NoBor]
+
+ style[one_btn14;border=false;bgimg=testformspec_bg.png;fgimg=testformspec_button_image.png]
+ style[one_btn14:hovered;bgimg=testformspec_bg_hovered.png;fgimg=testformspec_hovered.png;textcolor=yellow]
+ style[one_btn14:pressed;bgimg=testformspec_bg_pressed.png;fgimg=testformspec_pressed.png;textcolor=blue]
+ style[one_btn14:hovered+pressed;textcolor=purple]
+ image_button[0,9.6;1,1;testformspec_button_image.png;one_btn14;Bg]
+
+ style[one_btn15;border=false;bgcolor=#1cc;bgimg=testformspec_bg.png;bgimg_hovered=testformspec_bg_hovered.png;bgimg_pressed=testformspec_bg_pressed.png]
+ item_image_button[1.25,9.6;1,1;testformspec:item;one_btn15;Bg]
+
+ style[one_btn16;border=false;bgimg=testformspec_bg_9slice.png;bgimg_middle=4,6;padding=5,7;fgimg=testformspec_bg.png;fgimg_middle=1]
+ style[one_btn16:hovered;bgimg=testformspec_bg_9slice_hovered.png;fgimg=testformspec_bg_hovered.png]
+ style[one_btn16:pressed;bgimg=testformspec_bg_9slice_pressed.png;fgimg=testformspec_bg_pressed.png]
+ image_button[2.5,9.6;2,1;;one_btn16;9-Slice Bg]
+
+
+
+ container[2.75,0]
+
+ style[one_tb1;textcolor=Yellow]
+ tabheader[0,3;2.5,0.63;one_tb1;Yellow,Text,Tabs;1;false;false]
+
+ style[one_f1;textcolor=yellow]
+ field[0,4.25;2.5,0.8;one_f1;Field One;Yellow Text]
+
+ style[one_f2;border=false;textcolor=cyan]
+ field[0,5.75;2.5,0.8;one_f2;Field Two;Borderless Cyan Text]
+
+ style[one_f3;textcolor=yellow]
+ textarea[0,7.025;2.5,0.8;one_f3;Label;]] ..
+ minetest.formspec_escape("Yellow Text\nLine two") .. [[ ]
+
+ style[one_f4;border=false;textcolor=cyan]
+ textarea[0,8.324999999999999;2.5,0.8;one_f4;Label;]] ..
+ minetest.formspec_escape("Borderless Cyan Text\nLine two") .. [[ ]
+
+ container_end[]
+]]
+
+local scroll_fs =
+ "button[8.5,1;4,1;outside;Outside of container]"..
+ "box[1,1;8,6;#00aa]"..
+ "scroll_container[1,1;8,6;scrbar;vertical]"..
+ "button[0,1;1,1;lorem;Lorem]"..
+ "animated_image[0,1;4.5,1;clip_animated_image;testformspec_animation.png;4;100]" ..
+ "button[0,10;1,1;ipsum;Ipsum]"..
+ "pwdfield[2,2;1,1;lorem2;Lorem]"..
+ "list[current_player;main;4,4;1,5;]"..
+ "box[2,5;3,2;#ffff00]"..
+ "image[1,10;3,2;testformspec_item.png]"..
+ "image[3,1;testformspec_item.png]"..
+ "item_image[2,6;3,2;testformspec:node]"..
+ "label[2,15;bla Bli\nfoo bar]"..
+ "item_image_button[2,3;1,1;testformspec:node;itemimagebutton;ItemImageButton]"..
+ "tooltip[0,11;3,2;Buz;#f00;#000]"..
+ "box[0,11;3,2;#00ff00]"..
+ "hypertext[3,13;3,3;;" .. hypertext_basic .. "]" ..
+ "hypertext[3,17;3,3;;Hypertext with no scrollbar\\; the scroll container should scroll.]" ..
+ "textarea[3,21;3,1;textarea;;More scroll within scroll]" ..
+ "container[0,18]"..
+ "box[1,2;3,2;#0a0a]"..
+ "scroll_container[1,2;3,2;scrbar2;horizontal;0.06]"..
+ "button[0,0;6,1;butnest;Nest]"..
+ "label[10,0.5;nest]"..
+ "scroll_container_end[]"..
+ "scrollbar[1,0;3.5,0.3;horizontal;scrbar2;0]"..
+ "container_end[]"..
+ "dropdown[0,6;2;hmdrpdwn;apple,bulb;1]"..
+ "image_button[0,4;2,2;testformspec_button_image.png;imagebutton;bbbbtt;false;true;testformspec_pressed.png]"..
+ "box[1,22.5;4,1;#a00a]"..
+ "scroll_container_end[]"..
+ "scrollbaroptions[max=170]".. -- lowest seen pos is: 0.1*170+6=23 (factor*max+height)
+ "scrollbar[7.5,0;0.3,4;vertical;scrbar;0]"..
+ "scrollbar[8,0;0.3,4;vertical;scrbarhmmm;0]"..
+ "dropdown[0,6;2;hmdrpdwnnn;Outside,of,container;1]"
+
+--style_type[label;textcolor=green]
+--label[0,0;Green]
+--style_type[label;textcolor=blue]
+--label[0,1;Blue]
+--style_type[label;textcolor=;border=true]
+--label[1.2,0;Border]
+--style_type[label;border=true;bgcolor=red]
+--label[1.2,1;Background]
+--style_type[label;border=;bgcolor=]
+--label[0.75,2;Reset]
+
+local window = {
+ sizex = 12,
+ sizey = 13,
+ positionx = 0.5,
+ positiony = 0.5,
+ anchorx = 0.5,
+ anchory = 0.5,
+ paddingx = 0.05,
+ paddingy = 0.05
+}
+
+local pages = {
+ -- Real Coordinates
+ [[
+ formspec_version[3]
+ size[12,13]
+ image_button[0,0;1,1;logo.png;rc_image_button_1x1;1x1]
+ image_button[1,0;2,2;logo.png;rc_image_button_2x2;2x2]
+ button[0,2;1,1;rc_button_1x1;1x1]
+ button[1,2;2,2;rc_button_2x2;2x2]
+ item_image[0,4;1,1;air]
+ item_image[1,4;2,2;air]
+ item_image_button[0,6;1,1;testformspec:node;rc_item_image_button_1x1;1x1]
+ item_image_button[1,6;2,2;testformspec:node;rc_item_image_button_2x2;2x2]
+ field[3,.5;3,.5;rc_field;Field;text]
+ pwdfield[6,.5;3,1;rc_pwdfield;Password Field]
+ field[3,1;3,1;;Read-Only Field;text]
+ textarea[3,2;3,.5;rc_textarea_small;Textarea;text]
+ textarea[6,2;3,2;rc_textarea_big;Textarea;text\nmore text]
+ textarea[3,3;3,1;;Read-Only Textarea;text\nmore text]
+ textlist[3,4;3,2;rc_textlist;Textlist,Perfect Coordinates;1;false]
+ tableoptions[highlight=#ABCDEF75;background=#00000055;border=false]
+ table[6,4;3,2;rc_table;Table,Cool Stuff,Foo,Bar;2]
+ dropdown[3,6;3,1;rc_dropdown_small;This,is,a,dropdown;1]
+ dropdown[6,6;3,2;rc_dropdown_big;I,am,a,bigger,dropdown;5]
+ image[0,8;3,2;ignore.png]
+ box[3,7;3,1;#00A3FF]
+ checkbox[3,8;rc_checkbox_1;Check me!;false]
+ checkbox[3,9;rc_checkbox_2;Uncheck me now!;true]
+ scrollbar[0,11.5;11.5,.5;horizontal;rc_scrollbar_horizontal;500]
+ scrollbar[11.5,0;.5,11.5;vertical;rc_scrollbar_vertical;0]
+ list[current_player;main;6,8;3,2;1]
+ button[9,0;2.5,1;rc_empty_button_1;]
+ button[9,1;2.5,1;rc_empty_button_2;]
+ button[9,2;2.5,1;rc_empty_button_3;] ]]..
+ "label[9,0.5;This is a label.\nLine\nLine\nLine\nEnd]"..
+ [[button[9,3;1,1;rc_empty_button_4;]
+ vertlabel[9,4;VERT]
+ label[10,3;HORIZ]
+ tabheader[8,0;6,0.65;rc_tabheader;Tab 1,Tab 2,Tab 3,Secrets;1;false;false]
+ ]],
+ -- Style
+
+ "formspec_version[3]size[12,13]" ..
+ ("label[0.375,0.375;Styled - %s %s]"):format(
+ color("#F00", "red text"),
+ color("#77FF00CC", "green text")) ..
+ "label[6.375,0.375;Unstyled]" ..
+ "box[0,0.75;12,0.1;#999]" ..
+ "box[6,0.85;0.1,11.15;#999]" ..
+ "container[0.375,1.225]" ..
+ style_fs ..
+ "container_end[]container[6.375,1.225]" ..
+ style_fs:gsub("one_", "two_"):gsub("style%[[^%]]+%]", ""):gsub("style_type%[[^%]]+%]", "") ..
+ "container_end[]",
+
+ -- Noclip
+ "formspec_version[3]size[12,13]" ..
+ "label[0.1,0.5;Clip]" ..
+ "container[-2.5,1]" .. clip_fs:gsub("%%c", "false") .. "container_end[]" ..
+ "label[11,0.5;Noclip]" ..
+ "container[11.5,1]" .. clip_fs:gsub("%%c", "true") .. "container_end[]",
+
+ -- Hypertext
+ "size[12,13]real_coordinates[true]" ..
+ "container[0.5,0.5]" .. hypertext_fs .. "container_end[]",
+
+ -- Tabheaders
+ "size[12,13]real_coordinates[true]" ..
+ "container[0.5,1.5]" .. tabheaders_fs .. "container_end[]",
+
+ -- Inv
+ "size[12,13]real_coordinates[true]" .. inv_style_fs,
+
+ -- Window
+ function()
+ return "formspec_version[3]" ..
+ string.format("size[%s,%s]position[%s,%s]anchor[%s,%s]padding[%s,%s]",
+ window.sizex, window.sizey, window.positionx, window.positiony,
+ window.anchorx, window.anchory, window.paddingx, window.paddingy) ..
+ string.format("field[0.5,0.5;2.5,0.5;sizex;X Size;%s]field[3.5,0.5;2.5,0.5;sizey;Y Size;%s]" ..
+ "field[0.5,1.5;2.5,0.5;positionx;X Position;%s]field[3.5,1.5;2.5,0.5;positiony;Y Position;%s]" ..
+ "field[0.5,2.5;2.5,0.5;anchorx;X Anchor;%s]field[3.5,2.5;2.5,0.5;anchory;Y Anchor;%s]" ..
+ "field[0.5,3.5;2.5,0.5;paddingx;X Padding;%s]field[3.5,3.5;2.5,0.5;paddingy;Y Padding;%s]" ..
+ "button[2,4.5;2.5,0.5;submit_window;Submit]",
+ window.sizex, window.sizey, window.positionx, window.positiony,
+ window.anchorx, window.anchory, window.paddingx, window.paddingy) ..
+ "field_close_on_enter[sizex;false]field_close_on_enter[sizey;false]" ..
+ "field_close_on_enter[positionx;false]field_close_on_enter[positiony;false]" ..
+ "field_close_on_enter[anchorx;false]field_close_on_enter[anchory;false]" ..
+ "field_close_on_enter[paddingx;false]field_close_on_enter[paddingy;false]"
+ end,
+
+ -- Animation
+ [[
+ formspec_version[6]
+ size[12,13]
+ animated_image[0.5,0.5;1,1;;testformspec_animation.png;4;100]
+ animated_image[0.5,1.75;1,1;;testformspec_animation.jpg;4;100]
+ animated_image[1.75,0.5;1,1;;testformspec_animation.png;100;100]
+ animated_image[3,0.5;1,1;ani_img_1;testformspec_animation.png;4;1000]
+ image[0.5,3;1,1;testformspec_bg.png;1]
+ animated_image[0.5,4.25;1,1;;[combine:16x48:0,0=testformspec_bg.png:0,16=testformspec_bg_hovered.png:0,32=testformspec_bg_pressed.png;3;250;1;1]
+ image[0.5,5.5;2,1;testformspec_9slice.png;16,0,-16,-16]
+ animated_image[2.75,5.5;1.5,0.5;;[combine:300x140:0,0=testformspec_9slice.png:0,70=(testformspec_9slice.png^[transformFX);2;500;1;16,0,-16,-16]
+ button[4.25,0.5;1,1;ani_btn_1;Current
+Number]
+ animated_image[3,1.75;1,1;ani_img_2;testformspec_animation.png;4;1000;2]
+ button[4.25,1.75;1,1;ani_btn_2;Current
+Number]
+ animated_image[3,3;1,1;;testformspec_animation.png;4;0]
+ animated_image[3,4.25;1,1;;testformspec_animation.png;4;0;3]
+ animated_image[5.5,0.5;5,2;;testformspec_animation.png;4;100]
+ animated_image[5.5,2.75;5,2;;testformspec_animation.jpg;4;100]
+
+ ]],
+
+ -- Model
+ [[
+ formspec_version[3]
+ size[12,13]
+ style[m1;bgcolor=black]
+ style[m2;bgcolor=black]
+ label[5,1;all defaults]
+ label[5,5.1;angle = 0, 180
+continuous = false
+mouse control = false
+frame loop range = 0,30]
+ label[5,9.2;continuous = true
+mouse control = true]
+ model[0.5,0.1;4,4;m1;testformspec_character.b3d;testformspec_character.png]
+ model[0.5,4.2;4,4;m2;testformspec_character.b3d;testformspec_character.png;0,180;false;false;0,30]
+ model[0.5,8.3;4,4;m3;testformspec_chest.obj;default_chest_top.png,default_chest_top.png,default_chest_side.png,default_chest_side.png,default_chest_front.png,default_chest_inside.png;30,1;true;true]
+ ]],
+
+ -- Scroll containers
+ "formspec_version[3]size[12,13]" ..
+ scroll_fs,
+
+ -- Sound
+ [[
+ formspec_version[3]
+ size[12,13]
+ style[snd_btn;sound=soundstuff_mono]
+ style[snd_ibtn;sound=soundstuff_mono]
+ style[snd_drp;sound=soundstuff_mono]
+ style[snd_chk;sound=soundstuff_mono]
+ style[snd_tab;sound=soundstuff_mono]
+ button[0.5,0.5;2,1;snd_btn;Sound]
+ image_button[0.5,2;2,1;testformspec_item.png;snd_ibtn;Sound]
+ dropdown[0.5,4;4;snd_drp;Sound,Two,Three;]
+ checkbox[0.5,5.5.5;snd_chk;Sound;]
+ tabheader[0.5,7;8,0.65;snd_tab;Soundtab1,Soundtab2,Soundtab3;1;false;false]
+ ]],
+
+ -- Background
+ [[
+ formspec_version[3]
+ size[12,13]
+ box[0,0;12,13;#f0f1]
+ background[0,0;0,0;testformspec_bg.png;true]
+ box[3.9,2.9;6.2,4.2;#d00f]
+ scroll_container[4,3;6,4;scrbar;vertical]
+ background9[1,0.5;0,0;testformspec_bg_9slice.png;true;4,6]
+ label[0,0.2;Backgrounds are not be applied to scroll containers,]
+ label[0,0.5;but to the whole form.]
+ scroll_container_end[]
+ scrollbar[3.5,3;0.3,4;vertical;scrbar;0]
+ container[2,11]
+ box[-0.1,0.5;3.2,1;#fff5]
+ background[0,0;2,3;testformspec_bg.png;false]
+ background9[1,0;2,3;testformspec_bg_9slice.png;false;4,6]
+ container_end[]
+ ]],
+
+ -- Unsized
+ [[
+ formspec_version[3]
+ background9[0,0;0,0;testformspec_bg_9slice.png;true;4,6]
+ background[1,1;0,0;testformspec_bg.png;true]
+ ]],
+}
+
+local page_id = 2
+local function show_test_formspec(pname)
+ local page = pages[page_id]
+ if type(page) == "function" then
+ page = page()
+ end
+
+ local fs = page .. "tabheader[0,0;11,0.65;maintabs;Real Coord,Styles,Noclip,Hypertext,Tabs,Invs,Window,Anim,Model,ScrollC,Sound,Background,Unsized;" .. page_id .. ";false;false]"
+
+ minetest.show_formspec(pname, "testformspec:formspec", fs)
+end
+
+minetest.register_on_player_receive_fields(function(player, formname, fields)
+ if formname ~= "testformspec:formspec" then
+ return false
+ end
+
+ if fields.maintabs then
+ page_id = tonumber(fields.maintabs)
+ show_test_formspec(player:get_player_name())
+ return true
+ end
+
+ if fields.ani_img_1 and fields.ani_btn_1 then
+ minetest.chat_send_player(player:get_player_name(), "ani_img_1 = " .. tostring(fields.ani_img_1))
+ return true
+ elseif fields.ani_img_2 and fields.ani_btn_2 then
+ minetest.chat_send_player(player:get_player_name(), "ani_img_2 = " .. tostring(fields.ani_img_2))
+ return true
+ end
+
+ if fields.hypertext then
+ minetest.chat_send_player(player:get_player_name(), "Hypertext action received: " .. tostring(fields.hypertext))
+ return true
+ end
+
+ for name, value in pairs(fields) do
+ if window[name] then
+ print(name, window[name])
+ local num_val = tonumber(value) or 0
+
+ if name == "sizex" and num_val < 4 then
+ num_val = 6.5
+ elseif name == "sizey" and num_val < 5 then
+ num_val = 5.5
+ end
+
+ window[name] = num_val
+ print(name, window[name])
+ end
+ end
+
+ if fields.submit_window then
+ show_test_formspec(player:get_player_name())
+ end
+end)
+
+minetest.register_chatcommand("test_formspec", {
+ params = "",
+ description = "Open the test formspec",
+ func = function(name)
+ if not minetest.get_player_by_name(name) then
+ return false, "You need to be online!"
+ end
+
+ show_test_formspec(name)
+ return true
+ end,
+})
diff --git a/games/devtest/mods/testformspec/init.lua b/games/devtest/mods/testformspec/init.lua
new file mode 100644
index 000000000..23b565f08
--- /dev/null
+++ b/games/devtest/mods/testformspec/init.lua
@@ -0,0 +1,3 @@
+dofile(minetest.get_modpath("testformspec").."/dummy_items.lua")
+dofile(minetest.get_modpath("testformspec").."/formspec.lua")
+dofile(minetest.get_modpath("testformspec").."/callbacks.lua")
diff --git a/games/devtest/mods/testformspec/mod.conf b/games/devtest/mods/testformspec/mod.conf
new file mode 100644
index 000000000..00eac307a
--- /dev/null
+++ b/games/devtest/mods/testformspec/mod.conf
@@ -0,0 +1,2 @@
+name = testformspec
+description = Contains an example formspec to test all the features of formspecs
diff --git a/games/devtest/mods/testformspec/models/testformspec_character.b3d b/games/devtest/mods/testformspec/models/testformspec_character.b3d
new file mode 100644
index 000000000..8edbaf637
--- /dev/null
+++ b/games/devtest/mods/testformspec/models/testformspec_character.b3d
Binary files differ
diff --git a/games/devtest/mods/testformspec/models/testformspec_chest.obj b/games/devtest/mods/testformspec/models/testformspec_chest.obj
new file mode 100644
index 000000000..72ba175a0
--- /dev/null
+++ b/games/devtest/mods/testformspec/models/testformspec_chest.obj
@@ -0,0 +1,79 @@
+# Blender v2.78 (sub 0) OBJ File: 'chest-open.blend'
+# www.blender.org
+o Top_Cube.002_None_Top_Cube.002_None_bottom
+v -0.500000 0.408471 0.720970
+v -0.500000 1.115578 0.013863
+v -0.500000 0.894607 -0.207108
+v -0.500000 0.187501 0.499999
+v 0.500000 1.115578 0.013863
+v 0.500000 0.408471 0.720970
+v 0.500000 0.187501 0.499999
+v 0.500000 0.894607 -0.207108
+v -0.500000 0.187500 -0.500000
+v -0.500000 -0.500000 -0.500000
+v -0.500000 -0.500000 0.500000
+v 0.500000 0.187500 -0.500000
+v 0.500000 -0.500000 0.500000
+v 0.500000 -0.500000 -0.500000
+vt 0.0000 1.0000
+vt 0.0000 0.0000
+vt 1.0000 0.0000
+vt 1.0000 1.0000
+vt 1.0000 0.0000
+vt 1.0000 1.0000
+vt 0.0000 1.0000
+vt 0.0000 0.0000
+vt 0.0000 1.0000
+vt 1.0000 1.0000
+vt 1.0000 0.6875
+vt 0.0000 0.6875
+vt 1.0000 1.0000
+vt 0.0000 0.6875
+vt 1.0000 0.6875
+vt 1.0000 0.6875
+vt 1.0000 0.0000
+vt 0.0000 0.0000
+vt 1.0000 0.6875
+vt 1.0000 0.0000
+vt 1.0000 1.0000
+vt 1.0000 0.6875
+vt 1.0000 0.0000
+vt 0.0000 1.0000
+vt 0.0000 0.6875
+vt 0.0000 0.6875
+vt 0.0000 0.0000
+vt 1.0000 0.5000
+vt 1.0000 1.0000
+vt 0.0000 1.0000
+vt 0.0000 0.5000
+vt 0.0000 0.0000
+vt 1.0000 0.0000
+vn 0.0000 0.7071 0.7071
+vn -0.0000 -1.0000 -0.0000
+vn -1.0000 0.0000 0.0000
+vn 1.0000 0.0000 -0.0000
+vn 0.0000 -0.7071 0.7071
+vn 0.0000 0.0000 1.0000
+vn -0.0000 0.7071 -0.7071
+vn -0.0000 0.0000 -1.0000
+vn -0.0000 -0.7071 -0.7071
+vn -0.0000 1.0000 -0.0000
+g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Top
+s off
+f 6/1/1 5/2/1 2/3/1 1/4/1
+g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Bottom
+f 11/5/2 10/6/2 14/7/2 13/8/2
+g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Right-Left
+f 1/9/3 2/10/3 3/11/3 4/12/3
+f 5/13/4 6/1/4 7/14/4 8/15/4
+f 4/12/3 9/16/3 10/17/3 11/18/3
+f 12/19/4 7/14/4 13/8/4 14/20/4
+g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Back
+f 6/21/5 1/9/5 4/12/5 7/22/5
+f 7/22/6 4/12/6 11/18/6 13/23/6
+g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Front
+f 2/10/7 5/24/7 8/25/7 3/11/7
+f 9/16/8 12/26/8 14/27/8 10/17/8
+g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Inside
+f 4/28/9 3/29/9 8/30/9 7/31/9
+f 7/31/10 12/32/10 9/33/10 4/28/10
diff --git a/games/devtest/mods/testformspec/textures/default_chest_front.png b/games/devtest/mods/testformspec/textures/default_chest_front.png
new file mode 100644
index 000000000..85227d8fd
--- /dev/null
+++ b/games/devtest/mods/testformspec/textures/default_chest_front.png
Binary files differ
diff --git a/games/devtest/mods/testformspec/textures/default_chest_inside.png b/games/devtest/mods/testformspec/textures/default_chest_inside.png
new file mode 100644
index 000000000..5f7b6b132
--- /dev/null
+++ b/games/devtest/mods/testformspec/textures/default_chest_inside.png
Binary files differ
diff --git a/games/devtest/mods/testformspec/textures/default_chest_side.png b/games/devtest/mods/testformspec/textures/default_chest_side.png
new file mode 100644
index 000000000..44a65a43d
--- /dev/null
+++ b/games/devtest/mods/testformspec/textures/default_chest_side.png
Binary files differ
diff --git a/games/devtest/mods/testformspec/textures/default_chest_top.png b/games/devtest/mods/testformspec/textures/default_chest_top.png
new file mode 100644
index 000000000..f4a92ee07
--- /dev/null
+++ b/games/devtest/mods/testformspec/textures/default_chest_top.png
Binary files differ
diff --git a/games/devtest/mods/testformspec/textures/testformspec_9slice.png b/games/devtest/mods/testformspec/textures/testformspec_9slice.png
new file mode 100644
index 000000000..70b6412a4
--- /dev/null
+++ b/games/devtest/mods/testformspec/textures/testformspec_9slice.png
Binary files differ
diff --git a/games/devtest/mods/testformspec/textures/testformspec_animation.jpg b/games/devtest/mods/testformspec/textures/testformspec_animation.jpg
new file mode 100644
index 000000000..b98ca2677
--- /dev/null
+++ b/games/devtest/mods/testformspec/textures/testformspec_animation.jpg
Binary files differ
diff --git a/games/devtest/mods/testformspec/textures/testformspec_animation.png b/games/devtest/mods/testformspec/textures/testformspec_animation.png
new file mode 100644
index 000000000..b972e5dbb
--- /dev/null
+++ b/games/devtest/mods/testformspec/textures/testformspec_animation.png
Binary files differ
diff --git a/games/devtest/mods/testformspec/textures/testformspec_bg.png b/games/devtest/mods/testformspec/textures/testformspec_bg.png
new file mode 100644
index 000000000..cd1e50900
--- /dev/null
+++ b/games/devtest/mods/testformspec/textures/testformspec_bg.png
Binary files differ
diff --git a/games/devtest/mods/testformspec/textures/testformspec_bg_9slice.png b/games/devtest/mods/testformspec/textures/testformspec_bg_9slice.png
new file mode 100644
index 000000000..34433ac82
--- /dev/null
+++ b/games/devtest/mods/testformspec/textures/testformspec_bg_9slice.png
Binary files differ
diff --git a/games/devtest/mods/testformspec/textures/testformspec_bg_9slice_hovered.png b/games/devtest/mods/testformspec/textures/testformspec_bg_9slice_hovered.png
new file mode 100644
index 000000000..01c2dc777
--- /dev/null
+++ b/games/devtest/mods/testformspec/textures/testformspec_bg_9slice_hovered.png
Binary files differ
diff --git a/games/devtest/mods/testformspec/textures/testformspec_bg_9slice_pressed.png b/games/devtest/mods/testformspec/textures/testformspec_bg_9slice_pressed.png
new file mode 100644
index 000000000..0cbac7536
--- /dev/null
+++ b/games/devtest/mods/testformspec/textures/testformspec_bg_9slice_pressed.png
Binary files differ
diff --git a/games/devtest/mods/testformspec/textures/testformspec_bg_hovered.png b/games/devtest/mods/testformspec/textures/testformspec_bg_hovered.png
new file mode 100644
index 000000000..3ebbb988c
--- /dev/null
+++ b/games/devtest/mods/testformspec/textures/testformspec_bg_hovered.png
Binary files differ
diff --git a/games/devtest/mods/testformspec/textures/testformspec_bg_pressed.png b/games/devtest/mods/testformspec/textures/testformspec_bg_pressed.png
new file mode 100644
index 000000000..2fb5fc21e
--- /dev/null
+++ b/games/devtest/mods/testformspec/textures/testformspec_bg_pressed.png
Binary files differ
diff --git a/games/devtest/mods/testformspec/textures/testformspec_button_image.png b/games/devtest/mods/testformspec/textures/testformspec_button_image.png
new file mode 100644
index 000000000..75c438a9a
--- /dev/null
+++ b/games/devtest/mods/testformspec/textures/testformspec_button_image.png
Binary files differ
diff --git a/games/devtest/mods/testformspec/textures/testformspec_character.png b/games/devtest/mods/testformspec/textures/testformspec_character.png
new file mode 100644
index 000000000..05021781e
--- /dev/null
+++ b/games/devtest/mods/testformspec/textures/testformspec_character.png
Binary files differ
diff --git a/games/devtest/mods/testformspec/textures/testformspec_hovered.png b/games/devtest/mods/testformspec/textures/testformspec_hovered.png
new file mode 100644
index 000000000..3ccad30a2
--- /dev/null
+++ b/games/devtest/mods/testformspec/textures/testformspec_hovered.png
Binary files differ
diff --git a/games/devtest/mods/testformspec/textures/testformspec_item.png b/games/devtest/mods/testformspec/textures/testformspec_item.png
new file mode 100644
index 000000000..4fd823b55
--- /dev/null
+++ b/games/devtest/mods/testformspec/textures/testformspec_item.png
Binary files differ
diff --git a/games/devtest/mods/testformspec/textures/testformspec_node.png b/games/devtest/mods/testformspec/textures/testformspec_node.png
new file mode 100644
index 000000000..c107f28a3
--- /dev/null
+++ b/games/devtest/mods/testformspec/textures/testformspec_node.png
Binary files differ
diff --git a/games/devtest/mods/testformspec/textures/testformspec_pressed.png b/games/devtest/mods/testformspec/textures/testformspec_pressed.png
new file mode 100644
index 000000000..45c504f27
--- /dev/null
+++ b/games/devtest/mods/testformspec/textures/testformspec_pressed.png
Binary files differ
diff --git a/games/devtest/mods/testhud/init.lua b/games/devtest/mods/testhud/init.lua
new file mode 100644
index 000000000..2fa12fd71
--- /dev/null
+++ b/games/devtest/mods/testhud/init.lua
@@ -0,0 +1,81 @@
+local player_huds = {}
+
+local states = {
+ {0, "Normal font"},
+ {1, "Bold font"},
+ {2, "Italic font"},
+ {3, "Bold and italic font"},
+ {4, "Monospace font"},
+ {5, "Bold and monospace font"},
+ {7, "ZOMG all the font styles"},
+}
+
+
+local default_def = {
+ hud_elem_type = "text",
+ position = {x = 0.5, y = 0.5},
+ scale = {x = 2, y = 2},
+ alignment = { x = 0, y = 0 },
+}
+
+local function add_hud(player, state)
+ local def = table.copy(default_def)
+ local statetbl = states[state]
+ def.offset = {x = 0, y = 32 * state}
+ def.style = statetbl[1]
+ def.text = statetbl[2]
+ return player:hud_add(def)
+end
+
+minetest.register_on_leaveplayer(function(player)
+ player_huds[player:get_player_name()] = nil
+end)
+
+local etime = 0
+local state = 0
+
+minetest.register_globalstep(function(dtime)
+ etime = etime + dtime
+ if etime < 1 then
+ return
+ end
+ etime = 0
+ for _, player in ipairs(minetest.get_connected_players()) do
+ local huds = player_huds[player:get_player_name()]
+ if huds then
+ for i, hud_id in ipairs(huds) do
+ local statetbl = states[(state + i) % #states + 1]
+ player:hud_change(hud_id, "style", statetbl[1])
+ player:hud_change(hud_id, "text", statetbl[2])
+ end
+ end
+ end
+ state = state + 1
+end)
+
+minetest.register_chatcommand("hudfonts", {
+ params = "",
+ description = "Show/Hide some text on the HUD with various font options",
+ func = function(name, param)
+ local player = minetest.get_player_by_name(name)
+ local param = tonumber(param) or 0
+ param = math.min(math.max(param, 1), #states)
+ if player_huds[name] == nil then
+ player_huds[name] = {}
+ for i = 1, param do
+ table.insert(player_huds[name], add_hud(player, i))
+ end
+ minetest.chat_send_player(name, ("%d HUD element(s) added."):format(param))
+ else
+ local huds = player_huds[name]
+ if huds then
+ for _, hud_id in ipairs(huds) do
+ player:hud_remove(hud_id)
+ end
+ minetest.chat_send_player(name, "All HUD elements removed.")
+ end
+ player_huds[name] = nil
+ end
+ return true
+ end,
+})
diff --git a/games/devtest/mods/testhud/mod.conf b/games/devtest/mods/testhud/mod.conf
new file mode 100644
index 000000000..ed9f65c59
--- /dev/null
+++ b/games/devtest/mods/testhud/mod.conf
@@ -0,0 +1,2 @@
+name = testhud
+description = For testing HUD functionality
diff --git a/games/devtest/mods/testitems/init.lua b/games/devtest/mods/testitems/init.lua
new file mode 100644
index 000000000..33ebf50fc
--- /dev/null
+++ b/games/devtest/mods/testitems/init.lua
@@ -0,0 +1,55 @@
+local S = minetest.get_translator("testitems")
+
+--
+-- Texture overlays for items
+--
+
+-- For the global overlay color test
+local GLOBAL_COLOR_ARG = "orange"
+
+-- Punch handler to set random color with "color" argument in item metadata
+local overlay_on_use = function(itemstack, user, pointed_thing)
+ local meta = itemstack:get_meta()
+ local color = math.random(0x0, 0xFFFFFF)
+ local colorstr = string.format("#%06x", color)
+ meta:set_string("color", colorstr)
+ minetest.log("action", "[testitems] Color of "..itemstack:get_name().." changed to "..colorstr)
+ return itemstack
+end
+-- Place handler to clear item metadata color
+local overlay_on_place = function(itemstack, user, pointed_thing)
+ local meta = itemstack:get_meta()
+ meta:set_string("color", "")
+ return itemstack
+end
+
+minetest.register_craftitem("testitems:overlay_meta", {
+ description = S("Texture Overlay Test Item, Meta Color") .. "\n" ..
+ S("Image must be a square with rainbow cross (inventory and wield)") .. "\n" ..
+ S("Item meta color must only change square color") .. "\n" ..
+ S("Punch: Set random color") .. "\n" ..
+ S("Place: Clear color"),
+ -- Base texture: A grayscale square (can be colorized)
+ inventory_image = "testitems_overlay_base.png",
+ wield_image = "testitems_overlay_base.png",
+ -- Overlay: A rainbow cross (NOT to be colorized!)
+ inventory_overlay = "testitems_overlay_overlay.png",
+ wield_overlay = "testitems_overlay_overlay.png",
+
+ on_use = overlay_on_use,
+ on_place = overlay_on_place,
+ on_secondary_use = overlay_on_place,
+})
+minetest.register_craftitem("testitems:overlay_global", {
+ description = S("Texture Overlay Test Item, Global Color") .. "\n" ..
+ S("Image must be an orange square with rainbow cross (inventory and wield)"),
+ -- Base texture: A grayscale square (to be colorized)
+ inventory_image = "testitems_overlay_base.png",
+ wield_image = "testitems_overlay_base.png",
+ -- Overlay: A rainbow cross (NOT to be colorized!)
+ inventory_overlay = "testitems_overlay_overlay.png",
+ wield_overlay = "testitems_overlay_overlay.png",
+ color = GLOBAL_COLOR_ARG,
+})
+
+
diff --git a/games/devtest/mods/testitems/mod.conf b/games/devtest/mods/testitems/mod.conf
new file mode 100644
index 000000000..f91febe01
--- /dev/null
+++ b/games/devtest/mods/testitems/mod.conf
@@ -0,0 +1,2 @@
+name = testitems
+description = Test mod to test misc. items that are neither tools nor nodes
diff --git a/games/devtest/mods/testitems/textures/testitems_overlay_base.png b/games/devtest/mods/testitems/textures/testitems_overlay_base.png
new file mode 100644
index 000000000..f473623be
--- /dev/null
+++ b/games/devtest/mods/testitems/textures/testitems_overlay_base.png
Binary files differ
diff --git a/games/devtest/mods/testitems/textures/testitems_overlay_overlay.png b/games/devtest/mods/testitems/textures/testitems_overlay_overlay.png
new file mode 100644
index 000000000..75a7d9fc3
--- /dev/null
+++ b/games/devtest/mods/testitems/textures/testitems_overlay_overlay.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/README.md b/games/devtest/mods/testnodes/README.md
new file mode 100644
index 000000000..13ed972c0
--- /dev/null
+++ b/games/devtest/mods/testnodes/README.md
@@ -0,0 +1,11 @@
+# Test Nodes
+
+This mod contains a bunch of basic nodes to test development stuff.
+Most nodes are kept as minimal as possible in order to show off one particular feature of the engine, to make testing stuff easier.
+
+This mod includes tests for:
+
+* drawtypes
+* paramtype2's
+* node properties such as damage, drowning, falling, etc.
+* other random stuff
diff --git a/games/devtest/mods/testnodes/drawtypes.lua b/games/devtest/mods/testnodes/drawtypes.lua
new file mode 100644
index 000000000..208774f6c
--- /dev/null
+++ b/games/devtest/mods/testnodes/drawtypes.lua
@@ -0,0 +1,629 @@
+--[[ Drawtype Test: This file tests out and provides examples for
+all drawtypes in Minetest. It is attempted to keep the node
+definitions as simple and minimal as possible to keep
+side-effects to a minimum.
+
+How to read the node definitions:
+There are two parts which are separated by 2 newlines:
+The first part contains the things that are more or less essential
+for defining the drawtype (except description, which is
+at the top for readability).
+The second part (after the 2 newlines) contains stuff that are
+unrelated to the drawtype, stuff that is mostly there to make
+testing this node easier and more convenient.
+]]
+
+local S = minetest.get_translator("testnodes")
+
+-- A regular cube
+minetest.register_node("testnodes:normal", {
+ description = S("Normal Drawtype Test Node"),
+ drawtype = "normal",
+ tiles = { "testnodes_normal.png" },
+
+ groups = { dig_immediate = 3 },
+})
+
+-- Standard glasslike node
+minetest.register_node("testnodes:glasslike", {
+ description = S("Glasslike Drawtype Test Node"),
+ drawtype = "glasslike",
+ paramtype = "light",
+ tiles = { "testnodes_glasslike.png" },
+
+ groups = { dig_immediate = 3 },
+})
+
+-- Glasslike framed with the two textures (normal and "detail")
+minetest.register_node("testnodes:glasslike_framed", {
+ description = S("Glasslike Framed Drawtype Test Node"),
+ drawtype = "glasslike_framed",
+ paramtype = "light",
+ tiles = {
+ "testnodes_glasslike_framed.png",
+ "testnodes_glasslike_detail.png",
+ },
+
+
+ sunlight_propagates = true,
+ groups = { dig_immediate = 3 },
+})
+
+-- Like the one above, but without the "detail" texture (texture 2).
+-- This node was added to see how the engine behaves when the "detail" texture
+-- is missing.
+minetest.register_node("testnodes:glasslike_framed_no_detail", {
+ description = S("Glasslike Framed without Detail Drawtype Test Node"),
+ drawtype = "glasslike_framed",
+ paramtype = "light",
+ tiles = { "testnodes_glasslike_framed2.png" },
+
+
+ sunlight_propagates = true,
+ groups = { dig_immediate = 3 },
+})
+
+
+minetest.register_node("testnodes:glasslike_framed_optional", {
+ description = S("Glasslike Framed Optional Drawtype Test Node"),
+ drawtype = "glasslike_framed_optional",
+ paramtype = "light",
+ tiles = {
+ "testnodes_glasslike_framed_optional.png",
+ "testnodes_glasslike_detail.png",
+ },
+
+
+ sunlight_propagates = true,
+ groups = { dig_immediate = 3 },
+})
+
+
+
+minetest.register_node("testnodes:allfaces", {
+ description = S("Allfaces Drawtype Test Node"),
+ drawtype = "allfaces",
+ paramtype = "light",
+ tiles = { "testnodes_allfaces.png" },
+
+ groups = { dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:allfaces_optional", {
+ description = S("Allfaces Optional Drawtype Test Node"),
+ drawtype = "allfaces_optional",
+ paramtype = "light",
+ tiles = { "testnodes_allfaces_optional.png" },
+
+ groups = { dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:allfaces_optional_waving", {
+ description = S("Waving Allfaces Optional Drawtype Test Node"),
+ drawtype = "allfaces_optional",
+ paramtype = "light",
+ tiles = { "testnodes_allfaces_optional.png^[brighten" },
+ waving = 2,
+
+ groups = { dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:firelike", {
+ description = S("Firelike Drawtype Test Node"),
+ drawtype = "firelike",
+ paramtype = "light",
+ tiles = { "testnodes_firelike.png" },
+
+
+ walkable = false,
+ groups = { dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:fencelike", {
+ description = S("Fencelike Drawtype Test Node"),
+ drawtype = "fencelike",
+ paramtype = "light",
+ tiles = { "testnodes_fencelike.png" },
+
+ groups = { dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:torchlike", {
+ description = S("Floor Torchlike Drawtype Test Node"),
+ drawtype = "torchlike",
+ paramtype = "light",
+ tiles = { "testnodes_torchlike_floor.png^[colorize:#FF0000:64" },
+
+
+ walkable = false,
+ sunlight_propagates = true,
+ groups = { dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:torchlike_wallmounted", {
+ description = S("Wallmounted Torchlike Drawtype Test Node"),
+ drawtype = "torchlike",
+ paramtype = "light",
+ paramtype2 = "wallmounted",
+ tiles = {
+ "testnodes_torchlike_floor.png",
+ "testnodes_torchlike_ceiling.png",
+ "testnodes_torchlike_wall.png",
+ },
+
+
+ walkable = false,
+ sunlight_propagates = true,
+ groups = { dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:signlike", {
+ description = S("Floor Signlike Drawtype Test Node"),
+ drawtype = "signlike",
+ paramtype = "light",
+ tiles = { "testnodes_signlike.png^[colorize:#FF0000:64" },
+
+
+ walkable = false,
+ groups = { dig_immediate = 3 },
+ sunlight_propagates = true,
+})
+
+
+minetest.register_node("testnodes:signlike_wallmounted", {
+ description = S("Wallmounted Signlike Drawtype Test Node"),
+ drawtype = "signlike",
+ paramtype = "light",
+ paramtype2 = "wallmounted",
+ tiles = { "testnodes_signlike.png" },
+
+
+ walkable = false,
+ groups = { dig_immediate = 3 },
+ sunlight_propagates = true,
+})
+
+minetest.register_node("testnodes:plantlike", {
+ description = S("Plantlike Drawtype Test Node"),
+ drawtype = "plantlike",
+ paramtype = "light",
+ tiles = { "testnodes_plantlike.png" },
+
+
+ walkable = false,
+ sunlight_propagates = true,
+ groups = { dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:plantlike_waving", {
+ description = S("Waving Plantlike Drawtype Test Node"),
+ drawtype = "plantlike",
+ paramtype = "light",
+ tiles = { "testnodes_plantlike_waving.png" },
+ waving = 1,
+
+
+ walkable = false,
+ sunlight_propagates = true,
+ groups = { dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:plantlike_wallmounted", {
+ description = S("Wallmounted Plantlike Drawtype Test Node"),
+ drawtype = "plantlike",
+ paramtype = "light",
+ paramtype2 = "wallmounted",
+ tiles = { "testnodes_plantlike_wallmounted.png" },
+ leveled = 1,
+
+
+ walkable = false,
+ sunlight_propagates = true,
+ groups = { dig_immediate = 3 },
+})
+
+
+-- param2 will rotate
+local function rotate_on_rightclick(pos, node, clicker)
+ local def = minetest.registered_nodes[node.name]
+ local aux1 = clicker:get_player_control().aux1
+
+ local deg, deg_max
+ local color, color_mult = 0, 0
+ if def.paramtype2 == "degrotate" then
+ deg = node.param2
+ deg_max = 240
+ elseif def.paramtype2 == "colordegrotate" then
+ -- MSB [3x color, 5x rotation] LSB
+ deg = node.param2 % 2^5
+ deg_max = 24
+ color_mult = 2^5
+ color = math.floor(node.param2 / color_mult)
+ end
+
+ deg = (deg + (aux1 and 10 or 1)) % deg_max
+ node.param2 = color * color_mult + deg
+ minetest.swap_node(pos, node)
+ minetest.chat_send_player(clicker:get_player_name(),
+ "Rotation is now " .. deg .. " / " .. deg_max)
+end
+
+minetest.register_node("testnodes:plantlike_degrotate", {
+ description = S("Degrotate Plantlike Drawtype Test Node"),
+ drawtype = "plantlike",
+ paramtype = "light",
+ paramtype2 = "degrotate",
+ tiles = { "testnodes_plantlike_degrotate.png" },
+
+ on_rightclick = rotate_on_rightclick,
+ place_param2 = 7,
+ walkable = false,
+ sunlight_propagates = true,
+ groups = { dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:mesh_degrotate", {
+ description = S("Degrotate Mesh Drawtype Test Node"),
+ drawtype = "mesh",
+ paramtype = "light",
+ paramtype2 = "degrotate",
+ mesh = "testnodes_ocorner.obj",
+ tiles = { "testnodes_mesh_stripes2.png" },
+
+ on_rightclick = rotate_on_rightclick,
+ place_param2 = 10, -- 15°
+ sunlight_propagates = true,
+ groups = { dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:mesh_colordegrotate", {
+ description = S("Color Degrotate Mesh Drawtype Test Node"),
+ drawtype = "mesh",
+ paramtype = "light",
+ paramtype2 = "colordegrotate",
+ palette = "testnodes_palette_facedir.png",
+ mesh = "testnodes_ocorner.obj",
+ tiles = { "testnodes_mesh_stripes3.png" },
+
+ on_rightclick = rotate_on_rightclick,
+ -- color index 1, 1 step (=15°) rotated
+ place_param2 = 1 * 2^5 + 1,
+ sunlight_propagates = true,
+ groups = { dig_immediate = 3 },
+})
+
+-- param2 will change height
+minetest.register_node("testnodes:plantlike_leveled", {
+ description = S("Leveled Plantlike Drawtype Test Node"),
+ drawtype = "plantlike",
+ paramtype = "light",
+ paramtype2 = "leveled",
+ tiles = {
+ { name = "testnodes_plantlike_leveled.png", tileable_vertical = true },
+ },
+
+
+ -- We set a default param2 here only for convenience, to make the "plant" visible after placement
+ place_param2 = 8,
+ walkable = false,
+ sunlight_propagates = true,
+ groups = { dig_immediate = 3 },
+})
+
+-- param2 changes shape
+minetest.register_node("testnodes:plantlike_meshoptions", {
+ description = S("Meshoptions Plantlike Drawtype Test Node"),
+ drawtype = "plantlike",
+ paramtype = "light",
+ paramtype2 = "meshoptions",
+ tiles = { "testnodes_plantlike_meshoptions.png" },
+
+
+ walkable = false,
+ groups = { dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:plantlike_rooted", {
+ description = S("Rooted Plantlike Drawtype Test Node"),
+ drawtype = "plantlike_rooted",
+ paramtype = "light",
+ tiles = { "testnodes_plantlike_rooted_base.png" },
+ special_tiles = { "testnodes_plantlike_rooted.png" },
+
+ groups = { dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:plantlike_rooted_wallmounted", {
+ description = S("Wallmounted Rooted Plantlike Drawtype Test Node"),
+ drawtype = "plantlike_rooted",
+ paramtype = "light",
+ paramtype2 = "wallmounted",
+ tiles = {
+ "testnodes_plantlike_rooted_base.png",
+ "testnodes_plantlike_rooted_base.png",
+ "testnodes_plantlike_rooted_base_side_wallmounted.png" },
+ special_tiles = { "testnodes_plantlike_rooted_wallmounted.png" },
+
+ groups = { dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:plantlike_rooted_waving", {
+ description = S("Waving Rooted Plantlike Drawtype Test Node"),
+ drawtype = "plantlike_rooted",
+ paramtype = "light",
+ tiles = {
+ "testnodes_plantlike_rooted_base.png",
+ "testnodes_plantlike_rooted_base.png",
+ "testnodes_plantlike_rooted_base_side_waving.png",
+ },
+ special_tiles = { "testnodes_plantlike_rooted_waving.png" },
+ waving = 1,
+
+ groups = { dig_immediate = 3 },
+})
+
+-- param2 changes height
+minetest.register_node("testnodes:plantlike_rooted_leveled", {
+ description = S("Leveled Rooted Plantlike Drawtype Test Node"),
+ drawtype = "plantlike_rooted",
+ paramtype = "light",
+ paramtype2 = "leveled",
+ tiles = {
+ "testnodes_plantlike_rooted_base.png",
+ "testnodes_plantlike_rooted_base.png",
+ "testnodes_plantlike_rooted_base_side_leveled.png",
+ },
+ special_tiles = {
+ { name = "testnodes_plantlike_rooted_leveled.png", tileable_vertical = true },
+ },
+
+
+ -- We set a default param2 here only for convenience, to make the "plant" visible after placement
+ place_param2 = 8,
+ groups = { dig_immediate = 3 },
+})
+
+-- param2 changes shape
+minetest.register_node("testnodes:plantlike_rooted_meshoptions", {
+ description = S("Meshoptions Rooted Plantlike Drawtype Test Node"),
+ drawtype = "plantlike_rooted",
+ paramtype = "light",
+ paramtype2 = "meshoptions",
+ tiles = {
+ "testnodes_plantlike_rooted_base.png",
+ "testnodes_plantlike_rooted_base.png",
+ "testnodes_plantlike_rooted_base_side_meshoptions.png",
+ },
+ special_tiles = {
+ "testnodes_plantlike_rooted_meshoptions.png",
+ },
+
+ groups = { dig_immediate = 3 },
+})
+
+-- param2 changes rotation
+minetest.register_node("testnodes:plantlike_rooted_degrotate", {
+ description = S("Degrotate Rooted Plantlike Drawtype Test Node"),
+ drawtype = "plantlike_rooted",
+ paramtype = "light",
+ paramtype2 = "degrotate",
+ tiles = {
+ "testnodes_plantlike_rooted_base.png",
+ "testnodes_plantlike_rooted_base.png",
+ "testnodes_plantlike_rooted_base_side_degrotate.png",
+ },
+ special_tiles = {
+ "testnodes_plantlike_rooted_degrotate.png",
+ },
+
+ groups = { dig_immediate = 3 },
+})
+
+-- Demonstrative liquid nodes, source and flowing form.
+-- DRAWTYPE ONLY, NO LIQUID PHYSICS!
+-- Liquid ranges 0 to 8
+for r = 0, 8 do
+ minetest.register_node("testnodes:liquid_"..r, {
+ description = S("Source Liquid Drawtype Test Node, Range @1", r),
+ drawtype = "liquid",
+ paramtype = "light",
+ tiles = {
+ "testnodes_liquidsource_r"..r..".png^[colorize:#FFFFFF:100",
+ },
+ special_tiles = {
+ {name="testnodes_liquidsource_r"..r..".png^[colorize:#FFFFFF:100", backface_culling=false},
+ {name="testnodes_liquidsource_r"..r..".png^[colorize:#FFFFFF:100", backface_culling=true},
+ },
+ use_texture_alpha = "blend",
+
+
+ walkable = false,
+ liquid_range = r,
+ liquid_viscosity = 0,
+ liquid_alternative_flowing = "testnodes:liquid_flowing_"..r,
+ liquid_alternative_source = "testnodes:liquid_"..r,
+ groups = { dig_immediate = 3 },
+ })
+ minetest.register_node("testnodes:liquid_flowing_"..r, {
+ description = S("Flowing Liquid Drawtype Test Node, Range @1", r),
+ drawtype = "flowingliquid",
+ paramtype = "light",
+ paramtype2 = "flowingliquid",
+ tiles = {
+ "testnodes_liquidflowing_r"..r..".png^[colorize:#FFFFFF:100",
+ },
+ special_tiles = {
+ {name="testnodes_liquidflowing_r"..r..".png^[colorize:#FFFFFF:100", backface_culling=false},
+ {name="testnodes_liquidflowing_r"..r..".png^[colorize:#FFFFFF:100", backface_culling=false},
+ },
+ use_texture_alpha = "blend",
+
+
+ walkable = false,
+ liquid_range = r,
+ liquid_viscosity = 0,
+ liquid_alternative_flowing = "testnodes:liquid_flowing_"..r,
+ liquid_alternative_source = "testnodes:liquid_"..r,
+ groups = { dig_immediate = 3 },
+ })
+
+end
+
+-- Waving liquid test (drawtype only)
+minetest.register_node("testnodes:liquid_waving", {
+ description = S("Waving Source Liquid Drawtype Test Node"),
+ drawtype = "liquid",
+ paramtype = "light",
+ tiles = {
+ "testnodes_liquidsource.png^[colorize:#0000FF:127",
+ },
+ special_tiles = {
+ {name="testnodes_liquidsource.png^[colorize:#0000FF:127", backface_culling=false},
+ {name="testnodes_liquidsource.png^[colorize:#0000FF:127", backface_culling=true},
+ },
+ use_texture_alpha = "blend",
+ waving = 3,
+
+
+ walkable = false,
+ liquid_range = 1,
+ liquid_viscosity = 0,
+ liquid_alternative_flowing = "testnodes:liquid_flowing_waving",
+ liquid_alternative_source = "testnodes:liquid_waving",
+ groups = { dig_immediate = 3 },
+})
+minetest.register_node("testnodes:liquid_flowing_waving", {
+ description = S("Waving Flowing Liquid Drawtype Test Node"),
+ drawtype = "flowingliquid",
+ paramtype = "light",
+ paramtype2 = "flowingliquid",
+ tiles = {
+ "testnodes_liquidflowing.png^[colorize:#0000FF:127",
+ },
+ special_tiles = {
+ {name="testnodes_liquidflowing.png^[colorize:#0000FF:127", backface_culling=false},
+ {name="testnodes_liquidflowing.png^[colorize:#0000FF:127", backface_culling=false},
+ },
+ use_texture_alpha = "blend",
+ waving = 3,
+
+
+ walkable = false,
+ liquid_range = 1,
+ liquid_viscosity = 0,
+ liquid_alternative_flowing = "testnodes:liquid_flowing_waving",
+ liquid_alternative_source = "testnodes:liquid_waving",
+ groups = { dig_immediate = 3 },
+})
+
+-- Invisible node
+minetest.register_node("testnodes:airlike", {
+ description = S("Airlike Drawtype Test Node"),
+ drawtype = "airlike",
+ paramtype = "light",
+
+
+ walkable = false,
+ groups = { dig_immediate = 3 },
+ sunlight_propagates = true,
+})
+
+-- param2 changes liquid height
+minetest.register_node("testnodes:glassliquid", {
+ description = S("Glasslike Liquid Level Drawtype Test Node"),
+ drawtype = "glasslike_framed",
+ paramtype = "light",
+ paramtype2 = "glasslikeliquidlevel",
+ tiles = {
+ "testnodes_glasslikeliquid.png",
+ },
+ special_tiles = {
+ "testnodes_liquid.png",
+ },
+
+ groups = { dig_immediate = 3 },
+})
+
+-- Adding many raillike examples, primarily to demonstrate the behavior of
+-- "raillike groups". Nodes of the same type (rail, groupless, line, street)
+-- should connect to nodes of the same "rail type" (=same shape, different
+-- color) only.
+local rails = {
+ { "rail", {"testnodes_rail_straight.png", "testnodes_rail_curved.png", "testnodes_rail_t_junction.png", "testnodes_rail_crossing.png"} },
+ { "line", {"testnodes_line_straight.png", "testnodes_line_curved.png", "testnodes_line_t_junction.png", "testnodes_line_crossing.png"}, },
+ { "street", {"testnodes_street_straight.png", "testnodes_street_curved.png", "testnodes_street_t_junction.png", "testnodes_street_crossing.png"}, },
+ -- the "groupless" nodes are nodes in which the "connect_to_raillike" group is not set
+ { "groupless", {"testnodes_rail2_straight.png", "testnodes_rail2_curved.png", "testnodes_rail2_t_junction.png", "testnodes_rail2_crossing.png"} },
+}
+local colors = { "", "cyan", "red" }
+
+for r=1, #rails do
+ local id = rails[r][1]
+ local tiles = rails[r][2]
+ local raillike_group
+ if id ~= "groupless" then
+ raillike_group = minetest.raillike_group(id)
+ end
+ for c=1, #colors do
+ local color
+ if colors[c] ~= "" then
+ color = colors[c]
+ end
+ minetest.register_node("testnodes:raillike_"..id..c, {
+ description = S("Raillike Drawtype Test Node: @1 @2", id, c),
+ drawtype = "raillike",
+ paramtype = "light",
+ tiles = tiles,
+ groups = { connect_to_raillike = raillike_group, dig_immediate = 3 },
+
+
+ color = color,
+ selection_box = {
+ type = "fixed",
+ fixed = {{-0.5, -0.5, -0.5, 0.5, -0.4, 0.5}},
+ },
+ sunlight_propagates = true,
+ walkable = false,
+ })
+ end
+end
+
+
+
+-- Add visual_scale variants of previous nodes for half and double size
+local scale = function(subname, desc_double, desc_half)
+ local original = "testnodes:"..subname
+ local def = table.copy(minetest.registered_items[original])
+ def.visual_scale = 2.0
+ def.description = desc_double
+ minetest.register_node("testnodes:"..subname.."_double", def)
+ def = table.copy(minetest.registered_items[original])
+ def.visual_scale = 0.5
+ def.description = desc_half
+ minetest.register_node("testnodes:"..subname.."_half", def)
+end
+
+scale("allfaces",
+ S("Double-sized Allfaces Drawtype Test Node"),
+ S("Half-sized Allfaces Drawtype Test Node"))
+scale("allfaces_optional",
+ S("Double-sized Allfaces Optional Drawtype Test Node"),
+ S("Half-sized Allfaces Optional Drawtype Test Node"))
+scale("allfaces_optional_waving",
+ S("Double-sized Waving Allfaces Optional Drawtype Test Node"),
+ S("Half-sized Waving Allfaces Optional Drawtype Test Node"))
+scale("plantlike",
+ S("Double-sized Plantlike Drawtype Test Node"),
+ S("Half-sized Plantlike Drawtype Test Node"))
+scale("plantlike_wallmounted",
+ S("Double-sized Wallmounted Plantlike Drawtype Test Node"),
+ S("Half-sized Wallmounted Plantlike Drawtype Test Node"))
+scale("torchlike_wallmounted",
+ S("Double-sized Wallmounted Torchlike Drawtype Test Node"),
+ S("Half-sized Wallmounted Torchlike Drawtype Test Node"))
+scale("signlike_wallmounted",
+ S("Double-sized Wallmounted Signlike Drawtype Test Node"),
+ S("Half-sized Wallmounted Signlike Drawtype Test Node"))
+scale("firelike",
+ S("Double-sized Firelike Drawtype Test Node"),
+ S("Half-sized Firelike Drawtype Test Node"))
diff --git a/games/devtest/mods/testnodes/init.lua b/games/devtest/mods/testnodes/init.lua
new file mode 100644
index 000000000..d355c4278
--- /dev/null
+++ b/games/devtest/mods/testnodes/init.lua
@@ -0,0 +1,11 @@
+local path = minetest.get_modpath(minetest.get_current_modname())
+
+dofile(path.."/drawtypes.lua")
+dofile(path.."/meshes.lua")
+dofile(path.."/nodeboxes.lua")
+dofile(path.."/param2.lua")
+dofile(path.."/properties.lua")
+dofile(path.."/liquids.lua")
+dofile(path.."/light.lua")
+dofile(path.."/textures.lua")
+dofile(path.."/overlays.lua")
diff --git a/games/devtest/mods/testnodes/light.lua b/games/devtest/mods/testnodes/light.lua
new file mode 100644
index 000000000..8ab4416d9
--- /dev/null
+++ b/games/devtest/mods/testnodes/light.lua
@@ -0,0 +1,50 @@
+-- Test Nodes: Light test
+
+local S = minetest.get_translator("testnodes")
+
+-- All possible light levels
+for i=1, minetest.LIGHT_MAX do
+ minetest.register_node("testnodes:light"..i, {
+ description = S("Light Source (@1)", i),
+ paramtype = "light",
+ light_source = i,
+
+
+ tiles ={"testnodes_light_"..i..".png"},
+ drawtype = "glasslike",
+ walkable = false,
+ sunlight_propagates = true,
+ is_ground_content = false,
+ groups = {dig_immediate=3},
+ })
+end
+
+-- Lets light through, but not sunlight, leading to a
+-- reduction in light level when light passes through
+minetest.register_node("testnodes:sunlight_filter", {
+ description = S("Sunlight Filter") .."\n"..
+ S("Lets light through, but weakens sunlight"),
+ paramtype = "light",
+
+
+ drawtype = "glasslike",
+ tiles = {
+ "testnodes_sunlight_filter.png",
+ },
+ groups = { dig_immediate = 3 },
+})
+
+-- Lets light and sunlight through without obstruction
+minetest.register_node("testnodes:sunlight_propagator", {
+ description = S("Sunlight Propagator") .."\n"..
+ S("Lets all light through"),
+ paramtype = "light",
+ sunlight_propagates = true,
+
+
+ drawtype = "glasslike",
+ tiles = {
+ "testnodes_sunlight_filter.png^[brighten",
+ },
+ groups = { dig_immediate = 3 },
+})
diff --git a/games/devtest/mods/testnodes/liquids.lua b/games/devtest/mods/testnodes/liquids.lua
new file mode 100644
index 000000000..be33814af
--- /dev/null
+++ b/games/devtest/mods/testnodes/liquids.lua
@@ -0,0 +1,134 @@
+-- Add liquids for ranges and viscosity levels 0-8
+
+for d=0, 8 do
+ minetest.register_node("testnodes:rliquid_"..d, {
+ description = "Test Liquid Source, Range "..d,
+ drawtype = "liquid",
+ tiles = {"testnodes_liquidsource_r"..d..".png"},
+ special_tiles = {
+ {name = "testnodes_liquidsource_r"..d..".png", backface_culling = false},
+ {name = "testnodes_liquidsource_r"..d..".png", backface_culling = true},
+ },
+ use_texture_alpha = "blend",
+ paramtype = "light",
+ walkable = false,
+ buildable_to = true,
+ is_ground_content = false,
+ liquidtype = "source",
+ liquid_alternative_flowing = "testnodes:rliquid_flowing_"..d,
+ liquid_alternative_source = "testnodes:rliquid_"..d,
+ liquid_range = d,
+ })
+
+ minetest.register_node("testnodes:rliquid_flowing_"..d, {
+ description = "Flowing Test Liquid, Range "..d,
+ drawtype = "flowingliquid",
+ tiles = {"testnodes_liquidflowing_r"..d..".png"},
+ special_tiles = {
+ {name = "testnodes_liquidflowing_r"..d..".png", backface_culling = false},
+ {name = "testnodes_liquidflowing_r"..d..".png", backface_culling = false},
+ },
+ use_texture_alpha = "blend",
+ paramtype = "light",
+ paramtype2 = "flowingliquid",
+ walkable = false,
+ buildable_to = true,
+ is_ground_content = false,
+ liquidtype = "flowing",
+ liquid_alternative_flowing = "testnodes:rliquid_flowing_"..d,
+ liquid_alternative_source = "testnodes:rliquid_"..d,
+ liquid_range = d,
+ })
+
+ if d <= 7 then
+
+ local mod = "^[colorize:#000000:127"
+ minetest.register_node("testnodes:vliquid_"..d, {
+ description = "Test Liquid Source, Viscosity/Resistance "..d,
+ drawtype = "liquid",
+ tiles = {"testnodes_liquidsource_r"..d..".png"..mod},
+ special_tiles = {
+ {name = "testnodes_liquidsource_r"..d..".png"..mod, backface_culling = false},
+ {name = "testnodes_liquidsource_r"..d..".png"..mod, backface_culling = true},
+ },
+ use_texture_alpha = "blend",
+ paramtype = "light",
+ walkable = false,
+ buildable_to = true,
+ is_ground_content = false,
+ liquidtype = "source",
+ liquid_alternative_flowing = "testnodes:vliquid_flowing_"..d,
+ liquid_alternative_source = "testnodes:vliquid_"..d,
+ liquid_viscosity = d,
+ })
+
+ minetest.register_node("testnodes:vliquid_flowing_"..d, {
+ description = "Flowing Test Liquid, Viscosity/Resistance "..d,
+ drawtype = "flowingliquid",
+ tiles = {"testnodes_liquidflowing_r"..d..".png"..mod},
+ special_tiles = {
+ {name = "testnodes_liquidflowing_r"..d..".png"..mod, backface_culling = false},
+ {name = "testnodes_liquidflowing_r"..d..".png"..mod, backface_culling = false},
+ },
+ use_texture_alpha = "blend",
+ paramtype = "light",
+ paramtype2 = "flowingliquid",
+ walkable = false,
+ buildable_to = true,
+ is_ground_content = false,
+ liquidtype = "flowing",
+ liquid_alternative_flowing = "testnodes:vliquid_flowing_"..d,
+ liquid_alternative_source = "testnodes:vliquid_"..d,
+ liquid_viscosity = d,
+ })
+
+ mod = "^[colorize:#000000:192"
+ local v = 4
+ minetest.register_node("testnodes:vrliquid_"..d, {
+ description = "Test Liquid Source, Viscosity "..v..", Resistance "..d,
+ drawtype = "liquid",
+ tiles = {"testnodes_liquidsource_r"..d..".png"..mod},
+ special_tiles = {
+ {name = "testnodes_liquidsource_r"..d..".png"..mod, backface_culling = false},
+ {name = "testnodes_liquidsource_r"..d..".png"..mod, backface_culling = true},
+ },
+ use_texture_alpha = "blend",
+ paramtype = "light",
+ walkable = false,
+ pointable = false,
+ diggable = false,
+ buildable_to = true,
+ is_ground_content = false,
+ liquidtype = "source",
+ liquid_alternative_flowing = "testnodes:vrliquid_flowing_"..d,
+ liquid_alternative_source = "testnodes:vrliquid_"..d,
+ liquid_viscosity = v,
+ move_resistance = d,
+ })
+
+ minetest.register_node("testnodes:vrliquid_flowing_"..d, {
+ description = "Flowing Test Liquid, Viscosity "..v..", Resistance "..d,
+ drawtype = "flowingliquid",
+ tiles = {"testnodes_liquidflowing_r"..d..".png"..mod},
+ special_tiles = {
+ {name = "testnodes_liquidflowing_r"..d..".png"..mod, backface_culling = false},
+ {name = "testnodes_liquidflowing_r"..d..".png"..mod, backface_culling = false},
+ },
+ use_texture_alpha = "blend",
+ paramtype = "light",
+ paramtype2 = "flowingliquid",
+ walkable = false,
+ pointable = false,
+ diggable = false,
+ buildable_to = true,
+ is_ground_content = false,
+ liquidtype = "flowing",
+ liquid_alternative_flowing = "testnodes:vrliquid_flowing_"..d,
+ liquid_alternative_source = "testnodes:vrliquid_"..d,
+ liquid_viscosity = v,
+ move_resistance = d,
+ })
+
+ end
+
+end
diff --git a/games/devtest/mods/testnodes/meshes.lua b/games/devtest/mods/testnodes/meshes.lua
new file mode 100644
index 000000000..900abc180
--- /dev/null
+++ b/games/devtest/mods/testnodes/meshes.lua
@@ -0,0 +1,145 @@
+-- Meshes
+
+local S = minetest.get_translator("testnodes")
+
+local ocorner_cbox = {
+ 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 tall_pyr_cbox = {
+ type = "fixed",
+ fixed = {
+ { -0.5, -0.5, -0.5, 0.5, -0.25, 0.5 },
+ { -0.375, -0.25, -0.375, 0.375, 0, 0.375},
+ { -0.25, 0, -0.25, 0.25, 0.25, 0.25},
+ { -0.125, 0.25, -0.125, 0.125, 0.5, 0.125}
+ }
+}
+
+-- Normal mesh
+minetest.register_node("testnodes:mesh", {
+ description = S("Mesh Test Node"),
+ drawtype = "mesh",
+ mesh = "testnodes_pyramid.obj",
+ tiles = {"testnodes_mesh_stripes2.png"},
+ paramtype = "light",
+ collision_box = tall_pyr_cbox,
+
+ groups = {dig_immediate=3},
+})
+
+-- Facedir mesh: outer corner slope
+minetest.register_node("testnodes:mesh_facedir", {
+ description = S("Facedir Mesh Test Node"),
+ drawtype = "mesh",
+ mesh = "testnodes_ocorner.obj",
+ tiles = {"testnodes_mesh_stripes.png"},
+ paramtype = "light",
+ paramtype2 = "facedir",
+ collision_box = ocorner_cbox,
+
+ groups = {dig_immediate=3},
+})
+
+minetest.register_node("testnodes:mesh_colorfacedir", {
+ description = S("Color Facedir Mesh Test Node"),
+ drawtype = "mesh",
+ mesh = "testnodes_ocorner.obj",
+ tiles = {"testnodes_mesh_stripes3.png"},
+ paramtype = "light",
+ paramtype2 = "colorfacedir",
+ palette = "testnodes_palette_facedir.png",
+ collision_box = ocorner_cbox,
+
+ groups = {dig_immediate=3},
+})
+
+-- Wallmounted mesh: pyramid
+minetest.register_node("testnodes:mesh_wallmounted", {
+ description = S("Wallmounted Mesh Test Node"),
+ drawtype = "mesh",
+ mesh = "testnodes_pyramid.obj",
+ tiles = {"testnodes_mesh_stripes2.png"},
+ paramtype = "light",
+ paramtype2 = "wallmounted",
+ collision_box = tall_pyr_cbox,
+
+ groups = {dig_immediate=3},
+})
+
+minetest.register_node("testnodes:mesh_colorwallmounted", {
+ description = S("Color Wallmounted Mesh Test Node"),
+ drawtype = "mesh",
+ mesh = "testnodes_pyramid.obj",
+ tiles = {"testnodes_mesh_stripes3.png"},
+ paramtype = "light",
+ paramtype2 = "colorwallmounted",
+ palette = "testnodes_palette_wallmounted.png",
+ collision_box = tall_pyr_cbox,
+
+ groups = {dig_immediate=3},
+})
+
+
+minetest.register_node("testnodes:mesh_double", {
+ description = S("Double-sized Mesh Test Node"),
+ drawtype = "mesh",
+ mesh = "testnodes_pyramid.obj",
+ tiles = {"testnodes_mesh_stripes2.png"},
+ paramtype = "light",
+ collision_box = tall_pyr_cbox,
+ visual_scale = 2,
+
+ groups = {dig_immediate=3},
+})
+minetest.register_node("testnodes:mesh_half", {
+ description = S("Half-sized Mesh Test Node"),
+ drawtype = "mesh",
+ mesh = "testnodes_pyramid.obj",
+ tiles = {"testnodes_mesh_stripes2.png"},
+ paramtype = "light",
+ collision_box = tall_pyr_cbox,
+ visual_scale = 0.5,
+
+ groups = {dig_immediate=3},
+})
+
+minetest.register_node("testnodes:mesh_waving1", {
+ description = S("Plantlike-waving Mesh Test Node"),
+ drawtype = "mesh",
+ mesh = "testnodes_pyramid.obj",
+ tiles = {"testnodes_mesh_stripes4.png^[multiply:#B0FFB0"},
+ paramtype = "light",
+ collision_box = tall_pyr_cbox,
+ waving = 1,
+
+ groups = {dig_immediate=3},
+})
+minetest.register_node("testnodes:mesh_waving2", {
+ description = S("Leaflike-waving Mesh Test Node"),
+ drawtype = "mesh",
+ mesh = "testnodes_pyramid.obj",
+ tiles = {"testnodes_mesh_stripes4.png^[multiply:#FFFFB0"},
+ paramtype = "light",
+ collision_box = tall_pyr_cbox,
+ waving = 2,
+
+ groups = {dig_immediate=3},
+})
+minetest.register_node("testnodes:mesh_waving3", {
+ description = S("Liquidlike-waving Mesh Test Node"),
+ drawtype = "mesh",
+ mesh = "testnodes_pyramid.obj",
+ tiles = {"testnodes_mesh_stripes4.png^[multiply:#B0B0FF"},
+ paramtype = "light",
+ collision_box = tall_pyr_cbox,
+ waving = 3,
+
+ groups = {dig_immediate=3},
+})
diff --git a/games/devtest/mods/testnodes/mod.conf b/games/devtest/mods/testnodes/mod.conf
new file mode 100644
index 000000000..d894c3452
--- /dev/null
+++ b/games/devtest/mods/testnodes/mod.conf
@@ -0,0 +1,3 @@
+name = testnodes
+description = Contains a bunch of basic example nodes for demonstrative purposes, development and testing
+depends = stairs
diff --git a/games/devtest/mods/testnodes/models/testnodes_ocorner.obj b/games/devtest/mods/testnodes/models/testnodes_ocorner.obj
new file mode 100644
index 000000000..231d7056b
--- /dev/null
+++ b/games/devtest/mods/testnodes/models/testnodes_ocorner.obj
@@ -0,0 +1,23 @@
+# Blender v2.73 (sub 0) OBJ File: 'slope_test_ocorner_onetexture.blend'
+# www.blender.org
+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
+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
+s off
+f 3/1/1 2/2/1 4/3/1 5/4/1
+f 1/2/2 3/3/2 5/4/2
+f 1/1/3 2/3/3 3/4/3
+f 1/1/4 4/3/4 2/4/4
+f 1/2/5 5/3/5 4/4/5
diff --git a/games/devtest/mods/testnodes/models/testnodes_pyramid.obj b/games/devtest/mods/testnodes/models/testnodes_pyramid.obj
new file mode 100644
index 000000000..b305af2f8
--- /dev/null
+++ b/games/devtest/mods/testnodes/models/testnodes_pyramid.obj
@@ -0,0 +1,24 @@
+# Blender v2.73 (sub 0) OBJ File: 'slope_test_pyramid_onetexture.blend'
+# www.blender.org
+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.000000 0.500000 -0.000000
+vt 1.000000 1.000000
+vt 0.000000 1.000000
+vt 0.000000 0.000000
+vt 1.000000 0.000000
+vt 0.500000 1.000000
+vn 0.000000 -1.000000 0.000000
+vn -0.894400 0.447200 -0.000000
+vn 0.000000 0.447200 -0.894400
+vn 0.894400 0.447200 0.000000
+vn -0.000000 0.447200 0.894400
+s off
+f 1/1/1 2/2/1 3/3/1 4/4/1
+f 3/4/2 5/5/2 4/3/2
+f 5/5/3 1/3/3 4/4/3
+f 1/4/4 5/5/4 2/3/4
+f 2/4/5 5/5/5 3/3/5
diff --git a/games/devtest/mods/testnodes/nodeboxes.lua b/games/devtest/mods/testnodes/nodeboxes.lua
new file mode 100644
index 000000000..7e966fdce
--- /dev/null
+++ b/games/devtest/mods/testnodes/nodeboxes.lua
@@ -0,0 +1,81 @@
+local S = minetest.get_translator("testnodes")
+
+-- Nodebox examples and tests.
+
+-- An simple example nodebox with one centered box
+minetest.register_node("testnodes:nodebox_fixed", {
+ description = S("Fixed Nodebox Test Node"),
+ tiles = {"testnodes_nodebox.png"},
+ drawtype = "nodebox",
+ paramtype = "light",
+ node_box = {
+ type = "fixed",
+ fixed = {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25},
+ },
+
+ groups = {dig_immediate=3},
+})
+
+-- 50% higher than a regular node
+minetest.register_node("testnodes:nodebox_overhigh", {
+ description = S("+50% high Nodebox Test Node"),
+ tiles = {"testnodes_nodebox.png"},
+ drawtype = "nodebox",
+ paramtype = "light",
+ node_box = {
+ type = "fixed",
+ fixed = {-0.5, -0.5, -0.5, 0.5, 1, 0.5},
+ },
+
+ groups = {dig_immediate=3},
+})
+
+-- 95% higher than a regular node
+minetest.register_node("testnodes:nodebox_overhigh2", {
+ description = S("+95% high Nodebox Test Node"),
+ tiles = {"testnodes_nodebox.png"},
+ drawtype = "nodebox",
+ paramtype = "light",
+ node_box = {
+ type = "fixed",
+ -- Y max: more is possible, but glitchy
+ fixed = {-0.5, -0.5, -0.5, 0.5, 1.45, 0.5},
+ },
+
+ groups = {dig_immediate=3},
+})
+
+-- Height of nodebox changes with its param2 value
+minetest.register_node("testnodes:nodebox_leveled", {
+ description = S("Leveled Nodebox Test Node"),
+ tiles = {"testnodes_nodebox.png"},
+ drawtype = "nodebox",
+ paramtype = "light",
+ paramtype2 = "leveled",
+ node_box = {
+ type = "leveled",
+ fixed = {-0.5, 0.0, -0.5, 0.5, -0.499, 0.5},
+ },
+
+ groups = {dig_immediate=3},
+})
+
+-- Wall-like nodebox that connects to neighbors
+minetest.register_node("testnodes:nodebox_connected", {
+ description = S("Connected Nodebox Test Node"),
+ tiles = {"testnodes_nodebox.png"},
+ groups = {connected_nodebox=1, dig_immediate=3},
+ drawtype = "nodebox",
+ paramtype = "light",
+ connects_to = {"group:connected_nodebox"},
+ connect_sides = {"front", "back", "left", "right"},
+ node_box = {
+ type = "connected",
+ fixed = {-0.125, -0.500, -0.125, 0.125, 0.500, 0.125},
+ connect_front = {-0.125, -0.500, -0.500, 0.125, 0.400, -0.125},
+ connect_back = {-0.125, -0.500, 0.125, 0.125, 0.400, 0.500},
+ connect_left = {-0.500, -0.500, -0.125, -0.125, 0.400, 0.125},
+ connect_right = {0.125, -0.500, -0.125, 0.500, 0.400, 0.125},
+ },
+})
+
diff --git a/games/devtest/mods/testnodes/overlays.lua b/games/devtest/mods/testnodes/overlays.lua
new file mode 100644
index 000000000..294e06a16
--- /dev/null
+++ b/games/devtest/mods/testnodes/overlays.lua
@@ -0,0 +1,93 @@
+local S = minetest.get_translator("testnodes")
+
+minetest.register_node("testnodes:overlay", {
+ description = S("Texture Overlay Test Node") .. "\n" ..
+ S("Uncolorized"),
+ tiles = {{name = "testnodes_overlayable.png"}},
+ overlay_tiles = {{name = "testnodes_overlay.png"}},
+ groups = { dig_immediate = 2 },
+})
+minetest.register_node("testnodes:overlay_color_all", {
+ description = S("Texture Overlay Test Node, Colorized") .. "\n" ..
+ S("param2 changes color"),
+ tiles = {{name = "testnodes_overlayable.png"}},
+ overlay_tiles = {{name = "testnodes_overlay.png"}},
+ paramtype2 = "color",
+ palette = "testnodes_palette_full.png",
+
+
+ groups = { dig_immediate = 2 },
+})
+minetest.register_node("testnodes:overlay_color_overlay", {
+ description = S("Texture Overlay Test Node, Colorized Overlay") .. "\n" ..
+ S("param2 changes color of overlay"),
+ tiles = {{name = "testnodes_overlayable.png", color="white"}},
+ overlay_tiles = {{name = "testnodes_overlay.png"}},
+ paramtype2 = "color",
+ palette = "testnodes_palette_full.png",
+
+
+ groups = { dig_immediate = 2 },
+})
+minetest.register_node("testnodes:overlay_color_overlayed", {
+ description = S("Texture Overlay Test Node, Colorized Base") .. "\n" ..
+ S("param2 changes color of base texture"),
+ tiles = {{name = "testnodes_overlayable.png"}},
+ overlay_tiles = {{name = "testnodes_overlay.png", color="white"}},
+ paramtype2 = "color",
+ palette = "testnodes_palette_full.png",
+
+
+ groups = { dig_immediate = 2 },
+})
+
+local global_overlay_color = "#FF2000"
+minetest.register_node("testnodes:overlay_global", {
+ description = S("Texture Overlay Test Node, Global Color") .. "\n" ..
+ S("Global color = @1", global_overlay_color),
+ tiles = {{name = "testnodes_overlayable.png"}},
+ overlay_tiles = {{name = "testnodes_overlay.png"}},
+ color = global_overlay_color,
+
+
+ groups = { dig_immediate = 2 },
+})
+minetest.register_node("testnodes:overlay_global_color_all", {
+ description = S("Texture Overlay Test Node, Global Color + Colorized") .. "\n" ..
+ S("Global color = @1", global_overlay_color) .. "\n" ..
+ S("param2 changes color"),
+ tiles = {{name = "testnodes_overlayable.png"}},
+ overlay_tiles = {{name = "testnodes_overlay.png"}},
+ color = global_overlay_color,
+ paramtype2 = "color",
+ palette = "testnodes_palette_full.png",
+
+
+ groups = { dig_immediate = 2 },
+})
+minetest.register_node("testnodes:overlay_global_color_overlay", {
+ description = S("Texture Overlay Test Node, Global Color + Colorized Overlay") .. "\n" ..
+ S("Global color = @1", global_overlay_color) .. "\n" ..
+ S("param2 changes color of overlay"),
+ tiles = {{name = "testnodes_overlayable.png", color=global_overlay_color}},
+ overlay_tiles = {{name = "testnodes_overlay.png"}},
+ color = global_overlay_color,
+ paramtype2 = "color",
+ palette = "testnodes_palette_full.png",
+
+
+ groups = { dig_immediate = 2 },
+})
+minetest.register_node("testnodes:overlay_global_color_overlayed", {
+ description = S("Texture Overlay Test Node, Global Color + Colorized Base") .. "\n" ..
+ S("Global color = @1", global_overlay_color) .. "\n" ..
+ S("param2 changes color of base texture"),
+ tiles = {{name = "testnodes_overlayable.png"}},
+ overlay_tiles = {{name = "testnodes_overlay.png", color=global_overlay_color}},
+ color = global_overlay_color,
+ paramtype2 = "color",
+ palette = "testnodes_palette_full.png",
+
+
+ groups = { dig_immediate = 2 },
+})
diff --git a/games/devtest/mods/testnodes/param2.lua b/games/devtest/mods/testnodes/param2.lua
new file mode 100644
index 000000000..5d64376fa
--- /dev/null
+++ b/games/devtest/mods/testnodes/param2.lua
@@ -0,0 +1,168 @@
+-- This file is for misc. param2 tests that aren't covered in drawtypes.lua already.
+
+local S = minetest.get_translator("testnodes")
+
+minetest.register_node("testnodes:facedir", {
+ description = S("Facedir Test Node"),
+ paramtype2 = "facedir",
+ tiles = {
+ "testnodes_1.png",
+ "testnodes_2.png",
+ "testnodes_3.png",
+ "testnodes_4.png",
+ "testnodes_5.png",
+ "testnodes_6.png",
+ },
+
+ groups = { dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:facedir_nodebox", {
+ description = S("Facedir Nodebox Test Node"),
+ tiles = {
+ "testnodes_1.png",
+ "testnodes_2.png",
+ "testnodes_3.png",
+ "testnodes_4.png",
+ "testnodes_5.png",
+ "testnodes_6.png",
+ },
+ drawtype = "nodebox",
+ paramtype = "light",
+ paramtype2 = "facedir",
+ node_box = {
+ type = "fixed",
+ fixed = {-0.5, -0.5, -0.5, 0.2, 0.2, 0.2},
+ },
+
+ groups = {dig_immediate=3},
+})
+
+minetest.register_node("testnodes:wallmounted", {
+ description = S("Wallmounted Test Node"),
+ paramtype2 = "wallmounted",
+ tiles = {
+ "testnodes_1w.png",
+ "testnodes_2w.png",
+ "testnodes_3w.png",
+ "testnodes_4w.png",
+ "testnodes_5w.png",
+ "testnodes_6w.png",
+ },
+
+ groups = { dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:wallmounted_nodebox", {
+ description = S("Wallmounted Nodebox Test Node"),
+ paramtype2 = "wallmounted",
+ paramtype = "light",
+ tiles = {
+ "testnodes_1w.png",
+ "testnodes_2w.png",
+ "testnodes_3w.png",
+ "testnodes_4w.png",
+ "testnodes_5w.png",
+ "testnodes_6w.png",
+ },
+ drawtype = "nodebox",
+ node_box = {
+ type = "wallmounted",
+ wall_top = { -0.5, 0, -0.5, 0.5, 0.5, 0.5 },
+ wall_bottom = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 },
+ wall_side = { -0.5, -0.5, -0.5, 0, 0.5, 0.5 },
+ },
+
+ groups = { dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:color", {
+ description = S("Color Test Node"),
+ paramtype2 = "color",
+ palette = "testnodes_palette_full.png",
+ tiles = {
+ "testnodes_node.png",
+ },
+
+ groups = { dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:colorfacedir", {
+ description = S("Color Facedir Test Node"),
+ paramtype2 = "colorfacedir",
+ palette = "testnodes_palette_facedir.png",
+ tiles = {
+ "testnodes_1g.png",
+ "testnodes_2g.png",
+ "testnodes_3g.png",
+ "testnodes_4g.png",
+ "testnodes_5g.png",
+ "testnodes_6g.png",
+ },
+
+ groups = { dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:colorfacedir_nodebox", {
+ description = S("Color Facedir Nodebox Test Node"),
+ tiles = {
+ "testnodes_1g.png",
+ "testnodes_2g.png",
+ "testnodes_3g.png",
+ "testnodes_4g.png",
+ "testnodes_5g.png",
+ "testnodes_6g.png",
+ },
+ drawtype = "nodebox",
+ paramtype = "light",
+ paramtype2 = "colorfacedir",
+ palette = "testnodes_palette_facedir.png",
+ node_box = {
+ type = "fixed",
+ fixed = {-0.5, -0.5, -0.5, 0.2, 0.2, 0.2},
+ },
+
+ groups = {dig_immediate=3},
+})
+
+minetest.register_node("testnodes:colorwallmounted", {
+ description = S("Color Wallmounted Test Node"),
+ paramtype2 = "colorwallmounted",
+ paramtype = "light",
+ palette = "testnodes_palette_wallmounted.png",
+ tiles = {
+ "testnodes_1wg.png",
+ "testnodes_2wg.png",
+ "testnodes_3wg.png",
+ "testnodes_4wg.png",
+ "testnodes_5wg.png",
+ "testnodes_6wg.png",
+ },
+
+ groups = { dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:colorwallmounted_nodebox", {
+ description = S("Color Wallmounted Nodebox Test Node"),
+ paramtype2 = "colorwallmounted",
+ paramtype = "light",
+ palette = "testnodes_palette_wallmounted.png",
+ tiles = {
+ "testnodes_1wg.png",
+ "testnodes_2wg.png",
+ "testnodes_3wg.png",
+ "testnodes_4wg.png",
+ "testnodes_5wg.png",
+ "testnodes_6wg.png",
+ },
+ drawtype = "nodebox",
+ node_box = {
+ type = "wallmounted",
+ wall_top = { -0.5, 0, -0.5, 0.5, 0.5, 0.5 },
+ wall_bottom = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 },
+ wall_side = { -0.5, -0.5, -0.5, 0, 0.5, 0.5 },
+ },
+
+ groups = { dig_immediate = 3 },
+})
+
diff --git a/games/devtest/mods/testnodes/properties.lua b/games/devtest/mods/testnodes/properties.lua
new file mode 100644
index 000000000..bacd555cd
--- /dev/null
+++ b/games/devtest/mods/testnodes/properties.lua
@@ -0,0 +1,397 @@
+-- Test Nodes: Node property tests
+
+local S = minetest.get_translator("testnodes")
+
+-- Is supposed to fall when it doesn't rest on solid ground
+minetest.register_node("testnodes:falling", {
+ description = S("Falling Node"),
+ tiles = {
+ "testnodes_node.png",
+ "testnodes_node.png",
+ "testnodes_node_falling.png",
+ },
+ groups = { falling_node = 1, dig_immediate = 3 },
+})
+
+minetest.register_node("testnodes:falling_facedir", {
+ description = S("Falling Facedir Node"),
+ tiles = {
+ "testnodes_1.png",
+ "testnodes_2.png",
+ "testnodes_3.png",
+ "testnodes_4.png",
+ "testnodes_5.png",
+ "testnodes_6.png",
+ },
+ paramtype2 = "facedir",
+ groups = { falling_node = 1, dig_immediate = 3 },
+})
+
+-- Same as falling node, but will stop falling on top of liquids
+minetest.register_node("testnodes:falling_float", {
+ description = S("Falling+Floating Node"),
+ groups = { falling_node = 1, float = 1, dig_immediate = 3 },
+
+
+ tiles = {
+ "testnodes_node.png",
+ "testnodes_node.png",
+ "testnodes_node_falling.png",
+ },
+ color = "cyan",
+})
+
+-- This node attaches to the floor and drops as item
+-- when the floor is gone.
+minetest.register_node("testnodes:attached", {
+ description = S("Floor-Attached Node"),
+ tiles = {
+ "testnodes_attached_top.png",
+ "testnodes_attached_bottom.png",
+ "testnodes_attached_side.png",
+ },
+ groups = { attached_node = 1, dig_immediate = 3 },
+})
+
+-- This node attaches to the side of a node and drops as item
+-- when the node it attaches to is gone.
+minetest.register_node("testnodes:attached_wallmounted", {
+ description = S("Wallmounted Attached Node"),
+ paramtype2 = "wallmounted",
+ tiles = {
+ "testnodes_attachedw_top.png",
+ "testnodes_attachedw_bottom.png",
+ "testnodes_attachedw_side.png",
+ },
+ groups = { attached_node = 1, dig_immediate = 3 },
+})
+
+-- Jump disabled
+minetest.register_node("testnodes:nojump", {
+ description = S("Non-jumping Node"),
+ groups = {disable_jump=1, dig_immediate=3},
+ tiles = {"testnodes_nojump_top.png", "testnodes_nojump_side.png"},
+})
+
+-- Jump disabled plant
+minetest.register_node("testnodes:nojump_walkable", {
+ description = S("Non-jumping Plant Node"),
+ drawtype = "plantlike",
+ groups = {disable_jump=1, dig_immediate=3},
+ walkable = false,
+ tiles = {"testnodes_nojump_top.png"},
+})
+
+-- Climbable up and down with jump and sneak keys
+minetest.register_node("testnodes:climbable", {
+ description = S("Climbable Node"),
+ climbable = true,
+ walkable = false,
+
+
+ paramtype = "light",
+ sunlight_propagates = true,
+ is_ground_content = false,
+ tiles ={"testnodes_climbable_side.png"},
+ drawtype = "glasslike",
+ groups = {dig_immediate=3},
+})
+
+-- Climbable only downwards with sneak key
+minetest.register_node("testnodes:climbable_nojump", {
+ description = S("Downwards-climbable Node"),
+ climbable = true,
+ walkable = false,
+
+ groups = {disable_jump=1, dig_immediate=3},
+ drawtype = "glasslike",
+ tiles ={"testnodes_climbable_nojump_side.png"},
+ paramtype = "light",
+ sunlight_propagates = true,
+})
+
+-- A liquid in which you can't rise
+minetest.register_node("testnodes:liquid_nojump", {
+ description = S("Non-jumping Liquid Source Node"),
+ liquidtype = "source",
+ liquid_range = 1,
+ liquid_viscosity = 0,
+ liquid_alternative_flowing = "testnodes:liquidflowing_nojump",
+ liquid_alternative_source = "testnodes:liquid_nojump",
+ liquid_renewable = false,
+ groups = {disable_jump=1, dig_immediate=3},
+ walkable = false,
+
+ drawtype = "liquid",
+ tiles = {"testnodes_liquidsource.png^[colorize:#FF0000:127"},
+ special_tiles = {
+ {name = "testnodes_liquidsource.png^[colorize:#FF0000:127", backface_culling = false},
+ {name = "testnodes_liquidsource.png^[colorize:#FF0000:127", backface_culling = true},
+ },
+ use_texture_alpha = "blend",
+ paramtype = "light",
+ pointable = false,
+ liquids_pointable = true,
+ buildable_to = true,
+ is_ground_content = false,
+ post_effect_color = {a = 70, r = 255, g = 0, b = 200},
+})
+
+-- A liquid in which you can't rise (flowing variant)
+minetest.register_node("testnodes:liquidflowing_nojump", {
+ description = S("Non-jumping Flowing Liquid Node"),
+ liquidtype = "flowing",
+ liquid_range = 1,
+ liquid_viscosity = 0,
+ liquid_alternative_flowing = "testnodes:liquidflowing_nojump",
+ liquid_alternative_source = "testnodes:liquid_nojump",
+ liquid_renewable = false,
+ groups = {disable_jump=1, dig_immediate=3},
+ walkable = false,
+
+
+ drawtype = "flowingliquid",
+ tiles = {"testnodes_liquidflowing.png^[colorize:#FF0000:127"},
+ special_tiles = {
+ {name = "testnodes_liquidflowing.png^[colorize:#FF0000:127", backface_culling = false},
+ {name = "testnodes_liquidflowing.png^[colorize:#FF0000:127", backface_culling = false},
+ },
+ use_texture_alpha = "blend",
+ paramtype = "light",
+ paramtype2 = "flowingliquid",
+ pointable = false,
+ liquids_pointable = true,
+ buildable_to = true,
+ is_ground_content = false,
+ post_effect_color = {a = 70, r = 255, g = 0, b = 200},
+})
+
+-- A liquid which doesn't have liquid movement physics (source variant)
+minetest.register_node("testnodes:liquid_noswim", {
+ description = S("No-swim Liquid Source Node"),
+ liquidtype = "source",
+ liquid_range = 1,
+ liquid_viscosity = 0,
+ liquid_alternative_flowing = "testnodes:liquidflowing_noswim",
+ liquid_alternative_source = "testnodes:liquid_noswim",
+ liquid_renewable = false,
+ liquid_move_physics = false,
+ groups = {dig_immediate=3},
+ walkable = false,
+
+ drawtype = "liquid",
+ tiles = {"testnodes_liquidsource.png^[colorize:#FF00FF:127"},
+ special_tiles = {
+ {name = "testnodes_liquidsource.png^[colorize:#FF00FF:127", backface_culling = false},
+ {name = "testnodes_liquidsource.png^[colorize:#FF00FF:127", backface_culling = true},
+ },
+ use_texture_alpha = "blend",
+ paramtype = "light",
+ pointable = false,
+ liquids_pointable = true,
+ buildable_to = true,
+ is_ground_content = false,
+ post_effect_color = {a = 70, r = 255, g = 200, b = 200},
+})
+
+-- A liquid which doen't have liquid movement physics (flowing variant)
+minetest.register_node("testnodes:liquidflowing_noswim", {
+ description = S("No-swim Flowing Liquid Node"),
+ liquidtype = "flowing",
+ liquid_range = 1,
+ liquid_viscosity = 0,
+ liquid_alternative_flowing = "testnodes:liquidflowing_noswim",
+ liquid_alternative_source = "testnodes:liquid_noswim",
+ liquid_renewable = false,
+ liquid_move_physics = false,
+ groups = {dig_immediate=3},
+ walkable = false,
+
+
+ drawtype = "flowingliquid",
+ tiles = {"testnodes_liquidflowing.png^[colorize:#FF00FF:127"},
+ special_tiles = {
+ {name = "testnodes_liquidflowing.png^[colorize:#FF00FF:127", backface_culling = false},
+ {name = "testnodes_liquidflowing.png^[colorize:#FF00FF:127", backface_culling = false},
+ },
+ use_texture_alpha = "blend",
+ paramtype = "light",
+ paramtype2 = "flowingliquid",
+ pointable = false,
+ liquids_pointable = true,
+ buildable_to = true,
+ is_ground_content = false,
+ post_effect_color = {a = 70, r = 255, g = 200, b = 200},
+})
+
+
+
+-- Nodes that modify fall damage (various damage modifiers)
+for i=-100, 100, 25 do
+ if i ~= 0 then
+ local subname, descnum
+ if i < 0 then
+ subname = "m"..math.abs(i)
+ descnum = tostring(i)
+ else
+ subname = tostring(i)
+ descnum = S("+@1", i)
+ end
+ local tex, color, desc
+ if i > 0 then
+ local val = math.floor((i/100)*255)
+ tex = "testnodes_fall_damage_plus.png"
+ color = { b=0, g=255-val, r=255, a=255 }
+ desc = S("Fall Damage Node (+@1%)", i)
+ else
+ tex = "testnodes_fall_damage_minus.png"
+ if i == -100 then
+ color = { r=0, b=0, g=255, a=255 }
+ else
+ local val = math.floor((math.abs(i)/100)*255)
+ color = { r=0, b=255, g=255-val, a=255 }
+ end
+ desc = S("Fall Damage Node (-@1%)", math.abs(i))
+ end
+ minetest.register_node("testnodes:damage"..subname, {
+ description = desc,
+ groups = {fall_damage_add_percent=i, dig_immediate=3},
+
+
+ tiles = { tex },
+ is_ground_content = false,
+ color = color,
+ })
+ end
+end
+
+-- Bouncy nodes (various bounce levels)
+for i=-140, 180, 20 do
+ local val = math.floor(((i-20)/200)*255)
+ minetest.register_node(("testnodes:bouncy"..i):gsub("-","NEG"), {
+ description = S("Bouncy Node (@1%)", i),
+ groups = {bouncy=i, dig_immediate=3},
+
+
+ tiles ={"testnodes_bouncy.png"},
+ is_ground_content = false,
+ color = { r=255, g=255-val, b=val, a=255 },
+ })
+end
+
+-- Slippery nodes (various slippery levels)
+for i=1, 5 do
+ minetest.register_node("testnodes:slippery"..i, {
+ description = S("Slippery Node (@1)", i),
+ tiles ={"testnodes_slippery.png"},
+ is_ground_content = false,
+ groups = {slippery=i, dig_immediate=3},
+ color = { r=0, g=255, b=math.floor((i/5)*255), a=255 },
+ })
+end
+
+-- Move resistance nodes (various resistance levels)
+for r=0, 7 do
+ if r > 0 then
+ minetest.register_node("testnodes:move_resistance"..r, {
+ description = S("Move-resistant Node (@1)", r),
+ walkable = false,
+ move_resistance = r,
+
+ drawtype = "glasslike",
+ paramtype = "light",
+ sunlight_propagates = true,
+ tiles = { "testnodes_move_resistance.png" },
+ is_ground_content = false,
+ groups = { dig_immediate = 3 },
+ color = { b = 0, g = 255, r = math.floor((r/7)*255), a = 255 },
+ })
+ end
+
+ minetest.register_node("testnodes:move_resistance_liquidlike"..r, {
+ description = S("Move-resistant Node, liquidlike (@1)", r),
+ walkable = false,
+ move_resistance = r,
+ liquid_move_physics = true,
+
+ drawtype = "glasslike",
+ paramtype = "light",
+ sunlight_propagates = true,
+ tiles = { "testnodes_move_resistance.png" },
+ is_ground_content = false,
+ groups = { dig_immediate = 3 },
+ color = { b = 255, g = 0, r = math.floor((r/7)*255), a = 255 },
+ })
+end
+
+minetest.register_node("testnodes:climbable_move_resistance_4", {
+ description = S("Climbable Move-resistant Node (4)"),
+ walkable = false,
+ climbable = true,
+ move_resistance = 4,
+
+ drawtype = "glasslike",
+ paramtype = "light",
+ sunlight_propagates = true,
+ tiles = {"testnodes_climbable_resistance_side.png"},
+ is_ground_content = false,
+ groups = { dig_immediate = 3 },
+})
+
+-- By placing something on the node, the node itself will be replaced
+minetest.register_node("testnodes:buildable_to", {
+ description = S("Replacable Node"),
+ buildable_to = true,
+ tiles = {"testnodes_buildable_to.png"},
+ is_ground_content = false,
+ groups = {dig_immediate=3},
+})
+
+-- Nodes that deal damage to players that are inside them.
+-- Negative damage nodes should heal.
+for d=-3,3 do
+ if d ~= 0 then
+ local sub, tile
+ if d > 0 then
+ sub = tostring(d)
+ tile = "testnodes_damage.png"
+ else
+ sub = "m" .. tostring(math.abs(d))
+ tile = "testnodes_damage_neg.png"
+ end
+ if math.abs(d) == 2 then
+ tile = tile .. "^[colorize:#000000:70"
+ elseif math.abs(d) == 3 then
+ tile = tile .. "^[colorize:#000000:140"
+ end
+ minetest.register_node("testnodes:damage_"..sub, {
+ description = S("Damage Node (@1 damage per second)", d),
+ damage_per_second = d,
+
+
+ walkable = false,
+ is_ground_content = false,
+ drawtype = "allfaces",
+ paramtype = "light",
+ sunlight_propagates = true,
+ tiles = { tile },
+ groups = {dig_immediate=3},
+ })
+ end
+end
+
+-- Causes drowning damage
+minetest.register_node("testnodes:drowning_1", {
+ description = S("Drowning Node (@1 damage)", 1),
+ drowning = 1,
+
+
+ walkable = false,
+ is_ground_content = false,
+ drawtype = "allfaces",
+ paramtype = "light",
+ sunlight_propagates = true,
+ tiles = { "testnodes_drowning.png" },
+ groups = {dig_immediate=3},
+})
+
diff --git a/games/devtest/mods/testnodes/textures.lua b/games/devtest/mods/testnodes/textures.lua
new file mode 100644
index 000000000..2faacdd78
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures.lua
@@ -0,0 +1,290 @@
+-- Node texture tests
+
+local S = minetest.get_translator("testnodes")
+
+minetest.register_node("testnodes:6sides", {
+ description = S("Six Textures Test Node"),
+ tiles = {
+ "testnodes_normal1.png",
+ "testnodes_normal2.png",
+ "testnodes_normal3.png",
+ "testnodes_normal4.png",
+ "testnodes_normal5.png",
+ "testnodes_normal6.png",
+ },
+
+ groups = { dig_immediate = 2 },
+})
+
+minetest.register_node("testnodes:anim", {
+ description = S("Animated Test Node"),
+ tiles = {
+ { name = "testnodes_anim.png",
+ animation = {
+ type = "vertical_frames",
+ aspect_w = 16,
+ aspect_h = 16,
+ length = 4.0,
+ }, },
+ },
+
+ groups = { dig_immediate = 2 },
+})
+
+-- Node texture transparency test
+
+local alphas = { 64, 128, 191 }
+
+for a=1,#alphas do
+ local alpha = alphas[a]
+
+ -- Transparency taken from texture
+ minetest.register_node("testnodes:alpha_texture_"..alpha, {
+ description = S("Texture Alpha Test Node (@1)", alpha),
+ drawtype = "glasslike",
+ paramtype = "light",
+ tiles = {
+ "testnodes_alpha"..alpha..".png",
+ },
+ use_texture_alpha = "blend",
+
+ groups = { dig_immediate = 3 },
+ })
+
+ -- Transparency set via texture modifier
+ minetest.register_node("testnodes:alpha_"..alpha, {
+ description = S("Alpha Test Node (@1)", alpha),
+ drawtype = "glasslike",
+ paramtype = "light",
+ tiles = {
+ "testnodes_alpha.png^[opacity:" .. alpha,
+ },
+ use_texture_alpha = "blend",
+
+ groups = { dig_immediate = 3 },
+ })
+end
+
+-- Generate PNG textures
+
+local function mandelbrot(w, h, iterations)
+ local r = {}
+ for y=0, h-1 do
+ for x=0, w-1 do
+ local re = (x - w/2) * 4/w
+ local im = (y - h/2) * 4/h
+ -- zoom in on a nice view
+ re = re / 128 - 0.23
+ im = im / 128 - 0.82
+
+ local px, py = 0, 0
+ local i = 0
+ while px*px + py*py <= 4 and i < iterations do
+ px, py = px*px - py*py + re, 2 * px * py + im
+ i = i + 1
+ end
+ r[w*y+x+1] = i / iterations
+ end
+ end
+ return r
+end
+
+local function gen_checkers(w, h, tile)
+ local r = {}
+ for y=0, h-1 do
+ for x=0, w-1 do
+ local hori = math.floor(x / tile) % 2 == 0
+ local vert = math.floor(y / tile) % 2 == 0
+ r[w*y+x+1] = hori ~= vert and 1 or 0
+ end
+ end
+ return r
+end
+
+local fractal = mandelbrot(512, 512, 128)
+local frac_emb = mandelbrot(64, 64, 64)
+local checker = gen_checkers(512, 512, 32)
+
+local floor = math.floor
+local abs = math.abs
+local data_emb = {}
+local data_mb = {}
+local data_ck = {}
+for i=1, #frac_emb do
+ data_emb[i] = {
+ r = floor(abs(frac_emb[i] * 2 - 1) * 255),
+ g = floor(abs(1 - frac_emb[i]) * 255),
+ b = floor(frac_emb[i] * 255),
+ a = frac_emb[i] < 0.95 and 255 or 0,
+ }
+end
+for i=1, #fractal do
+ data_mb[i] = {
+ r = floor(fractal[i] * 255),
+ g = floor(abs(fractal[i] * 2 - 1) * 255),
+ b = floor(abs(1 - fractal[i]) * 255),
+ a = 255,
+ }
+ data_ck[i] = checker[i] > 0 and "#F80" or "#000"
+end
+
+local textures_path = minetest.get_modpath( minetest.get_current_modname() ) .. "/textures/"
+minetest.safe_file_write(
+ textures_path .. "testnodes_generated_mb.png",
+ minetest.encode_png(512,512,data_mb)
+)
+minetest.safe_file_write(
+ textures_path .. "testnodes_generated_ck.png",
+ minetest.encode_png(512,512,data_ck)
+)
+
+minetest.register_node("testnodes:generated_png_mb", {
+ description = S("Generated Mandelbrot PNG Test Node"),
+ tiles = { "testnodes_generated_mb.png" },
+
+ groups = { dig_immediate = 2 },
+})
+minetest.register_node("testnodes:generated_png_ck", {
+ description = S("Generated Checker PNG Test Node"),
+ tiles = { "testnodes_generated_ck.png" },
+
+ groups = { dig_immediate = 2 },
+})
+
+local png_emb = "[png:" .. minetest.encode_base64(minetest.encode_png(64,64,data_emb))
+
+minetest.register_node("testnodes:generated_png_emb", {
+ description = S("Generated In-Band Mandelbrot PNG Test Node"),
+ tiles = { png_emb },
+
+ groups = { dig_immediate = 2 },
+})
+minetest.register_node("testnodes:generated_png_src_emb", {
+ description = S("Generated In-Band Source Blit Mandelbrot PNG Test Node"),
+ tiles = { png_emb .. "^testnodes_damage_neg.png" },
+
+ groups = { dig_immediate = 2 },
+})
+minetest.register_node("testnodes:generated_png_dst_emb", {
+ description = S("Generated In-Band Dest Blit Mandelbrot PNG Test Node"),
+ tiles = { "testnodes_generated_ck.png^" .. png_emb },
+
+ groups = { dig_immediate = 2 },
+})
+
+--[[
+
+The following nodes can be used to demonstrate the TGA format support.
+
+Minetest supports TGA types 1, 2, 3 & 10. While adding the support for
+TGA type 9 (RLE-compressed, color-mapped) is easy, it is not advisable
+to do so, as it is not backwards compatible with any Minetest pre-5.5;
+content creators should therefore either use TGA type 1 or 10, or PNG.
+
+TODO: Types 1, 2 & 10 should have two test nodes each (i.e. bottom-top
+and top-bottom) for 16bpp (A1R5G5B5), 24bpp (B8G8R8), 32bpp (B8G8R8A8)
+colors.
+
+Note: Minetest requires the optional TGA footer for a texture to load.
+If a TGA image does not load in Minetest, append eight (8) null bytes,
+then the string “TRUEVISION-XFILE.”, then another null byte.
+
+]]--
+
+minetest.register_node("testnodes:tga_type1_24bpp_bt", {
+ description = S("TGA Type 1 (color-mapped RGB) 24bpp bottom-top Test Node"),
+ drawtype = "glasslike",
+ paramtype = "light",
+ sunlight_propagates = true,
+ tiles = { "testnodes_tga_type1_24bpp_bt.tga" },
+ groups = { dig_immediate = 2 },
+})
+
+minetest.register_node("testnodes:tga_type1_24bpp_tb", {
+ description = S("TGA Type 1 (color-mapped RGB) 24bpp top-bottom Test Node"),
+ drawtype = "glasslike",
+ paramtype = "light",
+ sunlight_propagates = true,
+ tiles = { "testnodes_tga_type1_24bpp_tb.tga" },
+ groups = { dig_immediate = 2 },
+})
+
+minetest.register_node("testnodes:tga_type2_16bpp_bt", {
+ description = S("TGA Type 2 (uncompressed RGB) 16bpp bottom-top Test Node"),
+ drawtype = "glasslike",
+ paramtype = "light",
+ sunlight_propagates = true,
+ tiles = { "testnodes_tga_type2_16bpp_bt.tga" },
+ use_texture_alpha = "clip",
+ groups = { dig_immediate = 2 },
+})
+
+minetest.register_node("testnodes:tga_type2_16bpp_tb", {
+ description = S("TGA Type 2 (uncompressed RGB) 16bpp top-bottom Test Node"),
+ drawtype = "glasslike",
+ paramtype = "light",
+ sunlight_propagates = true,
+ tiles = { "testnodes_tga_type2_16bpp_tb.tga" },
+ use_texture_alpha = "clip",
+ groups = { dig_immediate = 2 },
+})
+
+minetest.register_node("testnodes:tga_type2_32bpp_bt", {
+ description = S("TGA Type 2 (uncompressed RGB) 32bpp bottom-top Test Node"),
+ drawtype = "glasslike",
+ paramtype = "light",
+ sunlight_propagates = true,
+ tiles = { "testnodes_tga_type2_32bpp_bt.tga" },
+ use_texture_alpha = "blend",
+ groups = { dig_immediate = 2 },
+})
+
+minetest.register_node("testnodes:tga_type2_32bpp_tb", {
+ description = S("TGA Type 2 (uncompressed RGB) 32bpp top-bottom Test Node"),
+ drawtype = "glasslike",
+ paramtype = "light",
+ sunlight_propagates = true,
+ tiles = { "testnodes_tga_type2_32bpp_tb.tga" },
+ use_texture_alpha = "blend",
+ groups = { dig_immediate = 2 },
+})
+
+minetest.register_node("testnodes:tga_type3_16bpp_bt", {
+ description = S("TGA Type 3 (uncompressed grayscale) 16bpp bottom-top Test Node"),
+ drawtype = "glasslike",
+ paramtype = "light",
+ sunlight_propagates = true,
+ tiles = { "testnodes_tga_type3_16bpp_bt.tga" },
+ use_texture_alpha = "blend",
+ groups = { dig_immediate = 2 },
+})
+
+minetest.register_node("testnodes:tga_type3_16bpp_tb", {
+ description = S("TGA Type 3 (uncompressed grayscale) 16bpp top-bottom Test Node"),
+ drawtype = "glasslike",
+ paramtype = "light",
+ sunlight_propagates = true,
+ tiles = { "testnodes_tga_type3_16bpp_tb.tga" },
+ use_texture_alpha = "blend",
+ groups = { dig_immediate = 2 },
+})
+
+minetest.register_node("testnodes:tga_type10_32bpp_bt", {
+ description = S("TGA Type 10 (RLE-compressed RGB) 32bpp bottom-top Test Node"),
+ tiles = { "testnodes_tga_type10_32bpp_bt.tga" },
+ drawtype = "glasslike",
+ paramtype = "light",
+ sunlight_propagates = true,
+ use_texture_alpha = "blend",
+ groups = { dig_immediate = 2 },
+})
+
+minetest.register_node("testnodes:tga_type10_32bpp_tb", {
+ description = S("TGA Type 10 (RLE-compressed RGB) 32bpp top-bottom Test Node"),
+ drawtype = "glasslike",
+ paramtype = "light",
+ sunlight_propagates = true,
+ tiles = { "testnodes_tga_type10_32bpp_tb.tga" },
+ use_texture_alpha = "blend",
+ groups = { dig_immediate = 2 },
+})
diff --git a/games/devtest/mods/testnodes/textures/testnodes_1.png b/games/devtest/mods/testnodes/textures/testnodes_1.png
new file mode 100644
index 000000000..6730997e2
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_1.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_1g.png b/games/devtest/mods/testnodes/textures/testnodes_1g.png
new file mode 100644
index 000000000..529298ece
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_1g.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_1w.png b/games/devtest/mods/testnodes/textures/testnodes_1w.png
new file mode 100644
index 000000000..d24e571cc
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_1w.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_1wg.png b/games/devtest/mods/testnodes/textures/testnodes_1wg.png
new file mode 100644
index 000000000..b2eba0e9a
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_1wg.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_2.png b/games/devtest/mods/testnodes/textures/testnodes_2.png
new file mode 100644
index 000000000..6c87c868d
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_2.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_2g.png b/games/devtest/mods/testnodes/textures/testnodes_2g.png
new file mode 100644
index 000000000..cb9060f7b
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_2g.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_2w.png b/games/devtest/mods/testnodes/textures/testnodes_2w.png
new file mode 100644
index 000000000..b56874ee1
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_2w.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_2wg.png b/games/devtest/mods/testnodes/textures/testnodes_2wg.png
new file mode 100644
index 000000000..108dc87bb
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_2wg.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_3.png b/games/devtest/mods/testnodes/textures/testnodes_3.png
new file mode 100644
index 000000000..05b45629a
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_3.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_3g.png b/games/devtest/mods/testnodes/textures/testnodes_3g.png
new file mode 100644
index 000000000..5c84f5882
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_3g.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_3w.png b/games/devtest/mods/testnodes/textures/testnodes_3w.png
new file mode 100644
index 000000000..8b435cf01
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_3w.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_3wg.png b/games/devtest/mods/testnodes/textures/testnodes_3wg.png
new file mode 100644
index 000000000..9ee900667
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_3wg.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_4.png b/games/devtest/mods/testnodes/textures/testnodes_4.png
new file mode 100644
index 000000000..15e6ffec7
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_4.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_4g.png b/games/devtest/mods/testnodes/textures/testnodes_4g.png
new file mode 100644
index 000000000..8f144fae0
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_4g.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_4w.png b/games/devtest/mods/testnodes/textures/testnodes_4w.png
new file mode 100644
index 000000000..214e0df9d
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_4w.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_4wg.png b/games/devtest/mods/testnodes/textures/testnodes_4wg.png
new file mode 100644
index 000000000..888b3d482
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_4wg.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_5.png b/games/devtest/mods/testnodes/textures/testnodes_5.png
new file mode 100644
index 000000000..1ef1c728c
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_5.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_5g.png b/games/devtest/mods/testnodes/textures/testnodes_5g.png
new file mode 100644
index 000000000..30da4793a
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_5g.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_5w.png b/games/devtest/mods/testnodes/textures/testnodes_5w.png
new file mode 100644
index 000000000..b4cb42426
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_5w.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_5wg.png b/games/devtest/mods/testnodes/textures/testnodes_5wg.png
new file mode 100644
index 000000000..fac9db28e
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_5wg.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_6.png b/games/devtest/mods/testnodes/textures/testnodes_6.png
new file mode 100644
index 000000000..805813e57
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_6.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_6g.png b/games/devtest/mods/testnodes/textures/testnodes_6g.png
new file mode 100644
index 000000000..a88f4c9f8
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_6g.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_6w.png b/games/devtest/mods/testnodes/textures/testnodes_6w.png
new file mode 100644
index 000000000..e6bbf97d9
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_6w.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_6wg.png b/games/devtest/mods/testnodes/textures/testnodes_6wg.png
new file mode 100644
index 000000000..29ca933e0
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_6wg.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_airlike.png b/games/devtest/mods/testnodes/textures/testnodes_airlike.png
new file mode 100644
index 000000000..5a5664a2a
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_airlike.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_allfaces.png b/games/devtest/mods/testnodes/textures/testnodes_allfaces.png
new file mode 100644
index 000000000..c0a7dc550
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_allfaces.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_allfaces_optional.png b/games/devtest/mods/testnodes/textures/testnodes_allfaces_optional.png
new file mode 100644
index 000000000..1f6a17313
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_allfaces_optional.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_alpha.png b/games/devtest/mods/testnodes/textures/testnodes_alpha.png
new file mode 100644
index 000000000..157fa7386
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_alpha.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_alpha128.png b/games/devtest/mods/testnodes/textures/testnodes_alpha128.png
new file mode 100644
index 000000000..16babf6c7
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_alpha128.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_alpha191.png b/games/devtest/mods/testnodes/textures/testnodes_alpha191.png
new file mode 100644
index 000000000..f165d2887
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_alpha191.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_alpha64.png b/games/devtest/mods/testnodes/textures/testnodes_alpha64.png
new file mode 100644
index 000000000..c343c32c3
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_alpha64.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_anim.png b/games/devtest/mods/testnodes/textures/testnodes_anim.png
new file mode 100644
index 000000000..d321fe857
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_anim.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_attached_bottom.png b/games/devtest/mods/testnodes/textures/testnodes_attached_bottom.png
new file mode 100644
index 000000000..e01ae576f
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_attached_bottom.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_attached_side.png b/games/devtest/mods/testnodes/textures/testnodes_attached_side.png
new file mode 100644
index 000000000..9459cbb05
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_attached_side.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_attached_top.png b/games/devtest/mods/testnodes/textures/testnodes_attached_top.png
new file mode 100644
index 000000000..0148b41e0
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_attached_top.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_attachedw_bottom.png b/games/devtest/mods/testnodes/textures/testnodes_attachedw_bottom.png
new file mode 100644
index 000000000..488ad23a9
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_attachedw_bottom.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_attachedw_side.png b/games/devtest/mods/testnodes/textures/testnodes_attachedw_side.png
new file mode 100644
index 000000000..a02facbc7
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_attachedw_side.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_attachedw_top.png b/games/devtest/mods/testnodes/textures/testnodes_attachedw_top.png
new file mode 100644
index 000000000..1f4fc7b85
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_attachedw_top.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_bouncy.png b/games/devtest/mods/testnodes/textures/testnodes_bouncy.png
new file mode 100644
index 000000000..eabbbdfe4
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_bouncy.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_buildable_to.png b/games/devtest/mods/testnodes/textures/testnodes_buildable_to.png
new file mode 100644
index 000000000..23b5e54d2
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_buildable_to.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_climbable_nojump_side.png b/games/devtest/mods/testnodes/textures/testnodes_climbable_nojump_side.png
new file mode 100644
index 000000000..d5ca13033
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_climbable_nojump_side.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_climbable_resistance_side.png b/games/devtest/mods/testnodes/textures/testnodes_climbable_resistance_side.png
new file mode 100644
index 000000000..be01583e6
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_climbable_resistance_side.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_climbable_side.png b/games/devtest/mods/testnodes/textures/testnodes_climbable_side.png
new file mode 100644
index 000000000..c56ea90d7
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_climbable_side.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_damage.png b/games/devtest/mods/testnodes/textures/testnodes_damage.png
new file mode 100644
index 000000000..9de2ab5e8
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_damage.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_damage_neg.png b/games/devtest/mods/testnodes/textures/testnodes_damage_neg.png
new file mode 100644
index 000000000..85811bc8e
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_damage_neg.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_drowning.png b/games/devtest/mods/testnodes/textures/testnodes_drowning.png
new file mode 100644
index 000000000..57ffc8fcf
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_drowning.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_fall_damage_minus.png b/games/devtest/mods/testnodes/textures/testnodes_fall_damage_minus.png
new file mode 100644
index 000000000..88d3bdf58
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_fall_damage_minus.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_fall_damage_plus.png b/games/devtest/mods/testnodes/textures/testnodes_fall_damage_plus.png
new file mode 100644
index 000000000..61fdec2e3
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_fall_damage_plus.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_fencelike.png b/games/devtest/mods/testnodes/textures/testnodes_fencelike.png
new file mode 100644
index 000000000..84dea1b7c
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_fencelike.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_firelike.png b/games/devtest/mods/testnodes/textures/testnodes_firelike.png
new file mode 100644
index 000000000..ee59b0db1
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_firelike.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_glasslike.png b/games/devtest/mods/testnodes/textures/testnodes_glasslike.png
new file mode 100644
index 000000000..cf3e35414
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_glasslike.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_glasslike_detail.png b/games/devtest/mods/testnodes/textures/testnodes_glasslike_detail.png
new file mode 100644
index 000000000..30c9586e8
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_glasslike_detail.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_glasslike_framed.png b/games/devtest/mods/testnodes/textures/testnodes_glasslike_framed.png
new file mode 100644
index 000000000..8a513f21c
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_glasslike_framed.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_glasslike_framed2.png b/games/devtest/mods/testnodes/textures/testnodes_glasslike_framed2.png
new file mode 100644
index 000000000..4ea839c8b
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_glasslike_framed2.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_glasslike_framed_optional.png b/games/devtest/mods/testnodes/textures/testnodes_glasslike_framed_optional.png
new file mode 100644
index 000000000..37de77dd1
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_glasslike_framed_optional.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_glasslikeliquid.png b/games/devtest/mods/testnodes/textures/testnodes_glasslikeliquid.png
new file mode 100644
index 000000000..e1e96ffb9
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_glasslikeliquid.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_light.png b/games/devtest/mods/testnodes/textures/testnodes_light.png
new file mode 100644
index 000000000..4ba0081c3
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_light.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_1.png b/games/devtest/mods/testnodes/textures/testnodes_light_1.png
new file mode 100644
index 000000000..57adf5a4a
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_light_1.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_10.png b/games/devtest/mods/testnodes/textures/testnodes_light_10.png
new file mode 100644
index 000000000..483834770
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_light_10.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_11.png b/games/devtest/mods/testnodes/textures/testnodes_light_11.png
new file mode 100644
index 000000000..4c423d9b4
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_light_11.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_12.png b/games/devtest/mods/testnodes/textures/testnodes_light_12.png
new file mode 100644
index 000000000..bc7946d09
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_light_12.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_13.png b/games/devtest/mods/testnodes/textures/testnodes_light_13.png
new file mode 100644
index 000000000..0b63c84a6
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_light_13.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_14.png b/games/devtest/mods/testnodes/textures/testnodes_light_14.png
new file mode 100644
index 000000000..a817bd394
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_light_14.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_2.png b/games/devtest/mods/testnodes/textures/testnodes_light_2.png
new file mode 100644
index 000000000..852eaeff1
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_light_2.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_3.png b/games/devtest/mods/testnodes/textures/testnodes_light_3.png
new file mode 100644
index 000000000..79fc834cc
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_light_3.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_4.png b/games/devtest/mods/testnodes/textures/testnodes_light_4.png
new file mode 100644
index 000000000..75f8c6136
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_light_4.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_5.png b/games/devtest/mods/testnodes/textures/testnodes_light_5.png
new file mode 100644
index 000000000..b6eede0ae
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_light_5.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_6.png b/games/devtest/mods/testnodes/textures/testnodes_light_6.png
new file mode 100644
index 000000000..ef54addec
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_light_6.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_7.png b/games/devtest/mods/testnodes/textures/testnodes_light_7.png
new file mode 100644
index 000000000..4a885b0f6
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_light_7.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_8.png b/games/devtest/mods/testnodes/textures/testnodes_light_8.png
new file mode 100644
index 000000000..b283301e3
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_light_8.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_9.png b/games/devtest/mods/testnodes/textures/testnodes_light_9.png
new file mode 100644
index 000000000..2aa902358
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_light_9.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_line_crossing.png b/games/devtest/mods/testnodes/textures/testnodes_line_crossing.png
new file mode 100644
index 000000000..e566f2793
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_line_crossing.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_line_curved.png b/games/devtest/mods/testnodes/textures/testnodes_line_curved.png
new file mode 100644
index 000000000..ab9f8e720
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_line_curved.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_line_straight.png b/games/devtest/mods/testnodes/textures/testnodes_line_straight.png
new file mode 100644
index 000000000..4f33d9c6d
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_line_straight.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_line_t_junction.png b/games/devtest/mods/testnodes/textures/testnodes_line_t_junction.png
new file mode 100644
index 000000000..5668f6ea3
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_line_t_junction.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquid.png b/games/devtest/mods/testnodes/textures/testnodes_liquid.png
new file mode 100644
index 000000000..98ab270c2
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquid.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidflowing.png b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing.png
new file mode 100644
index 000000000..1736b89ba
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r0.png b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r0.png
new file mode 100644
index 000000000..e8a61039d
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r0.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r1.png b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r1.png
new file mode 100644
index 000000000..b4e45b42f
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r1.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r2.png b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r2.png
new file mode 100644
index 000000000..e064b8f2d
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r2.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r3.png b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r3.png
new file mode 100644
index 000000000..bef773968
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r3.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r4.png b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r4.png
new file mode 100644
index 000000000..de1001b2d
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r4.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r5.png b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r5.png
new file mode 100644
index 000000000..97b422e9a
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r5.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r6.png b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r6.png
new file mode 100644
index 000000000..4cd8e4e8e
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r6.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r7.png b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r7.png
new file mode 100644
index 000000000..711dd961c
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r7.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r8.png b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r8.png
new file mode 100644
index 000000000..9cf22b8ca
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r8.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidsource.png b/games/devtest/mods/testnodes/textures/testnodes_liquidsource.png
new file mode 100644
index 000000000..b3f29b702
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquidsource.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r0.png b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r0.png
new file mode 100644
index 000000000..da0a99623
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r0.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r1.png b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r1.png
new file mode 100644
index 000000000..66bf2be8f
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r1.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r2.png b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r2.png
new file mode 100644
index 000000000..fc5f65cb6
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r2.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r3.png b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r3.png
new file mode 100644
index 000000000..0f46e291e
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r3.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r4.png b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r4.png
new file mode 100644
index 000000000..0693a04d7
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r4.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r5.png b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r5.png
new file mode 100644
index 000000000..cc9d03992
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r5.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r6.png b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r6.png
new file mode 100644
index 000000000..e276a07ae
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r6.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r7.png b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r7.png
new file mode 100644
index 000000000..3534a4b15
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r7.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r8.png b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r8.png
new file mode 100644
index 000000000..ee1a8b169
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r8.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes.png b/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes.png
new file mode 100644
index 000000000..51b8e0025
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes2.png b/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes2.png
new file mode 100644
index 000000000..9ea65c1ec
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes2.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes3.png b/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes3.png
new file mode 100644
index 000000000..96bc55ac5
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes3.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes4.png b/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes4.png
new file mode 100644
index 000000000..fca33727d
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes4.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_move_resistance.png b/games/devtest/mods/testnodes/textures/testnodes_move_resistance.png
new file mode 100644
index 000000000..cac3944bf
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_move_resistance.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_node.png b/games/devtest/mods/testnodes/textures/testnodes_node.png
new file mode 100644
index 000000000..145099b3a
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_node.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_node_falling.png b/games/devtest/mods/testnodes/textures/testnodes_node_falling.png
new file mode 100644
index 000000000..44153185c
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_node_falling.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_nodebox.png b/games/devtest/mods/testnodes/textures/testnodes_nodebox.png
new file mode 100644
index 000000000..66e8dd663
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_nodebox.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_nojump_side.png b/games/devtest/mods/testnodes/textures/testnodes_nojump_side.png
new file mode 100644
index 000000000..6a64cfff0
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_nojump_side.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_nojump_top.png b/games/devtest/mods/testnodes/textures/testnodes_nojump_top.png
new file mode 100644
index 000000000..fe770838f
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_nojump_top.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_normal.png b/games/devtest/mods/testnodes/textures/testnodes_normal.png
new file mode 100644
index 000000000..a1acfd9fd
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_normal.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_normal1.png b/games/devtest/mods/testnodes/textures/testnodes_normal1.png
new file mode 100644
index 000000000..edaba77e4
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_normal1.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_normal2.png b/games/devtest/mods/testnodes/textures/testnodes_normal2.png
new file mode 100644
index 000000000..0080a9ee7
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_normal2.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_normal3.png b/games/devtest/mods/testnodes/textures/testnodes_normal3.png
new file mode 100644
index 000000000..0426ab216
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_normal3.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_normal4.png b/games/devtest/mods/testnodes/textures/testnodes_normal4.png
new file mode 100644
index 000000000..0d1922eb6
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_normal4.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_normal5.png b/games/devtest/mods/testnodes/textures/testnodes_normal5.png
new file mode 100644
index 000000000..0b7dcd2da
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_normal5.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_normal6.png b/games/devtest/mods/testnodes/textures/testnodes_normal6.png
new file mode 100644
index 000000000..f34a67d71
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_normal6.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_overlay.png b/games/devtest/mods/testnodes/textures/testnodes_overlay.png
new file mode 100644
index 000000000..1c69b5e08
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_overlay.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_overlayable.png b/games/devtest/mods/testnodes/textures/testnodes_overlayable.png
new file mode 100644
index 000000000..431bc94f4
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_overlayable.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_palette_facedir.png b/games/devtest/mods/testnodes/textures/testnodes_palette_facedir.png
new file mode 100644
index 000000000..8cf47bbbe
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_palette_facedir.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_palette_full.png b/games/devtest/mods/testnodes/textures/testnodes_palette_full.png
new file mode 100644
index 000000000..e0a5f8b34
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_palette_full.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_palette_wallmounted.png b/games/devtest/mods/testnodes/textures/testnodes_palette_wallmounted.png
new file mode 100644
index 000000000..682f3ac84
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_palette_wallmounted.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike.png
new file mode 100644
index 000000000..cc464444d
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_plantlike.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_degrotate.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_degrotate.png
new file mode 100644
index 000000000..01c81da8e
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_plantlike_degrotate.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_leveled.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_leveled.png
new file mode 100644
index 000000000..53504dbcd
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_plantlike_leveled.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_meshoptions.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_meshoptions.png
new file mode 100644
index 000000000..d504d459f
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_plantlike_meshoptions.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted.png
new file mode 100644
index 000000000..79cf2125e
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base.png
new file mode 100644
index 000000000..b9ee9e5be
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_degrotate.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_degrotate.png
new file mode 100644
index 000000000..85311cb2c
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_degrotate.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_leveled.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_leveled.png
new file mode 100644
index 000000000..bc602bafe
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_leveled.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_meshoptions.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_meshoptions.png
new file mode 100644
index 000000000..d10002375
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_meshoptions.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_wallmounted.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_wallmounted.png
new file mode 100644
index 000000000..b0be8d077
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_wallmounted.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_waving.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_waving.png
new file mode 100644
index 000000000..527817bc1
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_waving.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_degrotate.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_degrotate.png
new file mode 100644
index 000000000..45e75bdd3
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_degrotate.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_leveled.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_leveled.png
new file mode 100644
index 000000000..8954b2c34
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_leveled.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_meshoptions.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_meshoptions.png
new file mode 100644
index 000000000..a782d4874
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_meshoptions.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_wallmounted.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_wallmounted.png
new file mode 100644
index 000000000..421466407
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_wallmounted.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_waving.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_waving.png
new file mode 100644
index 000000000..112a0540f
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_waving.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_wallmounted.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_wallmounted.png
new file mode 100644
index 000000000..c89b29e30
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_plantlike_wallmounted.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_waving.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_waving.png
new file mode 100644
index 000000000..b584a8dc9
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_plantlike_waving.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_rail2_crossing.png b/games/devtest/mods/testnodes/textures/testnodes_rail2_crossing.png
new file mode 100644
index 000000000..530bbba7a
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_rail2_crossing.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_rail2_curved.png b/games/devtest/mods/testnodes/textures/testnodes_rail2_curved.png
new file mode 100644
index 000000000..4ed1ca00f
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_rail2_curved.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_rail2_straight.png b/games/devtest/mods/testnodes/textures/testnodes_rail2_straight.png
new file mode 100644
index 000000000..8749330d8
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_rail2_straight.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_rail2_t_junction.png b/games/devtest/mods/testnodes/textures/testnodes_rail2_t_junction.png
new file mode 100644
index 000000000..0517f6570
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_rail2_t_junction.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_rail_crossing.png b/games/devtest/mods/testnodes/textures/testnodes_rail_crossing.png
new file mode 100644
index 000000000..3916ce1ef
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_rail_crossing.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_rail_curved.png b/games/devtest/mods/testnodes/textures/testnodes_rail_curved.png
new file mode 100644
index 000000000..e44419848
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_rail_curved.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_rail_straight.png b/games/devtest/mods/testnodes/textures/testnodes_rail_straight.png
new file mode 100644
index 000000000..872d04fb9
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_rail_straight.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_rail_t_junction.png b/games/devtest/mods/testnodes/textures/testnodes_rail_t_junction.png
new file mode 100644
index 000000000..7e4af5182
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_rail_t_junction.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_signlike.png b/games/devtest/mods/testnodes/textures/testnodes_signlike.png
new file mode 100644
index 000000000..33ffcba6c
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_signlike.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_slippery.png b/games/devtest/mods/testnodes/textures/testnodes_slippery.png
new file mode 100644
index 000000000..b990468a1
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_slippery.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_street_crossing.png b/games/devtest/mods/testnodes/textures/testnodes_street_crossing.png
new file mode 100644
index 000000000..d6e35ad7a
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_street_crossing.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_street_curved.png b/games/devtest/mods/testnodes/textures/testnodes_street_curved.png
new file mode 100644
index 000000000..251b7fb71
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_street_curved.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_street_straight.png b/games/devtest/mods/testnodes/textures/testnodes_street_straight.png
new file mode 100644
index 000000000..639e24b93
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_street_straight.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_street_t_junction.png b/games/devtest/mods/testnodes/textures/testnodes_street_t_junction.png
new file mode 100644
index 000000000..713621e06
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_street_t_junction.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_sunlight_filter.png b/games/devtest/mods/testnodes/textures/testnodes_sunlight_filter.png
new file mode 100644
index 000000000..b38ea4072
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_sunlight_filter.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_bt.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_bt.tga
new file mode 100644
index 000000000..2dc587bc3
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_bt.tga
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_tb.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_tb.tga
new file mode 100644
index 000000000..b44a81c79
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_tb.tga
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_bt.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_bt.tga
new file mode 100644
index 000000000..d2c2ca6d2
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_bt.tga
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_tb.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_tb.tga
new file mode 100644
index 000000000..dfcb98864
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_tb.tga
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_bt.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_bt.tga
new file mode 100644
index 000000000..0206216bb
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_bt.tga
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_tb.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_tb.tga
new file mode 100644
index 000000000..2563f084b
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_tb.tga
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_bt.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_bt.tga
new file mode 100644
index 000000000..3350500f8
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_bt.tga
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_tb.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_tb.tga
new file mode 100644
index 000000000..216de0634
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_tb.tga
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_bt.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_bt.tga
new file mode 100644
index 000000000..695bb4bb1
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_bt.tga
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_tb.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_tb.tga
new file mode 100644
index 000000000..c08a093b2
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_tb.tga
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_torchlike_ceiling.png b/games/devtest/mods/testnodes/textures/testnodes_torchlike_ceiling.png
new file mode 100644
index 000000000..5d9862cc9
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_torchlike_ceiling.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_torchlike_floor.png b/games/devtest/mods/testnodes/textures/testnodes_torchlike_floor.png
new file mode 100644
index 000000000..adf1e002d
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_torchlike_floor.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_torchlike_wall.png b/games/devtest/mods/testnodes/textures/testnodes_torchlike_wall.png
new file mode 100644
index 000000000..cb442b22d
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_torchlike_wall.png
Binary files differ
diff --git a/games/devtest/mods/testpathfinder/README.md b/games/devtest/mods/testpathfinder/README.md
new file mode 100644
index 000000000..2b9d46e70
--- /dev/null
+++ b/games/devtest/mods/testpathfinder/README.md
@@ -0,0 +1,15 @@
+# Pathfinder Tester
+
+Usage:
+
+Use the Pathfinder Tester tool (`testpathfinder:testpathfinder`).
+Here's how it works:
+
+* Place on node: Set destination position
+* Punch: Find path
+* Sneak+punch: Select pathfinding algorithm
+
+Information will be shown in chat. If a path was found, all waypoints
+will be shown for a few seconds.
+
+See `init.lua` for config variables.
diff --git a/games/devtest/mods/testpathfinder/init.lua b/games/devtest/mods/testpathfinder/init.lua
new file mode 100644
index 000000000..67748afca
--- /dev/null
+++ b/games/devtest/mods/testpathfinder/init.lua
@@ -0,0 +1,136 @@
+local S = minetest.get_translator("testpathfinder")
+
+-- Config parameters
+
+-- Maximum direct distance between start and end
+local MAX_DIRECT_DISTANCE = 64
+-- Maximum search distance
+local MAX_SEARCH_DISTANCE = 32
+-- Maximum permitted jump height
+local MAX_JUMP = 1
+-- Maximum permitted drop height
+local MAX_DROP = 5
+-- If true, mod won't refuse to run pathfinder even at long distances
+local IGNORE_MAX_DISTANCE_SAFEGUARD = false
+
+-- End of config parameters
+
+local timer = 0
+local algorithms = {
+ "A*_noprefetch",
+ "A*",
+ "Dijkstra",
+}
+
+local function find_path_for_player(player, itemstack)
+ local meta = itemstack:get_meta()
+ if not meta then
+ return
+ end
+ local x = meta:get_int("pos_x")
+ local y = meta:get_int("pos_y")
+ local z = meta:get_int("pos_z")
+ local algo = meta:get_int("algorithm")
+ if x and y and z then
+ local pos2 = {x=x, y=y, z=z}
+ algo = algorithms[algo+1]
+ local pos1 = vector.round(player:get_pos())
+ -- Don't bother calling pathfinder for high distance to avoid freezing
+ if (not IGNORE_MAX_DISTANCE_SAFEGUARD) and (vector.distance(pos1, pos2) > MAX_DIRECT_DISTANCE) then
+ minetest.chat_send_player(player:get_player_name(), S("Destination too far away! Set a destination (via placing) within a distance of @1 and try again!", MAX_DIRECT_DISTANCE))
+ return
+ end
+ local str = S("Path from @1 to @2:",
+ minetest.pos_to_string(pos1),
+ minetest.pos_to_string(pos2))
+
+ minetest.chat_send_player(player:get_player_name(), str)
+ local time_start = minetest.get_us_time()
+ local path = minetest.find_path(pos1, pos2, MAX_SEARCH_DISTANCE, MAX_JUMP, MAX_DROP, algo)
+ local time_end = minetest.get_us_time()
+ local time_diff = time_end - time_start
+ str = ""
+ if not path then
+ minetest.chat_send_player(player:get_player_name(), S("No path!"))
+ minetest.chat_send_player(player:get_player_name(), S("Time: @1 ms", time_diff/1000))
+ return
+ end
+ for s=1, #path do
+ str = str .. minetest.pos_to_string(path[s]) .. "\n"
+ local t
+ if s == #path then
+ t = "testpathfinder_waypoint_end.png"
+ elseif s == 1 then
+ t = "testpathfinder_waypoint_start.png"
+ else
+ local c = math.floor(((#path-s)/#path)*255)
+ t = string.format("testpathfinder_waypoint.png^[multiply:#%02x%02x00", 0xFF-c, c)
+ end
+ minetest.add_particle({
+ pos = path[s],
+ expirationtime = 5 + 0.2 * s,
+ playername = player:get_player_name(),
+ glow = minetest.LIGHT_MAX,
+ texture = t,
+ size = 3,
+ })
+ end
+ minetest.chat_send_player(player:get_player_name(), str)
+ minetest.chat_send_player(player:get_player_name(), S("Path length: @1", #path))
+ minetest.chat_send_player(player:get_player_name(), S("Time: @1 ms", time_diff/1000))
+ end
+end
+
+local function set_destination(itemstack, user, pointed_thing)
+ if not (user and user:is_player()) then
+ return
+ end
+ local name = user:get_player_name()
+ local obj
+ local meta = itemstack:get_meta()
+ if pointed_thing.type == "node" then
+ local pos = pointed_thing.above
+ meta:set_int("pos_x", pos.x)
+ meta:set_int("pos_y", pos.y)
+ meta:set_int("pos_z", pos.z)
+ minetest.chat_send_player(user:get_player_name(), S("Destination set to @1", minetest.pos_to_string(pos)))
+ return itemstack
+ end
+end
+
+local function find_path_or_set_algorithm(itemstack, user, pointed_thing)
+ if not (user and user:is_player()) then
+ return
+ end
+ local ctrl = user:get_player_control()
+ -- No sneak: Find path
+ if not ctrl.sneak then
+ find_path_for_player(user, itemstack)
+ else
+ -- Sneak: Set algorithm
+ local meta = itemstack:get_meta()
+ local algo = meta:get_int("algorithm")
+ algo = (algo + 1) % #algorithms
+ meta:set_int("algorithm", algo)
+ minetest.chat_send_player(user:get_player_name(), S("Algorithm: @1", algorithms[algo+1]))
+ return itemstack
+ end
+end
+
+-- Punch: Find path
+-- Sneak+punch: Select pathfinding algorithm
+-- Place: Select destination node
+minetest.register_tool("testpathfinder:testpathfinder", {
+ description = S("Pathfinder Tester") .."\n"..
+ S("Finds path between 2 points") .."\n"..
+ S("Place on node: Select destination") .."\n"..
+ S("Punch: Find path from here") .."\n"..
+ S("Sneak+Punch: Change algorithm"),
+ inventory_image = "testpathfinder_testpathfinder.png",
+ groups = { testtool = 1, disable_repair = 1 },
+ on_use = find_path_or_set_algorithm,
+ on_secondary_use = set_destination,
+ on_place = set_destination,
+})
+
+
diff --git a/games/devtest/mods/testpathfinder/mod.conf b/games/devtest/mods/testpathfinder/mod.conf
new file mode 100644
index 000000000..e6034ae8c
--- /dev/null
+++ b/games/devtest/mods/testpathfinder/mod.conf
@@ -0,0 +1,2 @@
+name = testpathfinder
+description = Tool to test Minetest's pathfinder function
diff --git a/games/devtest/mods/testpathfinder/textures/testpathfinder_testpathfinder.png b/games/devtest/mods/testpathfinder/textures/testpathfinder_testpathfinder.png
new file mode 100644
index 000000000..37eef0565
--- /dev/null
+++ b/games/devtest/mods/testpathfinder/textures/testpathfinder_testpathfinder.png
Binary files differ
diff --git a/games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint.png b/games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint.png
new file mode 100644
index 000000000..661dcf906
--- /dev/null
+++ b/games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint.png
Binary files differ
diff --git a/games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint_end.png b/games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint_end.png
new file mode 100644
index 000000000..41a1cc549
--- /dev/null
+++ b/games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint_end.png
Binary files differ
diff --git a/games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint_start.png b/games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint_start.png
new file mode 100644
index 000000000..a22e31c3b
--- /dev/null
+++ b/games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint_start.png
Binary files differ
diff --git a/games/devtest/mods/testtools/README.md b/games/devtest/mods/testtools/README.md
new file mode 100644
index 000000000..72f0a2db0
--- /dev/null
+++ b/games/devtest/mods/testtools/README.md
@@ -0,0 +1,128 @@
+# Test Tools readme
+
+Test Tools is a mod for developers that adds a bunch of tools to directly manipulate nodes and entities. This is great for quickly testing out stuff.
+
+Here's the list of tools:
+
+## Remover
+Removes nodes and non-player entities that you punch.
+
+## Node Setter
+Replace a node with another one.
+
+First, punch a node you want to remember.
+Then rightclick any other node to replace it with the node you remembered.
+
+If you rightclick while pointing nothing, you can manually enter the node and param2.
+
+## Param2 Tool
+Change the value param2 of nodes.
+
+* Punch: Add 1 to param2
+* Sneak+Punch: Add 8 to param2
+* Place: Subtract 1 from param2
+* Sneak+Place: Subtract 8 from param2
+
+Note: Use the debug screen (F5) to see the param2 of the pointed node.
+
+## Falling Node Tool
+Turns nodes into falling nodes.
+
+Usage:
+
+* Punch node: Make it fall
+* Place: Try to teleport up to 2 units upwards, then make it fall
+
+## Node Meta Editor
+Edit and view metadata of nodes.
+
+Usage:
+
+* Punch: Open node metadata editor
+
+## Item Meta Editor
+Edit and view metadata of items.
+
+Usage:
+
+* Place/Punch: Opens item metadata editor of the item in the next
+ inventory slot from the wielded item
+
+## Entity Rotator
+Changes the entity rotation (with `set_rotation`).
+
+Usage:
+
+* Punch entity: Rotate yaw
+* Punch entity while holding down “Sneak” key: Rotate pitch
+* Punch entity while holding down “Special” key (aka “Aux”): Rotate roll
+
+Each usage rotates the entity by 22.5°.
+
+## Entity Spawner
+Spawns entities.
+
+Usage:
+
+* Punch to select entity or spawn one directly
+* Place to place selected entity
+
+## Object Property Editor
+Edits properties of objects.
+
+Usage:
+
+* Punch object to open a formspec that allows you to view and edit properties
+* Punch air to edit properties of your own player object
+
+To edit a property, select it in the list, enter a new value (in Lua syntax)
+and hit “Submit”.
+
+## Object Attacher
+Allows you to attach an object to another one.
+
+Basic usage:
+* First select the parent object, then the child object that should be attached
+* Selecting an object is done by punching it
+* Sneak+punch to detach selected object
+* If you punch air, you select yourself
+
+Configuration:
+* Place: Increase attachment Y position
+* Sneak+place: decrease attachment Y position
+* Aux+place: Increase attachment X rotation
+* Aux+Sneak+Rightclick: Decrease attachment X rotation
+
+Hint: To detach all objects nearby you (including on yourself), use the
+`/detach` server command.
+
+## Object Mover
+Move an object by a given distance.
+
+Usage:
+* Punch object into the direction you want to move it
+* Sneak+punch: Move object towards you
+* Place: Increase move distance
+* Sneak+place: Decrease move distance
+
+## Children Getter
+Shows list of objects that are attached to an object (aka "children") in chat.
+
+Usage:
+* Punch object: Show children of punched object
+* Punch air: Show your own children
+
+## Entity Visual Scaler
+Change visual size of entities
+
+Usage:
+
+* Punch entity to increase visual size
+* Sneak+punch entity to decrease visual size
+
+## Light Tool
+Show light level of node.
+
+Usage:
+* Punch: Show light info of node in front of the punched node's side
+* Place: Show light info of the node that you touched
diff --git a/games/devtest/mods/testtools/init.lua b/games/devtest/mods/testtools/init.lua
new file mode 100644
index 000000000..abc1ed79b
--- /dev/null
+++ b/games/devtest/mods/testtools/init.lua
@@ -0,0 +1,951 @@
+local S = minetest.get_translator("testtools")
+local F = minetest.formspec_escape
+
+dofile(minetest.get_modpath("testtools") .. "/light.lua")
+
+minetest.register_tool("testtools:param2tool", {
+ description = S("Param2 Tool") .."\n"..
+ S("Modify param2 value of nodes") .."\n"..
+ S("Punch: +1") .."\n"..
+ S("Sneak+Punch: +8") .."\n"..
+ S("Place: -1") .."\n"..
+ S("Sneak+Place: -8"),
+ inventory_image = "testtools_param2tool.png",
+ groups = { testtool = 1, disable_repair = 1 },
+ on_use = function(itemstack, user, pointed_thing)
+ local pos = minetest.get_pointed_thing_position(pointed_thing)
+ if pointed_thing.type ~= "node" or (not pos) then
+ return
+ end
+ local add = 1
+ if user then
+ local ctrl = user:get_player_control()
+ if ctrl.sneak then
+ add = 8
+ end
+ end
+ local node = minetest.get_node(pos)
+ node.param2 = node.param2 + add
+ minetest.swap_node(pos, node)
+ end,
+ on_place = function(itemstack, user, pointed_thing)
+ local pos = minetest.get_pointed_thing_position(pointed_thing)
+ if pointed_thing.type ~= "node" or (not pos) then
+ return
+ end
+ local add = -1
+ if user then
+ local ctrl = user:get_player_control()
+ if ctrl.sneak then
+ add = -8
+ end
+ end
+ local node = minetest.get_node(pos)
+ node.param2 = node.param2 + add
+ minetest.swap_node(pos, node)
+ end,
+})
+
+minetest.register_tool("testtools:node_setter", {
+ description = S("Node Setter") .."\n"..
+ S("Replace pointed node with something else") .."\n"..
+ S("Punch: Select pointed node") .."\n"..
+ S("Place on node: Replace node with selected node") .."\n"..
+ S("Place in air: Manually select a node"),
+ inventory_image = "testtools_node_setter.png",
+ groups = { testtool = 1, disable_repair = 1 },
+ on_use = function(itemstack, user, pointed_thing)
+ local pos = minetest.get_pointed_thing_position(pointed_thing)
+ if pointed_thing.type == "nothing" then
+ local meta = itemstack:get_meta()
+ meta:set_string("node", "air")
+ meta:set_int("node_param2", 0)
+ if user and user:is_player() then
+ minetest.chat_send_player(user:get_player_name(), S("Now placing: @1 (param2=@2)", "air", 0))
+ end
+ return itemstack
+ elseif pointed_thing.type ~= "node" or (not pos) then
+ return
+ end
+ local node = minetest.get_node(pos)
+ local meta = itemstack:get_meta()
+ meta:set_string("node", node.name)
+ meta:set_int("node_param2", node.param2)
+ if user and user:is_player() then
+ minetest.chat_send_player(user:get_player_name(), S("Now placing: @1 (param2=@2)", node.name, node.param2))
+ end
+ return itemstack
+ end,
+ on_secondary_use = function(itemstack, user, pointed_thing)
+ local meta = itemstack:get_meta()
+ local nodename = meta:get_string("node") or ""
+ local param2 = meta:get_int("node_param2") or 0
+
+ minetest.show_formspec(user:get_player_name(), "testtools:node_setter",
+ "size[4,4]"..
+ "field[0.5,1;3,1;nodename;"..F(S("Node name (itemstring):"))..";"..F(nodename).."]"..
+ "field[0.5,2;3,1;param2;"..F(S("param2:"))..";"..F(tostring(param2)).."]"..
+ "button_exit[0.5,3;3,1;submit;"..F(S("Submit")).."]"
+ )
+ end,
+ on_place = function(itemstack, user, pointed_thing)
+ local pos = minetest.get_pointed_thing_position(pointed_thing)
+ local meta = itemstack:get_meta()
+ local nodename = meta:get_string("node")
+ if nodename == "" and user and user:is_player() then
+ minetest.chat_send_player(user:get_player_name(), S("Punch a node first!"))
+ return
+ end
+ local param2 = meta:get_int("node_param2")
+ if not param2 then
+ param2 = 0
+ end
+ local node = { name = nodename, param2 = param2 }
+ if not minetest.registered_nodes[nodename] then
+ minetest.chat_send_player(user:get_player_name(), S("Cannot set unknown node: @1", nodename))
+ return
+ end
+ minetest.set_node(pos, node)
+ end,
+})
+
+minetest.register_tool("testtools:remover", {
+ description = S("Remover") .."\n"..
+ S("Punch: Remove pointed node or object"),
+ inventory_image = "testtools_remover.png",
+ groups = { testtool = 1, disable_repair = 1 },
+ on_use = function(itemstack, user, pointed_thing)
+ local pos = minetest.get_pointed_thing_position(pointed_thing)
+ if pointed_thing.type == "node" and pos ~= nil then
+ minetest.remove_node(pos)
+ elseif pointed_thing.type == "object" then
+ local obj = pointed_thing.ref
+ if not obj:is_player() then
+ obj:remove()
+ else
+ minetest.chat_send_player(user:get_player_name(), S("Can't remove players!"))
+ end
+ end
+ end,
+})
+
+minetest.register_tool("testtools:falling_node_tool", {
+ description = S("Falling Node Tool") .."\n"..
+ S("Punch: Make pointed node fall") .."\n"..
+ S("Place: Move pointed node 2 units upwards, then make it fall"),
+ inventory_image = "testtools_falling_node_tool.png",
+ groups = { testtool = 1, disable_repair = 1 },
+ on_place = function(itemstack, user, pointed_thing)
+ -- Teleport node 1-2 units upwards (if possible) and make it fall
+ local pos = minetest.get_pointed_thing_position(pointed_thing)
+ if pointed_thing.type ~= "node" or (not pos) then
+ return
+ end
+ local ok = false
+ local highest
+ for i=1,2 do
+ local above = {x=pos.x,y=pos.y+i,z=pos.z}
+ local n2 = minetest.get_node(above)
+ local def2 = minetest.registered_nodes[n2.name]
+ if def2 and (not def2.walkable) then
+ highest = above
+ else
+ break
+ end
+ end
+ if highest then
+ local node = minetest.get_node(pos)
+ local metatable = minetest.get_meta(pos):to_table()
+ minetest.remove_node(pos)
+ minetest.set_node(highest, node)
+ local meta_highest = minetest.get_meta(highest)
+ meta_highest:from_table(metatable)
+ ok = minetest.spawn_falling_node(highest)
+ else
+ ok = minetest.spawn_falling_node(pos)
+ end
+ if not ok and user and user:is_player() then
+ minetest.chat_send_player(user:get_player_name(), S("Falling node could not be spawned!"))
+ end
+ end,
+ on_use = function(itemstack, user, pointed_thing)
+ local pos = minetest.get_pointed_thing_position(pointed_thing)
+ if pointed_thing.type ~= "node" or (not pos) then
+ return
+ end
+ local ok = minetest.spawn_falling_node(pos)
+ if not ok and user and user:is_player() then
+ minetest.chat_send_player(user:get_player_name(), S("Falling node could not be spawned!"))
+ end
+ end,
+})
+
+minetest.register_tool("testtools:rotator", {
+ description = S("Entity Rotator") .. "\n" ..
+ S("Rotate pointed entity") .."\n"..
+ S("Punch: Yaw") .."\n"..
+ S("Sneak+Punch: Pitch") .."\n"..
+ S("Aux1+Punch: Roll"),
+ inventory_image = "testtools_entity_rotator.png",
+ groups = { testtool = 1, disable_repair = 1 },
+ on_use = function(itemstack, user, pointed_thing)
+ if pointed_thing.type ~= "object" then
+ return
+ end
+ local obj = pointed_thing.ref
+ if obj:is_player() then
+ -- No player rotation
+ return
+ else
+ local axis = "y"
+ if user and user:is_player() then
+ local ctrl = user:get_player_control()
+ if ctrl.sneak then
+ axis = "x"
+ elseif ctrl.aux1 then
+ axis = "z"
+ end
+ end
+ local rot = obj:get_rotation()
+ rot[axis] = rot[axis] + math.pi/8
+ if rot[axis] > math.pi*2 then
+ rot[axis] = rot[axis] - math.pi*2
+ end
+ obj:set_rotation(rot)
+ end
+ end,
+})
+
+local mover_config = function(itemstack, user, pointed_thing)
+ if not (user and user:is_player()) then
+ return
+ end
+ local name = user:get_player_name()
+ local ctrl = user:get_player_control()
+ local meta = itemstack:get_meta()
+ local dist = 1.0
+ if meta:contains("distance") then
+ dist = meta:get_int("distance")
+ end
+ if ctrl.sneak then
+ dist = dist - 1
+ else
+ dist = dist + 1
+ end
+ meta:set_int("distance", dist)
+ minetest.chat_send_player(user:get_player_name(), S("distance=@1/10", dist*2))
+ return itemstack
+end
+
+minetest.register_tool("testtools:object_mover", {
+ description = S("Object Mover") .."\n"..
+ S("Move pointed object towards or away from you") .."\n"..
+ S("Punch: Move by distance").."\n"..
+ S("Sneak+Punch: Move by negative distance").."\n"..
+ S("Place: Increase distance").."\n"..
+ S("Sneak+Place: Decrease distance"),
+ inventory_image = "testtools_object_mover.png",
+ groups = { testtool = 1, disable_repair = 1 },
+ on_place = mover_config,
+ on_secondary_use = mover_config,
+ on_use = function(itemstack, user, pointed_thing)
+ if pointed_thing.type ~= "object" then
+ return
+ end
+ local obj = pointed_thing.ref
+ if not (user and user:is_player()) then
+ return
+ end
+ local yaw = user:get_look_horizontal()
+ local dir = minetest.yaw_to_dir(yaw)
+ local pos = obj:get_pos()
+ local pitch = user:get_look_vertical()
+ if pitch > 0.25 * math.pi then
+ dir.y = -1
+ dir.x = 0
+ dir.z = 0
+ elseif pitch < -0.25 * math.pi then
+ dir.y = 1
+ dir.x = 0
+ dir.z = 0
+ end
+ local ctrl = user:get_player_control()
+ if ctrl.sneak then
+ dir = vector.multiply(dir, -1)
+ end
+ local meta = itemstack:get_meta()
+ if meta:contains("distance") then
+ local dist = meta:get_int("distance")
+ dir = vector.multiply(dir, dist*0.2)
+ end
+ pos = vector.add(pos, dir)
+ obj:set_pos(pos)
+ end,
+})
+
+
+
+minetest.register_tool("testtools:entity_scaler", {
+ description = S("Entity Visual Scaler") .."\n"..
+ S("Scale visual size of entities") .."\n"..
+ S("Punch: Increase size") .."\n"..
+ S("Sneak+Punch: Decrease scale"),
+ inventory_image = "testtools_entity_scaler.png",
+ groups = { testtool = 1, disable_repair = 1 },
+ on_use = function(itemstack, user, pointed_thing)
+ if pointed_thing.type ~= "object" then
+ return
+ end
+ local obj = pointed_thing.ref
+ if obj:is_player() then
+ -- No player scaling
+ return
+ else
+ local diff = 0.1
+ if user and user:is_player() then
+ local ctrl = user:get_player_control()
+ if ctrl.sneak then
+ diff = -0.1
+ end
+ end
+ local prop = obj:get_properties()
+ if not prop.visual_size then
+ prop.visual_size = { x=1, y=1, z=1 }
+ else
+ prop.visual_size = { x=prop.visual_size.x+diff, y=prop.visual_size.y+diff, z=prop.visual_size.z+diff }
+ if prop.visual_size.x <= 0.1 then
+ prop.visual_size.x = 0.1
+ end
+ if prop.visual_size.y <= 0.1 then
+ prop.visual_size.y = 0.1
+ end
+ if prop.visual_size.z <= 0.1 then
+ prop.visual_size.z = 0.1
+ end
+ end
+ obj:set_properties(prop)
+ end
+ end,
+})
+
+local selections = {}
+local entity_list
+local function get_entity_list()
+ if entity_list then
+ return entity_list
+ end
+ local ents = minetest.registered_entities
+ local list = {}
+ for k,_ in pairs(ents) do
+ table.insert(list, k)
+ end
+ table.sort(list)
+ entity_list = list
+ return entity_list
+end
+minetest.register_tool("testtools:entity_spawner", {
+ description = S("Entity Spawner") .."\n"..
+ S("Spawns entities") .."\n"..
+ S("Punch: Select entity to spawn") .."\n"..
+ S("Place: Spawn selected entity"),
+ inventory_image = "testtools_entity_spawner.png",
+ groups = { testtool = 1, disable_repair = 1 },
+ on_place = function(itemstack, user, pointed_thing)
+ local name = user:get_player_name()
+ if pointed_thing.type == "node" then
+ if selections[name] then
+ local pos = pointed_thing.above
+ minetest.add_entity(pos, get_entity_list()[selections[name]])
+ else
+ minetest.chat_send_player(name, S("Select an entity first (with punch key)!"))
+ end
+ end
+ end,
+ on_use = function(itemstack, user, pointed_thing)
+ if pointed_thing.type == "object" then
+ return
+ end
+ if user and user:is_player() then
+ local list = table.concat(get_entity_list(), ",")
+ local name = user:get_player_name()
+ local sel = selections[name] or ""
+ minetest.show_formspec(name, "testtools:entity_list",
+ "size[9,9]"..
+ "textlist[0,0;9,8;entity_list;"..list..";"..sel..";false]"..
+ "button[0,8;4,1;spawn;Spawn entity]"
+ )
+ end
+ end,
+})
+
+local function prop_to_string(property)
+ if type(property) == "string" then
+ return "\"" .. property .. "\""
+ elseif type(property) == "table" then
+ return tostring(dump(property)):gsub("\n", "")
+ else
+ return tostring(property)
+ end
+end
+
+local property_formspec_data = {}
+local property_formspec_index = {}
+local selected_objects = {}
+local function get_object_properties_form(obj, playername)
+ if not playername then return "" end
+ local props = obj:get_properties()
+ local str = ""
+ property_formspec_data[playername] = {}
+ local proplist = {}
+ for k,_ in pairs(props) do
+ table.insert(proplist, k)
+ end
+ table.sort(proplist)
+ for p=1, #proplist do
+ local k = proplist[p]
+ local v = props[k]
+ local newline = ""
+ newline = k .. " = "
+ newline = newline .. prop_to_string(v)
+ str = str .. F(newline)
+ if p < #proplist then
+ str = str .. ","
+ end
+ table.insert(property_formspec_data[playername], k)
+ end
+ return str
+end
+
+local editor_formspec_selindex = {}
+
+local editor_formspec = function(playername, obj, value, sel)
+ if not value then
+ value = ""
+ end
+ if not sel then
+ sel = ""
+ end
+ local list = get_object_properties_form(obj, playername)
+ local title
+ if obj:is_player() then
+ title = S("Object properties of player “@1”", obj:get_player_name())
+ else
+ local ent = obj:get_luaentity()
+ title = S("Object properties of @1", ent.name)
+ end
+ minetest.show_formspec(playername, "testtools:object_editor",
+ "size[9,9]"..
+ "label[0,0;"..F(title).."]"..
+ "textlist[0,0.5;9,7.5;object_props;"..list..";"..sel..";false]"..
+ "field[0.2,8.75;8,1;value;"..F(S("Value"))..";"..F(value).."]"..
+ "field_close_on_enter[value;false]"..
+ "button[8,8.5;1,1;submit;"..F(S("Submit")).."]"
+ )
+end
+
+minetest.register_tool("testtools:object_editor", {
+ description = S("Object Property Editor") .."\n"..
+ S("Edit properties of objects") .."\n"..
+ S("Punch object: Edit object") .."\n"..
+ S("Punch air: Edit yourself"),
+ inventory_image = "testtools_object_editor.png",
+ groups = { testtool = 1, disable_repair = 1 },
+ on_use = function(itemstack, user, pointed_thing)
+ if user and user:is_player() then
+ local name = user:get_player_name()
+
+ if pointed_thing.type == "object" then
+ selected_objects[name] = pointed_thing.ref
+ elseif pointed_thing.type == "nothing" then
+ -- Use on yourself if pointing nothing
+ selected_objects[name] = user
+ else
+ -- Unsupported pointed thing
+ return
+ end
+
+ local sel = editor_formspec_selindex[name]
+ local val
+ if selected_objects[name] and selected_objects[name]:get_properties() then
+ local props = selected_objects[name]:get_properties()
+ local keys = property_formspec_data[name]
+ if property_formspec_index[name] and props then
+ local key = keys[property_formspec_index[name]]
+ val = prop_to_string(props[key])
+ end
+ end
+
+ editor_formspec(name, selected_objects[name], val, sel)
+ end
+ end,
+})
+
+local ent_parent = {}
+local ent_child = {}
+local DEFAULT_ATTACH_OFFSET_Y = 11
+
+local attacher_config = function(itemstack, user, pointed_thing)
+ if not (user and user:is_player()) then
+ return
+ end
+ if pointed_thing.type == "object" then
+ return
+ end
+ local name = user:get_player_name()
+ local ctrl = user:get_player_control()
+ local meta = itemstack:get_meta()
+ if ctrl.aux1 then
+ local rot_x = meta:get_float("rot_x")
+ if ctrl.sneak then
+ rot_x = rot_x - math.pi/8
+ else
+ rot_x = rot_x + math.pi/8
+ end
+ if rot_x > 6.2 then
+ rot_x = 0
+ elseif rot_x < 0 then
+ rot_x = math.pi * (15/8)
+ end
+ minetest.chat_send_player(name, S("rotation=@1", minetest.pos_to_string({x=rot_x,y=0,z=0})))
+ meta:set_float("rot_x", rot_x)
+ else
+ local pos_y
+ if meta:contains("pos_y") then
+ pos_y = meta:get_int("pos_y")
+ else
+ pos_y = DEFAULT_ATTACH_OFFSET_Y
+ end
+ if ctrl.sneak then
+ pos_y = pos_y - 1
+ else
+ pos_y = pos_y + 1
+ end
+ minetest.chat_send_player(name, S("position=@1", minetest.pos_to_string({x=0,y=pos_y,z=0})))
+ meta:set_int("pos_y", pos_y)
+ end
+ return itemstack
+end
+
+minetest.register_tool("testtools:object_attacher", {
+ description = S("Object Attacher") .."\n"..
+ S("Attach object to another") .."\n"..
+ S("Punch objects to first select parent object, then the child object to attach") .."\n"..
+ S("Punch air to select yourself") .."\n"..
+ S("Place: Incease attachment Y offset") .."\n"..
+ S("Sneak+Place: Decease attachment Y offset") .."\n"..
+ S("Aux1+Place: Incease attachment rotation") .."\n"..
+ S("Aux1+Sneak+Place: Decrease attachment rotation"),
+ inventory_image = "testtools_object_attacher.png",
+ groups = { testtool = 1, disable_repair = 1 },
+ on_place = attacher_config,
+ on_secondary_use = attacher_config,
+ on_use = function(itemstack, user, pointed_thing)
+ if user and user:is_player() then
+ local name = user:get_player_name()
+ local selected_object
+ if pointed_thing.type == "object" then
+ selected_object = pointed_thing.ref
+ elseif pointed_thing.type == "nothing" then
+ selected_object = user
+ else
+ return
+ end
+ local ctrl = user:get_player_control()
+ if ctrl.sneak then
+ if selected_object:get_attach() then
+ selected_object:set_detach()
+ minetest.chat_send_player(name, S("Object detached!"))
+ else
+ minetest.chat_send_player(name, S("Object is not attached!"))
+ end
+ return
+ end
+ local parent = ent_parent[name]
+ local child = ent_child[name]
+ local ename = S("<unknown>")
+ if not parent then
+ parent = selected_object
+ ent_parent[name] = parent
+ elseif not child then
+ child = selected_object
+ ent_child[name] = child
+ end
+ local entity = selected_object:get_luaentity()
+ if entity then
+ ename = entity.name
+ elseif selected_object:is_player() then
+ ename = selected_object:get_player_name()
+ end
+ if selected_object == parent then
+ minetest.chat_send_player(name, S("Parent object selected: @1", ename))
+ elseif selected_object == child then
+ minetest.chat_send_player(name, S("Child object selected: @1", ename))
+ end
+ if parent and child then
+ if parent == child then
+ minetest.chat_send_player(name, S("Can't attach an object to itself!"))
+ ent_parent[name] = nil
+ ent_child[name] = nil
+ return
+ end
+ local meta = itemstack:get_meta()
+ local y
+ if meta:contains("pos_y") then
+ y = meta:get_int("pos_y")
+ else
+ y = DEFAULT_ATTACH_OFFSET_Y
+ end
+ local rx = meta:get_float("rot_x") or 0
+ local offset = {x=0,y=y,z=0}
+ local angle = {x=rx,y=0,z=0}
+ child:set_attach(parent, "", offset, angle)
+ local check_parent = child:get_attach()
+ if check_parent then
+ minetest.chat_send_player(name, S("Object attached! position=@1, rotation=@2",
+ minetest.pos_to_string(offset), minetest.pos_to_string(angle)))
+ else
+ minetest.chat_send_player(name, S("Attachment failed!"))
+ end
+ ent_parent[name] = nil
+ ent_child[name] = nil
+ end
+ end
+ end,
+})
+
+local function print_object(obj)
+ if obj:is_player() then
+ return "player '"..obj:get_player_name().."'"
+ elseif obj:get_luaentity() then
+ return "LuaEntity '"..obj:get_luaentity().name.."'"
+ else
+ return "object"
+ end
+end
+
+minetest.register_tool("testtools:children_getter", {
+ description = S("Children Getter") .."\n"..
+ S("Shows list of objects attached to object") .."\n"..
+ S("Punch object to show its 'children'") .."\n"..
+ S("Punch air to show your own 'children'"),
+ inventory_image = "testtools_children_getter.png",
+ groups = { testtool = 1, disable_repair = 1 },
+ on_use = function(itemstack, user, pointed_thing)
+ if user and user:is_player() then
+ local name = user:get_player_name()
+ local selected_object
+ local self_name
+ if pointed_thing.type == "object" then
+ selected_object = pointed_thing.ref
+ elseif pointed_thing.type == "nothing" then
+ selected_object = user
+ else
+ return
+ end
+ self_name = print_object(selected_object)
+ local children = selected_object:get_children()
+ local ret = ""
+ for c=1, #children do
+ ret = ret .. "* " .. print_object(children[c])
+ if c < #children then
+ ret = ret .. "\n"
+ end
+ end
+ if ret == "" then
+ ret = S("No children attached to @1.", self_name)
+ else
+ ret = S("Children of @1:", self_name) .. "\n" .. ret
+ end
+ minetest.chat_send_player(user:get_player_name(), ret)
+ end
+ end,
+})
+
+-- Use loadstring to parse param as a Lua value
+local function use_loadstring(param, player)
+ -- For security reasons, require 'server' priv, just in case
+ -- someone is actually crazy enough to run this on a public server.
+ local privs = minetest.get_player_privs(player:get_player_name())
+ if not privs.server then
+ return false, "You need 'server' privilege to change object properties!"
+ end
+ if not param then
+ return false, "Failed: parameter is nil"
+ end
+ --[[ DANGER ZONE ]]
+ -- Interpret string as Lua value
+ local func, errormsg = loadstring("return (" .. param .. ")")
+ if not func then
+ return false, "Failed: " .. errormsg
+ end
+
+ -- Apply sandbox here using setfenv
+ setfenv(func, {})
+
+ -- Run it
+ local good, errOrResult = pcall(func)
+ if not good then
+ -- A Lua error was thrown
+ return false, "Failed: " .. errOrResult
+ end
+
+ -- errOrResult will be the value
+ return true, errOrResult
+end
+
+-- Item Meta Editor + Node Meta Editor
+local node_meta_posses = {}
+local meta_latest_keylist = {}
+
+local function show_meta_formspec(user, metatype, pos_or_item, key, value, keylist)
+ local textlist
+ if keylist then
+ textlist = "textlist[0,0.5;2.5,6.5;keylist;"..keylist.."]"
+ else
+ textlist = ""
+ end
+
+ local form = "size[15,9]"..
+ "label[0,0;"..F(S("Current keys:")).."]"..
+ textlist..
+ "field[3,0.5;12,1;key;"..F(S("Key"))..";"..F(key).."]"..
+ "textarea[3,1.5;12,6;value;"..F(S("Value (use empty value to delete key)"))..";"..F(value).."]"..
+ "button[4,8;3,1;set;"..F(S("Set value")).."]"
+
+ local extra_label
+ local formname
+ if metatype == "node" then
+ formname = "testtools:node_meta_editor"
+ extra_label = S("pos = @1", minetest.pos_to_string(pos_or_item))
+ else
+ formname = "testtools:item_meta_editor"
+ extra_label = S("item = @1", pos_or_item:get_name())
+ end
+ form = form .. "label[0,7.2;"..F(extra_label).."]"
+
+ minetest.show_formspec(user:get_player_name(), formname, form)
+end
+
+local function get_meta_keylist(meta, playername, escaped)
+ local keys = {}
+ local ekeys = {}
+ local mtable = meta:to_table()
+ for k,_ in pairs(mtable.fields) do
+ table.insert(keys, k)
+ if escaped then
+ table.insert(ekeys, F(k))
+ else
+ table.insert(ekeys, k)
+ end
+ end
+ if playername then
+ meta_latest_keylist[playername] = keys
+ end
+ return table.concat(ekeys, ",")
+end
+
+minetest.register_tool("testtools:node_meta_editor", {
+ description = S("Node Meta Editor") .. "\n" ..
+ S("Place: Edit node metadata"),
+ inventory_image = "testtools_node_meta_editor.png",
+ groups = { testtool = 1, disable_repair = 1 },
+ on_place = function(itemstack, user, pointed_thing)
+ if pointed_thing.type ~= "node" then
+ return itemstack
+ end
+ if not user:is_player() then
+ return itemstack
+ end
+ local pos = pointed_thing.under
+ node_meta_posses[user:get_player_name()] = pos
+ local meta = minetest.get_meta(pos)
+ local inv = meta:get_inventory()
+ show_meta_formspec(user, "node", pos, "", "", get_meta_keylist(meta, user:get_player_name(), true))
+ return itemstack
+ end,
+})
+
+local function get_item_next_to_wielded_item(player)
+ local inv = player:get_inventory()
+ local wield = player:get_wield_index()
+ local itemstack = inv:get_stack("main", wield+1)
+ return itemstack
+end
+local function set_item_next_to_wielded_item(player, itemstack)
+ local inv = player:get_inventory()
+ local wield = player:get_wield_index()
+ inv:set_stack("main", wield+1, itemstack)
+end
+
+local function use_item_meta_editor(itemstack, user, pointed_thing)
+ if not user:is_player() then
+ return itemstack
+ end
+ local item_to_edit = get_item_next_to_wielded_item(user)
+ if item_to_edit:is_empty() then
+ minetest.chat_send_player(user:get_player_name(), S("Place an item next to the Item Meta Editor in your inventory first!"))
+ return itemstack
+ end
+ local meta = item_to_edit:get_meta()
+ show_meta_formspec(user, "item", item_to_edit, "", "", get_meta_keylist(meta, user:get_player_name(), true))
+ return itemstack
+end
+
+minetest.register_tool("testtools:item_meta_editor", {
+ description = S("Item Meta Editor") .. "\n" ..
+ S("Punch/Place: Edit item metadata of item in the next inventory slot"),
+ inventory_image = "testtools_item_meta_editor.png",
+ groups = { testtool = 1, disable_repair = 1 },
+ on_use = use_item_meta_editor,
+ on_secondary_use = use_item_meta_editor,
+ on_place = use_item_meta_editor,
+})
+
+minetest.register_on_player_receive_fields(function(player, formname, fields)
+ if not (player and player:is_player()) then
+ return
+ end
+ if formname == "testtools:entity_list" then
+ local name = player:get_player_name()
+ if fields.entity_list then
+ local expl = minetest.explode_textlist_event(fields.entity_list)
+ if expl.type == "DCL" then
+ local pos = vector.add(player:get_pos(), {x=0,y=1,z=0})
+ selections[name] = expl.index
+ minetest.add_entity(pos, get_entity_list()[expl.index])
+ return
+ elseif expl.type == "CHG" then
+ selections[name] = expl.index
+ return
+ end
+ elseif fields.spawn and selections[name] then
+ local pos = vector.add(player:get_pos(), {x=0,y=1,z=0})
+ minetest.add_entity(pos, get_entity_list()[selections[name]])
+ return
+ end
+ elseif formname == "testtools:object_editor" then
+ local name = player:get_player_name()
+ if fields.object_props then
+ local expl = minetest.explode_textlist_event(fields.object_props)
+ if expl.type == "DCL" or expl.type == "CHG" then
+ property_formspec_index[name] = expl.index
+
+ local props = selected_objects[name]:get_properties()
+ local keys = property_formspec_data[name]
+ if (not property_formspec_index[name]) or (not props) then
+ return
+ end
+ local key = keys[property_formspec_index[name]]
+ editor_formspec_selindex[name] = expl.index
+ editor_formspec(name, selected_objects[name], prop_to_string(props[key]), expl.index)
+ return
+ end
+ end
+ if fields.key_enter_field == "value" or fields.submit then
+ local props = selected_objects[name]:get_properties()
+ local keys = property_formspec_data[name]
+ if (not property_formspec_index[name]) or (not props) then
+ return
+ end
+ local key = keys[property_formspec_index[name]]
+ if not key then
+ return
+ end
+ local success, str = use_loadstring(fields.value, player)
+ if success then
+ props[key] = str
+ else
+ minetest.chat_send_player(name, str)
+ return
+ end
+ selected_objects[name]:set_properties(props)
+ local sel = editor_formspec_selindex[name]
+ editor_formspec(name, selected_objects[name], prop_to_string(props[key]), sel)
+ return
+ end
+ elseif formname == "testtools:node_setter" then
+ local playername = player:get_player_name()
+ local witem = player:get_wielded_item()
+ if witem:get_name() == "testtools:node_setter" then
+ if fields.nodename and fields.param2 then
+ local param2 = tonumber(fields.param2)
+ if not param2 then
+ return
+ end
+ local meta = witem:get_meta()
+ meta:set_string("node", fields.nodename)
+ meta:set_int("node_param2", param2)
+ player:set_wielded_item(witem)
+ end
+ end
+ elseif formname == "testtools:node_meta_editor" or formname == "testtools:item_meta_editor" then
+ local name = player:get_player_name()
+ local metatype
+ local pos_or_item
+ if formname == "testtools:node_meta_editor" then
+ metatype = "node"
+ pos_or_item = node_meta_posses[name]
+ else
+ metatype = "item"
+ pos_or_item = get_item_next_to_wielded_item(player)
+ end
+ if fields.keylist then
+ local evnt = minetest.explode_textlist_event(fields.keylist)
+ if evnt.type == "DCL" or evnt.type == "CHG" then
+ local keylist_table = meta_latest_keylist[name]
+ if metatype == "node" and not pos_or_item then
+ return
+ end
+ local meta
+ if metatype == "node" then
+ meta = minetest.get_meta(pos_or_item)
+ else
+ meta = pos_or_item:get_meta()
+ end
+ if not keylist_table then
+ return
+ end
+ if #keylist_table == 0 then
+ return
+ end
+ local key = keylist_table[evnt.index]
+ local value = meta:get_string(key)
+ local keylist_escaped = {}
+ for k,v in pairs(keylist_table) do
+ keylist_escaped[k] = F(v)
+ end
+ local keylist = table.concat(keylist_escaped, ",")
+ show_meta_formspec(player, metatype, pos_or_item, key, value, keylist)
+ return
+ end
+ elseif fields.key and fields.key ~= "" and fields.value then
+ if metatype == "node" and not pos_or_item then
+ return
+ end
+ local meta
+ if metatype == "node" then
+ meta = minetest.get_meta(pos_or_item)
+ elseif metatype == "item" then
+ if pos_or_item:is_empty() then
+ return
+ end
+ meta = pos_or_item:get_meta()
+ end
+ if fields.set then
+ meta:set_string(fields.key, fields.value)
+ if metatype == "item" then
+ set_item_next_to_wielded_item(player, pos_or_item)
+ end
+ show_meta_formspec(player, metatype, pos_or_item, fields.key, fields.value,
+ get_meta_keylist(meta, name, true))
+ end
+ return
+ end
+ end
+end)
+
+minetest.register_on_leaveplayer(function(player)
+ local name = player:get_player_name()
+ meta_latest_keylist[name] = nil
+ node_meta_posses[name] = nil
+end)
diff --git a/games/devtest/mods/testtools/light.lua b/games/devtest/mods/testtools/light.lua
new file mode 100644
index 000000000..afca9a489
--- /dev/null
+++ b/games/devtest/mods/testtools/light.lua
@@ -0,0 +1,37 @@
+
+local S = minetest.get_translator("testtools")
+
+local function get_func(is_place)
+ return function(itemstack, user, pointed_thing)
+ local pos
+ if is_place then
+ pos = pointed_thing.under
+ else
+ pos = pointed_thing.above
+ end
+ if pointed_thing.type ~= "node" or not pos then
+ return
+ end
+
+ local node = minetest.get_node(pos)
+ local pstr = minetest.pos_to_string(pos)
+ local time = minetest.get_timeofday()
+ local sunlight = minetest.get_natural_light(pos)
+ local artificial = minetest.get_artificial_light(node.param1)
+ local message = ("pos=%s | param1=0x%02x | " ..
+ "sunlight=%d | artificial=%d | timeofday=%.5f" )
+ :format(pstr, node.param1, sunlight, artificial, time)
+ minetest.chat_send_player(user:get_player_name(), message)
+ end
+end
+
+minetest.register_tool("testtools:lighttool", {
+ description = S("Light Tool") .. "\n" ..
+ S("Show light values of node") .. "\n" ..
+ S("Punch: Light of node above touched node") .. "\n" ..
+ S("Place: Light of touched node itself"),
+ inventory_image = "testtools_lighttool.png",
+ groups = { testtool = 1, disable_repair = 1 },
+ on_use = get_func(false),
+ on_place = get_func(true),
+})
diff --git a/games/devtest/mods/testtools/mod.conf b/games/devtest/mods/testtools/mod.conf
new file mode 100644
index 000000000..cde1b2685
--- /dev/null
+++ b/games/devtest/mods/testtools/mod.conf
@@ -0,0 +1,2 @@
+name = testtools
+description = Some tools to directly manipulate nodes and entities. Great for development and testing
diff --git a/games/devtest/mods/testtools/textures/testtools_children_getter.png b/games/devtest/mods/testtools/textures/testtools_children_getter.png
new file mode 100644
index 000000000..b7fa34025
--- /dev/null
+++ b/games/devtest/mods/testtools/textures/testtools_children_getter.png
Binary files differ
diff --git a/games/devtest/mods/testtools/textures/testtools_entity_rotator.png b/games/devtest/mods/testtools/textures/testtools_entity_rotator.png
new file mode 100644
index 000000000..17ebb2d35
--- /dev/null
+++ b/games/devtest/mods/testtools/textures/testtools_entity_rotator.png
Binary files differ
diff --git a/games/devtest/mods/testtools/textures/testtools_entity_scaler.png b/games/devtest/mods/testtools/textures/testtools_entity_scaler.png
new file mode 100644
index 000000000..4909c25b0
--- /dev/null
+++ b/games/devtest/mods/testtools/textures/testtools_entity_scaler.png
Binary files differ
diff --git a/games/devtest/mods/testtools/textures/testtools_entity_spawner.png b/games/devtest/mods/testtools/textures/testtools_entity_spawner.png
new file mode 100644
index 000000000..6199e0145
--- /dev/null
+++ b/games/devtest/mods/testtools/textures/testtools_entity_spawner.png
Binary files differ
diff --git a/games/devtest/mods/testtools/textures/testtools_falling_node_tool.png b/games/devtest/mods/testtools/textures/testtools_falling_node_tool.png
new file mode 100644
index 000000000..30099a7ef
--- /dev/null
+++ b/games/devtest/mods/testtools/textures/testtools_falling_node_tool.png
Binary files differ
diff --git a/games/devtest/mods/testtools/textures/testtools_item_meta_editor.png b/games/devtest/mods/testtools/textures/testtools_item_meta_editor.png
new file mode 100644
index 000000000..5cebb0a9d
--- /dev/null
+++ b/games/devtest/mods/testtools/textures/testtools_item_meta_editor.png
Binary files differ
diff --git a/games/devtest/mods/testtools/textures/testtools_lighttool.png b/games/devtest/mods/testtools/textures/testtools_lighttool.png
new file mode 100644
index 000000000..6f744b7fa
--- /dev/null
+++ b/games/devtest/mods/testtools/textures/testtools_lighttool.png
Binary files differ
diff --git a/games/devtest/mods/testtools/textures/testtools_node_meta_editor.png b/games/devtest/mods/testtools/textures/testtools_node_meta_editor.png
new file mode 100644
index 000000000..89eafd65c
--- /dev/null
+++ b/games/devtest/mods/testtools/textures/testtools_node_meta_editor.png
Binary files differ
diff --git a/games/devtest/mods/testtools/textures/testtools_node_setter.png b/games/devtest/mods/testtools/textures/testtools_node_setter.png
new file mode 100644
index 000000000..8599438de
--- /dev/null
+++ b/games/devtest/mods/testtools/textures/testtools_node_setter.png
Binary files differ
diff --git a/games/devtest/mods/testtools/textures/testtools_object_attacher.png b/games/devtest/mods/testtools/textures/testtools_object_attacher.png
new file mode 100644
index 000000000..4d9bf6fd1
--- /dev/null
+++ b/games/devtest/mods/testtools/textures/testtools_object_attacher.png
Binary files differ
diff --git a/games/devtest/mods/testtools/textures/testtools_object_editor.png b/games/devtest/mods/testtools/textures/testtools_object_editor.png
new file mode 100644
index 000000000..d1ce9cecd
--- /dev/null
+++ b/games/devtest/mods/testtools/textures/testtools_object_editor.png
Binary files differ
diff --git a/games/devtest/mods/testtools/textures/testtools_object_mover.png b/games/devtest/mods/testtools/textures/testtools_object_mover.png
new file mode 100644
index 000000000..8b14e9fb2
--- /dev/null
+++ b/games/devtest/mods/testtools/textures/testtools_object_mover.png
Binary files differ
diff --git a/games/devtest/mods/testtools/textures/testtools_param2tool.png b/games/devtest/mods/testtools/textures/testtools_param2tool.png
new file mode 100644
index 000000000..dbc663575
--- /dev/null
+++ b/games/devtest/mods/testtools/textures/testtools_param2tool.png
Binary files differ
diff --git a/games/devtest/mods/testtools/textures/testtools_remover.png b/games/devtest/mods/testtools/textures/testtools_remover.png
new file mode 100644
index 000000000..73f14cd54
--- /dev/null
+++ b/games/devtest/mods/testtools/textures/testtools_remover.png
Binary files differ
diff --git a/games/devtest/mods/tiled/init.lua b/games/devtest/mods/tiled/init.lua
new file mode 100644
index 000000000..68ead8e3a
--- /dev/null
+++ b/games/devtest/mods/tiled/init.lua
@@ -0,0 +1,33 @@
+minetest.register_node("tiled:tiled", {
+ description = "Tiled Node (world-aligned)",
+ tiles = {{
+ name = "tiled_tiled.png",
+ align_style = "world",
+ scale = 8,
+ }},
+ groups = {cracky=3},
+})
+
+minetest.register_node("tiled:tiled_n", {
+ description = "Tiled Node (node-aligned)",
+ tiles = {{
+ name = "tiled_tiled.png",
+ align_style = "node",
+ scale = 8,
+ }},
+ groups = {cracky=3},
+})
+
+stairs.register_stair_and_slab("tiled_n", "tiled:tiled",
+ {cracky=3},
+ {{name="tiled_tiled.png", align_style="node", scale=8}},
+ "Tiled Stair (node-aligned)",
+ "Tiled Slab (node-aligned)")
+
+stairs.register_stair_and_slab("tiled", "tiled:tiled",
+ {cracky=3},
+ {{name="tiled_tiled.png", align_style="world", scale=8}},
+ "Tiled Stair (world-aligned)",
+ "Tiled Slab (world-aligned)")
+
+
diff --git a/games/devtest/mods/tiled/mod.conf b/games/devtest/mods/tiled/mod.conf
new file mode 100644
index 000000000..78b19f93b
--- /dev/null
+++ b/games/devtest/mods/tiled/mod.conf
@@ -0,0 +1,3 @@
+name = tiled
+description = Add nodes with a special texture that spans multiple nodes (aka "world-aligned")
+depends = stairs
diff --git a/games/devtest/mods/tiled/textures/tiled_tiled.png b/games/devtest/mods/tiled/textures/tiled_tiled.png
new file mode 100644
index 000000000..363a26487
--- /dev/null
+++ b/games/devtest/mods/tiled/textures/tiled_tiled.png
Binary files differ
diff --git a/games/devtest/mods/unittests/async_env.lua b/games/devtest/mods/unittests/async_env.lua
new file mode 100644
index 000000000..b7edf941e
--- /dev/null
+++ b/games/devtest/mods/unittests/async_env.lua
@@ -0,0 +1,168 @@
+-- helper
+
+core.register_async_dofile(core.get_modpath(core.get_current_modname()) ..
+ DIR_DELIM .. "inside_async_env.lua")
+
+local function deepequal(a, b)
+ if type(a) == "function" then
+ return type(b) == "function"
+ elseif type(a) ~= "table" then
+ return a == b
+ elseif type(b) ~= "table" then
+ return false
+ end
+ for k, v in pairs(a) do
+ if not deepequal(v, b[k]) then
+ return false
+ end
+ end
+ for k, v in pairs(b) do
+ if not deepequal(a[k], v) then
+ return false
+ end
+ end
+ return true
+end
+
+-- Object Passing / Serialization
+
+local test_object = {
+ name = "stairs:stair_glass",
+ type = "node",
+ groups = {oddly_breakable_by_hand = 3, cracky = 3, stair = 1},
+ description = "Glass Stair",
+ sounds = {
+ dig = {name = "default_glass_footstep", gain = 0.5},
+ footstep = {name = "default_glass_footstep", gain = 0.3},
+ dug = {name = "default_break_glass", gain = 1}
+ },
+ node_box = {
+ fixed = {
+ {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
+ {-0.5, 0, 0, 0.5, 0.5, 0.5}
+ },
+ type = "fixed"
+ },
+ tiles = {
+ {name = "stairs_glass_split.png", backface_culling = true},
+ {name = "default_glass.png", backface_culling = true},
+ {name = "stairs_glass_stairside.png^[transformFX", backface_culling = true}
+ },
+ on_place = function(itemstack, placer)
+ return core.is_player(placer)
+ end,
+ sunlight_propagates = true,
+ is_ground_content = false,
+ light_source = 0,
+}
+
+local function test_object_passing()
+ local tmp = core.serialize_roundtrip(test_object)
+ assert(deepequal(test_object, tmp))
+
+ local circular_key = {"foo", "bar"}
+ circular_key[circular_key] = true
+ tmp = core.serialize_roundtrip(circular_key)
+ assert(tmp[1] == "foo")
+ assert(tmp[2] == "bar")
+ assert(tmp[tmp] == true)
+
+ local circular_value = {"foo"}
+ circular_value[2] = circular_value
+ tmp = core.serialize_roundtrip(circular_value)
+ assert(tmp[1] == "foo")
+ assert(tmp[2] == tmp)
+
+ -- Two-segment cycle
+ local cycle_seg_1, cycle_seg_2 = {}, {}
+ cycle_seg_1[1] = cycle_seg_2
+ cycle_seg_2[1] = cycle_seg_1
+ tmp = core.serialize_roundtrip(cycle_seg_1)
+ assert(tmp[1][1] == tmp)
+
+ -- Duplicated value without a cycle
+ local acyclic_dup_holder = {}
+ tmp = ItemStack("")
+ acyclic_dup_holder[tmp] = tmp
+ tmp = core.serialize_roundtrip(acyclic_dup_holder)
+ for k, v in pairs(tmp) do
+ assert(rawequal(k, v))
+ end
+end
+unittests.register("test_object_passing", test_object_passing)
+
+local function test_userdata_passing(_, pos)
+ -- basic userdata passing
+ local obj = table.copy(test_object.tiles[1])
+ obj.test = ItemStack("default:cobble 99")
+ local tmp = core.serialize_roundtrip(obj)
+ assert(type(tmp.test) == "userdata")
+ assert(obj.test:to_string() == tmp.test:to_string())
+
+ -- object can't be passed, should error
+ obj = core.raycast(pos, pos)
+ assert(not pcall(core.serialize_roundtrip, obj))
+
+ -- VManip
+ local vm = core.get_voxel_manip(pos, pos)
+ local expect = vm:get_node_at(pos)
+ local vm2 = core.serialize_roundtrip(vm)
+ assert(deepequal(vm2:get_node_at(pos), expect))
+end
+unittests.register("test_userdata_passing", test_userdata_passing, {map=true})
+
+-- Asynchronous jobs
+
+local function test_handle_async(cb)
+ -- Basic test including mod name tracking and unittests.async_test()
+ -- which is defined inside_async_env.lua
+ local func = function(x)
+ return core.get_last_run_mod(), _VERSION, unittests[x]()
+ end
+ local expect = {core.get_last_run_mod(), _VERSION, true}
+
+ core.handle_async(func, function(...)
+ if not deepequal(expect, {...}) then
+ return cb("Values did not equal")
+ end
+ if core.get_last_run_mod() ~= expect[1] then
+ return cb("Mod name not tracked correctly")
+ end
+
+ -- Test passing of nil arguments and return values
+ core.handle_async(function(a, b)
+ return a, b
+ end, function(a, b)
+ if b ~= 123 then
+ return cb("Argument went missing")
+ end
+ cb()
+ end, nil, 123)
+ end, "async_test")
+end
+unittests.register("test_handle_async", test_handle_async, {async=true})
+
+local function test_userdata_passing2(cb, _, pos)
+ -- VManip: check transfer into other env
+ local vm = core.get_voxel_manip(pos, pos)
+ local expect = vm:get_node_at(pos)
+
+ core.handle_async(function(vm_, pos_)
+ return vm_:get_node_at(pos_)
+ end, function(ret)
+ if not deepequal(expect, ret) then
+ return cb("Node data mismatch (one-way)")
+ end
+
+ -- VManip: test a roundtrip
+ core.handle_async(function(vm_)
+ return vm_
+ end, function(vm2)
+ if not deepequal(expect, vm2:get_node_at(pos)) then
+ return cb("Node data mismatch (roundtrip)")
+ end
+ cb()
+ end, vm)
+ end, vm, pos)
+end
+unittests.register("test_userdata_passing2", test_userdata_passing2, {map=true, async=true})
diff --git a/games/devtest/mods/unittests/crafting.lua b/games/devtest/mods/unittests/crafting.lua
new file mode 100644
index 000000000..8c16d3efb
--- /dev/null
+++ b/games/devtest/mods/unittests/crafting.lua
@@ -0,0 +1,112 @@
+dofile(core.get_modpath(core.get_current_modname()) .. "/crafting_prepare.lua")
+
+-- Test minetest.clear_craft function
+local function test_clear_craft()
+ -- Clearing by output
+ minetest.register_craft({
+ output = "foo",
+ recipe = {{"bar"}}
+ })
+ minetest.register_craft({
+ output = "foo 4",
+ recipe = {{"foo", "bar"}}
+ })
+ assert(#minetest.get_all_craft_recipes("foo") == 2)
+ minetest.clear_craft({output="foo"})
+ assert(minetest.get_all_craft_recipes("foo") == nil)
+ -- Clearing by input
+ minetest.register_craft({
+ output = "foo 4",
+ recipe = {{"foo", "bar"}}
+ })
+ assert(#minetest.get_all_craft_recipes("foo") == 1)
+ minetest.clear_craft({recipe={{"foo", "bar"}}})
+ assert(minetest.get_all_craft_recipes("foo") == nil)
+end
+unittests.register("test_clear_craft", test_clear_craft)
+
+-- Test minetest.get_craft_result function
+local function test_get_craft_result()
+ -- normal
+ local input = {
+ method = "normal",
+ width = 2,
+ items = {"", "unittests:coal_lump", "", "unittests:stick"}
+ }
+ minetest.log("info", "[unittests] torch crafting input: "..dump(input))
+ local output, decremented_input = minetest.get_craft_result(input)
+ minetest.log("info", "[unittests] torch crafting output: "..dump(output))
+ minetest.log("info", "[unittests] torch crafting decremented input: "..dump(decremented_input))
+ assert(output.item)
+ minetest.log("info", "[unittests] torch crafting output.item:to_table(): "..dump(output.item:to_table()))
+ assert(output.item:get_name() == "unittests:torch")
+ assert(output.item:get_count() == 4)
+
+ -- fuel
+ input = {
+ method = "fuel",
+ width = 1,
+ items = {"unittests:coal_lump"}
+ }
+ minetest.log("info", "[unittests] coal fuel input: "..dump(input))
+ output, decremented_input = minetest.get_craft_result(input)
+ minetest.log("info", "[unittests] coal fuel output: "..dump(output))
+ minetest.log("info", "[unittests] coal fuel decremented input: "..dump(decremented_input))
+ assert(output.time)
+ assert(output.time > 0)
+
+ -- cooking
+ input = {
+ method = "cooking",
+ width = 1,
+ items = {"unittests:iron_lump"}
+ }
+ minetest.log("info", "[unittests] iron lump cooking input: "..dump(output))
+ output, decremented_input = minetest.get_craft_result(input)
+ minetest.log("info", "[unittests] iron lump cooking output: "..dump(output))
+ minetest.log("info", "[unittests] iron lump cooking decremented input: "..dump(decremented_input))
+ assert(output.time)
+ assert(output.time > 0)
+ assert(output.item)
+ minetest.log("info", "[unittests] iron lump cooking output.item:to_table(): "..dump(output.item:to_table()))
+ assert(output.item:get_name() == "unittests:steel_ingot")
+ assert(output.item:get_count() == 1)
+
+ -- tool repair (repairable)
+ input = {
+ method = "normal",
+ width = 2,
+ -- Using a wear of 60000
+ items = {"unittests:repairable_tool 1 60000", "unittests:repairable_tool 1 60000"}
+ }
+ minetest.log("info", "[unittests] repairable tool crafting input: "..dump(input))
+ output, decremented_input = minetest.get_craft_result(input)
+ minetest.log("info", "[unittests] repairable tool crafting output: "..dump(output))
+ minetest.log("info", "[unittests] repairable tool crafting decremented input: "..dump(decremented_input))
+ assert(output.item)
+ minetest.log("info", "[unittests] repairable tool crafting output.item:to_table(): "..dump(output.item:to_table()))
+ assert(output.item:get_name() == "unittests:repairable_tool")
+ -- Test the wear value.
+ -- See src/craftdef.cpp in Minetest source code for the formula. The formula to calculate
+ -- the value 51187 is:
+ -- 65536 - ((65536-60000)+(65536-60000)) + floor(additonal_wear * 65536 + 0.5) = 51187
+ -- where additional_wear = 0.05
+ assert(output.item:get_wear() == 51187)
+ assert(output.item:get_count() == 1)
+
+ -- failing tool repair (unrepairable)
+ input = {
+ method = "normal",
+ width = 2,
+ items = {"unittests:unrepairable_tool 1 60000", "unittests:unrepairable_tool 1 60000"}
+ }
+ minetest.log("info", "[unittests] unrepairable tool crafting input: "..dump(input))
+ output, decremented_input = minetest.get_craft_result(input)
+ minetest.log("info", "[unittests] unrepairable tool crafting output: "..dump(output))
+ minetest.log("info", "[unittests] unrepairable tool crafting decremented input: "..dump(decremented_input))
+ assert(output.item)
+ minetest.log("info", "[unittests] unrepairable tool crafting output.item:to_table(): "..dump(output.item:to_table()))
+ -- unrepairable tool must not yield any output
+ assert(output.item:is_empty())
+end
+unittests.register("test_get_craft_result", test_get_craft_result)
diff --git a/games/devtest/mods/unittests/crafting_prepare.lua b/games/devtest/mods/unittests/crafting_prepare.lua
new file mode 100644
index 000000000..5cf5775e0
--- /dev/null
+++ b/games/devtest/mods/unittests/crafting_prepare.lua
@@ -0,0 +1,94 @@
+-- Registering some dummy items and recipes for the crafting tests
+
+minetest.register_craftitem("unittests:torch", {
+ description = "Crafting Test Item: Torch",
+ inventory_image = "unittests_torch.png",
+
+ groups = { dummy = 1 },
+})
+minetest.register_craftitem("unittests:coal_lump", {
+ description = "Crafting Test Item: Coal Lump",
+ inventory_image = "unittests_coal_lump.png",
+
+ groups = { dummy = 1 },
+})
+minetest.register_craftitem("unittests:stick", {
+ description = "Crafting Test Item: Stick",
+ inventory_image = "unittests_stick.png",
+
+ groups = { dummy = 1 },
+})
+minetest.register_craftitem("unittests:iron_lump", {
+ description = "Crafting Test Item: Iron Lump",
+ inventory_image = "unittests_iron_lump.png",
+
+ groups = { dummy = 1 },
+})
+minetest.register_craftitem("unittests:steel_ingot", {
+ description = "Crafting Test Item: Steel Ingot",
+ inventory_image = "unittests_steel_ingot.png",
+
+ groups = { dummy = 1 },
+})
+
+-- Use aliases in recipes for more complete testing
+
+minetest.register_alias("unittests:steel_ingot_alias", "unittests:steel_ingot")
+minetest.register_alias("unittests:coal_lump_alias", "unittests:coal_lump")
+minetest.register_alias("unittests:iron_lump_alias", "unittests:iron_lump")
+
+-- Recipes for tests: Normal crafting, cooking and fuel
+
+minetest.register_craft({
+ output = 'unittests:torch 4',
+ recipe = {
+ {'unittests:coal_lump_alias'},
+ {'unittests:stick'},
+ }
+})
+
+minetest.register_craft({
+ type = "cooking",
+ output = "unittests:steel_ingot_alias",
+ recipe = "unittests:iron_lump_alias",
+})
+
+minetest.register_craft({
+ type = "fuel",
+ recipe = "unittests:coal_lump_alias",
+ burntime = 40,
+})
+
+-- Test tool repair
+minetest.register_craft({
+ type = "toolrepair",
+ additional_wear = -0.05,
+})
+
+-- Test the disable_repair=1 group
+minetest.register_tool("unittests:unrepairable_tool", {
+ description = "Crafting Test Item: Unrepairable Tool",
+ inventory_image = "unittests_unrepairable_tool.png",
+ tool_capabilities = {
+ groupcaps = {
+ cracky = {
+ times = {3, 2, 1},
+ }
+ }
+ },
+ groups = { disable_repair = 1, dummy = 1 }
+})
+
+minetest.register_tool("unittests:repairable_tool", {
+ description = "Crafting Test Item: Repairable Tool",
+ inventory_image = "unittests_repairable_tool.png",
+ tool_capabilities = {
+ groupcaps = {
+ cracky = {
+ times = {3, 2, 1},
+ }
+ }
+ },
+
+ groups = { dummy = 1 },
+})
diff --git a/games/devtest/mods/unittests/entity.lua b/games/devtest/mods/unittests/entity.lua
new file mode 100644
index 000000000..68635cad7
--- /dev/null
+++ b/games/devtest/mods/unittests/entity.lua
@@ -0,0 +1,132 @@
+local log = {}
+
+local function insert_log(...)
+ log[#log+1] = string.format(...)
+end
+
+local function objref_str(self, ref)
+ if ref and ref:is_player() then
+ return "player"
+ end
+ return self.object == ref and "self" or tostring(ref)
+end
+
+core.register_entity("unittests:callbacks", {
+ initial_properties = {
+ hp_max = 5,
+ visual = "upright_sprite",
+ textures = { "unittests_stick.png" },
+ static_save = false,
+ },
+
+ on_activate = function(self, staticdata, dtime_s)
+ self.object:set_armor_groups({test = 100})
+ assert(self.object:get_hp() == self.initial_properties.hp_max)
+ insert_log("on_activate(%d)", #staticdata)
+ end,
+ on_deactivate = function(self, removal)
+ insert_log("on_deactivate(%s)", tostring(removal))
+ end,
+ on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
+ insert_log("on_punch(%s, %.1f, %d)", objref_str(self, puncher),
+ time_from_last_punch, damage)
+ end,
+ on_death = function(self, killer)
+ assert(self.object:get_hp() == 0)
+ insert_log("on_death(%s)", objref_str(self, killer))
+ end,
+ on_rightclick = function(self, clicker)
+ insert_log("on_rightclick(%s)", objref_str(self, clicker))
+ end,
+ on_attach_child = function(self, child)
+ insert_log("on_attach_child(%s)", objref_str(self, child))
+ end,
+ on_detach_child = function(self, child)
+ insert_log("on_detach_child(%s)", objref_str(self, child))
+ end,
+ on_detach = function(self, parent)
+ insert_log("on_detach(%s)", objref_str(self, parent))
+ end,
+ get_staticdata = function(self)
+ assert(false)
+ end,
+})
+
+--
+
+local function check_log(expect)
+ if #expect ~= #log then
+ error("Log mismatch: " .. core.write_json(log))
+ end
+ for i, s in ipairs(expect) do
+ if log[i] ~= s then
+ error("Log mismatch at " .. i .. ": " .. core.write_json(log))
+ end
+ end
+ log = {} -- clear it for next time
+end
+
+local function test_entity_lifecycle(_, pos)
+ log = {}
+
+ -- with binary in staticdata
+ local obj = core.add_entity(pos, "unittests:callbacks", "abc\000def")
+ check_log({"on_activate(7)"})
+
+ obj:set_hp(0)
+ check_log({"on_death(nil)", "on_deactivate(true)"})
+
+ -- objectref must be invalid now
+ assert(obj:get_velocity() == nil)
+end
+unittests.register("test_entity_lifecycle", test_entity_lifecycle, {map=true})
+
+local function test_entity_interact(_, pos)
+ log = {}
+
+ local obj = core.add_entity(pos, "unittests:callbacks")
+ check_log({"on_activate(0)"})
+
+ -- rightclick
+ obj:right_click(obj)
+ check_log({"on_rightclick(self)"})
+
+ -- useless punch
+ obj:punch(obj, 0.5, {})
+ check_log({"on_punch(self, 0.5, 0)"})
+
+ -- fatal punch
+ obj:punch(obj, 1.9, {
+ full_punch_interval = 1.0,
+ damage_groups = { test = 10 },
+ })
+ check_log({
+ -- does 10 damage even though we only have 5 hp
+ "on_punch(self, 1.9, 10)",
+ "on_death(self)",
+ "on_deactivate(true)"
+ })
+end
+unittests.register("test_entity_interact", test_entity_interact, {map=true})
+
+local function test_entity_attach(player, pos)
+ log = {}
+
+ local obj = core.add_entity(pos, "unittests:callbacks")
+ check_log({"on_activate(0)"})
+
+ -- attach player to entity
+ player:set_attach(obj)
+ check_log({"on_attach_child(player)"})
+ player:set_detach()
+ check_log({"on_detach_child(player)"})
+
+ -- attach entity to player
+ obj:set_attach(player)
+ check_log({})
+ obj:set_detach()
+ check_log({"on_detach(player)"})
+
+ obj:remove()
+end
+unittests.register("test_entity_attach", test_entity_attach, {player=true, map=true})
diff --git a/games/devtest/mods/unittests/init.lua b/games/devtest/mods/unittests/init.lua
new file mode 100644
index 000000000..0e041be76
--- /dev/null
+++ b/games/devtest/mods/unittests/init.lua
@@ -0,0 +1,202 @@
+unittests = {}
+
+unittests.list = {}
+
+-- name: Name of the test
+-- func:
+-- for sync: function(player, pos), should error on failure
+-- for async: function(callback, player, pos)
+-- MUST call callback() or callback("error msg") in case of error once test is finished
+-- this means you cannot use assert() in the test implementation
+-- opts: {
+-- player = false, -- Does test require a player?
+-- map = false, -- Does test require map access?
+-- async = false, -- Does the test run asynchronously? (read notes above!)
+-- }
+function unittests.register(name, func, opts)
+ local def = table.copy(opts or {})
+ def.name = name
+ def.func = func
+ table.insert(unittests.list, def)
+end
+
+function unittests.on_finished(all_passed)
+ -- free to override
+end
+
+-- Calls invoke with a callback as argument
+-- Suspends coroutine until that callback is called
+-- Return values are passed through
+local function await(invoke)
+ local co = coroutine.running()
+ assert(co)
+ local called_early = true
+ invoke(function(...)
+ if called_early == true then
+ called_early = {...}
+ else
+ coroutine.resume(co, ...)
+ co = nil
+ end
+ end)
+ if called_early ~= true then
+ -- callback was already called before yielding
+ return unpack(called_early)
+ end
+ called_early = nil
+ return coroutine.yield()
+end
+
+function unittests.run_one(idx, counters, out_callback, player, pos)
+ local def = unittests.list[idx]
+ if not def.player then
+ player = nil
+ elseif player == nil then
+ out_callback(false)
+ return false
+ end
+ if not def.map then
+ pos = nil
+ elseif pos == nil then
+ out_callback(false)
+ return false
+ end
+
+ local tbegin = core.get_us_time()
+ local function done(status, err)
+ local tend = core.get_us_time()
+ local ms_taken = (tend - tbegin) / 1000
+
+ if not status then
+ core.log("error", err)
+ end
+ print(string.format("[%s] %s - %dms",
+ status and "PASS" or "FAIL", def.name, ms_taken))
+ counters.time = counters.time + ms_taken
+ counters.total = counters.total + 1
+ if status then
+ counters.passed = counters.passed + 1
+ end
+ end
+
+ if def.async then
+ core.log("info", "[unittest] running " .. def.name .. " (async)")
+ def.func(function(err)
+ done(err == nil, err)
+ out_callback(true)
+ end, player, pos)
+ else
+ core.log("info", "[unittest] running " .. def.name)
+ local status, err = pcall(def.func, player, pos)
+ done(status, err)
+ out_callback(true)
+ end
+
+ return true
+end
+
+local function wait_for_player(callback)
+ if #core.get_connected_players() > 0 then
+ return callback(core.get_connected_players()[1])
+ end
+ local first = true
+ core.register_on_joinplayer(function(player)
+ if first then
+ callback(player)
+ first = false
+ end
+ end)
+end
+
+local function wait_for_map(player, callback)
+ local check = function()
+ if core.get_node_or_nil(player:get_pos()) ~= nil then
+ callback()
+ else
+ core.after(0, check)
+ end
+ end
+ check()
+end
+
+function unittests.run_all()
+ -- This runs in a coroutine so it uses await().
+ local counters = { time = 0, total = 0, passed = 0 }
+
+ -- Run standalone tests first
+ for idx = 1, #unittests.list do
+ local def = unittests.list[idx]
+ def.done = await(function(cb)
+ unittests.run_one(idx, counters, cb, nil, nil)
+ end)
+ end
+
+ -- Wait for a player to join, run tests that require a player
+ local player = await(wait_for_player)
+ for idx = 1, #unittests.list do
+ local def = unittests.list[idx]
+ if not def.done then
+ def.done = await(function(cb)
+ unittests.run_one(idx, counters, cb, player, nil)
+ end)
+ end
+ end
+
+ -- Wait for the world to generate/load, run tests that require map access
+ await(function(cb)
+ wait_for_map(player, cb)
+ end)
+ local pos = vector.round(player:get_pos())
+ for idx = 1, #unittests.list do
+ local def = unittests.list[idx]
+ if not def.done then
+ def.done = await(function(cb)
+ unittests.run_one(idx, counters, cb, player, pos)
+ end)
+ end
+ end
+
+ -- Print stats
+ assert(#unittests.list == counters.total)
+ print(string.rep("+", 80))
+ print(string.format("Unit Test Results: %s",
+ counters.total == counters.passed and "PASSED" or "FAILED"))
+ print(string.format(" %d / %d failed tests.",
+ counters.total - counters.passed, counters.total))
+ print(string.format(" Testing took %dms total.", counters.time))
+ print(string.rep("+", 80))
+ unittests.on_finished(counters.total == counters.passed)
+ return counters.total == counters.passed
+end
+
+--------------
+
+local modpath = core.get_modpath("unittests")
+dofile(modpath .. "/misc.lua")
+dofile(modpath .. "/player.lua")
+dofile(modpath .. "/crafting.lua")
+dofile(modpath .. "/itemdescription.lua")
+dofile(modpath .. "/async_env.lua")
+dofile(modpath .. "/entity.lua")
+
+--------------
+
+if core.settings:get_bool("devtest_unittests_autostart", false) then
+ core.after(0, function()
+ coroutine.wrap(unittests.run_all)()
+ end)
+else
+ core.register_chatcommand("unittests", {
+ privs = {basic_privs=true},
+ description = "Runs devtest unittests (may modify player or map state)",
+ func = function(name, param)
+ unittests.on_finished = function(ok)
+ core.chat_send_player(name,
+ (ok and "All tests passed." or "There were test failures.") ..
+ " Check the console for detailed output.")
+ end
+ coroutine.wrap(unittests.run_all)()
+ return true, ""
+ end,
+ })
+end
diff --git a/games/devtest/mods/unittests/inside_async_env.lua b/games/devtest/mods/unittests/inside_async_env.lua
new file mode 100644
index 000000000..4ed0fccd2
--- /dev/null
+++ b/games/devtest/mods/unittests/inside_async_env.lua
@@ -0,0 +1,25 @@
+unittests = {}
+
+core.log("info", "Hello World")
+
+local function do_tests()
+ assert(core == minetest)
+ -- stuff that should not be here
+ assert(not core.get_player_by_name)
+ assert(not core.set_node)
+ assert(not core.object_refs)
+ -- stuff that should be here
+ assert(ItemStack)
+ assert(core.registered_items[""])
+ -- alias handling
+ assert(core.registered_items["unittests:steel_ingot_alias"].name ==
+ "unittests:steel_ingot")
+end
+
+function unittests.async_test()
+ local ok, err = pcall(do_tests)
+ if not ok then
+ core.log("error", err)
+ end
+ return ok
+end
diff --git a/games/devtest/mods/unittests/itemdescription.lua b/games/devtest/mods/unittests/itemdescription.lua
new file mode 100644
index 000000000..b4c218c98
--- /dev/null
+++ b/games/devtest/mods/unittests/itemdescription.lua
@@ -0,0 +1,42 @@
+local full_description = "Description Test Item\nFor testing item decription"
+minetest.register_tool("unittests:description_test", {
+ description = full_description,
+ inventory_image = "unittests_description_test.png",
+})
+
+minetest.register_chatcommand("item_description", {
+ param = "",
+ description = "Show the short and full description of the wielded item.",
+ func = function(name)
+ local player = minetest.get_player_by_name(name)
+ local item = player:get_wielded_item()
+ return true, string.format("short_description: %s\ndescription: %s",
+ item:get_short_description(), item:get_description())
+ end
+})
+
+local function test_short_desc()
+ local function get_short_description(item)
+ return ItemStack(item):get_short_description()
+ end
+
+ local stack = ItemStack("unittests:description_test")
+ assert(stack:get_short_description() == "Description Test Item")
+ assert(get_short_description("unittests:description_test") == "Description Test Item")
+ assert(minetest.registered_items["unittests:description_test"].short_description == nil)
+ assert(stack:get_description() == full_description)
+ assert(stack:get_description() == minetest.registered_items["unittests:description_test"].description)
+
+ stack:get_meta():set_string("description", "Hello World")
+ assert(stack:get_short_description() == "Hello World")
+ assert(stack:get_description() == "Hello World")
+ assert(get_short_description(stack) == "Hello World")
+ assert(get_short_description("unittests:description_test") == "Description Test Item")
+
+ stack:get_meta():set_string("short_description", "Foo Bar")
+ assert(stack:get_short_description() == "Foo Bar")
+ assert(stack:get_description() == "Hello World")
+
+ return true
+end
+unittests.register("test_short_desc", test_short_desc)
diff --git a/games/devtest/mods/unittests/misc.lua b/games/devtest/mods/unittests/misc.lua
new file mode 100644
index 000000000..4811c8008
--- /dev/null
+++ b/games/devtest/mods/unittests/misc.lua
@@ -0,0 +1,82 @@
+local function test_random()
+ -- Try out PseudoRandom
+ local pseudo = PseudoRandom(13)
+ assert(pseudo:next() == 22290)
+ assert(pseudo:next() == 13854)
+end
+unittests.register("test_random", test_random)
+
+local function test_dynamic_media(cb, player)
+ if core.get_player_information(player:get_player_name()).protocol_version < 40 then
+ core.log("warning", "test_dynamic_media: Client too old, skipping test.")
+ return cb()
+ end
+
+ -- Check that the client acknowledges media transfers
+ local path = core.get_worldpath() .. "/test_media.obj"
+ local f = io.open(path, "w")
+ f:write("# contents don't matter\n")
+ f:close()
+
+ local call_ok = false
+ local ok = core.dynamic_add_media({
+ filepath = path,
+ to_player = player:get_player_name(),
+ }, function(name)
+ if not call_ok then
+ return cb("impossible condition")
+ end
+ cb()
+ end)
+ if not ok then
+ return cb("dynamic_add_media() returned error")
+ end
+ call_ok = true
+
+ -- if the callback isn't called this test will just hang :shrug:
+end
+unittests.register("test_dynamic_media", test_dynamic_media, {async=true, player=true})
+
+local function test_v3f_metatable(player)
+ assert(vector.check(player:get_pos()))
+end
+unittests.register("test_v3f_metatable", test_v3f_metatable, {player=true})
+
+local function test_v3s16_metatable(player, pos)
+ local node = minetest.get_node(pos)
+ local found_pos = minetest.find_node_near(pos, 0, node.name, true)
+ assert(vector.check(found_pos))
+end
+unittests.register("test_v3s16_metatable", test_v3s16_metatable, {map=true})
+
+local function test_clear_meta(_, pos)
+ local ref = core.get_meta(pos)
+
+ for way = 1, 3 do
+ ref:set_string("foo", "bar")
+ assert(ref:contains("foo"))
+
+ if way == 1 then
+ ref:from_table({})
+ elseif way == 2 then
+ ref:from_table(nil)
+ else
+ ref:set_string("foo", "")
+ end
+
+ assert(#core.find_nodes_with_meta(pos, pos) == 0, "clearing failed " .. way)
+ end
+end
+unittests.register("test_clear_meta", test_clear_meta, {map=true})
+
+local on_punch_called
+minetest.register_on_punchnode(function()
+ on_punch_called = true
+end)
+unittests.register("test_punch_node", function(_, pos)
+ minetest.place_node(pos, {name="basenodes:dirt"})
+ on_punch_called = false
+ minetest.punch_node(pos)
+ minetest.remove_node(pos)
+ -- currently failing: assert(on_punch_called)
+end, {map=true})
diff --git a/games/devtest/mods/unittests/mod.conf b/games/devtest/mods/unittests/mod.conf
new file mode 100644
index 000000000..fa94e01a6
--- /dev/null
+++ b/games/devtest/mods/unittests/mod.conf
@@ -0,0 +1,3 @@
+name = unittests
+description = Adds automated unit tests for the engine
+depends = basenodes
diff --git a/games/devtest/mods/unittests/player.lua b/games/devtest/mods/unittests/player.lua
new file mode 100644
index 000000000..fa0557960
--- /dev/null
+++ b/games/devtest/mods/unittests/player.lua
@@ -0,0 +1,70 @@
+--
+-- HP Change Reasons
+--
+local expect = nil
+minetest.register_on_player_hpchange(function(player, hp, reason)
+ if expect == nil then
+ return
+ end
+
+ for key, value in pairs(reason) do
+ assert(expect[key] == value)
+ end
+ for key, value in pairs(expect) do
+ assert(reason[key] == value)
+ end
+
+ expect = nil
+end)
+
+local function run_hpchangereason_tests(player)
+ local old_hp = player:get_hp()
+
+ player:set_hp(20)
+ expect = { type = "set_hp", from = "mod" }
+ player:set_hp(3)
+ assert(expect == nil)
+
+ expect = { a = 234, type = "set_hp", from = "mod" }
+ player:set_hp(7, { a= 234 })
+ assert(expect == nil)
+
+ expect = { df = 3458973454, type = "fall", from = "mod" }
+ player:set_hp(10, { type = "fall", df = 3458973454 })
+ assert(expect == nil)
+
+ player:set_hp(old_hp)
+end
+unittests.register("test_hpchangereason", run_hpchangereason_tests, {player=true})
+
+--
+-- Player meta
+--
+local function run_player_meta_tests(player)
+ local meta = player:get_meta()
+ meta:set_string("foo", "bar")
+ assert(meta:contains("foo"))
+ assert(meta:get_string("foo") == "bar")
+ assert(meta:get("foo") == "bar")
+
+ local meta2 = player:get_meta()
+ assert(meta2:get_string("foo") == "bar")
+ assert(meta2:get("foo") == "bar")
+ assert(meta:equals(meta2))
+
+ meta:set_string("bob", "dillan")
+ assert(meta:get_string("foo") == "bar")
+ assert(meta:get_string("bob") == "dillan")
+ assert(meta:get("bob") == "dillan")
+ assert(meta2:get_string("foo") == "bar")
+ assert(meta2:get_string("bob") == "dillan")
+ assert(meta2:get("bob") == "dillan")
+ assert(meta:equals(meta2))
+
+ meta:set_string("foo", "")
+ assert(not meta:contains("foo"))
+ assert(meta:get("foo") == nil)
+ assert(meta:get_string("foo") == "")
+ assert(meta:equals(meta2))
+end
+unittests.register("test_player_meta", run_player_meta_tests, {player=true})
diff --git a/games/devtest/mods/unittests/textures/default_dirt.png b/games/devtest/mods/unittests/textures/default_dirt.png
new file mode 100644
index 000000000..58670305d
--- /dev/null
+++ b/games/devtest/mods/unittests/textures/default_dirt.png
Binary files differ
diff --git a/games/devtest/mods/unittests/textures/unittests_coal_lump.png b/games/devtest/mods/unittests/textures/unittests_coal_lump.png
new file mode 100644
index 000000000..f460d909e
--- /dev/null
+++ b/games/devtest/mods/unittests/textures/unittests_coal_lump.png
Binary files differ
diff --git a/games/devtest/mods/unittests/textures/unittests_description_test.png b/games/devtest/mods/unittests/textures/unittests_description_test.png
new file mode 100644
index 000000000..a6be43314
--- /dev/null
+++ b/games/devtest/mods/unittests/textures/unittests_description_test.png
Binary files differ
diff --git a/games/devtest/mods/unittests/textures/unittests_iron_lump.png b/games/devtest/mods/unittests/textures/unittests_iron_lump.png
new file mode 100644
index 000000000..22f43e9cc
--- /dev/null
+++ b/games/devtest/mods/unittests/textures/unittests_iron_lump.png
Binary files differ
diff --git a/games/devtest/mods/unittests/textures/unittests_repairable_tool.png b/games/devtest/mods/unittests/textures/unittests_repairable_tool.png
new file mode 100644
index 000000000..46fbbaa74
--- /dev/null
+++ b/games/devtest/mods/unittests/textures/unittests_repairable_tool.png
Binary files differ
diff --git a/games/devtest/mods/unittests/textures/unittests_steel_ingot.png b/games/devtest/mods/unittests/textures/unittests_steel_ingot.png
new file mode 100644
index 000000000..6977696a2
--- /dev/null
+++ b/games/devtest/mods/unittests/textures/unittests_steel_ingot.png
Binary files differ
diff --git a/games/devtest/mods/unittests/textures/unittests_stick.png b/games/devtest/mods/unittests/textures/unittests_stick.png
new file mode 100644
index 000000000..ffdce70d4
--- /dev/null
+++ b/games/devtest/mods/unittests/textures/unittests_stick.png
Binary files differ
diff --git a/games/devtest/mods/unittests/textures/unittests_torch.png b/games/devtest/mods/unittests/textures/unittests_torch.png
new file mode 100644
index 000000000..ba5eebef0
--- /dev/null
+++ b/games/devtest/mods/unittests/textures/unittests_torch.png
Binary files differ
diff --git a/games/devtest/mods/unittests/textures/unittests_unrepairable_tool.png b/games/devtest/mods/unittests/textures/unittests_unrepairable_tool.png
new file mode 100644
index 000000000..c676213a5
--- /dev/null
+++ b/games/devtest/mods/unittests/textures/unittests_unrepairable_tool.png
Binary files differ
diff --git a/games/devtest/mods/util_commands/init.lua b/games/devtest/mods/util_commands/init.lua
new file mode 100644
index 000000000..c37364042
--- /dev/null
+++ b/games/devtest/mods/util_commands/init.lua
@@ -0,0 +1,309 @@
+minetest.register_chatcommand("hotbar", {
+ params = "<size>",
+ description = "Set hotbar size",
+ func = function(name, param)
+ local player = minetest.get_player_by_name(name)
+ if not player then
+ return false, "No player."
+ end
+ local size = tonumber(param)
+ if not size then
+ return false, "Missing or incorrect size parameter!"
+ end
+ local ok = player:hud_set_hotbar_itemcount(size)
+ if ok then
+ return true
+ else
+ return false, "Invalid item count!"
+ end
+ end,
+})
+
+minetest.register_chatcommand("hp", {
+ params = "<hp>",
+ description = "Set your health",
+ func = function(name, param)
+ local player = minetest.get_player_by_name(name)
+ if not player then
+ return false, "No player."
+ end
+ local hp = tonumber(param)
+ if not hp then
+ return false, "Missing or incorrect hp parameter!"
+ end
+ player:set_hp(hp)
+ return true
+ end,
+})
+
+minetest.register_on_joinplayer(function(player)
+ player:set_properties({zoom_fov = 15})
+end)
+
+minetest.register_chatcommand("zoomfov", {
+ params = "[<FOV>]",
+ description = "Set or display your zoom_fov",
+ func = function(name, param)
+ local player = minetest.get_player_by_name(name)
+ if not player then
+ return false, "No player."
+ end
+ if param == "" then
+ local fov = player:get_properties().zoom_fov
+ return true, "zoom_fov = "..tostring(fov)
+ end
+ local fov = tonumber(param)
+ if not fov then
+ return false, "Missing or incorrect zoom_fov parameter!"
+ end
+ player:set_properties({zoom_fov = fov})
+ fov = player:get_properties().zoom_fov
+ return true, "zoom_fov = "..tostring(fov)
+ end,
+})
+
+local s_infplace = minetest.settings:get("devtest_infplace")
+if s_infplace == "true" then
+ infplace = true
+elseif s_infplace == "false" then
+ infplace = false
+else
+ infplace = minetest.is_creative_enabled("")
+end
+
+minetest.register_chatcommand("infplace", {
+ params = "",
+ description = "Toggle infinite node placement",
+ func = function(name, param)
+ infplace = not infplace
+ if infplace then
+ minetest.chat_send_all("Infinite node placement enabled!")
+ minetest.log("action", "Infinite node placement enabled")
+ else
+ minetest.chat_send_all("Infinite node placement disabled!")
+ minetest.log("action", "Infinite node placement disabled")
+ end
+ return true
+ end,
+})
+
+minetest.register_chatcommand("detach", {
+ params = "[<radius>]",
+ description = "Detach all objects nearby",
+ func = function(name, param)
+ local radius = tonumber(param)
+ if type(radius) ~= "number" then
+ radius = 8
+ end
+ if radius < 1 then
+ radius = 1
+ end
+ local player = minetest.get_player_by_name(name)
+ if not player then
+ return false, "No player."
+ end
+ local objs = minetest.get_objects_inside_radius(player:get_pos(), radius)
+ local num = 0
+ for o=1, #objs do
+ if objs[o]:get_attach() then
+ objs[o]:set_detach()
+ num = num + 1
+ end
+ end
+ return true, string.format("%d object(s) detached.", num)
+ end,
+})
+
+minetest.register_chatcommand("use_tool", {
+ params = "(dig <group> <leveldiff>) | (hit <damage_group> <time_from_last_punch>) [<uses>]",
+ description = "Apply tool wear a number of times, as if it were used for digging",
+ func = function(name, param)
+ local player = minetest.get_player_by_name(name)
+ if not player then
+ return false, "No player."
+ end
+ local mode, group, level, uses = string.match(param, "([a-z]+) ([a-z0-9]+) (-?%d+) (%d+)")
+ if not mode then
+ mode, group, level = string.match(param, "([a-z]+) ([a-z0-9]+) (-?%d+)")
+ uses = 1
+ end
+ if not mode or not group or not level then
+ return false
+ end
+ if mode ~= "dig" and mode ~= "hit" then
+ return false
+ end
+ local tool = player:get_wielded_item()
+ local caps = tool:get_tool_capabilities()
+ if not caps or tool:get_count() == 0 then
+ return false, "No tool in hand."
+ end
+ local actual_uses = 0
+ for u=1, uses do
+ local wear = tool:get_wear()
+ local dp
+ if mode == "dig" then
+ dp = minetest.get_dig_params({[group]=3, level=level}, caps, wear)
+ else
+ dp = minetest.get_hit_params({[group]=100}, caps, level, wear)
+ end
+ tool:add_wear(dp.wear)
+ actual_uses = actual_uses + 1
+ if tool:get_count() == 0 then
+ break
+ end
+ end
+ player:set_wielded_item(tool)
+ if tool:get_count() == 0 then
+ return true, string.format("Tool used %d time(s). "..
+ "The tool broke after %d use(s).", uses, actual_uses)
+ else
+ local wear = tool:get_wear()
+ return true, string.format("Tool used %d time(s). "..
+ "Final wear=%d", uses, wear)
+ end
+ end,
+})
+
+
+
+-- Use this to test waypoint capabilities
+minetest.register_chatcommand("test_waypoints", {
+ params = "[change_immediate]",
+ description = "tests waypoint capabilities",
+ func = function(name, params)
+ local player = minetest.get_player_by_name(name)
+ local regular = player:hud_add {
+ hud_elem_type = "waypoint",
+ name = "regular waypoint",
+ text = "m",
+ number = 0xFF0000,
+ world_pos = vector.add(player:get_pos(), {x = 0, y = 1.5, z = 0})
+ }
+ local reduced_precision = player:hud_add {
+ hud_elem_type = "waypoint",
+ name = "better waypoint",
+ text = "m (0.5 steps, precision = 2)",
+ precision = 10,
+ number = 0xFFFF00,
+ world_pos = vector.add(player:get_pos(), {x = 0, y = 1, z = 0})
+ }
+ local function change()
+ if regular then
+ player:hud_change(regular, "world_pos", vector.add(player:get_pos(), {x = 0, y = 3, z = 0}))
+ end
+ if reduced_precision then
+ player:hud_change(reduced_precision, "precision", 2)
+ end
+ end
+ if params ~= "" then
+ -- change immediate
+ change()
+ else
+ minetest.after(0.5, change)
+ end
+ regular = regular or "error"
+ reduced_precision = reduced_precision or "error"
+ local hidden_distance = player:hud_add {
+ hud_elem_type = "waypoint",
+ name = "waypoint with hidden distance",
+ text = "this text is hidden as well (precision = 0)",
+ precision = 0,
+ number = 0x0000FF,
+ world_pos = vector.add(player:get_pos(), {x = 0, y = 0.5, z = 0})
+ } or "error"
+ local image_waypoint = player:hud_add {
+ hud_elem_type = "image_waypoint",
+ text = "wieldhand.png",
+ world_pos = player:get_pos(),
+ scale = {x = 10, y = 10},
+ offset = {x = 0, y = -32}
+ } or "error"
+ minetest.chat_send_player(name, "Waypoint IDs: regular: " .. regular .. ", reduced precision: " .. reduced_precision ..
+ ", hidden distance: " .. hidden_distance .. ", image waypoint: " .. image_waypoint)
+ end
+})
+
+-- Unlimited node placement
+minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack)
+ if placer and placer:is_player() then
+ return infplace
+ end
+end)
+
+-- Don't pick up if the item is already in the inventory
+local old_handle_node_drops = minetest.handle_node_drops
+function minetest.handle_node_drops(pos, drops, digger)
+ if not digger or not digger:is_player() or not infplace then
+ return old_handle_node_drops(pos, drops, digger)
+ end
+ local inv = digger:get_inventory()
+ if inv then
+ for _, item in ipairs(drops) do
+ if not inv:contains_item("main", item, true) then
+ inv:add_item("main", item)
+ end
+ end
+ end
+end
+
+minetest.register_chatcommand("set_displayed_itemcount", {
+ params = "(-s \"<string>\" [-c <color>]) | -a <alignment_num>",
+ description = "Set the displayed itemcount of the wielded item",
+ func = function(name, param)
+ local player = minetest.get_player_by_name(name)
+ local item = player:get_wielded_item()
+ local meta = item:get_meta()
+ local flag1 = param:sub(1, 2)
+ if flag1 == "-s" then
+ if param:sub(3, 4) ~= " \"" then
+ return false, "Error: Space and string with \"s expected after -s."
+ end
+ local se = param:find("\"", 5, true)
+ if not se then
+ return false, "Error: String with two \"s expected after -s."
+ end
+ local s = param:sub(5, se - 1)
+ if param:sub(se + 1, se + 4) == " -c " then
+ s = minetest.colorize(param:sub(se + 5), s)
+ end
+ meta:set_string("count_meta", s)
+ elseif flag1 == "-a" then
+ local num = tonumber(param:sub(4))
+ if not num then
+ return false, "Error: Invalid number: "..param:sub(4)
+ end
+ meta:set_int("count_alignment", num)
+ else
+ return false
+ end
+ player:set_wielded_item(item)
+ return true, "Displayed itemcount set."
+ end,
+})
+
+minetest.register_chatcommand("dump_item", {
+ params = "",
+ description = "Prints a dump of the wielded item in table form",
+ func = function(name, param)
+ local player = minetest.get_player_by_name(name)
+ local item = player:get_wielded_item()
+ local str = dump(item:to_table())
+ print(str)
+ return true, str
+ end,
+})
+
+-- shadow control
+minetest.register_on_joinplayer(function (player)
+ player:set_lighting({shadows={intensity = 0.33}})
+end)
+
+core.register_chatcommand("set_shadow", {
+ params = "<shadow_intensity>",
+ description = "Set shadow parameters of current player.",
+ func = function(player_name, param)
+ local shadow_intensity = tonumber(param)
+ minetest.get_player_by_name(player_name):set_lighting({shadows = { intensity = shadow_intensity} })
+ end
+})
diff --git a/games/devtest/mods/util_commands/mod.conf b/games/devtest/mods/util_commands/mod.conf
new file mode 100644
index 000000000..fea6dd3e9
--- /dev/null
+++ b/games/devtest/mods/util_commands/mod.conf
@@ -0,0 +1,2 @@
+name = util_commands
+description = Random server commands to make testing easier and more convenient
diff --git a/games/devtest/screenshot.png b/games/devtest/screenshot.png
new file mode 100644
index 000000000..7324883f6
--- /dev/null
+++ b/games/devtest/screenshot.png
Binary files differ
diff --git a/games/devtest/settingtypes.txt b/games/devtest/settingtypes.txt
new file mode 100644
index 000000000..c4365643e
--- /dev/null
+++ b/games/devtest/settingtypes.txt
@@ -0,0 +1,32 @@
+# If enabled, nodes won't be used up when placed.
+# Note: This behavior can also be toggled in-game with the /infplace command.
+#
+# - true: enabled
+# - false: disabled
+# - auto: only enabled when Creative Mode is enabled (default)
+devtest_infplace (Infinite node placement) enum auto true,false,auto
+
+# If enabled, new players receive some initial items when joining for the first time.
+give_initial_stuff (Give initial stuff) bool true
+
+# If enabled, automated tests of the Lua API such as player health, crafting and PseudoRandom will be performed on startup.
+devtest_unittests_autostart (Perform unit tests) bool false
+
+# If enabled, the game will use all mapgen aliases for the v6 mapgen.
+# If disabled, it will only use a minimal set of mapgen aliases.
+# If enabled, there should be biome-specific tree, leaves and ground nodes. If disabled, stuff should use fallback nodes (like stone instead of desert stone).
+#
+# Many mapgen aliases have fallback values when no value is provided. Having this setting disabled can be useful to test whether those fallback values are functional.
+devtest_v6_mapgen_aliases (Use all v6 mapgen aliases) bool false
+
+# If enabled, the game will use dungeon stairs by enabling the corresponding mapgen aliases.
+#
+# Disabling this setting can be useful to test whether dungeons still work when stairs are not defined.
+devtest_dungeon_stairs (Generate dungeon stairs) bool false
+
+# If enabled, the mapgen alias 'mapgen_mossycobble' will be used. This should enable random mossy cobblestone in dungeons.
+# If disabled, it won't be used. The engine should fall back to cobble instead.
+devtest_dungeon_mossycobble (Generate mossy cobblestone) bool false
+
+# If enabled, some very basic biomes will be registered.
+devtest_register_biomes (Register biomes) bool true
diff --git a/games/minimal/game.conf b/games/minimal/game.conf
deleted file mode 100644
index 99bfaf0a4..000000000
--- a/games/minimal/game.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-name = Minimal development test
-
diff --git a/games/minimal/menu/background.png b/games/minimal/menu/background.png
deleted file mode 100644
index ea5fbdce5..000000000
--- a/games/minimal/menu/background.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/menu/icon.png b/games/minimal/menu/icon.png
deleted file mode 100644
index 8ef675023..000000000
--- a/games/minimal/menu/icon.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/bucket/depends.txt b/games/minimal/mods/bucket/depends.txt
deleted file mode 100644
index 3a7daa1d7..000000000
--- a/games/minimal/mods/bucket/depends.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-default
-
diff --git a/games/minimal/mods/bucket/init.lua b/games/minimal/mods/bucket/init.lua
deleted file mode 100644
index dcd59ed38..000000000
--- a/games/minimal/mods/bucket/init.lua
+++ /dev/null
@@ -1,95 +0,0 @@
--- bucket (Minetest 0.4 mod)
--- A bucket, which can pick up water and lava
-
-minetest.register_alias("bucket", "bucket:bucket_empty")
-minetest.register_alias("bucket_water", "bucket:bucket_water")
-minetest.register_alias("bucket_lava", "bucket:bucket_lava")
-
-minetest.register_craft({
- output = 'bucket:bucket_empty 1',
- recipe = {
- {'default:steel_ingot', '', 'default:steel_ingot'},
- {'', 'default:steel_ingot', ''},
- }
-})
-
-bucket = {}
-bucket.liquids = {}
-
--- Register a new liquid
--- source = name of the source node
--- flowing = name of the flowing node
--- itemname = name of the new bucket item (or nil if liquid is not takeable)
--- inventory_image = texture of the new bucket item (ignored if itemname == nil)
--- This function can be called from any mod (that depends on bucket).
-function bucket.register_liquid(source, flowing, itemname, inventory_image)
- bucket.liquids[source] = {
- source = source,
- flowing = flowing,
- itemname = itemname,
- }
- bucket.liquids[flowing] = bucket.liquids[source]
-
- if itemname ~= nil then
- minetest.register_craftitem(itemname, {
- inventory_image = inventory_image,
- stack_max = 1,
- liquids_pointable = true,
- on_use = function(itemstack, user, pointed_thing)
- -- Must be pointing to node
- if pointed_thing.type ~= "node" then
- return
- end
- -- Check if pointing to a liquid
- n = minetest.get_node(pointed_thing.under)
- if bucket.liquids[n.name] == nil then
- -- Not a liquid
- minetest.add_node(pointed_thing.above, {name=source})
- elseif n.name ~= source then
- -- It's a liquid
- minetest.add_node(pointed_thing.under, {name=source})
- end
- return {name="bucket:bucket_empty"}
- end
- })
- end
-end
-
-minetest.register_craftitem("bucket:bucket_empty", {
- inventory_image = "bucket.png",
- stack_max = 1,
- liquids_pointable = true,
- on_use = function(itemstack, user, pointed_thing)
- -- Must be pointing to node
- if pointed_thing.type ~= "node" then
- return
- end
- -- Check if pointing to a liquid source
- n = minetest.get_node(pointed_thing.under)
- liquiddef = bucket.liquids[n.name]
- if liquiddef ~= nil and liquiddef.source == n.name and liquiddef.itemname ~= nil then
- minetest.add_node(pointed_thing.under, {name="air"})
- return {name=liquiddef.itemname}
- end
- end,
-})
-
-bucket.register_liquid(
- "default:water_source",
- "default:water_flowing",
- "bucket:bucket_water",
- "bucket_water.png"
-)
-
-bucket.register_liquid(
- "default:lava_source",
- "default:lava_flowing",
- "bucket:bucket_lava",
- "bucket_lava.png"
-)
-
-minetest.register_craft({
- type = "fuel",
- recipe = "bucket:bucket_lava",
- burntime = 60,
-})
diff --git a/games/minimal/mods/bucket/textures/bucket.png b/games/minimal/mods/bucket/textures/bucket.png
deleted file mode 100644
index b775a9fd3..000000000
--- a/games/minimal/mods/bucket/textures/bucket.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/bucket/textures/bucket_lava.png b/games/minimal/mods/bucket/textures/bucket_lava.png
deleted file mode 100644
index 889ed61d4..000000000
--- a/games/minimal/mods/bucket/textures/bucket_lava.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/bucket/textures/bucket_water.png b/games/minimal/mods/bucket/textures/bucket_water.png
deleted file mode 100644
index a3c9d72f7..000000000
--- a/games/minimal/mods/bucket/textures/bucket_water.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/init.lua b/games/minimal/mods/default/init.lua
deleted file mode 100644
index bff7860e3..000000000
--- a/games/minimal/mods/default/init.lua
+++ /dev/null
@@ -1,1797 +0,0 @@
--- default (Minetest 0.4 mod)
--- Most default stuff
-
--- The API documentation in here was moved into doc/lua_api.txt
-
-WATER_ALPHA = 160
-WATER_VISC = 1
-LAVA_VISC = 7
-LIGHT_MAX = 14
-
--- Definitions made by this mod that other mods can use too
-default = {}
-
--- Load other files
-dofile(minetest.get_modpath("default").."/mapgen.lua")
-
--- Set a noticeable inventory formspec for players
-minetest.register_on_joinplayer(function(player)
- local cb = function(player)
- minetest.chat_send_player(player:get_player_name(), "This is the [minimal] \"Minimal Development Test\" game. Use [minetest_game] for the real thing.")
- end
- minetest.after(2.0, cb, player)
-end)
-
---
--- Tool definition
---
-
--- The hand
-minetest.register_item(":", {
- type = "none",
- wield_image = "wieldhand.png",
- wield_scale = {x=1,y=1,z=2.5},
- tool_capabilities = {
- full_punch_interval = 1.0,
- max_drop_level = 0,
- groupcaps = {
- fleshy = {times={[2]=2.00, [3]=1.00}, uses=0, maxlevel=1},
- crumbly = {times={[2]=3.00, [3]=0.70}, uses=0, maxlevel=1},
- snappy = {times={[3]=0.40}, uses=0, maxlevel=1},
- oddly_breakable_by_hand = {times={[1]=7.00,[2]=4.00,[3]=1.40}, uses=0, maxlevel=3},
- }
- }
-})
-
-minetest.register_tool("default:pick_wood", {
- description = "Wooden Pickaxe",
- inventory_image = "default_tool_woodpick.png",
- tool_capabilities = {
- max_drop_level=0,
- groupcaps={
- cracky={times={[2]=2.00, [3]=1.20}, uses=10, maxlevel=1}
- }
- },
-})
-minetest.register_tool("default:pick_stone", {
- description = "Stone Pickaxe",
- inventory_image = "default_tool_stonepick.png",
- tool_capabilities = {
- max_drop_level=0,
- groupcaps={
- cracky={times={[1]=2.00, [2]=1.20, [3]=0.80}, uses=20, maxlevel=1}
- }
- },
-})
-minetest.register_tool("default:pick_steel", {
- description = "Steel Pickaxe",
- inventory_image = "default_tool_steelpick.png",
- tool_capabilities = {
- max_drop_level=1,
- groupcaps={
- cracky={times={[1]=4.00, [2]=1.60, [3]=1.00}, uses=10, maxlevel=2}
- }
- },
-})
-minetest.register_tool("default:pick_mese", {
- description = "Mese Pickaxe",
- inventory_image = "default_tool_mesepick.png",
- tool_capabilities = {
- full_punch_interval = 1.0,
- max_drop_level=3,
- groupcaps={
- cracky={times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=20, maxlevel=3},
- crumbly={times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=20, maxlevel=3},
- snappy={times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=20, maxlevel=3}
- }
- },
-})
-minetest.register_tool("default:shovel_wood", {
- description = "Wooden Shovel",
- inventory_image = "default_tool_woodshovel.png",
- tool_capabilities = {
- max_drop_level=0,
- groupcaps={
- crumbly={times={[1]=2.00, [2]=0.80, [3]=0.50}, uses=10, maxlevel=1}
- }
- },
-})
-minetest.register_tool("default:shovel_stone", {
- description = "Stone Shovel",
- inventory_image = "default_tool_stoneshovel.png",
- tool_capabilities = {
- max_drop_level=0,
- groupcaps={
- crumbly={times={[1]=1.20, [2]=0.50, [3]=0.30}, uses=20, maxlevel=1}
- }
- },
-})
-minetest.register_tool("default:shovel_steel", {
- description = "Steel Shovel",
- inventory_image = "default_tool_steelshovel.png",
- tool_capabilities = {
- max_drop_level=1,
- groupcaps={
- crumbly={times={[1]=1.00, [2]=0.70, [3]=0.60}, uses=10, maxlevel=2}
- }
- },
-})
-minetest.register_tool("default:axe_wood", {
- description = "Wooden Axe",
- inventory_image = "default_tool_woodaxe.png",
- tool_capabilities = {
- max_drop_level=0,
- groupcaps={
- choppy={times={[2]=1.40, [3]=0.80}, uses=10, maxlevel=1},
- fleshy={times={[2]=1.50, [3]=0.80}, uses=10, maxlevel=1}
- }
- },
-})
-minetest.register_tool("default:axe_stone", {
- description = "Stone Axe",
- inventory_image = "default_tool_stoneaxe.png",
- tool_capabilities = {
- max_drop_level=0,
- groupcaps={
- choppy={times={[1]=1.50, [2]=1.00, [3]=0.60}, uses=20, maxlevel=1},
- fleshy={times={[2]=1.30, [3]=0.70}, uses=20, maxlevel=1}
- }
- },
-})
-minetest.register_tool("default:axe_steel", {
- description = "Steel Axe",
- inventory_image = "default_tool_steelaxe.png",
- tool_capabilities = {
- max_drop_level=1,
- groupcaps={
- choppy={times={[1]=2.00, [2]=1.60, [3]=1.00}, uses=10, maxlevel=2},
- fleshy={times={[2]=1.10, [3]=0.60}, uses=40, maxlevel=1}
- }
- },
-})
-minetest.register_tool("default:sword_wood", {
- description = "Wooden Sword",
- inventory_image = "default_tool_woodsword.png",
- tool_capabilities = {
- full_punch_interval = 1.0,
- max_drop_level=0,
- groupcaps={
- fleshy={times={[2]=1.10, [3]=0.60}, uses=10, maxlevel=1},
- snappy={times={[2]=1.00, [3]=0.50}, uses=10, maxlevel=1},
- choppy={times={[3]=1.00}, uses=20, maxlevel=0}
- }
- }
-})
-minetest.register_tool("default:sword_stone", {
- description = "Stone Sword",
- inventory_image = "default_tool_stonesword.png",
- tool_capabilities = {
- full_punch_interval = 1.0,
- max_drop_level=0,
- groupcaps={
- fleshy={times={[2]=0.80, [3]=0.40}, uses=20, maxlevel=1},
- snappy={times={[2]=0.80, [3]=0.40}, uses=20, maxlevel=1},
- choppy={times={[3]=0.90}, uses=20, maxlevel=0}
- }
- }
-})
-minetest.register_tool("default:sword_steel", {
- description = "Steel Sword",
- inventory_image = "default_tool_steelsword.png",
- tool_capabilities = {
- full_punch_interval = 1.0,
- max_drop_level=1,
- groupcaps={
- fleshy={times={[1]=2.00, [2]=0.80, [3]=0.40}, uses=10, maxlevel=2},
- snappy={times={[2]=0.70, [3]=0.30}, uses=40, maxlevel=1},
- choppy={times={[3]=0.70}, uses=40, maxlevel=0}
- }
- }
-})
-
---
--- Crafting definition
---
-
-minetest.register_craft({
- output = 'default:wood 4',
- recipe = {
- {'default:tree'},
- }
-})
-
-minetest.register_craft({
- output = 'default:stick 4',
- recipe = {
- {'default:wood'},
- }
-})
-
-minetest.register_craft({
- output = 'default:fence_wood 2',
- recipe = {
- {'default:stick', 'default:stick', 'default:stick'},
- {'default:stick', 'default:stick', 'default:stick'},
- }
-})
-
-minetest.register_craft({
- output = 'default:sign_wall',
- recipe = {
- {'default:wood', 'default:wood', 'default:wood'},
- {'default:wood', 'default:wood', 'default:wood'},
- {'', 'default:stick', ''},
- }
-})
-
-minetest.register_craft({
- output = 'default:torch 4',
- recipe = {
- {'default:coal_lump'},
- {'default:stick'},
- }
-})
-
-minetest.register_craft({
- output = 'default:pick_wood',
- recipe = {
- {'default:wood', 'default:wood', 'default:wood'},
- {'', 'default:stick', ''},
- {'', 'default:stick', ''},
- }
-})
-
-minetest.register_craft({
- output = 'default:pick_stone',
- recipe = {
- {'default:cobble', 'default:cobble', 'default:cobble'},
- {'', 'default:stick', ''},
- {'', 'default:stick', ''},
- }
-})
-
-minetest.register_craft({
- output = 'default:pick_steel',
- recipe = {
- {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
- {'', 'default:stick', ''},
- {'', 'default:stick', ''},
- }
-})
-
-minetest.register_craft({
- output = 'default:pick_mese',
- recipe = {
- {'default:mese', 'default:mese', 'default:mese'},
- {'', 'default:stick', ''},
- {'', 'default:stick', ''},
- }
-})
-
-minetest.register_craft({
- output = 'default:shovel_wood',
- recipe = {
- {'default:wood'},
- {'default:stick'},
- {'default:stick'},
- }
-})
-
-minetest.register_craft({
- output = 'default:shovel_stone',
- recipe = {
- {'default:cobble'},
- {'default:stick'},
- {'default:stick'},
- }
-})
-
-minetest.register_craft({
- output = 'default:shovel_steel',
- recipe = {
- {'default:steel_ingot'},
- {'default:stick'},
- {'default:stick'},
- }
-})
-
-minetest.register_craft({
- output = 'default:axe_wood',
- recipe = {
- {'default:wood', 'default:wood'},
- {'default:wood', 'default:stick'},
- {'', 'default:stick'},
- }
-})
-
-minetest.register_craft({
- output = 'default:axe_stone',
- recipe = {
- {'default:cobble', 'default:cobble'},
- {'default:cobble', 'default:stick'},
- {'', 'default:stick'},
- }
-})
-
-minetest.register_craft({
- output = 'default:axe_steel',
- recipe = {
- {'default:steel_ingot', 'default:steel_ingot'},
- {'default:steel_ingot', 'default:stick'},
- {'', 'default:stick'},
- }
-})
-
-minetest.register_craft({
- output = 'default:sword_wood',
- recipe = {
- {'default:wood'},
- {'default:wood'},
- {'default:stick'},
- }
-})
-
-minetest.register_craft({
- output = 'default:sword_stone',
- recipe = {
- {'default:cobble'},
- {'default:cobble'},
- {'default:stick'},
- }
-})
-
-minetest.register_craft({
- output = 'default:sword_steel',
- recipe = {
- {'default:steel_ingot'},
- {'default:steel_ingot'},
- {'default:stick'},
- }
-})
-
-minetest.register_craft({
- output = 'default:rail 15',
- recipe = {
- {'default:steel_ingot', '', 'default:steel_ingot'},
- {'default:steel_ingot', 'default:stick', 'default:steel_ingot'},
- {'default:steel_ingot', '', 'default:steel_ingot'},
- }
-})
-
-minetest.register_craft({
- output = 'default:chest',
- recipe = {
- {'default:wood', 'default:wood', 'default:wood'},
- {'default:wood', '', 'default:wood'},
- {'default:wood', 'default:wood', 'default:wood'},
- }
-})
-
-minetest.register_craft({
- output = 'default:chest_locked',
- recipe = {
- {'default:wood', 'default:wood', 'default:wood'},
- {'default:wood', 'default:steel_ingot', 'default:wood'},
- {'default:wood', 'default:wood', 'default:wood'},
- }
-})
-
-minetest.register_craft({
- output = 'default:furnace',
- recipe = {
- {'default:cobble', 'default:cobble', 'default:cobble'},
- {'default:cobble', '', 'default:cobble'},
- {'default:cobble', 'default:cobble', 'default:cobble'},
- }
-})
-
-minetest.register_craft({
- output = 'default:steelblock',
- recipe = {
- {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
- {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
- {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
- }
-})
-
-minetest.register_craft({
- output = 'default:sandstone',
- recipe = {
- {'default:sand', 'default:sand'},
- {'default:sand', 'default:sand'},
- }
-})
-
-minetest.register_craft({
- output = 'default:clay',
- recipe = {
- {'default:clay_lump', 'default:clay_lump'},
- {'default:clay_lump', 'default:clay_lump'},
- }
-})
-
-minetest.register_craft({
- output = 'default:brick',
- recipe = {
- {'default:clay_brick', 'default:clay_brick'},
- {'default:clay_brick', 'default:clay_brick'},
- }
-})
-
-minetest.register_craft({
- output = 'default:paper',
- recipe = {
- {'default:papyrus', 'default:papyrus', 'default:papyrus'},
- }
-})
-
-minetest.register_craft({
- output = 'default:book',
- recipe = {
- {'default:paper'},
- {'default:paper'},
- {'default:paper'},
- }
-})
-
-minetest.register_craft({
- output = 'default:bookshelf',
- recipe = {
- {'default:wood', 'default:wood', 'default:wood'},
- {'default:book', 'default:book', 'default:book'},
- {'default:wood', 'default:wood', 'default:wood'},
- }
-})
-
-minetest.register_craft({
- output = 'default:ladder',
- recipe = {
- {'default:stick', '', 'default:stick'},
- {'default:stick', 'default:stick', 'default:stick'},
- {'default:stick', '', 'default:stick'},
- }
-})
-
--- Tool repair
-minetest.register_craft({
- type = "toolrepair",
- additional_wear = -0.02,
-})
-
---
--- Cooking recipes
---
-
-minetest.register_craft({
- type = "cooking",
- output = "default:glass",
- recipe = "default:sand",
-})
-
-minetest.register_craft({
- type = "cooking",
- output = "default:coal_lump",
- recipe = "default:tree",
-})
-
-minetest.register_craft({
- type = "cooking",
- output = "default:stone",
- recipe = "default:cobble",
-})
-
-minetest.register_craft({
- type = "cooking",
- output = "default:steel_ingot",
- recipe = "default:iron_lump",
-})
-
-minetest.register_craft({
- type = "cooking",
- output = "default:clay_brick",
- recipe = "default:clay_lump",
-})
-
---
--- Fuels
---
-
-minetest.register_craft({
- type = "fuel",
- recipe = "default:tree",
- burntime = 30,
-})
-
-minetest.register_craft({
- type = "fuel",
- recipe = "default:junglegrass",
- burntime = 2,
-})
-
-minetest.register_craft({
- type = "fuel",
- recipe = "default:leaves",
- burntime = 1,
-})
-
-minetest.register_craft({
- type = "fuel",
- recipe = "default:cactus",
- burntime = 15,
-})
-
-minetest.register_craft({
- type = "fuel",
- recipe = "default:papyrus",
- burntime = 1,
-})
-
-minetest.register_craft({
- type = "fuel",
- recipe = "default:bookshelf",
- burntime = 30,
-})
-
-minetest.register_craft({
- type = "fuel",
- recipe = "default:fence_wood",
- burntime = 15,
-})
-
-minetest.register_craft({
- type = "fuel",
- recipe = "default:ladder",
- burntime = 5,
-})
-
-minetest.register_craft({
- type = "fuel",
- recipe = "default:wood",
- burntime = 7,
-})
-
-minetest.register_craft({
- type = "fuel",
- recipe = "default:mese",
- burntime = 30,
-})
-
-minetest.register_craft({
- type = "fuel",
- recipe = "default:lava_source",
- burntime = 60,
-})
-
-minetest.register_craft({
- type = "fuel",
- recipe = "default:torch",
- burntime = 4,
-})
-
-minetest.register_craft({
- type = "fuel",
- recipe = "default:sign_wall",
- burntime = 10,
-})
-
-minetest.register_craft({
- type = "fuel",
- recipe = "default:chest",
- burntime = 30,
-})
-
-minetest.register_craft({
- type = "fuel",
- recipe = "default:chest_locked",
- burntime = 30,
-})
-
-minetest.register_craft({
- type = "fuel",
- recipe = "default:nyancat",
- burntime = 1,
-})
-
-minetest.register_craft({
- type = "fuel",
- recipe = "default:nyancat_rainbow",
- burntime = 1,
-})
-
-minetest.register_craft({
- type = "fuel",
- recipe = "default:sapling",
- burntime = 10,
-})
-
-minetest.register_craft({
- type = "fuel",
- recipe = "default:apple",
- burntime = 3,
-})
-
-minetest.register_craft({
- type = "fuel",
- recipe = "default:coal_lump",
- burntime = 40,
-})
-
---
--- Node definitions
---
-
--- Default node sounds
-
-function default.node_sound_defaults(table)
- table = table or {}
- table.footstep = table.footstep or
- {name="", gain=1.0}
- table.dug = table.dug or
- {name="default_dug_node", gain=1.0}
- return table
-end
-
-function default.node_sound_stone_defaults(table)
- table = table or {}
- table.footstep = table.footstep or
- {name="default_hard_footstep", gain=0.2}
- default.node_sound_defaults(table)
- return table
-end
-
-function default.node_sound_dirt_defaults(table)
- table = table or {}
- table.footstep = table.footstep or
- {name="", gain=0.5}
- --table.dug = table.dug or
- -- {name="default_dirt_break", gain=0.5}
- table.place = table.place or
- {name="default_grass_footstep", gain=0.5}
- default.node_sound_defaults(table)
- return table
-end
-
-function default.node_sound_sand_defaults(table)
- table = table or {}
- table.footstep = table.footstep or
- {name="default_grass_footstep", gain=0.25}
- --table.dug = table.dug or
- -- {name="default_dirt_break", gain=0.25}
- table.dug = table.dug or
- {name="", gain=0.25}
- default.node_sound_defaults(table)
- return table
-end
-
-function default.node_sound_wood_defaults(table)
- table = table or {}
- table.footstep = table.footstep or
- {name="default_hard_footstep", gain=0.3}
- default.node_sound_defaults(table)
- return table
-end
-
-function default.node_sound_leaves_defaults(table)
- table = table or {}
- table.footstep = table.footstep or
- {name="default_grass_footstep", gain=0.25}
- table.dig = table.dig or
- {name="default_dig_crumbly", gain=0.4}
- table.dug = table.dug or
- {name="", gain=1.0}
- default.node_sound_defaults(table)
- return table
-end
-
-function default.node_sound_glass_defaults(table)
- table = table or {}
- table.footstep = table.footstep or
- {name="default_stone_footstep", gain=0.25}
- table.dug = table.dug or
- {name="default_break_glass", gain=1.0}
- default.node_sound_defaults(table)
- return table
-end
-
--- Register nodes
-
-minetest.register_node("default:stone", {
- description = "Stone",
- tiles ={"default_stone.png"},
- groups = {cracky=3},
- drop = 'default:cobble',
- legacy_mineral = true,
- sounds = default.node_sound_stone_defaults(),
-})
-
-minetest.register_node("default:stone_with_coal", {
- description = "Stone with coal",
- tiles ={"default_stone.png^default_mineral_coal.png"},
- groups = {cracky=3},
- drop = 'default:coal_lump',
- sounds = default.node_sound_stone_defaults(),
-})
-
-minetest.register_node("default:stone_with_iron", {
- description = "Stone with iron",
- tiles ={"default_stone.png^default_mineral_iron.png"},
- groups = {cracky=3},
- drop = 'default:iron_lump',
- sounds = default.node_sound_stone_defaults(),
-})
-
-minetest.register_node("default:dirt_with_grass", {
- description = "Dirt with grass",
- tiles ={"default_grass.png", "default_dirt.png",
- {name = "default_dirt.png^default_grass_side.png",
- tileable_vertical = false}},
- groups = {crumbly=3, soil=1},
- drop = 'default:dirt',
- sounds = default.node_sound_dirt_defaults({
- footstep = {name="default_grass_footstep", gain=0.4},
- }),
-})
-
-minetest.register_node("default:dirt_with_grass_footsteps", {
- description = "Dirt with grass and footsteps",
- tiles ={"default_grass_footsteps.png", "default_dirt.png",
- {name = "default_dirt.png^default_grass_side.png",
- tileable_vertical = false}},
- groups = {crumbly=3, soil=1},
- drop = 'default:dirt',
- sounds = default.node_sound_dirt_defaults({
- footstep = {name="default_grass_footstep", gain=0.4},
- }),
-})
-
-minetest.register_node("default:dirt", {
- description = "Dirt",
- tiles ={"default_dirt.png"},
- groups = {crumbly=3, soil=1},
- sounds = default.node_sound_dirt_defaults(),
-})
-
-minetest.register_node("default:sand", {
- description = "Sand",
- tiles ={"default_sand.png"},
- groups = {crumbly=3, falling_node=1},
- sounds = default.node_sound_sand_defaults(),
-})
-
-minetest.register_node("default:gravel", {
- description = "Gravel",
- tiles ={"default_gravel.png"},
- groups = {crumbly=2, falling_node=1},
- sounds = default.node_sound_dirt_defaults({
- footstep = {name="default_gravel_footstep", gain=0.45},
- }),
-})
-
-minetest.register_node("default:sandstone", {
- description = "Sandstone",
- tiles ={"default_sandstone.png"},
- groups = {crumbly=2,cracky=2},
- drop = 'default:sand',
- sounds = default.node_sound_stone_defaults(),
-})
-
-minetest.register_node("default:clay", {
- description = "Clay",
- tiles ={"default_clay.png"},
- groups = {crumbly=3},
- drop = 'default:clay_lump 4',
- sounds = default.node_sound_dirt_defaults({
- footstep = "",
- }),
-})
-
-minetest.register_node("default:brick", {
- description = "Brick",
- tiles ={"default_brick.png"},
- is_ground_content = false,
- groups = {cracky=3},
- drop = 'default:clay_brick 4',
- sounds = default.node_sound_stone_defaults(),
-})
-
-minetest.register_node("default:tree", {
- description = "Tree",
- tiles ={"default_tree_top.png", "default_tree_top.png", "default_tree.png"},
- is_ground_content = false,
- groups = {snappy=2,choppy=2,oddly_breakable_by_hand=1},
- sounds = default.node_sound_wood_defaults(),
-})
-
-minetest.register_node("default:junglegrass", {
- description = "Jungle Grass",
- drawtype = "plantlike",
- visual_scale = 1.3,
- tiles ={"default_junglegrass.png"},
- inventory_image = "default_junglegrass.png",
- wield_image = "default_junglegrass.png",
- paramtype = "light",
- walkable = false,
- groups = {snappy=3,attached_node=1},
- sounds = default.node_sound_leaves_defaults(),
-})
-
-minetest.register_node("default:leaves", {
- description = "Leaves",
- drawtype = "allfaces_optional",
- visual_scale = 1.3,
- tiles ={"default_leaves.png"},
- paramtype = "light",
- is_ground_content = false,
- groups = {snappy=3},
- drop = {
- max_items = 1,
- items = {
- {
- -- player will get sapling with 1/20 chance
- items = {'default:sapling'},
- rarity = 20,
- },
- {
- -- player will get leaves only if he get no saplings,
- -- this is because max_items is 1
- items = {'default:leaves'},
- }
- }
- },
- sounds = default.node_sound_leaves_defaults(),
-})
-
-minetest.register_node("default:cactus", {
- description = "Cactus",
- tiles ={"default_cactus_top.png", "default_cactus_top.png", "default_cactus_side.png"},
- groups = {snappy=2,choppy=3},
- sounds = default.node_sound_wood_defaults(),
-})
-
-minetest.register_node("default:papyrus", {
- description = "Papyrus",
- drawtype = "plantlike",
- tiles ={"default_papyrus.png"},
- inventory_image = "default_papyrus.png",
- wield_image = "default_papyrus.png",
- paramtype = "light",
- walkable = false,
- groups = {snappy=3},
- sounds = default.node_sound_leaves_defaults(),
-})
-
-minetest.register_node("default:bookshelf", {
- description = "Bookshelf",
- tiles ={"default_wood.png", "default_wood.png", "default_bookshelf.png"},
- is_ground_content = false,
- groups = {snappy=2,choppy=3,oddly_breakable_by_hand=2},
- sounds = default.node_sound_wood_defaults(),
-})
-
-minetest.register_node("default:glass", {
- description = "Glass",
- drawtype = "glasslike",
- tiles ={"default_glass.png"},
- paramtype = "light",
- is_ground_content = false,
- sunlight_propagates = true,
- groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
- sounds = default.node_sound_glass_defaults(),
-})
-
-minetest.register_node("default:fence_wood", {
- description = "Wooden Fence",
- drawtype = "fencelike",
- tiles ={"default_wood.png"},
- inventory_image = "default_fence.png",
- wield_image = "default_fence.png",
- paramtype = "light",
- is_ground_content = false,
- 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},
- sounds = default.node_sound_wood_defaults(),
-})
-
-minetest.register_node("default:rail", {
- description = "Rail",
- drawtype = "raillike",
- tiles ={"default_rail.png", "default_rail_curved.png", "default_rail_t_junction.png", "default_rail_crossing.png"},
- inventory_image = "default_rail.png",
- wield_image = "default_rail.png",
- paramtype = "light",
- is_ground_content = false,
- walkable = false,
- selection_box = {
- type = "fixed",
- fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
- },
- groups = {bendy=2,snappy=1,dig_immediate=2},
-})
-
-minetest.register_node("default:ladder", {
- description = "Ladder",
- drawtype = "signlike",
- tiles ={"default_ladder.png"},
- inventory_image = "default_ladder.png",
- wield_image = "default_ladder.png",
- paramtype = "light",
- paramtype2 = "wallmounted",
- is_ground_content = false,
- walkable = false,
- climbable = true,
- selection_box = {
- type = "wallmounted",
- --wall_top = = <default>
- --wall_bottom = = <default>
- --wall_side = = <default>
- },
- groups = {snappy=2,choppy=2,oddly_breakable_by_hand=3},
- legacy_wallmounted = true,
- sounds = default.node_sound_wood_defaults(),
-})
-
-minetest.register_node("default:wood", {
- description = "Wood",
- tiles ={"default_wood.png"},
- is_ground_content = false,
- groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
- sounds = default.node_sound_wood_defaults(),
-})
-
-minetest.register_node("default:mese", {
- description = "Mese",
- tiles ={"default_mese.png"},
- groups = {cracky=1,level=2},
- sounds = default.node_sound_defaults(),
-})
-
-minetest.register_node("default:cloud", {
- description = "Cloud",
- tiles ={"default_cloud.png"},
- is_ground_content = false,
- sounds = default.node_sound_defaults(),
-})
-
-minetest.register_node("default:water_flowing", {
- description = "Water (flowing)",
- inventory_image = minetest.inventorycube("default_water.png"),
- drawtype = "flowingliquid",
- tiles ={"default_water.png"},
- special_tiles = {
- {name="default_water.png", backface_culling=false},
- {name="default_water.png", backface_culling=true},
- },
- alpha = WATER_ALPHA,
- paramtype = "light",
- walkable = false,
- pointable = false,
- diggable = false,
- buildable_to = true,
- is_ground_content = false,
- drowning = 1,
- liquidtype = "flowing",
- liquid_alternative_flowing = "default:water_flowing",
- liquid_alternative_source = "default:water_source",
- liquid_viscosity = WATER_VISC,
- post_effect_color = {a=64, r=100, g=100, b=200},
- groups = {water=3, liquid=3},
-})
-
-minetest.register_node("default:water_source", {
- description = "Water",
- inventory_image = minetest.inventorycube("default_water.png"),
- drawtype = "liquid",
- tiles ={"default_water.png"},
- special_tiles = {
- -- New-style water source material (mostly unused)
- {name="default_water.png", backface_culling=false},
- },
- alpha = WATER_ALPHA,
- paramtype = "light",
- walkable = false,
- pointable = false,
- diggable = false,
- buildable_to = true,
- is_ground_content = false,
- drowning = 1,
- liquidtype = "source",
- liquid_alternative_flowing = "default:water_flowing",
- liquid_alternative_source = "default:water_source",
- liquid_viscosity = WATER_VISC,
- post_effect_color = {a=64, r=100, g=100, b=200},
- groups = {water=3, liquid=3},
-})
-
-minetest.register_node("default:lava_flowing", {
- description = "Lava (flowing)",
- inventory_image = minetest.inventorycube("default_lava.png"),
- drawtype = "flowingliquid",
- tiles ={"default_lava.png"},
- special_tiles = {
- {
- image="default_lava_flowing_animated.png",
- backface_culling=false,
- animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
- },
- {
- image="default_lava_flowing_animated.png",
- backface_culling=true,
- animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
- },
- },
- paramtype = "light",
- light_source = LIGHT_MAX - 1,
- walkable = false,
- pointable = false,
- diggable = false,
- buildable_to = true,
- is_ground_content = false,
- drowning = 1,
- liquidtype = "flowing",
- liquid_alternative_flowing = "default:lava_flowing",
- liquid_alternative_source = "default:lava_source",
- liquid_viscosity = LAVA_VISC,
- damage_per_second = 4*2,
- post_effect_color = {a=192, r=255, g=64, b=0},
- groups = {lava=3, liquid=2, hot=3},
-})
-
-minetest.register_node("default:lava_source", {
- description = "Lava",
- inventory_image = minetest.inventorycube("default_lava.png"),
- drawtype = "liquid",
- --tiles ={"default_lava.png"},
- tiles ={
- {name="default_lava_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}}
- },
- special_tiles = {
- -- New-style lava source material (mostly unused)
- {name="default_lava.png", backface_culling=false},
- },
- paramtype = "light",
- light_source = LIGHT_MAX - 1,
- walkable = false,
- pointable = false,
- diggable = false,
- buildable_to = true,
- is_ground_content = false,
- drowning = 1,
- liquidtype = "source",
- liquid_alternative_flowing = "default:lava_flowing",
- liquid_alternative_source = "default:lava_source",
- liquid_viscosity = LAVA_VISC,
- damage_per_second = 4*2,
- post_effect_color = {a=192, r=255, g=64, b=0},
- groups = {lava=3, liquid=2, hot=3},
-})
-
-minetest.register_node("default:torch", {
- description = "Torch",
- drawtype = "torchlike",
- tiles ={"default_torch_on_floor.png", "default_torch_on_ceiling.png", "default_torch.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,attached_node=1},
- legacy_wallmounted = true,
- sounds = default.node_sound_defaults(),
-})
-
-minetest.register_node("default:sign_wall", {
- description = "Sign",
- drawtype = "signlike",
- tiles ={"default_sign_wall.png"},
- inventory_image = "default_sign_wall.png",
- wield_image = "default_sign_wall.png",
- paramtype = "light",
- paramtype2 = "wallmounted",
- sunlight_propagates = true,
- is_ground_content = false,
- walkable = false,
- selection_box = {
- type = "wallmounted",
- --wall_top = <default>
- --wall_bottom = <default>
- --wall_side = <default>
- },
- groups = {choppy=2,dig_immediate=2,attached_node=1},
- legacy_wallmounted = true,
- sounds = default.node_sound_defaults(),
- on_construct = function(pos)
- --local n = minetest.get_node(pos)
- local meta = minetest.get_meta(pos)
- meta:set_string("formspec", "field[text;;${text}]")
- meta:set_string("infotext", "\"\"")
- end,
- on_receive_fields = function(pos, formname, fields, sender)
- --print("Sign at "..minetest.pos_to_string(pos).." got "..dump(fields))
- local meta = minetest.get_meta(pos)
- fields.text = fields.text or ""
- print((sender:get_player_name() or "").." wrote \""..fields.text..
- "\" to sign at "..minetest.pos_to_string(pos))
- meta:set_string("text", fields.text)
- meta:set_string("infotext", '"'..fields.text..'"')
- end,
-})
-
-minetest.register_node("default:chest", {
- description = "Chest",
- tiles ={"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
- "default_chest_side.png", "default_chest_side.png", "default_chest_front.png"},
- paramtype2 = "facedir",
- groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
- legacy_facedir_simple = true,
- is_ground_content = false,
- sounds = default.node_sound_wood_defaults(),
- on_construct = function(pos)
- local meta = minetest.get_meta(pos)
- meta:set_string("formspec",
- "size[8,9]"..
- "list[current_name;main;0,0;8,4;]"..
- "list[current_player;main;0,5;8,4;]" ..
- "listring[]")
- meta:set_string("infotext", "Chest")
- local inv = meta:get_inventory()
- inv:set_size("main", 8*4)
- end,
- can_dig = function(pos,player)
- local meta = minetest.get_meta(pos);
- local inv = meta:get_inventory()
- return inv:is_empty("main")
- end,
-})
-
-local function has_locked_chest_privilege(meta, player)
- if player:get_player_name() ~= meta:get_string("owner") then
- return false
- end
- return true
-end
-
-minetest.register_node("default:chest_locked", {
- description = "Locked Chest",
- tiles ={"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
- "default_chest_side.png", "default_chest_side.png", "default_chest_lock.png"},
- paramtype2 = "facedir",
- groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
- legacy_facedir_simple = true,
- is_ground_content = false,
- sounds = default.node_sound_wood_defaults(),
- after_place_node = function(pos, placer)
- local meta = minetest.get_meta(pos)
- meta:set_string("owner", placer:get_player_name() or "")
- meta:set_string("infotext", "Locked Chest (owned by "..
- meta:get_string("owner")..")")
- end,
- on_construct = function(pos)
- local meta = minetest.get_meta(pos)
- meta:set_string("formspec",
- "size[8,9]"..
- "list[current_name;main;0,0;8,4;]"..
- "list[current_player;main;0,5;8,4;]" ..
- "listring[]")
- meta:set_string("infotext", "Locked Chest")
- meta:set_string("owner", "")
- local inv = meta:get_inventory()
- inv:set_size("main", 8*4)
- end,
- can_dig = function(pos,player)
- local meta = minetest.get_meta(pos);
- local inv = meta:get_inventory()
- return inv:is_empty("main")
- end,
- allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
- local meta = minetest.get_meta(pos)
- if not has_locked_chest_privilege(meta, player) then
- minetest.log("action", player:get_player_name()..
- " tried to access a locked chest belonging to "..
- meta:get_string("owner").." at "..
- minetest.pos_to_string(pos))
- return 0
- end
- return count
- end,
- allow_metadata_inventory_put = function(pos, listname, index, stack, player)
- local meta = minetest.get_meta(pos)
- if not has_locked_chest_privilege(meta, player) then
- minetest.log("action", player:get_player_name()..
- " tried to access a locked chest belonging to "..
- meta:get_string("owner").." at "..
- minetest.pos_to_string(pos))
- return 0
- end
- return stack:get_count()
- end,
- allow_metadata_inventory_take = function(pos, listname, index, stack, player)
- local meta = minetest.get_meta(pos)
- if not has_locked_chest_privilege(meta, player) then
- minetest.log("action", player:get_player_name()..
- " tried to access a locked chest belonging to "..
- meta:get_string("owner").." at "..
- minetest.pos_to_string(pos))
- return 0
- end
- return stack:get_count()
- end,
- on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
- minetest.log("action", player:get_player_name()..
- " moves stuff in locked chest at "..minetest.pos_to_string(pos))
- end,
- on_metadata_inventory_put = function(pos, listname, index, stack, player)
- minetest.log("action", player:get_player_name()..
- " moves stuff to locked chest at "..minetest.pos_to_string(pos))
- end,
- on_metadata_inventory_take = function(pos, listname, index, stack, player)
- minetest.log("action", player:get_player_name()..
- " takes stuff from locked chest at "..minetest.pos_to_string(pos))
- end,
-})
-
-default.furnace_inactive_formspec =
- "size[8,9]"..
- "image[2,2;1,1;default_furnace_fire_bg.png]"..
- "list[current_name;fuel;2,3;1,1;]"..
- "list[current_name;src;2,1;1,1;]"..
- "list[current_name;dst;5,1;2,2;]"..
- "list[current_player;main;0,5;8,4;]" ..
- "listring[current_name;dst]" ..
- "listring[current_player;main]" ..
- "listring[current_name;src]" ..
- "listring[current_player;main]"
-
-minetest.register_node("default:furnace", {
- description = "Furnace",
- tiles ={"default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png",
- "default_furnace_side.png", "default_furnace_side.png", "default_furnace_front.png"},
- paramtype2 = "facedir",
- groups = {cracky=2},
- legacy_facedir_simple = true,
- is_ground_content = false,
- sounds = default.node_sound_stone_defaults(),
- on_construct = function(pos)
- local meta = minetest.get_meta(pos)
- meta:set_string("formspec", default.furnace_inactive_formspec)
- meta:set_string("infotext", "Furnace")
- local inv = meta:get_inventory()
- inv:set_size("fuel", 1)
- inv:set_size("src", 1)
- inv:set_size("dst", 4)
- end,
- can_dig = function(pos,player)
- local meta = minetest.get_meta(pos);
- local inv = meta:get_inventory()
- if not inv:is_empty("fuel") then
- return false
- elseif not inv:is_empty("dst") then
- return false
- elseif not inv:is_empty("src") then
- return false
- end
- return true
- end,
-})
-
-minetest.register_node("default:furnace_active", {
- description = "Furnace",
- tiles ={"default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png",
- "default_furnace_side.png", "default_furnace_side.png", "default_furnace_front_active.png"},
- paramtype2 = "facedir",
- light_source = 8,
- drop = "default:furnace",
- groups = {cracky=2},
- legacy_facedir_simple = true,
- is_ground_content = false,
- sounds = default.node_sound_stone_defaults(),
- on_construct = function(pos)
- local meta = minetest.get_meta(pos)
- meta:set_string("formspec", default.furnace_inactive_formspec)
- meta:set_string("infotext", "Furnace");
- local inv = meta:get_inventory()
- inv:set_size("fuel", 1)
- inv:set_size("src", 1)
- inv:set_size("dst", 4)
- end,
- can_dig = function(pos,player)
- local meta = minetest.get_meta(pos);
- local inv = meta:get_inventory()
- if not inv:is_empty("fuel") then
- return false
- elseif not inv:is_empty("dst") then
- return false
- elseif not inv:is_empty("src") then
- return false
- end
- return true
- end,
-})
-
-function swap_node(pos,name)
- local node = minetest.get_node(pos)
- if node.name == name then
- return
- end
- node.name = name
- minetest.swap_node(pos, node)
-end
-
-minetest.register_abm({
- nodenames = {"default:furnace","default:furnace_active"},
- interval = 1.0,
- chance = 1,
- action = function(pos, node, active_object_count, active_object_count_wider)
- local meta = minetest.get_meta(pos)
- for i, name in ipairs({
- "fuel_totaltime",
- "fuel_time",
- "src_totaltime",
- "src_time"
- }) do
- if meta:get_string(name) == "" then
- meta:set_float(name, 0.0)
- end
- end
-
- local inv = meta:get_inventory()
-
- local srclist = inv:get_list("src")
- local cooked = nil
-
- if srclist then
- cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
- end
-
- local was_active = false
-
- if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
- was_active = true
- meta:set_float("fuel_time", meta:get_float("fuel_time") + 1)
- meta:set_float("src_time", meta:get_float("src_time") + 1)
- if cooked and cooked.item and meta:get_float("src_time") >= cooked.time then
- -- check if there's room for output in "dst" list
- if inv:room_for_item("dst",cooked.item) then
- -- Put result in "dst" list
- inv:add_item("dst", cooked.item)
- -- take stuff from "src" list
- srcstack = inv:get_stack("src", 1)
- srcstack:take_item()
- inv:set_stack("src", 1, srcstack)
- else
- print("Could not insert '"..cooked.item:to_string().."'")
- end
- meta:set_string("src_time", 0)
- end
- end
-
- if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
- local percent = math.floor(meta:get_float("fuel_time") /
- meta:get_float("fuel_totaltime") * 100)
- meta:set_string("infotext","Furnace active: "..percent.."%")
- swap_node(pos,"default:furnace_active")
- meta:set_string("formspec",
- "size[8,9]"..
- "image[2,2;1,1;default_furnace_fire_bg.png^[lowpart:"..
- (100-percent)..":default_furnace_fire_fg.png]"..
- "list[current_name;fuel;2,3;1,1;]"..
- "list[current_name;src;2,1;1,1;]"..
- "list[current_name;dst;5,1;2,2;]"..
- "list[current_player;main;0,5;8,4;]" ..
- "listring[current_name;dst]" ..
- "listring[current_player;main]" ..
- "listring[current_name;src]" ..
- "listring[current_player;main]")
- return
- end
-
- local fuel = nil
- local cooked = nil
- local fuellist = inv:get_list("fuel")
- local srclist = inv:get_list("src")
-
- if srclist then
- cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
- end
- if fuellist then
- fuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
- end
-
- if fuel.time <= 0 then
- meta:set_string("infotext","Furnace out of fuel")
- swap_node(pos,"default:furnace")
- meta:set_string("formspec", default.furnace_inactive_formspec)
- return
- end
-
- if cooked.item:is_empty() then
- if was_active then
- meta:set_string("infotext","Furnace is empty")
- swap_node(pos,"default:furnace")
- meta:set_string("formspec", default.furnace_inactive_formspec)
- end
- return
- end
-
- meta:set_string("fuel_totaltime", fuel.time)
- meta:set_string("fuel_time", 0)
-
- local stack = inv:get_stack("fuel", 1)
- stack:take_item()
- inv:set_stack("fuel", 1, stack)
- end,
-})
-
-minetest.register_node("default:cobble", {
- description = "Cobble",
- tiles ={"default_cobble.png"},
- is_ground_content = false,
- groups = {cracky=3},
- sounds = default.node_sound_stone_defaults(),
-})
-
-minetest.register_node("default:mossycobble", {
- description = "Mossy Cobble",
- tiles ={"default_mossycobble.png"},
- is_ground_content = false,
- groups = {cracky=3},
- sounds = default.node_sound_stone_defaults(),
-})
-
-minetest.register_node("default:steelblock", {
- description = "Steel Block",
- tiles ={"default_steel_block.png"},
- is_ground_content = false,
- groups = {snappy=1,bendy=2},
- sounds = default.node_sound_stone_defaults(),
-})
-
-minetest.register_node("default:nyancat", {
- description = "Nyancat",
- tiles ={"default_nc_side.png", "default_nc_side.png", "default_nc_side.png",
- "default_nc_side.png", "default_nc_back.png", "default_nc_front.png"},
- inventory_image = "default_nc_front.png",
- paramtype2 = "facedir",
- groups = {cracky=2},
- legacy_facedir_simple = true,
- is_ground_content = false,
- sounds = default.node_sound_defaults(),
-})
-
-minetest.register_node("default:nyancat_rainbow", {
- description = "Nyancat Rainbow",
- tiles ={"default_nc_rb.png"},
- inventory_image = "default_nc_rb.png",
- is_ground_content = false,
- groups = {cracky=2},
- sounds = default.node_sound_defaults(),
-})
-
-minetest.register_node("default:sapling", {
- description = "Sapling",
- drawtype = "plantlike",
- visual_scale = 1.0,
- tiles ={"default_sapling.png"},
- inventory_image = "default_sapling.png",
- wield_image = "default_sapling.png",
- paramtype = "light",
- walkable = false,
- groups = {snappy=2,dig_immediate=3,attached_node=1},
- sounds = default.node_sound_defaults(),
-})
-
-minetest.register_node("default:apple", {
- description = "Apple",
- drawtype = "plantlike",
- visual_scale = 1.0,
- tiles ={"default_apple.png"},
- inventory_image = "default_apple.png",
- paramtype = "light",
- is_ground_content = false,
- sunlight_propagates = true,
- walkable = false,
- groups = {fleshy=3,dig_immediate=3},
- on_use = minetest.item_eat(4),
- sounds = default.node_sound_defaults(),
-})
-
---
--- Grow tree function
---
-
-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_apple = minetest.get_content_id("default:apple")
-function default.grow_tree(data, a, pos, is_apple_tree, seed)
- --[[
- NOTE: Tree-placing code is currently duplicated in the engine
- and in games that have saplings; both are deprecated but not
- replaced yet
- ]]--
- local pr = PseudoRandom(seed)
- local th = pr:next(4, 5)
- local x, y, z = pos.x, pos.y, pos.z
- for yy = y, y+th-1 do
- local vi = a:index(x, yy, z)
- if a:contains(x, yy, z) and (data[vi] == c_air or yy == y) then
- data[vi] = c_tree
- end
- end
- y = y+th-1 -- (x, y, z) is now last piece of trunk
- local leaves_a = VoxelArea:new{MinEdge={x=-2, y=-1, z=-2}, MaxEdge={x=2, y=2, z=2}}
- local leaves_buffer = {}
-
- -- Force leaves near the trunk
- local d = 1
- for xi = -d, d do
- for yi = -d, d do
- for zi = -d, d do
- leaves_buffer[leaves_a:index(xi, yi, zi)] = true
- end
- end
- end
-
- -- Add leaves randomly
- for iii = 1, 8 do
- local d = 1
- local xx = pr:next(leaves_a.MinEdge.x, leaves_a.MaxEdge.x - d)
- local yy = pr:next(leaves_a.MinEdge.y, leaves_a.MaxEdge.y - d)
- local zz = pr:next(leaves_a.MinEdge.z, leaves_a.MaxEdge.z - d)
-
- for xi = 0, d do
- for yi = 0, d do
- for zi = 0, d do
- leaves_buffer[leaves_a:index(xx+xi, yy+yi, zz+zi)] = true
- end
- end
- end
- end
-
- -- Add the leaves
- for xi = leaves_a.MinEdge.x, leaves_a.MaxEdge.x do
- for yi = leaves_a.MinEdge.y, leaves_a.MaxEdge.y do
- for zi = leaves_a.MinEdge.z, leaves_a.MaxEdge.z do
- if a:contains(x+xi, y+yi, z+zi) then
- local vi = a:index(x+xi, y+yi, z+zi)
- if data[vi] == c_air or data[vi] == c_ignore then
- if leaves_buffer[leaves_a:index(xi, yi, zi)] then
- if is_apple_tree and pr:next(1, 100) <= 10 then
- data[vi] = c_apple
- else
- data[vi] = c_leaves
- end
- end
- end
- end
- end
- end
- end
-end
-
---
--- ABMs
---
-
-minetest.register_abm({
- nodenames = {"default:sapling"},
- interval = 10,
- chance = 50,
- action = function(pos, node)
- if minetest.get_item_group(minetest.get_node(
- {x = pos.x, y = pos.y - 1, z = pos.z}).name, "soil") == 0 then
- return
- end
- print("A sapling grows into a tree at "..minetest.pos_to_string(pos))
- local vm = minetest.get_voxel_manip()
- local minp, maxp = vm:read_from_map({x=pos.x-16, y=pos.y, z=pos.z-16}, {x=pos.x+16, y=pos.y+16, z=pos.z+16})
- local a = VoxelArea:new{MinEdge=minp, MaxEdge=maxp}
- local data = vm:get_data()
- default.grow_tree(data, a, pos, math.random(1, 4) == 1, math.random(1,100000))
- vm:set_data(data)
- vm:write_to_map(data)
- vm:update_map()
- end
-})
-
-minetest.register_abm({
- nodenames = {"default:dirt"},
- interval = 2,
- chance = 200,
- action = function(pos, node)
- local above = {x=pos.x, y=pos.y+1, z=pos.z}
- local name = minetest.get_node(above).name
- local nodedef = minetest.registered_nodes[name]
- if nodedef and (nodedef.sunlight_propagates or nodedef.paramtype == "light")
- and nodedef.liquidtype == "none"
- and (minetest.get_node_light(above) or 0) >= 13 then
- if name == "default:snow" or name == "default:snowblock" then
- minetest.set_node(pos, {name = "default:dirt_with_snow"})
- else
- minetest.set_node(pos, {name = "default:dirt_with_grass"})
- end
- end
- end
-})
-
-minetest.register_abm({
- nodenames = {"default:dirt_with_grass"},
- interval = 2,
- chance = 20,
- action = function(pos, node)
- local above = {x=pos.x, y=pos.y+1, z=pos.z}
- local name = minetest.get_node(above).name
- local nodedef = minetest.registered_nodes[name]
- if name ~= "ignore" and nodedef
- and not ((nodedef.sunlight_propagates or nodedef.paramtype == "light")
- and nodedef.liquidtype == "none") then
- minetest.set_node(pos, {name = "default:dirt"})
- end
- end
-})
-
---
--- Crafting items
---
-
-minetest.register_craftitem("default:stick", {
- description = "Stick",
- inventory_image = "default_stick.png",
-})
-
-minetest.register_craftitem("default:paper", {
- description = "Paper",
- inventory_image = "default_paper.png",
-})
-
-minetest.register_craftitem("default:book", {
- description = "Book",
- inventory_image = "default_book.png",
-})
-
-minetest.register_craftitem("default:coal_lump", {
- description = "Lump of coal",
- inventory_image = "default_coal_lump.png",
-})
-
-minetest.register_craftitem("default:iron_lump", {
- description = "Lump of iron",
- inventory_image = "default_iron_lump.png",
-})
-
-minetest.register_craftitem("default:clay_lump", {
- description = "Lump of clay",
- inventory_image = "default_clay_lump.png",
-})
-
-minetest.register_craftitem("default:steel_ingot", {
- description = "Steel ingot",
- inventory_image = "default_steel_ingot.png",
-})
-
-minetest.register_craftitem("default:clay_brick", {
- description = "Clay brick",
- inventory_image = "default_steel_ingot.png",
- inventory_image = "default_clay_brick.png",
-})
-
-minetest.register_craftitem("default:scorched_stuff", {
- description = "Scorched stuff",
- inventory_image = "default_scorched_stuff.png",
-})
-
---
--- Support old code
---
-
-function default.spawn_falling_node(p, nodename)
- spawn_falling_node(p, nodename)
-end
-
--- Horrible crap to support old code
--- Don't use this and never do what this does, it's completely wrong!
--- (More specifically, the client and the C++ code doesn't get the group)
-function default.register_falling_node(nodename, texture)
- minetest.log("error", debug.traceback())
- minetest.log('error', "WARNING: default.register_falling_node is deprecated")
- if minetest.registered_nodes[nodename] then
- minetest.registered_nodes[nodename].groups.falling_node = 1
- end
-end
-
---
--- Global callbacks
---
-
--- Global environment step function
-function on_step(dtime)
- -- print("on_step")
-end
-minetest.register_globalstep(on_step)
-
-function on_placenode(p, node)
- --print("on_placenode")
-end
-minetest.register_on_placenode(on_placenode)
-
-function on_dignode(p, node)
- --print("on_dignode")
-end
-minetest.register_on_dignode(on_dignode)
-
-function on_punchnode(p, node)
-end
-minetest.register_on_punchnode(on_punchnode)
-
---
--- Test some things
---
-
-local function test_get_craft_result()
- minetest.log("info", "test_get_craft_result()")
- -- normal
- local input = {
- method = "normal",
- width = 2,
- items = {"", "default:coal_lump", "", "default:stick"}
- }
- minetest.log("info", "torch crafting input: "..dump(input))
- local output, decremented_input = minetest.get_craft_result(input)
- minetest.log("info", "torch crafting output: "..dump(output))
- minetest.log("info", "torch crafting decremented input: "..dump(decremented_input))
- assert(output.item)
- minetest.log("info", "torch crafting output.item:to_table(): "..dump(output.item:to_table()))
- assert(output.item:get_name() == "default:torch")
- assert(output.item:get_count() == 4)
- -- fuel
- local input = {
- method = "fuel",
- width = 1,
- items = {"default:coal_lump"}
- }
- minetest.log("info", "coal fuel input: "..dump(input))
- local output, decremented_input = minetest.get_craft_result(input)
- minetest.log("info", "coal fuel output: "..dump(output))
- minetest.log("info", "coal fuel decremented input: "..dump(decremented_input))
- assert(output.time)
- assert(output.time > 0)
- -- cook
- local input = {
- method = "cooking",
- width = 1,
- items = {"default:cobble"}
- }
- minetest.log("info", "cobble cooking input: "..dump(output))
- local output, decremented_input = minetest.get_craft_result(input)
- minetest.log("info", "cobble cooking output: "..dump(output))
- minetest.log("info", "cobble cooking decremented input: "..dump(decremented_input))
- assert(output.time)
- assert(output.time > 0)
- assert(output.item)
- minetest.log("info", "cobble cooking output.item:to_table(): "..dump(output.item:to_table()))
- assert(output.item:get_name() == "default:stone")
- assert(output.item:get_count() == 1)
-end
-test_get_craft_result()
-
---
--- Done, print some random stuff
---
-
---print("minetest.registered_entities:")
---dump2(minetest.registered_entities)
-
--- END
-
diff --git a/games/minimal/mods/default/mapgen.lua b/games/minimal/mods/default/mapgen.lua
deleted file mode 100644
index 65b67dae5..000000000
--- a/games/minimal/mods/default/mapgen.lua
+++ /dev/null
@@ -1,136 +0,0 @@
---
--- Aliases for map generator outputs
---
-
-
-minetest.register_alias("mapgen_stone", "default:stone")
-minetest.register_alias("mapgen_dirt", "default:dirt")
-minetest.register_alias("mapgen_dirt_with_grass", "default:dirt_with_grass")
-minetest.register_alias("mapgen_sand", "default:sand")
-minetest.register_alias("mapgen_water_source", "default:water_source")
-minetest.register_alias("mapgen_lava_source", "default:lava_source")
-minetest.register_alias("mapgen_gravel", "default:gravel")
-
-minetest.register_alias("mapgen_tree", "default:tree")
-minetest.register_alias("mapgen_leaves", "default:leaves")
-minetest.register_alias("mapgen_apple", "default:apple")
-minetest.register_alias("mapgen_junglegrass", "default:junglegrass")
-
-minetest.register_alias("mapgen_cobble", "default:cobble")
-minetest.register_alias("mapgen_stair_cobble", "stairs:stair_cobble")
-minetest.register_alias("mapgen_mossycobble", "default:mossycobble")
-
-
---
--- Ore generation
---
-
-
--- Blob ore first to avoid other ores inside blobs
-
-minetest.register_ore({
- ore_type = "blob",
- ore = "default:clay",
- wherein = {"default:sand"},
- clust_scarcity = 24*24*24,
- clust_size = 7,
- y_min = -15,
- y_max = 0,
- noise_threshold = 0,
- noise_params = {
- offset=0.35,
- scale=0.2,
- spread={x=5, y=5, z=5},
- seed=-316,
- octaves=1,
- persist=0.5
- },
-})
-
-minetest.register_ore({
- ore_type = "scatter",
- ore = "default:stone_with_coal",
- wherein = "default:stone",
- clust_scarcity = 8*8*8,
- clust_num_ores = 8,
- clust_size = 3,
- y_min = -31000,
- y_max = 64,
-})
-
-minetest.register_ore({
- ore_type = "scatter",
- ore = "default:stone_with_iron",
- wherein = "default:stone",
- clust_scarcity = 12*12*12,
- clust_num_ores = 3,
- clust_size = 2,
- y_min = -15,
- y_max = 2,
-})
-
-minetest.register_ore({
- ore_type = "scatter",
- ore = "default:stone_with_iron",
- wherein = "default:stone",
- clust_scarcity = 9*9*9,
- clust_num_ores = 5,
- clust_size = 3,
- y_min = -63,
- y_max = -16,
-})
-
-minetest.register_ore({
- ore_type = "scatter",
- ore = "default:stone_with_iron",
- wherein = "default:stone",
- clust_scarcity = 7*7*7,
- clust_num_ores = 5,
- clust_size = 3,
- y_min = -31000,
- y_max = -64,
-})
-
-
---
--- Register biomes for biome API
---
-
-
-minetest.clear_registered_biomes()
-minetest.clear_registered_decorations()
-
-minetest.register_biome({
- name = "default:grassland",
- --node_dust = "",
- node_top = "default:dirt_with_grass",
- depth_top = 1,
- node_filler = "default:dirt",
- depth_filler = 1,
- --node_stone = "",
- --node_water_top = "",
- --depth_water_top = ,
- --node_water = "",
- y_min = 5,
- y_max = 31000,
- heat_point = 50,
- humidity_point = 50,
-})
-
-minetest.register_biome({
- name = "default:grassland_ocean",
- --node_dust = "",
- node_top = "default:sand",
- depth_top = 1,
- node_filler = "default:sand",
- depth_filler = 2,
- --node_stone = "",
- --node_water_top = "",
- --depth_water_top = ,
- --node_water = "",
- y_min = -31000,
- y_max = 4,
- heat_point = 50,
- humidity_point = 50,
-})
-
diff --git a/games/minimal/mods/default/sounds/default_grass_footstep.1.ogg b/games/minimal/mods/default/sounds/default_grass_footstep.1.ogg
deleted file mode 100644
index ce625d92b..000000000
--- a/games/minimal/mods/default/sounds/default_grass_footstep.1.ogg
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/bubble.png b/games/minimal/mods/default/textures/bubble.png
deleted file mode 100644
index 3bca7e11c..000000000
--- a/games/minimal/mods/default/textures/bubble.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/crack_anylength.png b/games/minimal/mods/default/textures/crack_anylength.png
deleted file mode 100644
index d9b49f911..000000000
--- a/games/minimal/mods/default/textures/crack_anylength.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_apple.png b/games/minimal/mods/default/textures/default_apple.png
deleted file mode 100644
index 4473dca28..000000000
--- a/games/minimal/mods/default/textures/default_apple.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_book.png b/games/minimal/mods/default/textures/default_book.png
deleted file mode 100644
index ea14a372a..000000000
--- a/games/minimal/mods/default/textures/default_book.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_bookshelf.png b/games/minimal/mods/default/textures/default_bookshelf.png
deleted file mode 100644
index f225e3449..000000000
--- a/games/minimal/mods/default/textures/default_bookshelf.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_brick.png b/games/minimal/mods/default/textures/default_brick.png
deleted file mode 100644
index def1cf0b1..000000000
--- a/games/minimal/mods/default/textures/default_brick.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_cactus_side.png b/games/minimal/mods/default/textures/default_cactus_side.png
deleted file mode 100644
index 128a4d28a..000000000
--- a/games/minimal/mods/default/textures/default_cactus_side.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_cactus_top.png b/games/minimal/mods/default/textures/default_cactus_top.png
deleted file mode 100644
index eda1a0bb6..000000000
--- a/games/minimal/mods/default/textures/default_cactus_top.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_chest_front.png b/games/minimal/mods/default/textures/default_chest_front.png
deleted file mode 100644
index 55b076c35..000000000
--- a/games/minimal/mods/default/textures/default_chest_front.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_chest_lock.png b/games/minimal/mods/default/textures/default_chest_lock.png
deleted file mode 100644
index 4b2d1af6c..000000000
--- a/games/minimal/mods/default/textures/default_chest_lock.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_chest_side.png b/games/minimal/mods/default/textures/default_chest_side.png
deleted file mode 100644
index ae4847cb6..000000000
--- a/games/minimal/mods/default/textures/default_chest_side.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_chest_top.png b/games/minimal/mods/default/textures/default_chest_top.png
deleted file mode 100644
index ac41551b0..000000000
--- a/games/minimal/mods/default/textures/default_chest_top.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_clay.png b/games/minimal/mods/default/textures/default_clay.png
deleted file mode 100644
index 070b69e48..000000000
--- a/games/minimal/mods/default/textures/default_clay.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_clay_brick.png b/games/minimal/mods/default/textures/default_clay_brick.png
deleted file mode 100644
index e25633b70..000000000
--- a/games/minimal/mods/default/textures/default_clay_brick.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_clay_lump.png b/games/minimal/mods/default/textures/default_clay_lump.png
deleted file mode 100644
index ceed6fa75..000000000
--- a/games/minimal/mods/default/textures/default_clay_lump.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_cloud.png b/games/minimal/mods/default/textures/default_cloud.png
deleted file mode 100644
index faf0ec13d..000000000
--- a/games/minimal/mods/default/textures/default_cloud.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_coal_lump.png b/games/minimal/mods/default/textures/default_coal_lump.png
deleted file mode 100644
index dae47e342..000000000
--- a/games/minimal/mods/default/textures/default_coal_lump.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_cobble.png b/games/minimal/mods/default/textures/default_cobble.png
deleted file mode 100644
index 2a28d25a5..000000000
--- a/games/minimal/mods/default/textures/default_cobble.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_dirt.png b/games/minimal/mods/default/textures/default_dirt.png
deleted file mode 100644
index 7cb9c89a6..000000000
--- a/games/minimal/mods/default/textures/default_dirt.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_fence.png b/games/minimal/mods/default/textures/default_fence.png
deleted file mode 100644
index e3510c52a..000000000
--- a/games/minimal/mods/default/textures/default_fence.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_furnace_fire_bg.png b/games/minimal/mods/default/textures/default_furnace_fire_bg.png
deleted file mode 100644
index e3370f438..000000000
--- a/games/minimal/mods/default/textures/default_furnace_fire_bg.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_furnace_fire_fg.png b/games/minimal/mods/default/textures/default_furnace_fire_fg.png
deleted file mode 100644
index 7a126e325..000000000
--- a/games/minimal/mods/default/textures/default_furnace_fire_fg.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_furnace_front.png b/games/minimal/mods/default/textures/default_furnace_front.png
deleted file mode 100644
index 4da398c0a..000000000
--- a/games/minimal/mods/default/textures/default_furnace_front.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_furnace_front_active.png b/games/minimal/mods/default/textures/default_furnace_front_active.png
deleted file mode 100644
index 06c4ab3ef..000000000
--- a/games/minimal/mods/default/textures/default_furnace_front_active.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_furnace_side.png b/games/minimal/mods/default/textures/default_furnace_side.png
deleted file mode 100644
index c729de9bf..000000000
--- a/games/minimal/mods/default/textures/default_furnace_side.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_glass.png b/games/minimal/mods/default/textures/default_glass.png
deleted file mode 100644
index fd665a40c..000000000
--- a/games/minimal/mods/default/textures/default_glass.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_grass.png b/games/minimal/mods/default/textures/default_grass.png
deleted file mode 100644
index 1d76708a0..000000000
--- a/games/minimal/mods/default/textures/default_grass.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_grass_footsteps.png b/games/minimal/mods/default/textures/default_grass_footsteps.png
deleted file mode 100644
index 8349033d6..000000000
--- a/games/minimal/mods/default/textures/default_grass_footsteps.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_grass_side.png b/games/minimal/mods/default/textures/default_grass_side.png
deleted file mode 100644
index 4f4f680be..000000000
--- a/games/minimal/mods/default/textures/default_grass_side.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_gravel.png b/games/minimal/mods/default/textures/default_gravel.png
deleted file mode 100644
index 4b47e2346..000000000
--- a/games/minimal/mods/default/textures/default_gravel.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_iron_lump.png b/games/minimal/mods/default/textures/default_iron_lump.png
deleted file mode 100644
index 6b515f66d..000000000
--- a/games/minimal/mods/default/textures/default_iron_lump.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_junglegrass.png b/games/minimal/mods/default/textures/default_junglegrass.png
deleted file mode 100644
index 7066f7dd9..000000000
--- a/games/minimal/mods/default/textures/default_junglegrass.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_ladder.png b/games/minimal/mods/default/textures/default_ladder.png
deleted file mode 100644
index 46757b884..000000000
--- a/games/minimal/mods/default/textures/default_ladder.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_lava_flowing_animated.png b/games/minimal/mods/default/textures/default_lava_flowing_animated.png
deleted file mode 100644
index 0bbd13606..000000000
--- a/games/minimal/mods/default/textures/default_lava_flowing_animated.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_lava_source_animated.png b/games/minimal/mods/default/textures/default_lava_source_animated.png
deleted file mode 100644
index aa9d57cf1..000000000
--- a/games/minimal/mods/default/textures/default_lava_source_animated.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_leaves.png b/games/minimal/mods/default/textures/default_leaves.png
deleted file mode 100644
index 00ce4471c..000000000
--- a/games/minimal/mods/default/textures/default_leaves.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_mese.png b/games/minimal/mods/default/textures/default_mese.png
deleted file mode 100644
index 123f0f4b9..000000000
--- a/games/minimal/mods/default/textures/default_mese.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_mineral_coal.png b/games/minimal/mods/default/textures/default_mineral_coal.png
deleted file mode 100644
index 0f52062af..000000000
--- a/games/minimal/mods/default/textures/default_mineral_coal.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_mineral_iron.png b/games/minimal/mods/default/textures/default_mineral_iron.png
deleted file mode 100644
index 6c894ce1c..000000000
--- a/games/minimal/mods/default/textures/default_mineral_iron.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_mossycobble.png b/games/minimal/mods/default/textures/default_mossycobble.png
deleted file mode 100644
index 5082953a6..000000000
--- a/games/minimal/mods/default/textures/default_mossycobble.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_nc_back.png b/games/minimal/mods/default/textures/default_nc_back.png
deleted file mode 100644
index e479ace83..000000000
--- a/games/minimal/mods/default/textures/default_nc_back.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_nc_front.png b/games/minimal/mods/default/textures/default_nc_front.png
deleted file mode 100644
index c9dd6a330..000000000
--- a/games/minimal/mods/default/textures/default_nc_front.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_nc_rb.png b/games/minimal/mods/default/textures/default_nc_rb.png
deleted file mode 100644
index 685a22ccf..000000000
--- a/games/minimal/mods/default/textures/default_nc_rb.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_nc_side.png b/games/minimal/mods/default/textures/default_nc_side.png
deleted file mode 100644
index bc85427ae..000000000
--- a/games/minimal/mods/default/textures/default_nc_side.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_paper.png b/games/minimal/mods/default/textures/default_paper.png
deleted file mode 100644
index 3c31f77c2..000000000
--- a/games/minimal/mods/default/textures/default_paper.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_papyrus.png b/games/minimal/mods/default/textures/default_papyrus.png
deleted file mode 100644
index 3707e4081..000000000
--- a/games/minimal/mods/default/textures/default_papyrus.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_rail.png b/games/minimal/mods/default/textures/default_rail.png
deleted file mode 100644
index 777e10c00..000000000
--- a/games/minimal/mods/default/textures/default_rail.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_rail_crossing.png b/games/minimal/mods/default/textures/default_rail_crossing.png
deleted file mode 100644
index a988c4740..000000000
--- a/games/minimal/mods/default/textures/default_rail_crossing.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_rail_curved.png b/games/minimal/mods/default/textures/default_rail_curved.png
deleted file mode 100644
index f87e826c9..000000000
--- a/games/minimal/mods/default/textures/default_rail_curved.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_rail_t_junction.png b/games/minimal/mods/default/textures/default_rail_t_junction.png
deleted file mode 100644
index fd25b5ba6..000000000
--- a/games/minimal/mods/default/textures/default_rail_t_junction.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_sand.png b/games/minimal/mods/default/textures/default_sand.png
deleted file mode 100644
index 1a56cc737..000000000
--- a/games/minimal/mods/default/textures/default_sand.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_sandstone.png b/games/minimal/mods/default/textures/default_sandstone.png
deleted file mode 100644
index bd9cb8692..000000000
--- a/games/minimal/mods/default/textures/default_sandstone.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_sapling.png b/games/minimal/mods/default/textures/default_sapling.png
deleted file mode 100644
index 93602322c..000000000
--- a/games/minimal/mods/default/textures/default_sapling.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_scorched_stuff.png b/games/minimal/mods/default/textures/default_scorched_stuff.png
deleted file mode 100644
index c7efc7e58..000000000
--- a/games/minimal/mods/default/textures/default_scorched_stuff.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_sign_wall.png b/games/minimal/mods/default/textures/default_sign_wall.png
deleted file mode 100644
index 93c075a2d..000000000
--- a/games/minimal/mods/default/textures/default_sign_wall.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_steel_block.png b/games/minimal/mods/default/textures/default_steel_block.png
deleted file mode 100644
index 9c0a0e248..000000000
--- a/games/minimal/mods/default/textures/default_steel_block.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_steel_ingot.png b/games/minimal/mods/default/textures/default_steel_ingot.png
deleted file mode 100644
index ad133bc12..000000000
--- a/games/minimal/mods/default/textures/default_steel_ingot.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_stick.png b/games/minimal/mods/default/textures/default_stick.png
deleted file mode 100644
index 055a6ac04..000000000
--- a/games/minimal/mods/default/textures/default_stick.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_stone.png b/games/minimal/mods/default/textures/default_stone.png
deleted file mode 100644
index a835fe002..000000000
--- a/games/minimal/mods/default/textures/default_stone.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_tnt_bottom.png b/games/minimal/mods/default/textures/default_tnt_bottom.png
deleted file mode 100644
index 4eda0603f..000000000
--- a/games/minimal/mods/default/textures/default_tnt_bottom.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_tnt_side.png b/games/minimal/mods/default/textures/default_tnt_side.png
deleted file mode 100644
index c259726d6..000000000
--- a/games/minimal/mods/default/textures/default_tnt_side.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_tnt_top.png b/games/minimal/mods/default/textures/default_tnt_top.png
deleted file mode 100644
index a031a34ad..000000000
--- a/games/minimal/mods/default/textures/default_tnt_top.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_tool_mesepick.png b/games/minimal/mods/default/textures/default_tool_mesepick.png
deleted file mode 100644
index 2b5e12cdb..000000000
--- a/games/minimal/mods/default/textures/default_tool_mesepick.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_tool_steelaxe.png b/games/minimal/mods/default/textures/default_tool_steelaxe.png
deleted file mode 100644
index fae19dd0d..000000000
--- a/games/minimal/mods/default/textures/default_tool_steelaxe.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_tool_steelpick.png b/games/minimal/mods/default/textures/default_tool_steelpick.png
deleted file mode 100644
index 3a8f58643..000000000
--- a/games/minimal/mods/default/textures/default_tool_steelpick.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_tool_steelshovel.png b/games/minimal/mods/default/textures/default_tool_steelshovel.png
deleted file mode 100644
index d5b1bc6bc..000000000
--- a/games/minimal/mods/default/textures/default_tool_steelshovel.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_tool_steelsword.png b/games/minimal/mods/default/textures/default_tool_steelsword.png
deleted file mode 100644
index efc61a0d1..000000000
--- a/games/minimal/mods/default/textures/default_tool_steelsword.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_tool_stoneaxe.png b/games/minimal/mods/default/textures/default_tool_stoneaxe.png
deleted file mode 100644
index 532e16fbc..000000000
--- a/games/minimal/mods/default/textures/default_tool_stoneaxe.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_tool_stoneshovel.png b/games/minimal/mods/default/textures/default_tool_stoneshovel.png
deleted file mode 100644
index 7bbd2d407..000000000
--- a/games/minimal/mods/default/textures/default_tool_stoneshovel.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_tool_stonesword.png b/games/minimal/mods/default/textures/default_tool_stonesword.png
deleted file mode 100644
index 533b8734f..000000000
--- a/games/minimal/mods/default/textures/default_tool_stonesword.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_tool_woodaxe.png b/games/minimal/mods/default/textures/default_tool_woodaxe.png
deleted file mode 100644
index 6e70f4a21..000000000
--- a/games/minimal/mods/default/textures/default_tool_woodaxe.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_tool_woodshovel.png b/games/minimal/mods/default/textures/default_tool_woodshovel.png
deleted file mode 100644
index e0b3608db..000000000
--- a/games/minimal/mods/default/textures/default_tool_woodshovel.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_tool_woodsword.png b/games/minimal/mods/default/textures/default_tool_woodsword.png
deleted file mode 100644
index 8099af139..000000000
--- a/games/minimal/mods/default/textures/default_tool_woodsword.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_torch.png b/games/minimal/mods/default/textures/default_torch.png
deleted file mode 100644
index 21d98bdbb..000000000
--- a/games/minimal/mods/default/textures/default_torch.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_torch_on_ceiling.png b/games/minimal/mods/default/textures/default_torch_on_ceiling.png
deleted file mode 100644
index dccd380b2..000000000
--- a/games/minimal/mods/default/textures/default_torch_on_ceiling.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_torch_on_floor.png b/games/minimal/mods/default/textures/default_torch_on_floor.png
deleted file mode 100644
index c22010750..000000000
--- a/games/minimal/mods/default/textures/default_torch_on_floor.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_tree.png b/games/minimal/mods/default/textures/default_tree.png
deleted file mode 100644
index 65abfc243..000000000
--- a/games/minimal/mods/default/textures/default_tree.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_tree_top.png b/games/minimal/mods/default/textures/default_tree_top.png
deleted file mode 100644
index 3e6bd5262..000000000
--- a/games/minimal/mods/default/textures/default_tree_top.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_wood.png b/games/minimal/mods/default/textures/default_wood.png
deleted file mode 100644
index 57c1d7c12..000000000
--- a/games/minimal/mods/default/textures/default_wood.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/heart.png b/games/minimal/mods/default/textures/heart.png
deleted file mode 100644
index c25f43b9a..000000000
--- a/games/minimal/mods/default/textures/heart.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/player.png b/games/minimal/mods/default/textures/player.png
deleted file mode 100644
index cf5d83f10..000000000
--- a/games/minimal/mods/default/textures/player.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/player_back.png b/games/minimal/mods/default/textures/player_back.png
deleted file mode 100644
index d498674eb..000000000
--- a/games/minimal/mods/default/textures/player_back.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/treeprop.png b/games/minimal/mods/default/textures/treeprop.png
deleted file mode 100644
index eb8a8e6c4..000000000
--- a/games/minimal/mods/default/textures/treeprop.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/default/textures/wieldhand.png b/games/minimal/mods/default/textures/wieldhand.png
deleted file mode 100644
index dbed6ad0c..000000000
--- a/games/minimal/mods/default/textures/wieldhand.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/errorhandler_test/init.lua b/games/minimal/mods/errorhandler_test/init.lua
deleted file mode 100644
index 9d1535c1d..000000000
--- a/games/minimal/mods/errorhandler_test/init.lua
+++ /dev/null
@@ -1,106 +0,0 @@
---
--- exception handler test module
---
---
--- To avoid this from crashing the module will startup in inactive mode.
--- to make specific errors happen you need to cause them by following
--- chat command:
---
--- exceptiontest <location> <errortype>
---
--- location has to be one of:
--- * mapgen: cause in next on_generate call
--- * entity_step: spawn a entity and make it do error in on_step
--- * globalstep: do error in next globalstep
--- * immediate: cause right in chat handler
---
--- errortypes defined are:
--- * segv: make sigsegv happen
--- * zerodivision: cause a division by zero to happen
--- * exception: throw an exception
-
-if core.cause_error == nil or
- type(core.cause_error) ~= "function" then
- return
-end
-
-
-core.log("action", "WARNING: loading exception handler test module!")
-
-local exceptiondata = {
- tocause = "none",
- mapgen = false,
- entity_step = false,
- globalstep = false,
-}
-
-local exception_entity =
-{
- on_step = function(self, dtime)
- if exceptiondata.entity_step then
- core.cause_error(exceptiondata.tocause)
- end
- end,
-}
-local exception_entity_name = "errorhandler_test:error_entity"
-
-local function exception_chat_handler(playername, param)
- local parameters = param:split(" ")
-
- if #parameters ~= 2 then
- core.chat_send_player(playername, "Invalid argument count for exceptiontest")
- end
-
- core.log("error", "Causing error at:" .. parameters[1])
-
- if parameters[1] == "mapgen" then
- exceptiondata.tocause = parameters[2]
- exceptiondata.mapgen = true
- elseif parameters[1] == "entity_step" then
- --spawn entity at player location
- local player = core.get_player_by_name(playername)
-
- if player:is_player() then
- local pos = player:getpos()
-
- core.add_entity(pos, exception_entity_name)
- end
-
- exceptiondata.tocause = parameters[2]
- exceptiondata.entity_step = true
-
- elseif parameters[1] == "globalstep" then
- exceptiondata.tocause = parameters[2]
- exceptiondata.globalstep = true
-
- elseif parameters[1] == "immediate" then
- core.cause_error(parameters[2])
-
- else
- core.chat_send_player(playername, "Invalid error location: " .. dump(parameters[1]))
- end
-end
-
-core.register_chatcommand("exceptiontest",
- {
- params = "<location> <errortype>",
- description = "cause a given error to happen.\n" ..
- " location=(mapgen,entity_step,globalstep,immediate)\n" ..
- " errortype=(segv,zerodivision,exception)",
- func = exception_chat_handler,
- privs = { server=true }
- })
-
-core.register_globalstep(function(dtime)
- if exceptiondata.globalstep then
- core.cause_error(exceptiondata.tocause)
- end
-end)
-
-core.register_on_generated(function(minp, maxp, blockseed)
- if exceptiondata.mapgen then
- core.cause_error(exceptiondata.tocause)
- end
-end)
-
-core.register_entity(exception_entity_name, exception_entity)
diff --git a/games/minimal/mods/experimental/depends.txt b/games/minimal/mods/experimental/depends.txt
deleted file mode 100644
index 3a7daa1d7..000000000
--- a/games/minimal/mods/experimental/depends.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-default
-
diff --git a/games/minimal/mods/experimental/init.lua b/games/minimal/mods/experimental/init.lua
deleted file mode 100644
index 729191bce..000000000
--- a/games/minimal/mods/experimental/init.lua
+++ /dev/null
@@ -1,601 +0,0 @@
---
--- Experimental things
---
-
--- For testing random stuff
-
-experimental = {}
-
-function experimental.print_to_everything(msg)
- minetest.log("action", msg)
- minetest.chat_send_all(msg)
-end
-
---[[
-experimental.player_visual_index = 0
-function switch_player_visual()
- for _, obj in pairs(minetest.get_connected_players()) do
- if experimental.player_visual_index == 0 then
- obj:set_properties({visual="upright_sprite"})
- else
- obj:set_properties({visual="cube"})
- end
- end
- experimental.player_visual_index = (experimental.player_visual_index + 1) % 2
- minetest.after(1.0, switch_player_visual)
-end
-minetest.after(1.0, switch_player_visual)
-]]
-
-minetest.register_node("experimental:soundblock", {
- tile_images = {"unknown_node.png", "default_tnt_bottom.png",
- "default_tnt_side.png", "default_tnt_side.png",
- "default_tnt_side.png", "default_tnt_side.png"},
- inventory_image = minetest.inventorycube("unknown_node.png",
- "default_tnt_side.png", "default_tnt_side.png"),
- groups = {dig_immediate=3},
-})
-
-minetest.register_alias("sb", "experimental:soundblock")
-
-minetest.register_abm({
- nodenames = {"experimental:soundblock"},
- interval = 1,
- chance = 1,
- action = function(p0, node, _, _)
- minetest.sound_play("default_grass_footstep", {pos=p0, gain=0.5})
- end,
-})
-
---[[
-stepsound = -1
-function test_sound()
- print("test_sound")
- stepsound = minetest.sound_play("default_grass_footstep", {gain=1.0})
- minetest.after(2.0, test_sound)
- --minetest.after(0.1, test_sound_stop)
-end
-function test_sound_stop()
- print("test_sound_stop")
- minetest.sound_stop(stepsound)
- minetest.after(2.0, test_sound)
-end
-test_sound()
---]]
-
-function on_step(dtime)
- -- print("experimental on_step")
- --[[
- objs = minetest.get_objects_inside_radius({x=0,y=0,z=0}, 10)
- for k, obj in pairs(objs) do
- name = obj:get_player_name()
- if name then
- print(name.." at "..dump(obj:getpos()))
- print(name.." dir: "..dump(obj:get_look_dir()))
- print(name.." pitch: "..dump(obj:get_look_pitch()))
- print(name.." yaw: "..dump(obj:get_look_yaw()))
- else
- print("Some object at "..dump(obj:getpos()))
- end
- end
- --]]
- --[[
- if experimental.t1 == nil then
- experimental.t1 = 0
- end
- experimental.t1 = experimental.t1 + dtime
- if experimental.t1 >= 2 then
- experimental.t1 = experimental.t1 - 2
- minetest.log("time of day is "..minetest.get_timeofday())
- if experimental.day then
- minetest.log("forcing day->night")
- experimental.day = false
- minetest.set_timeofday(0.0)
- else
- minetest.log("forcing night->day")
- experimental.day = true
- minetest.set_timeofday(0.5)
- end
- minetest.log("time of day is "..minetest.get_timeofday())
- end
- --]]
-end
-minetest.register_globalstep(on_step)
-
---
--- Random stuff
---
-
---
--- TNT (not functional)
---
-
-minetest.register_craft({
- output = 'experimental:tnt',
- recipe = {
- {'default:wood'},
- {'default:coal_lump'},
- {'default:wood'}
- }
-})
-
-minetest.register_node("experimental:tnt", {
- tile_images = {"default_tnt_top.png", "default_tnt_bottom.png",
- "default_tnt_side.png", "default_tnt_side.png",
- "default_tnt_side.png", "default_tnt_side.png"},
- inventory_image = minetest.inventorycube("default_tnt_top.png",
- "default_tnt_side.png", "default_tnt_side.png"),
- drop = '', -- Get nothing
- material = {
- diggability = "not",
- },
-})
-
-minetest.register_on_punchnode(function(p, node)
- if node.name == "experimental:tnt" then
- minetest.remove_node(p)
- minetest.add_entity(p, "experimental:tnt")
- nodeupdate(p)
- end
-end)
-
-local TNT = {
- -- Static definition
- physical = true, -- Collides with things
- -- weight = 5,
- collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
- visual = "cube",
- textures = {"default_tnt_top.png", "default_tnt_bottom.png",
- "default_tnt_side.png", "default_tnt_side.png",
- "default_tnt_side.png", "default_tnt_side.png"},
- -- Initial value for our timer
- timer = 0,
- -- Number of punches required to defuse
- health = 1,
- blinktimer = 0,
- blinkstatus = true,
-}
-
--- Called when a TNT object is created
-function TNT:on_activate(staticdata)
- print("TNT:on_activate()")
- self.object:setvelocity({x=0, y=4, z=0})
- self.object:setacceleration({x=0, y=-10, z=0})
- self.object:settexturemod("^[brighten")
- self.object:set_armor_groups({immortal=1})
-end
-
--- Called periodically
-function TNT:on_step(dtime)
- --print("TNT:on_step()")
- self.timer = self.timer + dtime
- self.blinktimer = self.blinktimer + dtime
- if self.blinktimer > 0.5 then
- self.blinktimer = self.blinktimer - 0.5
- if self.blinkstatus then
- self.object:settexturemod("")
- else
- self.object:settexturemod("^[brighten")
- end
- self.blinkstatus = not self.blinkstatus
- end
-end
-
--- Called when object is punched
-function TNT:on_punch(hitter)
- print("TNT:on_punch()")
- self.health = self.health - 1
- if self.health <= 0 then
- self.object:remove()
- hitter:get_inventory():add_item("main", "experimental:tnt")
- --hitter:set_hp(hitter:get_hp() - 1)
- end
-end
-
--- Called when object is right-clicked
-function TNT:on_rightclick(clicker)
- --pos = self.object:getpos()
- --pos = {x=pos.x, y=pos.y+0.1, z=pos.z}
- --self.object:moveto(pos, false)
-end
-
---print("TNT dump: "..dump(TNT))
---print("Registering TNT");
-minetest.register_entity("experimental:tnt", TNT)
-
--- Add TNT's old name also
-minetest.register_alias("TNT", "experimental:tnt")
-
---
--- The dummyball!
---
-
-minetest.register_entity("experimental:dummyball", {
- initial_properties = {
- hp_max = 20,
- physical = false,
- collisionbox = {-0.4,-0.4,-0.4, 0.4,0.4,0.4},
- visual = "sprite",
- visual_size = {x=1, y=1},
- textures = {"experimental_dummyball.png"},
- spritediv = {x=1, y=3},
- initial_sprite_basepos = {x=0, y=0},
- },
-
- phase = 0,
- phasetimer = 0,
-
- on_activate = function(self, staticdata)
- minetest.log("Dummyball activated!")
- end,
-
- on_step = function(self, dtime)
- self.phasetimer = self.phasetimer + dtime
- if self.phasetimer > 2.0 then
- self.phasetimer = self.phasetimer - 2.0
- self.phase = self.phase + 1
- if self.phase >= 3 then
- self.phase = 0
- end
- self.object:setsprite({x=0, y=self.phase})
- phasearmor = {
- [0]={cracky=3},
- [1]={crumbly=3},
- [2]={fleshy=3}
- }
- self.object:set_armor_groups(phasearmor[self.phase])
- end
- end,
-
- on_punch = function(self, hitter)
- end,
-})
-
-minetest.register_on_chat_message(function(name, message)
- local cmd = "/dummyball"
- if message:sub(0, #cmd) == cmd then
- count = tonumber(message:sub(#cmd+1)) or 1
- if not minetest.get_player_privs(name)["give"] then
- minetest.chat_send_player(name, "you don't have permission to spawn (give)")
- return true -- Handled chat message
- end
- if not minetest.get_player_privs(name)["interact"] then
- minetest.chat_send_player(name, "you don't have permission to interact")
- return true -- Handled chat message
- end
- if count >= 2 and not minetest.get_player_privs(name)["server"] then
- minetest.chat_send_player(name, "you don't have " ..
- "permission to spawn multiple " ..
- "dummyballs (server)")
- return true -- Handled chat message
- end
- local player = minetest.get_player_by_name(name)
- if player == nil then
- print("Unable to spawn entity, player is nil")
- return true -- Handled chat message
- end
- local entityname = "experimental:dummyball"
- local p = player:getpos()
- p.y = p.y + 1
- for i = 1,count do
- minetest.add_entity(p, entityname)
- end
- minetest.chat_send_player(name, '"'..entityname
- ..'" spawned '..tostring(count)..' time(s).');
- return true -- Handled chat message
- end
-end)
-
---
--- A test entity for testing animated and yaw-modulated sprites
---
-
-minetest.register_entity("experimental:testentity", {
- -- Static definition
- physical = true, -- Collides with things
- -- weight = 5,
- collisionbox = {-0.7,-1.35,-0.7, 0.7,1.0,0.7},
- --collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
- visual = "sprite",
- visual_size = {x=2, y=3},
- textures = {"dungeon_master.png^[makealpha:128,0,0^[makealpha:128,128,0"},
- spritediv = {x=6, y=5},
- initial_sprite_basepos = {x=0, y=0},
-
- on_activate = function(self, staticdata)
- print("testentity.on_activate")
- self.object:setsprite({x=0,y=0}, 1, 0, true)
- --self.object:setsprite({x=0,y=0}, 4, 0.3, true)
-
- -- Set gravity
- self.object:setacceleration({x=0, y=-10, z=0})
- -- Jump a bit upwards
- self.object:setvelocity({x=0, y=10, z=0})
- end,
-
- on_punch = function(self, hitter)
- self.object:remove()
- hitter:add_to_inventory('craft testobject1 1')
- end,
-})
-
---
--- More random stuff
---
-
-minetest.register_on_respawnplayer(function(player)
- print("on_respawnplayer")
- -- player:setpos({x=0, y=30, z=0})
- -- return true
-end)
-
-minetest.register_on_generated(function(minp, maxp)
- --print("on_generated: minp="..dump(minp).." maxp="..dump(maxp))
- --cp = {x=(minp.x+maxp.x)/2, y=(minp.y+maxp.y)/2, z=(minp.z+maxp.z)/2}
- --minetest.add_node(cp, {name="sand"})
-end)
-
--- Example setting get
---print("setting max_users = " .. dump(minetest.setting_get("max_users")))
---print("setting asdf = " .. dump(minetest.setting_get("asdf")))
-
-minetest.register_on_chat_message(function(name, message)
- --[[print("on_chat_message: name="..dump(name).." message="..dump(message))
- local cmd = "/testcommand"
- if message:sub(0, #cmd) == cmd then
- print(cmd.." invoked")
- return true
- end
- local cmd = "/help"
- if message:sub(0, #cmd) == cmd then
- print("script-overridden help command")
- minetest.chat_send_all("script-overridden help command")
- return true
- end]]
-end)
-
--- Grow papyrus on TNT every 10 seconds
---[[minetest.register_abm({
- nodenames = {"TNT"},
- interval = 10.0,
- chance = 1,
- action = function(pos, node, active_object_count, active_object_count_wider)
- print("TNT ABM action")
- pos.y = pos.y + 1
- minetest.add_node(pos, {name="papyrus"})
- end,
-})]]
-
--- Replace texts of alls signs with "foo" every 10 seconds
---[[minetest.register_abm({
- nodenames = {"sign_wall"},
- interval = 10.0,
- chance = 1,
- action = function(pos, node, active_object_count, active_object_count_wider)
- print("ABM: Sign text changed")
- local meta = minetest.get_meta(pos)
- meta:set_text("foo")
- end,
-})]]
-
---[[local ncpos = nil
-local ncq = 1
-local ncstuff = {
- {2, 1, 0, 3}, {3, 0, 1, 2}, {4, -1, 0, 1}, {5, -1, 0, 1}, {6, 0, -1, 0},
- {7, 0, -1, 0}, {8, 1, 0, 3}, {9, 1, 0, 3}, {10, 1, 0, 3}, {11, 0, 1, 2},
- {12, 0, 1, 2}, {13, 0, 1, 2}, {14, -1, 0, 1}, {15, -1, 0, 1}, {16, -1, 0, 1},
- {17, -1, 0, 1}, {18, 0, -1, 0}, {19, 0, -1, 0}, {20, 0, -1, 0}, {21, 0, -1, 0},
- {22, 1, 0, 3}, {23, 1, 0, 3}, {24, 1, 0, 3}, {25, 1, 0, 3}, {10, 0, 1, 2}
-}
-local ncold = {}
-local nctime = nil
-
-minetest.register_abm({
- nodenames = {"dirt_with_grass"},
- interval = 100000.0,
- chance = 1,
- action = function(pos, node, active_object_count, active_object_count_wider)
- if ncpos ~= nil then
- return
- end
-
- if pos.x % 16 ~= 8 or pos.z % 16 ~= 8 then
- return
- end
-
- pos.y = pos.y + 1
- n = minetest.get_node(pos)
- print(dump(n))
- if n.name ~= "air" then
- return
- end
-
- pos.y = pos.y + 2
- ncpos = pos
- nctime = os.clock()
- minetest.add_node(ncpos, {name="nyancat"})
- end
-})
-
-minetest.register_abm({
- nodenames = {"nyancat"},
- interval = 1.0,
- chance = 1,
- action = function(pos, node, active_object_count, active_object_count_wider)
- if ncpos == nil then
- return
- end
- if pos.x == ncpos.x and pos.y == ncpos.y and pos.z == ncpos.z then
- clock = os.clock()
- if clock - nctime < 0.1 then
- return
- end
- nctime = clock
-
- s0 = ncstuff[ncq]
- ncq = s0[1]
- s1 = ncstuff[ncq]
- p0 = pos
- p1 = {x = p0.x + s0[2], y = p0.y, z = p0.z + s0[3]}
- p2 = {x = p1.x + s1[2], y = p1.y, z = p1.z + s1[3]}
- table.insert(ncold, 1, p0)
- while #ncold >= 10 do
- minetest.add_node(ncold[#ncold], {name="air"})
- table.remove(ncold, #ncold)
- end
- minetest.add_node(p0, {name="nyancat_rainbow"})
- minetest.add_node(p1, {name="nyancat", param1=s0[4]})
- minetest.add_node(p2, {name="air"})
- ncpos = p1
- end
- end,
-})--]]
-
-minetest.register_node("experimental:tester_node_1", {
- description = "Tester Node 1 (construct/destruct/timer)",
- tile_images = {"wieldhand.png"},
- groups = {oddly_breakable_by_hand=2},
- sounds = default.node_sound_wood_defaults(),
- -- This was known to cause a bug in minetest.item_place_node() when used
- -- via minetest.place_node(), causing a placer with no position
- paramtype2 = "facedir",
-
- on_construct = function(pos)
- experimental.print_to_everything("experimental:tester_node_1:on_construct("..minetest.pos_to_string(pos)..")")
- local meta = minetest.get_meta(pos)
- meta:set_string("mine", "test")
- local timer = minetest.get_node_timer(pos)
- timer:start(4, 3)
- end,
-
- after_place_node = function(pos, placer)
- experimental.print_to_everything("experimental:tester_node_1:after_place_node("..minetest.pos_to_string(pos)..")")
- local meta = minetest.get_meta(pos)
- if meta:get_string("mine") == "test" then
- experimental.print_to_everything("correct metadata found")
- else
- experimental.print_to_everything("incorrect metadata found")
- end
- end,
-
- on_destruct = function(pos)
- experimental.print_to_everything("experimental:tester_node_1:on_destruct("..minetest.pos_to_string(pos)..")")
- end,
-
- after_destruct = function(pos)
- experimental.print_to_everything("experimental:tester_node_1:after_destruct("..minetest.pos_to_string(pos)..")")
- end,
-
- after_dig_node = function(pos, oldnode, oldmetadata, digger)
- experimental.print_to_everything("experimental:tester_node_1:after_dig_node("..minetest.pos_to_string(pos)..")")
- end,
-
- on_timer = function(pos, elapsed)
- experimental.print_to_everything("on_timer(): elapsed="..dump(elapsed))
- return true
- end,
-})
-
-minetest.register_craftitem("experimental:tester_tool_1", {
- description = "Tester Tool 1",
- inventory_image = "experimental_tester_tool_1.png",
- on_use = function(itemstack, user, pointed_thing)
- --print(dump(pointed_thing))
- if pointed_thing.type == "node" then
- if minetest.get_node(pointed_thing.under).name == "experimental:tester_node_1" then
- local p = pointed_thing.under
- minetest.log("action", "Tester tool used at "..minetest.pos_to_string(p))
- minetest.dig_node(p)
- else
- local p = pointed_thing.above
- minetest.log("action", "Tester tool used at "..minetest.pos_to_string(p))
- minetest.place_node(p, {name="experimental:tester_node_1"})
- end
- end
- end,
-})
-
-minetest.register_craft({
- output = 'experimental:tester_tool_1',
- recipe = {
- {'group:crumbly'},
- {'group:crumbly'},
- }
-})
-
---[[minetest.register_on_joinplayer(function(player)
- minetest.after(3, function()
- player:set_inventory_formspec("size[8,7.5]"..
- "image[1,0.6;1,2;player.png]"..
- "list[current_player;main;0,3.5;8,4;]"..
- "list[current_player;craft;3,0;3,3;]"..
- "list[current_player;craftpreview;7,1;1,1;]")
- end)
-end)]]
-
--- Create a detached inventory
-local inv = minetest.create_detached_inventory("test_inventory", {
- allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
- experimental.print_to_everything("allow move asked")
- return count -- Allow all
- end,
- allow_put = function(inv, listname, index, stack, player)
- experimental.print_to_everything("allow put asked")
- return 1 -- Allow only 1
- end,
- allow_take = function(inv, listname, index, stack, player)
- experimental.print_to_everything("allow take asked")
- return 4 -- Allow 4 at max
- end,
- on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
- experimental.print_to_everything(player:get_player_name().." moved items")
- end,
- on_put = function(inv, listname, index, stack, player)
- experimental.print_to_everything(player:get_player_name().." put items")
- end,
- on_take = function(inv, listname, index, stack, player)
- experimental.print_to_everything(player:get_player_name().." took items")
- end,
-})
-inv:set_size("main", 4*6)
-inv:add_item("main", "experimental:tester_tool_1")
-inv:add_item("main", "experimental:tnt 5")
-
-minetest.register_chatcommand("test1", {
- params = "",
- description = "Test 1: Modify player's inventory view",
- func = function(name, param)
- local player = minetest.get_player_by_name(name)
- if not player then
- return
- end
- player:set_inventory_formspec(
- "size[13,7.5]"..
- "image[6,0.6;1,2;player.png]"..
- "list[current_player;main;5,3.5;8,4;]"..
- "list[current_player;craft;8,0;3,3;]"..
- "list[current_player;craftpreview;12,1;1,1;]"..
- "list[detached:test_inventory;main;0,0;4,6;0]"..
- "button[0.5,7;2,1;button1;Button 1]"..
- "button_exit[2.5,7;2,1;button2;Exit Button]"
- )
- minetest.chat_send_player(name, "Done.");
- end,
-})
-
-minetest.register_on_player_receive_fields(function(player, formname, fields)
- experimental.print_to_everything("Inventory fields 1: player="..player:get_player_name()..", fields="..dump(fields))
-end)
-minetest.register_on_player_receive_fields(function(player, formname, fields)
- experimental.print_to_everything("Inventory fields 2: player="..player:get_player_name()..", fields="..dump(fields))
- return true -- Disable the first callback
-end)
-minetest.register_on_player_receive_fields(function(player, formname, fields)
- experimental.print_to_everything("Inventory fields 3: player="..player:get_player_name()..", fields="..dump(fields))
-end)
-
-minetest.log("experimental modname="..dump(minetest.get_current_modname()))
-minetest.log("experimental modpath="..dump(minetest.get_modpath("experimental")))
-minetest.log("experimental worldpath="..dump(minetest.get_worldpath()))
-
--- END
diff --git a/games/minimal/mods/experimental/textures/experimental_dummyball.png b/games/minimal/mods/experimental/textures/experimental_dummyball.png
deleted file mode 100644
index 256414f46..000000000
--- a/games/minimal/mods/experimental/textures/experimental_dummyball.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/experimental/textures/experimental_tester_tool_1.png b/games/minimal/mods/experimental/textures/experimental_tester_tool_1.png
deleted file mode 100644
index 587923c86..000000000
--- a/games/minimal/mods/experimental/textures/experimental_tester_tool_1.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/give_initial_stuff/depends.txt b/games/minimal/mods/give_initial_stuff/depends.txt
deleted file mode 100644
index 3a7daa1d7..000000000
--- a/games/minimal/mods/give_initial_stuff/depends.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-default
-
diff --git a/games/minimal/mods/give_initial_stuff/init.lua b/games/minimal/mods/give_initial_stuff/init.lua
deleted file mode 100644
index 29b835c7d..000000000
--- a/games/minimal/mods/give_initial_stuff/init.lua
+++ /dev/null
@@ -1,16 +0,0 @@
-minetest.register_on_newplayer(function(player)
- print("[minimal] giving initial stuff to player")
- player:get_inventory():add_item('main', 'default:pick_stone')
- player:get_inventory():add_item('main', 'default:torch 99')
- player:get_inventory():add_item('main', 'default:cobble 99')
- player:get_inventory():add_item('main', 'default:wood 99')
- player:get_inventory():add_item('main', 'default:axe_steel')
- player:get_inventory():add_item('main', 'default:shovel_steel')
- player:get_inventory():add_item('main', 'default:pick_wood')
- player:get_inventory():add_item('main', 'default:pick_steel')
- player:get_inventory():add_item('main', 'default:pick_mese')
- player:get_inventory():add_item('main', 'default:mese 99')
- player:get_inventory():add_item('main', 'default:water_source 99')
- player:get_inventory():add_item('main', 'experimental:tester_tool_1')
-end)
-
diff --git a/games/minimal/mods/legacy/depends.txt b/games/minimal/mods/legacy/depends.txt
deleted file mode 100644
index 3a7daa1d7..000000000
--- a/games/minimal/mods/legacy/depends.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-default
-
diff --git a/games/minimal/mods/legacy/init.lua b/games/minimal/mods/legacy/init.lua
deleted file mode 100644
index 98ad69be0..000000000
--- a/games/minimal/mods/legacy/init.lua
+++ /dev/null
@@ -1,128 +0,0 @@
--- legacy (Minetest 0.4 mod)
--- Provides as much backwards-compatibility as feasible
-
---
--- Aliases to support loading 0.3 and old 0.4 worlds and inventories
---
-
-minetest.register_alias("stone", "default:stone")
-minetest.register_alias("stone_with_coal", "default:stone_with_coal")
-minetest.register_alias("stone_with_iron", "default:stone_with_iron")
-minetest.register_alias("dirt_with_grass", "default:dirt_with_grass")
-minetest.register_alias("dirt_with_grass_footsteps", "default:dirt_with_grass_footsteps")
-minetest.register_alias("dirt", "default:dirt")
-minetest.register_alias("sand", "default:sand")
-minetest.register_alias("gravel", "default:gravel")
-minetest.register_alias("sandstone", "default:sandstone")
-minetest.register_alias("clay", "default:clay")
-minetest.register_alias("brick", "default:brick")
-minetest.register_alias("tree", "default:tree")
-minetest.register_alias("jungletree", "default:jungletree")
-minetest.register_alias("junglegrass", "default:junglegrass")
-minetest.register_alias("leaves", "default:leaves")
-minetest.register_alias("cactus", "default:cactus")
-minetest.register_alias("papyrus", "default:papyrus")
-minetest.register_alias("bookshelf", "default:bookshelf")
-minetest.register_alias("glass", "default:glass")
-minetest.register_alias("wooden_fence", "default:fence_wood")
-minetest.register_alias("rail", "default:rail")
-minetest.register_alias("ladder", "default:ladder")
-minetest.register_alias("wood", "default:wood")
-minetest.register_alias("mese", "default:mese")
-minetest.register_alias("cloud", "default:cloud")
-minetest.register_alias("water_flowing", "default:water_flowing")
-minetest.register_alias("water_source", "default:water_source")
-minetest.register_alias("lava_flowing", "default:lava_flowing")
-minetest.register_alias("lava_source", "default:lava_source")
-minetest.register_alias("torch", "default:torch")
-minetest.register_alias("sign_wall", "default:sign_wall")
-minetest.register_alias("furnace", "default:furnace")
-minetest.register_alias("chest", "default:chest")
-minetest.register_alias("locked_chest", "default:chest_locked")
-minetest.register_alias("cobble", "default:cobble")
-minetest.register_alias("mossycobble", "default:mossycobble")
-minetest.register_alias("steelblock", "default:steelblock")
-minetest.register_alias("nyancat", "default:nyancat")
-minetest.register_alias("nyancat_rainbow", "default:nyancat_rainbow")
-minetest.register_alias("sapling", "default:sapling")
-minetest.register_alias("apple", "default:apple")
-
-minetest.register_alias("WPick", "default:pick_wood")
-minetest.register_alias("STPick", "default:pick_stone")
-minetest.register_alias("SteelPick", "default:pick_steel")
-minetest.register_alias("MesePick", "default:pick_mese")
-minetest.register_alias("WShovel", "default:shovel_wood")
-minetest.register_alias("STShovel", "default:shovel_stone")
-minetest.register_alias("SteelShovel", "default:shovel_steel")
-minetest.register_alias("WAxe", "default:axe_wood")
-minetest.register_alias("STAxe", "default:axe_stone")
-minetest.register_alias("SteelAxe", "default:axe_steel")
-minetest.register_alias("WSword", "default:sword_wood")
-minetest.register_alias("STSword", "default:sword_stone")
-minetest.register_alias("SteelSword", "default:sword_steel")
-
-minetest.register_alias("Stick", "default:stick")
-minetest.register_alias("paper", "default:paper")
-minetest.register_alias("book", "default:book")
-minetest.register_alias("lump_of_coal", "default:coal_lump")
-minetest.register_alias("lump_of_iron", "default:iron_lump")
-minetest.register_alias("lump_of_clay", "default:clay_lump")
-minetest.register_alias("steel_ingot", "default:steel_ingot")
-minetest.register_alias("clay_brick", "default:clay_brick")
-minetest.register_alias("scorched_stuff", "default:scorched_stuff")
-
---
--- Old items
---
-
-minetest.register_craftitem(":rat", {
- description = "Rat",
- inventory_image = "rat.png",
- on_drop = function(item, dropper, pos)
- item:take_item()
- return item
- end,
- on_place = function(item, dropped, pointed)
- pos = minetest.get_pointed_thing_position(pointed, true)
- if pos ~= nil then
- item:take_item()
- return item
- end
- end
-})
-
-minetest.register_craftitem(":cooked_rat", {
- description = "Cooked rat",
- inventory_image = "cooked_rat.png",
- on_use = minetest.item_eat(6),
-})
-
-minetest.register_craftitem(":firefly", {
- description = "Firefly",
- inventory_image = "firefly.png",
- on_drop = function(item, dropper, pos)
- item:take_item()
- return item
- end,
- on_place = function(item, dropped, pointed)
- pos = minetest.get_pointed_thing_position(pointed, true)
- if pos ~= nil then
- item:take_item()
- return item
- end
- end
-})
-
-minetest.register_craft({
- type = "cooking",
- output = "cooked_rat",
- recipe = "rat",
-})
-
-minetest.register_craft({
- type = "cooking",
- output = "scorched_stuff",
- recipe = "cooked_rat",
-})
-
--- END
diff --git a/games/minimal/mods/legacy/textures/apple_iron.png b/games/minimal/mods/legacy/textures/apple_iron.png
deleted file mode 100644
index db5945856..000000000
--- a/games/minimal/mods/legacy/textures/apple_iron.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/legacy/textures/cooked_rat.png b/games/minimal/mods/legacy/textures/cooked_rat.png
deleted file mode 100644
index 776dc4ee0..000000000
--- a/games/minimal/mods/legacy/textures/cooked_rat.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/legacy/textures/dungeon_master.png b/games/minimal/mods/legacy/textures/dungeon_master.png
deleted file mode 100644
index d52d8ccd7..000000000
--- a/games/minimal/mods/legacy/textures/dungeon_master.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/legacy/textures/fireball.png b/games/minimal/mods/legacy/textures/fireball.png
deleted file mode 100644
index 124469ce4..000000000
--- a/games/minimal/mods/legacy/textures/fireball.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/legacy/textures/firefly.png b/games/minimal/mods/legacy/textures/firefly.png
deleted file mode 100644
index ea95a6a84..000000000
--- a/games/minimal/mods/legacy/textures/firefly.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/legacy/textures/oerkki1.png b/games/minimal/mods/legacy/textures/oerkki1.png
deleted file mode 100644
index 061709c80..000000000
--- a/games/minimal/mods/legacy/textures/oerkki1.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/legacy/textures/oerkki1_damaged.png b/games/minimal/mods/legacy/textures/oerkki1_damaged.png
deleted file mode 100644
index b2a30337e..000000000
--- a/games/minimal/mods/legacy/textures/oerkki1_damaged.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/legacy/textures/rat.png b/games/minimal/mods/legacy/textures/rat.png
deleted file mode 100644
index 04cf9b865..000000000
--- a/games/minimal/mods/legacy/textures/rat.png
+++ /dev/null
Binary files differ
diff --git a/games/minimal/mods/stairs/depends.txt b/games/minimal/mods/stairs/depends.txt
deleted file mode 100644
index 4ad96d515..000000000
--- a/games/minimal/mods/stairs/depends.txt
+++ /dev/null
@@ -1 +0,0 @@
-default
diff --git a/games/minimal/mods/test/init.lua b/games/minimal/mods/test/init.lua
deleted file mode 100644
index 051b47906..000000000
--- a/games/minimal/mods/test/init.lua
+++ /dev/null
@@ -1,11 +0,0 @@
---
--- Minimal Development Test
--- Mod: test
---
-
--- Try out PseudoRandom
-pseudo = PseudoRandom(13)
-assert(pseudo:next() == 22290)
-assert(pseudo:next() == 13854)
-
-