From e3c0824250c7c1043b05165cff653c07541d0c26 Mon Sep 17 00:00:00 2001 From: MoNTE48 Date: Sun, 2 Jun 2019 01:49:20 +0200 Subject: [PATCH] Replace Potions mod on Replacing potions mod on PEP. Add Vessels, Playereffects, Playerphysics. Playerplus now working on playerphysics API. Added more items in creative inventory, other --- builtin/game/item.lua | 6 +- games/default/files/bucket/init.lua | 3 - .../files/creative/categories/brewing.lua | 27 +- .../files/creative/categories/building.lua | 19 +- .../files/creative/categories/decorative.lua | 56 +- .../files/creative/categories/foodstuffs.lua | 13 + .../files/creative/categories/materials.lua | 3 + .../files/creative/categories/misc.lua | 33 +- .../files/creative/categories/tools.lua | 3 + games/default/files/creative/inventory.lua | 7 +- games/default/files/default/nodes.lua | 8 +- games/default/files/flowers/init.lua | 7 - games/default/files/mobs_redo/api.lua | 2 +- games/default/files/mobs_redo/crafts.lua | 18 +- .../mobs_redo/textures/mobs_magic_lasso.png | Bin 171 -> 0 bytes .../files/{potions => player}/modpack.txt | 0 games/default/files/player/pep/README.md | 78 +++ games/default/files/player/pep/depends.txt | 7 + games/default/files/player/pep/init.lua | 447 +++++++++++++++ .../files/player/pep/textures/pep_breath.png | Bin 0 -> 843 bytes .../pep/textures/pep_glass_bottle_overlay.png | Bin 0 -> 222 bytes .../files/player/pep/textures/pep_grav0.png | Bin 0 -> 637 bytes .../player/pep/textures/pep_gravreset.png | Bin 0 -> 758 bytes .../player/pep/textures/pep_jumpminus.png | Bin 0 -> 755 bytes .../player/pep/textures/pep_jumpplus.png | Bin 0 -> 782 bytes .../player/pep/textures/pep_jumpreset.png | Bin 0 -> 795 bytes .../player/pep/textures/pep_manaregen.png | Bin 0 -> 778 bytes .../player/pep/textures/pep_manaregen2.png | Bin 0 -> 772 bytes .../files/player/pep/textures/pep_mole.png | Bin 0 -> 759 bytes .../files/player/pep/textures/pep_regen.png | Bin 0 -> 783 bytes .../files/player/pep/textures/pep_regen2.png | Bin 0 -> 791 bytes .../player/pep/textures/pep_speedminus.png | Bin 0 -> 757 bytes .../player/pep/textures/pep_speedplus.png | Bin 0 -> 768 bytes .../player/pep/textures/pep_speedreset.png | Bin 0 -> 767 bytes .../files/player/playereffects/README.md | 228 ++++++++ .../files/player/playereffects/init.lua | 522 ++++++++++++++++++ .../files/player/playerphysics/README.md | 123 +++++ .../files/player/playerphysics/init.lua | 43 ++ .../default/files/player/playerplus/README.md | 20 + .../files/player/playerplus/depends.txt | 2 + .../files/{ => player}/playerplus/init.lua | 83 +-- .../files/{ => player}/playerplus/license.txt | 0 games/default/files/player_api/api.lua | 7 +- games/default/files/playerplus/README.md | 31 -- games/default/files/playerplus/depends.txt | 2 - .../default/files/potions/potions/README.txt | 33 -- games/default/files/potions/potions/init.lua | 71 --- .../files/potions/potions/lib/Vec3_1-0.lua | 398 ------------- .../files/potions/potionspack/depends.txt | 3 - .../files/potions/potionspack/init.lua | 164 ------ .../potionspack/textures/potions_black.png | Bin 160 -> 0 bytes .../potionspack/textures/potions_blue.png | Bin 127 -> 0 bytes .../potionspack/textures/potions_brown.png | Bin 171 -> 0 bytes .../potionspack/textures/potions_cyan.png | Bin 197 -> 0 bytes .../potionspack/textures/potions_darkblue.png | Bin 192 -> 0 bytes .../potionspack/textures/potions_darkgrey.png | Bin 153 -> 0 bytes .../potionspack/textures/potions_darkred.png | Bin 176 -> 0 bytes .../potionspack/textures/potions_dull.png | Bin 166 -> 0 bytes .../potionspack/textures/potions_green.png | Bin 176 -> 0 bytes .../textures/potions_lightgrey.png | Bin 153 -> 0 bytes .../potionspack/textures/potions_orange.png | Bin 187 -> 0 bytes .../potionspack/textures/potions_particle.png | Bin 540 -> 0 bytes .../potionspack/textures/potions_pink.png | Bin 284 -> 0 bytes .../potionspack/textures/potions_purple.png | Bin 207 -> 0 bytes .../potionspack/textures/potions_red.png | Bin 192 -> 0 bytes .../potionspack/textures/potions_shatter.png | Bin 115 -> 0 bytes .../potionspack/textures/potions_white.png | Bin 153 -> 0 bytes .../potionspack/textures/potions_yellow.png | Bin 192 -> 0 bytes games/default/files/vessels/README.txt | 9 + games/default/files/vessels/depends.txt | 1 + games/default/files/vessels/init.lua | 108 ++++ games/default/files/vessels/license.txt | 16 + .../textures/vessels_glass_bottle.png} | Bin .../files/vessels/textures/vessels_shelf.png | Bin 0 -> 349 bytes 74 files changed, 1742 insertions(+), 859 deletions(-) delete mode 100644 games/default/files/mobs_redo/textures/mobs_magic_lasso.png rename games/default/files/{potions => player}/modpack.txt (100%) create mode 100644 games/default/files/player/pep/README.md create mode 100644 games/default/files/player/pep/depends.txt create mode 100644 games/default/files/player/pep/init.lua create mode 100644 games/default/files/player/pep/textures/pep_breath.png create mode 100644 games/default/files/player/pep/textures/pep_glass_bottle_overlay.png create mode 100644 games/default/files/player/pep/textures/pep_grav0.png create mode 100644 games/default/files/player/pep/textures/pep_gravreset.png create mode 100644 games/default/files/player/pep/textures/pep_jumpminus.png create mode 100644 games/default/files/player/pep/textures/pep_jumpplus.png create mode 100644 games/default/files/player/pep/textures/pep_jumpreset.png create mode 100644 games/default/files/player/pep/textures/pep_manaregen.png create mode 100644 games/default/files/player/pep/textures/pep_manaregen2.png create mode 100644 games/default/files/player/pep/textures/pep_mole.png create mode 100644 games/default/files/player/pep/textures/pep_regen.png create mode 100644 games/default/files/player/pep/textures/pep_regen2.png create mode 100644 games/default/files/player/pep/textures/pep_speedminus.png create mode 100644 games/default/files/player/pep/textures/pep_speedplus.png create mode 100644 games/default/files/player/pep/textures/pep_speedreset.png create mode 100644 games/default/files/player/playereffects/README.md create mode 100644 games/default/files/player/playereffects/init.lua create mode 100644 games/default/files/player/playerphysics/README.md create mode 100644 games/default/files/player/playerphysics/init.lua create mode 100644 games/default/files/player/playerplus/README.md create mode 100644 games/default/files/player/playerplus/depends.txt rename games/default/files/{ => player}/playerplus/init.lua (72%) rename games/default/files/{ => player}/playerplus/license.txt (100%) delete mode 100644 games/default/files/playerplus/README.md delete mode 100644 games/default/files/playerplus/depends.txt delete mode 100644 games/default/files/potions/potions/README.txt delete mode 100644 games/default/files/potions/potions/init.lua delete mode 100644 games/default/files/potions/potions/lib/Vec3_1-0.lua delete mode 100644 games/default/files/potions/potionspack/depends.txt delete mode 100644 games/default/files/potions/potionspack/init.lua delete mode 100644 games/default/files/potions/potionspack/textures/potions_black.png delete mode 100644 games/default/files/potions/potionspack/textures/potions_blue.png delete mode 100644 games/default/files/potions/potionspack/textures/potions_brown.png delete mode 100644 games/default/files/potions/potionspack/textures/potions_cyan.png delete mode 100644 games/default/files/potions/potionspack/textures/potions_darkblue.png delete mode 100644 games/default/files/potions/potionspack/textures/potions_darkgrey.png delete mode 100644 games/default/files/potions/potionspack/textures/potions_darkred.png delete mode 100644 games/default/files/potions/potionspack/textures/potions_dull.png delete mode 100644 games/default/files/potions/potionspack/textures/potions_green.png delete mode 100644 games/default/files/potions/potionspack/textures/potions_lightgrey.png delete mode 100644 games/default/files/potions/potionspack/textures/potions_orange.png delete mode 100644 games/default/files/potions/potionspack/textures/potions_particle.png delete mode 100644 games/default/files/potions/potionspack/textures/potions_pink.png delete mode 100644 games/default/files/potions/potionspack/textures/potions_purple.png delete mode 100644 games/default/files/potions/potionspack/textures/potions_red.png delete mode 100644 games/default/files/potions/potionspack/textures/potions_shatter.png delete mode 100644 games/default/files/potions/potionspack/textures/potions_white.png delete mode 100644 games/default/files/potions/potionspack/textures/potions_yellow.png create mode 100644 games/default/files/vessels/README.txt create mode 100644 games/default/files/vessels/depends.txt create mode 100644 games/default/files/vessels/init.lua create mode 100644 games/default/files/vessels/license.txt rename games/default/files/{potions/potionspack/textures/potions_bottle.png => vessels/textures/vessels_glass_bottle.png} (100%) create mode 100644 games/default/files/vessels/textures/vessels_shelf.png diff --git a/builtin/game/item.lua b/builtin/game/item.lua index 9f0200a6a..81573f07e 100644 --- a/builtin/game/item.lua +++ b/builtin/game/item.lua @@ -458,9 +458,9 @@ function core.item_drop(itemstack, dropper, pos) obj:get_luaentity().dropped_by = dropper:get_player_name() else obj:set_velocity({ - x = math.random(-2.5, 2.5), - y = math.random(1, 4), - z = math.random(-2.5, 2.5) + x = math.random(-2, 2), + y = math.random(2, 4), + z = math.random(-2, 2) }) end return itemstack diff --git a/games/default/files/bucket/init.lua b/games/default/files/bucket/init.lua index c50000659..dd20f6fce 100644 --- a/games/default/files/bucket/init.lua +++ b/games/default/files/bucket/init.lua @@ -1,6 +1,3 @@ --- MultiCraft game mod: bucket --- See README.txt for licensing and other information. - minetest.register_alias("bucket", "bucket:bucket_empty") minetest.register_alias("bucket_water", "bucket:bucket_water") minetest.register_alias("bucket_lava", "bucket:bucket_lava") diff --git a/games/default/files/creative/categories/brewing.lua b/games/default/files/creative/categories/brewing.lua index 97a803106..8b5a5423d 100644 --- a/games/default/files/creative/categories/brewing.lua +++ b/games/default/files/creative/categories/brewing.lua @@ -1,17 +1,16 @@ return { - "potionspack:antigravity", - "potionspack:speed", - "potionspack:speedii", - "potionspack:whatwillthisdo", - "potionspack:harmingii", - "potionspack:regenii", - "potionspack:regen", - "potionspack:instanthealthii", - "potionspack:instanthealth", - "potionspack:confusion", - "potionspack:inversion", - "potionspack:harming", "vessels:glass_bottle", - "potions:glass_bottle", - "potionspack:antigravityii", + "pep", + "pep:speedplus", + "pep:speedminus", + "pep:speedreset", + "pep:breath", + "pep:regen", + "pep:regen2", + "pep:grav0", + "pep:gravreset", + "pep:jumpplus", + "pep:jumpminus", + "pep:jumpreset", + "pep:mole", } \ No newline at end of file diff --git a/games/default/files/creative/categories/building.lua b/games/default/files/creative/categories/building.lua index c5777664b..6a3b51a3a 100644 --- a/games/default/files/creative/categories/building.lua +++ b/games/default/files/creative/categories/building.lua @@ -1,19 +1,16 @@ return { + "default:cobble", "default:redsandstonecarved", "default:gravel", "default:glowstone", - "default:glass_pink", "default:wood", "default:slimeblock", "default:ice", - "default:glass_lime", "default:obsidian", "default:sand", "default:redsandstonesmooth", "default:dirt_with_snow", "default:packedice", - "default:glass_blue", - "default:glass_silver", "default:stone_with_diamond", "default:cobble", "default:bedrock", @@ -23,8 +20,6 @@ return { "default:stone_with_emerald", "default:dirt_with_dry_grass", "default:stone_with_lapis", - "default:glass_green", - "default:glass_orange", "default:emeraldblock", "wallet:wallmossy", "default:lapisblock", @@ -32,32 +27,20 @@ return { "default:stone_with_gold", "default:goldblock", "default:quartz_ore", - "sponge:sponge", - "default:glass_white", - "default:glass_purple", - "default:glass_gray", - "default:glass", - "default:glass_red", - "default:glass_magenta", "default:stonebrickmossy", "default:stone_with_iron", - "default:bookshelf", "default:dirt", "default:diamondblock", "default:steelblock", "default:dirt_with_grass", "default:stonebrickcarved", "default:stone_with_bluestone", - "default:glass_brown", "default:snowblock", - "default:glass_black", "wallet:wall", "default:quartz_pillar", "default:redsand", - "default:glass_light_blue", "default:stone", "default:sandstone", - "default:glass_yellow", "default:sandstonesmooth", "default:clay", "default:stonebrickcracked", diff --git a/games/default/files/creative/categories/decorative.lua b/games/default/files/creative/categories/decorative.lua index 7e0656424..4e4bd04d9 100644 --- a/games/default/files/creative/categories/decorative.lua +++ b/games/default/files/creative/categories/decorative.lua @@ -1,35 +1,57 @@ return { - "xpanes:pane_glass_black", - "xpanes:pane_glass_gray", - "xpanes:pane_glass_purple", - "xpanes:pane_glass_pink", "default:dry_shrub", - "xpanes:pane_glass_lime", "default:chest", - "xpanes:pane_glass_red", - "default:cobble", - "xpanes:pane_glass_green", "default:grass", "itemframes:frame", - "xpanes:pane_glass_white", - "xpanes:pane_glass_blue", - "xpanes:pane_glass_brown", - "xpanes:pane_glass_magenta", "default:cactus", "default:ladder", "default:stonebrick", "default:vine", "default:dry_grass", "fences:fence_wood", - "xpanes:pane_iron", "default:stonebrickmossy", - "xpanes:pane_glass_light_blue", "default:stonebrickcarved", + "default:stone", + "default:stonebrickcracked", + "default:mossycobble", + "default:bookshelf", + "vessels:shelf", + "beds:bed", + "workbench:workbench", + "sponge:sponge", + + "default:glass", + "default:glass_black", + "default:glass_blue", + "default:glass_brown", + "default:glass_gray", + "default:glass_green", + "default:glass_pink", + "default:glass_light_blue", + "default:glass_lime", + "default:glass_magenta", + "default:glass_orange", + "default:glass_purple", + "default:glass_red", + "default:glass_silver", + "default:glass_white", + "default:glass_yellow", + + "xpanes:pane_glass_lime", + "xpanes:pane_glass_red", + "xpanes:pane_glass_green", + "xpanes:pane_glass_black", + "xpanes:pane_glass_gray", + "xpanes:pane_glass_purple", + "xpanes:pane_glass_pink", + "xpanes:pane_glass_white", + "xpanes:pane_glass_blue", + "xpanes:pane_glass_brown", + "xpanes:pane_glass_magenta", + "xpanes:pane_glass_light_blue", "xpanes:pane_glass_natural", "xpanes:pane_glass_silver", "xpanes:pane_glass_yellow", "xpanes:pane_glass_orange", - "default:stone", - "default:stonebrickcracked", - "default:mossycobble", + "xpanes:pane_iron", } \ No newline at end of file diff --git a/games/default/files/creative/categories/foodstuffs.lua b/games/default/files/creative/categories/foodstuffs.lua index c7320ff3a..add90cf2e 100644 --- a/games/default/files/creative/categories/foodstuffs.lua +++ b/games/default/files/creative/categories/foodstuffs.lua @@ -3,4 +3,17 @@ return { "default:apple_gold", "default:fish", "default:apple", + "farming:bread", + "flowers:mushroom_red", + "flowers:mushroom_brown", + "mobs:chicken_egg_fried", + "mobs:chicken_raw", + "mobs:chicken_cooked", + "mobs:bucket_milk", + "mobs:cheese", + "mobs_monster:rotten_flesh", + "mobs:meat_raw", + "mobs:meat", + "mobs:pork_raw", + "mobs:pork", } \ No newline at end of file diff --git a/games/default/files/creative/categories/materials.lua b/games/default/files/creative/categories/materials.lua index 25b3d97ad..1f3fe062f 100644 --- a/games/default/files/creative/categories/materials.lua +++ b/games/default/files/creative/categories/materials.lua @@ -15,4 +15,7 @@ return { "default:sugarcane", "default:stick", "default:gunpowder", + "default:book", + "default:paper", + "workbench:hammer", } \ No newline at end of file diff --git a/games/default/files/creative/categories/misc.lua b/games/default/files/creative/categories/misc.lua index aba2ed85e..4f2dffc73 100644 --- a/games/default/files/creative/categories/misc.lua +++ b/games/default/files/creative/categories/misc.lua @@ -1,10 +1,39 @@ return { "default:snow", - "default:book", "mesecons_materials:glue", - "default:paper", "bucket:bucket_empty", "bucket:bucket_water", "bucket:bucket_river_water", "bucket:bucket_lava", + + "mobs_animal:bear", + "mobs_animal:bunny", + "mobs_animal:chicken", + "mobs_animal:cow", + "mobs_animal:dog", + "mobs_animal:kitten", + "mobs_animal:pig", + "mobs_animal:wolf", + + "mobs_animal:sheep_grey", + "mobs_animal:sheep_magenta", + "mobs_animal:sheep_pink", + "mobs_animal:sheep_white", + "mobs_animal:sheep_magenta", + "mobs_animal:sheep_orange", + "mobs_animal:sheep_blue", + "mobs_animal:sheep_dark_grey", + "mobs_animal:sheep_pink", + "mobs_animal:sheep_red", + "mobs_animal:sheep_dark_green", + "mobs_animal:sheep_violet", + "mobs_animal:sheep_white", + "mobs_animal:sheep_black", + "mobs_animal:sheep_yellow", + "mobs_animal:sheep_brown", + + "mobs_monster:spider", + "mobs_monster:small_spider", + "mobs_monster:skeleton", + "mobs_monster:zombie", } \ No newline at end of file diff --git a/games/default/files/creative/categories/tools.lua b/games/default/files/creative/categories/tools.lua index 80117e4c2..5c68d2457 100644 --- a/games/default/files/creative/categories/tools.lua +++ b/games/default/files/creative/categories/tools.lua @@ -20,4 +20,7 @@ return { "farming:hoe_gold", "farming:hoe_diamond", "default:pole", + "mobs:shears", + "watch:0", + "fire:flint_and_steel", } \ No newline at end of file diff --git a/games/default/files/creative/inventory.lua b/games/default/files/creative/inventory.lua index 907ac883e..8476ec692 100644 --- a/games/default/files/creative/inventory.lua +++ b/games/default/files/creative/inventory.lua @@ -56,7 +56,7 @@ bg["food"] = "default_apple.png" bg["tools"] = "default_tool_diamondpick.png" bg["combat"] = "default_tool_steelsword.png" bg["matr"] = "default_emerald.png" -bg["brew"] = "potions_bottle.png" +bg["brew"] = "vessels_glass_bottle.png" bg["all"] = "default_paper.png" local function init_creative_cache(tab_name, group) @@ -132,8 +132,9 @@ local function get_button_formspec(player_name, start_i) if not item then return buttons end - buttons = buttons.."item_image_button[".. - (x + 0.01)..","..(y + 1.67)..";1,1;"..item..";"..item..";]" + buttons = buttons.."item_image[".. + (x + 0.01)..","..(y + 1.67)..";1,1;"..item.."]image_button[".. + (x + 0.01)..","..(y + 1.67)..";1,1;blank.png;"..item..";;;false]" i = i + 1 end end diff --git a/games/default/files/default/nodes.lua b/games/default/files/default/nodes.lua index 5026d6e7b..8665a58dd 100644 --- a/games/default/files/default/nodes.lua +++ b/games/default/files/default/nodes.lua @@ -1250,10 +1250,10 @@ minetest.register_node("default:lava_flowing", { -- local bookshelf_formspec = - "size[8,7;]" .. - "list[context;books;0,0.3;8,2;]" .. - "list[current_player;main;0,2.85;8,1;]" .. - "list[current_player;main;0,4.08;8,3;8]" .. + "size[9,7;]" .. + "list[context;books;0,0.3;9,2;]" .. + "list[current_player;main;0,2.85;9,1;]" .. + "list[current_player;main;0,4.08;9,3;9]" .. "listring[context;books]" .. "listring[current_player;main]" diff --git a/games/default/files/flowers/init.lua b/games/default/files/flowers/init.lua index ae81fbec7..8f053c1c7 100644 --- a/games/default/files/flowers/init.lua +++ b/games/default/files/flowers/init.lua @@ -1,17 +1,11 @@ --- MultiCraft game mod: default --- See README.txt for licensing and other information. - - -- Namespace for functions flowers = {} - -- Map Generation dofile(minetest.get_modpath("flowers") .. "/mapgen.lua") - -- -- Flowers -- @@ -26,7 +20,6 @@ minetest.register_alias("flowers:flower_allium", "flowers:allium") minetest.register_alias("flowers:flower_dandelion_white", "flowers:dandelion_white") minetest.register_alias("flowers:dandelion_white", "flowers:oxeye_daisy") - -- Flower registration local function add_simple_flower(name, desc, box, f_groups) diff --git a/games/default/files/mobs_redo/api.lua b/games/default/files/mobs_redo/api.lua index a7486efbf..50c6ba32c 100644 --- a/games/default/files/mobs_redo/api.lua +++ b/games/default/files/mobs_redo/api.lua @@ -82,7 +82,7 @@ local mob_class = { owner = "", order = "", jump_height = 4, - lifetimer = 1200, -- was 20 minutes + lifetimer = 600, -- was 10 minutes physical = true, collisionbox = {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25}, visual_size = {x = 1, y = 1}, diff --git a/games/default/files/mobs_redo/crafts.lua b/games/default/files/mobs_redo/crafts.lua index b4ee7359e..8d82b8528 100644 --- a/games/default/files/mobs_redo/crafts.lua +++ b/games/default/files/mobs_redo/crafts.lua @@ -65,23 +65,9 @@ minetest.register_craft({ cooktime = 5, }) --- lasso -minetest.register_tool("mobs:lasso", { - description = "Lasso (right-click animal to put in inventory)", - inventory_image = "mobs_magic_lasso.png", - groups = {flammable = 2}, -}) +minetest.register_alias("mobs:magic_lasso", "farming:string") +minetest.register_alias("mobs:lasso", "farming:string") - minetest.register_craft({ - output = "mobs:lasso", - recipe = { - {"farming:string", "", "farming:string"}, - {"", "default:diamond", ""}, - {"farming:string", "", "farming:string"}, - } - }) - -minetest.register_alias("mobs:magic_lasso", "mobs:lasso") -- shears (right click to shear animal) minetest.register_tool("mobs:shears", { description = "Steel Shears (right-click to shear)", diff --git a/games/default/files/mobs_redo/textures/mobs_magic_lasso.png b/games/default/files/mobs_redo/textures/mobs_magic_lasso.png deleted file mode 100644 index 11bb8b3d8b53e16df610eb303e09c652a81b0cf7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHV5AX?b6=Yxt^*32FFY4T(w)@vs zl%$(^0;L#Bg8YIR9G=}s19H4PT^vI=WLXa|avoveV7-ve{5Phtk+nrM;(rkP6`$rk z?;YQsF)Mm9VVT{MmCmz%O;C0}doE|P`FXjmJMWwByp_Gg*LhvzEoPr)d$|?t{%2Hg RNdrw~@O1TaS?83{1OO6TJ7)j@ diff --git a/games/default/files/potions/modpack.txt b/games/default/files/player/modpack.txt similarity index 100% rename from games/default/files/potions/modpack.txt rename to games/default/files/player/modpack.txt diff --git a/games/default/files/player/pep/README.md b/games/default/files/player/pep/README.md new file mode 100644 index 000000000..72ba61d6e --- /dev/null +++ b/games/default/files/player/pep/README.md @@ -0,0 +1,78 @@ +# Pep: Player Effects Potions +Version 1.4.0 + +## Introduction +This little mod adds some simple potions which add temporary effects when consumed. +Currently, the potions affect breath, health, player gravity, running speed and jump height. + + * License of everything: MIT License + +## List of potions and crafting recipes +All crafting recipes are shapeless. + +### Breath +#### Air potion +Gives you breath underwater for 30s. +Craft: 8 papyri, 1 glass bottle. + +All 8 papyri must occupy one slot. + +### Gravity +#### Non-gravity potion +Negates all gravity for you, for 20s. +Craft: 1 mese crystal, 1 glass bottle + +#### Gravity neutralizer +Clears all your gravity effects. +Craft: 1 non-gravity potion, 1 iron lump + +### Jump height +#### High jumping potion +Lets you jump higher for 30s. +Craft: 1 orange tulip, 1 grass, 2 mese crystal fragments, 1 glass bottle + +#### Low jumping potion +Makes you jump lower for 30s. +Craft: 1 leaves block, 1 jungle leaves block, 1 iron lump, 1 yellow dandelion, 1 glass bottle + +#### Jump neutralier +Clears all jump effects. +Craft: 1 high jumping potion, 1 low jumping potion. + + +### Health +#### Weak healing potion +Gives you 1 HP every 2 seconds, 10 times. +Craft: 1 cactus, 1 flour, 1 brown mushroom, 1 glass bottle. + +#### Strong healing potion +Gives you 2 HP every second, 10 times. +Craft: 1 gold lump, 1 flour, 1 weak healing potion. + + +### Walking speed +#### Running potion +Makes you run faster for 30s. +Craft: 1 pine sapling, 1 cactus, 1 yellow dandelion, 1 jungle grass, 1 glass bottle. + +#### Slug potion +Makes you walk slower for 30s. +Craft: 1 dry grass, 1 ice, 1 glass bottle. + +#### Speed neutralizer +Clears all running speed effects. +Craft: 1 running potion, 1 slug potion. + +### Mana (needs Mana mod) +#### Weak mana potion +Increases mana regeneration rate by 0.5 for 10 seconds. +Craft: 2 dry shrubs, 1 cotton seed, 1 mese crystal fragment, 1 glass bottle. + +#### Strong mana potion +Increases mana regeneration rate by 1 for 10 seconds. +Craft: 4 dry shrubs, 1 jungle sapling, 1 acacia tree sapling, 1 mese crystal fragment, 1 weak mana potion. + +### Other potions +#### Mole potion +Digs out two blocks directly in front of you, for 18 seconds. +Craft: 1 steel pickaxe, 1 steel shovel, 1 glass bottle. diff --git a/games/default/files/player/pep/depends.txt b/games/default/files/player/pep/depends.txt new file mode 100644 index 000000000..34feae0cc --- /dev/null +++ b/games/default/files/player/pep/depends.txt @@ -0,0 +1,7 @@ +playereffects +playerphysics? +default? +vessels? +flowers? +farming? +intllib? diff --git a/games/default/files/player/pep/init.lua b/games/default/files/player/pep/init.lua new file mode 100644 index 000000000..20de66fe6 --- /dev/null +++ b/games/default/files/player/pep/init.lua @@ -0,0 +1,447 @@ +-- Boilerplate to support localized strings if intllib mod is installed. +local S +if minetest.get_modpath("intllib") then + S = intllib.Getter() +else + S = function(s) return s end +end +local ppa = minetest.get_modpath("playerphysics") + +pep = {} +function pep.register_potion(potiondef) + local on_use + if(potiondef.effect_type ~= nil) then + on_use = function(itemstack, user, pointed_thing) + -- Particles + minetest.add_particlespawner({ + amount = 40, + time = 0.1, + minpos = pointed_thing.above, + maxpos = pointed_thing.above, + minvel = {x = -1, y = 1, z = -1}, + maxvel = {x = 1, y = 2, z = 1}, + minacc = {x = 0, y = -5, z = 0}, + maxacc = {x = 0, y = -9, z = 0}, + minexptime = 1, + maxexptime = 3, + minsize = 1, + maxsize = 3, + collisiondetection = false, + vertical = false, + texture = "pep_"..potiondef.basename..".png", + }) + playereffects.apply_effect_type(potiondef.effect_type, potiondef.duration, user) + itemstack:take_item() + return itemstack + end + else + on_use = function(itemstack, user, pointed_thing) + -- Particles + minetest.add_particlespawner({ + amount = 40, + time = 0.1, + minpos = pointed_thing.above, + maxpos = pointed_thing.above, + minvel = {x = -1, y = 1, z = -1}, + maxvel = {x = 1, y = 2, z = 1}, + minacc = {x = 0, y = -5, z = 0}, + maxacc = {x = 0, y = -9, z = 0}, + minexptime = 1, + maxexptime = 3, + minsize = 1, + maxsize = 3, + collisiondetection = false, + vertical = false, + texture = "pep_"..potiondef.basename..".png", + }) + itemstack:take_item() + return itemstack + end + end + minetest.register_craftitem("pep:"..potiondef.basename, { + description = string.format(S("Glass Bottle (%s)"), potiondef.contentstring), + _doc_items_longdesc = potiondef.longdesc, + _doc_items_usagehelp = S("Hold it in your hand, then left-click to drink it."), + inventory_image = "pep_"..potiondef.basename..".png^[mask:pep_glass_bottle_overlay.png", + wield_image = "pep_"..potiondef.basename..".png^[mask:pep_glass_bottle_overlay.png", + on_use = on_use, + groups = {vessel = 1}, + }) +end + +pep.moles = {} + +function pep.enable_mole_mode(playername) + pep.moles[playername] = true +end + +function pep.disable_mole_mode(playername) + pep.moles[playername] = false +end + +function pep.yaw_to_vector(yaw) + local tau = math.pi*2 + + yaw = yaw % tau + if yaw < tau/8 then + return { x=0, y=0, z=1} + elseif yaw < (3/8)*tau then + return { x=-1, y=0, z=0 } + elseif yaw < (5/8)*tau then + return { x=0, y=0, z=-1 } + elseif yaw < (7/8)*tau then + return { x=1, y=0, z=0 } + else + return { x=0, y=0, z=1} + end +end + +function pep.moledig(playername) + local player = minetest.get_player_by_name(playername) + + local yaw = player:get_look_yaw() + -- fix stupid oddity of Minetest, adding pi/2 to the actual player's look yaw... + -- TODO: Remove this code as soon as Minetest fixes this. + yaw = yaw - math.pi/2 + + local pos = vector.round(player:getpos()) + + local v = pep.yaw_to_vector(yaw) + + local digpos1 = vector.add(pos, v) + local digpos2 = { x = digpos1.x, y = digpos1.y+1, z = digpos1.z } + + local try_dig = function(pos) + local n = minetest.get_node(pos) + local ndef = minetest.registered_nodes[n.name] + if ndef.walkable and ndef.diggable then + if ndef.can_dig ~= nil then + if ndef.can_dig() then + return true + else + return false + end + else + return true + end + else + return false + end + end + + local dig = function(pos) + if try_dig(pos) then + local n = minetest.get_node(pos) + local ndef = minetest.registered_nodes[n.name] + if ndef.sounds ~= nil then + minetest.sound_play(ndef.sounds.dug, { pos = pos }) + end + -- TODO: Replace this code as soon Minetest removes support for this function + local drops = minetest.get_node_drops(n.name, "default:pick_steel") + minetest.dig_node(pos) + local inv = player:get_inventory() + local leftovers = {} + for i=1,#drops do + table.insert(leftovers, inv:add_item("main", drops[i])) + end + for i=1,#leftovers do + minetest.add_item(pos, leftovers[i]) + end + end + end + + dig(digpos1) + dig(digpos2) +end + +pep.timer = 0 + +minetest.register_globalstep(function(dtime) + pep.timer = pep.timer + dtime + if pep.timer > 0.5 then + for playername, is_mole in pairs(pep.moles) do + if is_mole then + pep.moledig(playername) + end + end + pep.timer = 0 + end +end) + +local add_physic = function(player, attribute, value) + if ppa then + playerphysics.add_physics_factor(player, attribute, "pep:"..attribute, value) + else + player:set_physics_override({[attribute]=value}) + end +end +local remove_physic = function(player, attribute) + if ppa then + playerphysics.remove_physics_factor(player, attribute, "pep:"..attribute) + else + player:set_physics_override({[attribute]=1}) + end +end + +playereffects.register_effect_type("pepspeedplus", S("High speed"), "pep_speedplus.png", {"speed"}, + function(player) + add_physic(player, "speed", 2) + end, + function(effect, player) + remove_physic(player, "speed") + end +) +playereffects.register_effect_type("pepspeedminus", S("Low speed"), "pep_speedminus.png", {"speed"}, + function(player) + add_physic(player, "speed", 0.5) + end, + function(effect, player) + remove_physic(player, "speed") + end +) +playereffects.register_effect_type("pepspeedreset", S("Speed neutralizer"), "pep_speedreset.png", {"speed"}, + function() end, function() end) +playereffects.register_effect_type("pepjumpplus", S("High jump"), "pep_jumpplus.png", {"jump"}, + function(player) + add_physic(player, "jump", 2) + end, + function(effect, player) + remove_physic(player, "jump") + end +) +playereffects.register_effect_type("pepjumpminus", S("Low jump"), "pep_jumpminus.png", {"jump"}, + function(player) + add_physic(player, "jump", 0.5) + end, + function(effect, player) + remove_physic(player, "jump") + end +) +playereffects.register_effect_type("pepjumpreset", S("Jump height neutralizer"), "pep_jumpreset.png", {"jump"}, + function() end, function() end) +playereffects.register_effect_type("pepgrav0", S("No gravity"), "pep_grav0.png", {"gravity"}, + function(player) + add_physic(player, "gravity", 0) + end, + function(effect, player) + remove_physic(player, "gravity") + end +) +playereffects.register_effect_type("pepgravreset", S("Gravity neutralizer"), "pep_gravreset.png", {"gravity"}, + function() end, function() end) +playereffects.register_effect_type("pepregen", S("Regeneration"), "pep_regen.png", {"health"}, + function(player) + player:set_hp(player:get_hp()+1) + end, + nil, nil, nil, 2 +) +playereffects.register_effect_type("pepregen2", S("Strong regeneration"), "pep_regen2.png", {"health"}, + function(player) + player:set_hp(player:get_hp()+2) + end, + nil, nil, nil, 1 +) +playereffects.register_effect_type("pepbreath", S("Perfect breath"), "pep_breath.png", {"breath"}, + function(player) + player:set_breath(player:get_breath()+2) + end, + nil, nil, nil, 1 +) +playereffects.register_effect_type("pepmole", S("Mole mode"), "pep_mole.png", {"autodig"}, + function(player) + pep.enable_mole_mode(player:get_player_name()) + end, + function(effect, player) + pep.disable_mole_mode(player:get_player_name()) + end +) + +pep.register_potion({ + basename = "speedplus", + contentstring = S("Running Potion"), + longdesc = S("Drinking it will make you run faster for 30 seconds."), + effect_type = "pepspeedplus", + duration = 30, +}) +pep.register_potion({ + basename = "speedminus", + contentstring = S("Slug Potion"), + longdesc = S("Drinking it will make you walk slower for 30 seconds."), + effect_type = "pepspeedminus", + duration = 30, +}) +pep.register_potion({ + basename = "speedreset", + contentstring = S("Speed Neutralizer"), + longdesc = S("Drinking it will stop all speed effects you may currently have."), + effect_type = "pepspeedreset", + duration = 0 +}) +pep.register_potion({ + basename = "breath", + contentstring = S("Air Potion"), + longdesc = S("Drinking it gives you breath underwater for 30 seconds."), + effect_type = "pepbreath", + duration = 30, +}) +pep.register_potion({ + basename = "regen", + contentstring = S("Weak Healing Potion"), + longdesc = S("Drinking it makes you regenerate health. Every 2 seconds, you get 1 HP, 10 times in total."), + effect_type = "pepregen", + duration = 10, +}) +pep.register_potion({ + basename = "regen2", + contentstring = S("Strong Healing Potion"), + longdesc = S("Drinking it makes you regenerate health quickly. Every second you get 2 HP, 10 times in total."), + effect_type = "pepregen2", + duration = 10, +}) +pep.register_potion({ + basename = "grav0", + contentstring = S("Non-Gravity Potion"), + longdesc = S("When you drink this potion, gravity stops affecting you, as if you were in space. The effect lasts for 20 seconds."), + effect_type = "pepgrav0", + duration = 20, +}) +pep.register_potion({ + basename = "gravreset", + contentstring = S("Gravity Neutralizer"), + longdesc = S("Drinking it will stop all gravity effects you currently have."), + effect_type = "pepgravreset", + duration = 0, +}) +pep.register_potion({ + basename = "jumpplus", + contentstring = S("High Jumping Potion"), + longdesc = S("Drinking it will make you jump higher for 30 seconds."), + effect_type = "pepjumpplus", + duration = 30, +}) +pep.register_potion({ + basename = "jumpminus", + contentstring = S("Low Jumping Potion"), + longdesc = S("Drinking it will make you jump lower for 30 seconds."), + effect_type = "pepjumpminus", + duration = 30, +}) +pep.register_potion({ + basename = "jumpreset", + contentstring = S("Jump Neutralizer"), + longdesc = S("Drinking it will stop all jumping effects you may currently have."), + effect_type = "pepjumpreset", + duration = 0, +}) +pep.register_potion({ + basename = "mole", + contentstring = S("Mole Potion"), + longdesc = S("Drinking it will start an effect which will magically attempt to mine any two blocks in front of you horizontally, as if you were using a steel pickaxe on them. The effect lasts for 18 seconds."), + effect_type = "pepmole", + duration = 18, +}) + + +--[=[ register crafts ]=] +--[[ normal potions ]] +if(minetest.get_modpath("vessels")~=nil) then +if(minetest.get_modpath("default")~=nil) then + minetest.register_craft({ + type = "shapeless", + output = "pep:breath", + recipe = { "default:papyrus", "default:papyrus", "default:papyrus", "default:papyrus", + "default:papyrus", "default:papyrus", "default:papyrus", "default:papyrus", "vessels:glass_bottle" } + }) + minetest.register_craft({ + type = "shapeless", + output = "pep:speedminus", + recipe = { "default:dry_grass_1", "default:ice", "vessels:glass_bottle" } + }) + if(minetest.get_modpath("flowers") ~= nil) then + minetest.register_craft({ + type = "shapeless", + output = "pep:jumpplus", + recipe = { "flowers:flower_tulip", "default:grass_1", "default:mese_crystal_fragment", + "default:mese_crystal_fragment", "vessels:glass_bottle" } + }) + minetest.register_craft({ + type = "shapeless", + output = "pep:poisoner", + recipe = { "flowers:mushroom_red", "flowers:mushroom_red", "flowers:mushroom_red", "vessels:glass_bottle" } + }) + + if(minetest.get_modpath("farming") ~= nil) then + minetest.register_craft({ + type = "shapeless", + output = "pep:regen", + recipe = { "default:cactus", "farming:flour", "flowers:mushroom_brown", "vessels:glass_bottle" } + }) + end + end + if(minetest.get_modpath("farming") ~= nil) then + minetest.register_craft({ + type = "shapeless", + output = "pep:regen2", + recipe = { "default:gold_lump", "farming:flour", "pep:regen" } + }) + + minetest.register_craft({ + type = "shapeless", + output = "pep:jumpminus", + recipe = { "default:leaves", "default:jungleleaves", "default:iron_lump", "flowers:dandelion_yellow", "vessels:glass_bottle" } + }) + minetest.register_craft({ + type = "shapeless", + output = "pep:grav0", + recipe = { "default:mese_crystal", "vessels:glass_bottle" } + }) + minetest.register_craft({ + type = "shapeless", + output = "pep:mole", + recipe = { "default:pick_steel", "default:shovel_steel", "vessels:glass_bottle" }, + }) + minetest.register_craft({ + type = "shapeless", + output = "pep:gravreset" , + recipe = { "pep:grav0", "default:iron_lump" } + }) +end +if(minetest.get_modpath("flowers") ~= nil) then + minetest.register_craft({ + type = "shapeless", + output = "pep:speedplus", + recipe = { "default:pine_sapling", "default:cactus", "flowers:dandelion_yellow", "default:junglegrass", "vessels:glass_bottle" } + }) +end +end +end + +--[[ independent crafts ]] + +minetest.register_craft({ + type = "shapeless", + output = "pep:speedreset", + recipe = { "pep:speedplus", "pep:speedminus" } +}) +minetest.register_craft({ + type = "shapeless", + output = "pep:jumpreset", + recipe = { "pep:jumpplus", "pep:jumpminus" } +}) + + +--[[ aliases ]] + +minetest.register_alias("potionspack:antigravity", "pep:grav0") +minetest.register_alias("potionspack:antigravityii", "pep:gravreset") +minetest.register_alias("potionspack:speed", "pep:speedminus") +minetest.register_alias("potionspack:speedii", "pep:speedplus") +minetest.register_alias("potionspack:inversion", "pep:speedreset") +minetest.register_alias("potionspack:confusion", "pep:breath") +minetest.register_alias("potionspack:whatwillthisdo", "pep:mole") +minetest.register_alias("potionspack:instanthealth", "pep:regen") +minetest.register_alias("potionspack:instanthealthii", "pep:regen2") +minetest.register_alias("potionspack:regen", "pep:regen") +minetest.register_alias("potionspack:regenii", "pep:regen2") +minetest.register_alias("potionspack:harming", "pep:gravreset") +minetest.register_alias("potionspack:harmingii", "pep:gravreset") diff --git a/games/default/files/player/pep/textures/pep_breath.png b/games/default/files/player/pep/textures/pep_breath.png new file mode 100644 index 0000000000000000000000000000000000000000..52f9d0908bfa650df16f57e7db60a67d8dc767ad GIT binary patch literal 843 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dya{_!qTu+}qedf%W^XJbWKYskw zsZ+;}9lLPh!if_nu3Wit_Uze<7cU+?di2PVBZm(kK5*c`xpU_(UAlDh=FO8QPaZmS z=-|PF`}gm^cJ12Lt5KCPvSsVmtq&eN*t~i3y?ggwzI?f1!-l6% zpWeB1XUdF4tAOq_DGBlmentl1i*^oVU|`bnba4!+U}QbW+N5mGz+iAwE{!LBX5ad^ z|Nn=1o{fm*n`?Sx=l(OVj=K8syzURas+oW0zRlU4ucm}gQB#~F_3*I*N+`s?Hd|t#Cw&a=biua_L>DH zuMPb~TDIlBw2R?ey?4u5i3wTfKTcg$t;HPsHpM~e^aWi3x8#2u7PELoLmN%xYHWAD z?%HxGW=BN?^Ah{VeY_uDv#nja^ZYtz+dqYmt-j9sI(_=tFB6+TdoT3<7&uvEpXcNA zCBCQDtWsw*DUjg%RX=M&rH zw+~;HTmPl#}w@o%9DP*NT|5o_4t;sy{Y~;Cco{4w~Q>Vt-n|zT6x9n?5}gT z%1?Knw$`n<(sy^;r#e5&8CzW~v|6h_%>MJc=+^@0&Ibp}%~PCrZjm*<74Gg9v zpWR;Q=J%#baY`qZ=~b!n2;&DBzW_^z~yebrn2dO~W}d80tH zN&}xu%Q~jGH}M?G^nP8;7TdOpd&|-<7TPS1qQCd5*c?mV7f`zFKjSF@rMYPvj$Q$# OItEWyKbLh*2~7aVQ`dk1 literal 0 HcmV?d00001 diff --git a/games/default/files/player/pep/textures/pep_glass_bottle_overlay.png b/games/default/files/player/pep/textures/pep_glass_bottle_overlay.png new file mode 100644 index 0000000000000000000000000000000000000000..2202e941f12c98ffe1f4762db6c504c8098af546 GIT binary patch literal 222 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJrJgR1Ar*|t5|a`{dYZI%&in7L za_irH;jAC^ljnc?KlR$@=C0 z%V&@N^EVNa66ABRVB%P&n4EI@nqcc zAY68!;fGwTu5XR~CK-pmrOMYC4YoR8Wt<{@&_titamI`a_J<2^X)LvuU}aG6kaGyT STp|o~FoUP7pUXO@geCySKUTf~ literal 0 HcmV?d00001 diff --git a/games/default/files/player/pep/textures/pep_grav0.png b/games/default/files/player/pep/textures/pep_grav0.png new file mode 100644 index 0000000000000000000000000000000000000000..e7f6d31d0db7cf15157d9e2c70d701c475f69811 GIT binary patch literal 637 zcmV-@0)qXCP)$!m7O=y2@}s$b_AScmgRqx{uj^v zF;V2}&N^xy!QIq!i7pKzCU~g^7j?N3icDQ8E)*{;(>awXBW5h`+x7^x{l{L-@+BG~ z;=Q~ZpR!onvcRM_9tWR_Qf>L3+EeMYU!tNQpo=)+WtikMufD?A(+Ah5xU-+h91V0} z9I8>h3J$gQe(oCS?aayGW`UVYx`eHEp#(V3^PZ-dR7d&RHsR;yh}{&Ief_w1!^A@a zk3k`Hak)?PajdA!r5U#phQrgm1`eZq$cFc}j*~KG$k zV>s#SdKLI<;G}#(EV?iDzpEG;oLBS$4-Sbl-U?pwleDlTIudm zz9@=*)!n*B9IJ!aDYi6+ZziDUyyV&&byD&!eoMztzmu(3v#C||rRl#ccBfALoZI17 Xl1?-APD`Af00000NkvXXu0mjfJfJu0 literal 0 HcmV?d00001 diff --git a/games/default/files/player/pep/textures/pep_gravreset.png b/games/default/files/player/pep/textures/pep_gravreset.png new file mode 100644 index 0000000000000000000000000000000000000000..374da5f99b11c7eb95d91e0ca1a62c4ecdb52f05 GIT binary patch literal 758 zcmV0ju|Bx~Nf+P2VBKDCo z|9u|vjxYazAoP?q|Bo>LmpK1^AM<${?tC5bdmQkVH~*M9|92SdnL7V<7V4Ti|C>Dj zoj(6~8SQo#>zqCRobph5p}66SLh=%hveqeTC25aeYtIl}+|0vkz0 zK~#7F1;K@3Bsl;8Fxehvo~3Yd{M3JQFA3n(6xi?b51G0QD)d{+d8tpXopo{ZK&KHG zMj-MYShjclRMkx}g7vC&Se28nq8LUc%4U8ZDK$}@Vd=<*pE`C9#-{`!@d*@N(@A&I z^p#DOQI0TMTr+3W`d5pw8gk8m6sU7TIYrf0*79_S-?bCC9UISGI~by2*xoBhClvV2 z{Y@BK0zeG%8W1jdJtpf5Pq83l>EqZef?4QVUS1Pi+(aV>q9VOkVMX;+Ir;p%$vfMX z&h&Vj_bcD(B<}pRl!V7`U_(}kpcVT%ds{sjpLKG(g!WPVT3>!*rXSoS(cp|dxH;{) z>`#w9=?Cya6^fQ5L)a|60*?J_*RO3N9FH>npvYug746aImEr=rD`NLF@Jc5OSNxFCjz zucr@UU*v|WUfpC!H2%2+mKn`F6sOZUE#^W=r>!wzxbHJhAx&}hp?J%u4odAZ{dzs~ z7ya=bqQ-queO`{&O~2OyRBnx?3}}~YR<@JwjU;9&KXUJdZ*F;>@!ykGOLs5IW|c5s o%S9slGp5Tk(#X?uGu0ga2Q|_mo#W(2LjV8(07*qoM6N<$f`J%tp#T5? literal 0 HcmV?d00001 diff --git a/games/default/files/player/pep/textures/pep_jumpminus.png b/games/default/files/player/pep/textures/pep_jumpminus.png new file mode 100644 index 0000000000000000000000000000000000000000..d10fac3d35e442dd2ffd7e5e70dfea654650a1fd GIT binary patch literal 755 zcmVn8vIM*sgr@$M=A|3m-(N$~9`|Nlt;|40A-Mepn< z?CB)`|4i-bCIA0Q>gOW=|4ZlOALip8|Nl+p;vMMaAnWKO&?jn60006WNkl1S4#9cB!8#k@a* z^bV{-u6*5ZiO9_soM<&Zt54DB{5R=)z=xd+bkQ$AI8}8y%@E$`OrP2N9cOi zg231gB5ys&Pi~pwjoxr|xxNS6B!K3#g51xp%u~l7NqtvHDy>Ri>s=CZLtCD#SsB#n zN~|$;ct=^U)uaIlRSfqc0EK%E^<-p>s@FKLdn zQg%^OXNj_XoxnOWl#g!Z3x?SJ^R~oV(eYT`d-EbiCn)coN&BilZ^>m6#Bgd`*&&+9 z@$j_MA*2_Ht!K>B$^%sL?=OV$bQ{R{2ki0Kjy lhHuBzm8xydgNq~X{{yW@rE7phaTvC6#u6_ z>3$XJe-{6yJ^!db>wp*kq&xqmJpZae^-g0Cyb7p#;BY`BrQuN9Uyz$vwj|=6j zJwNX`0}VW1Vz%sPfsVtj^rp)?r6oUq*hrjt%1U z>R6PTD^AAJQ0&Q`Y0^4e>h$CEsd0?14*K`gcsL}xR?!dD-#r6|LW%vnvX4gnus40{ zO0ET0OTgX!j$MP$)6LDyyHHy<>Nbcl(I&ZF?esQFs)Z&&YgeeL%S^guweFWr#fyva#{|~VXB-2G-VIFtEyH&&yii{$jr}iO?-3i0}JENY8W&Rf=b8h=k&TE-+*6zLS?h{7; z1^bua-n^2p8pUOsv?zcl4#RR$D|_gj;XVwIib^xeVNpMCT^qa&jGTCzy22FDM1!uZ z=C9->t5!-+KM{?~6<>#eueNvGeSpWyjk<`)jT?PERYwZ9ehsDL9f!x|It75y(|CCJNUvd|Ia=D&_4IU zFaOm;?zkrOzAXRLLjTi2_P{RjyD9(IMfJZe^1Lel*+>7{NdMSI@VY4f) zh+0S1K?iv%MxUTL_v6PQftXF#y42CSNvNmRYzXD8En!zuW$?5d&9v=O{}J4LU7`KR z3Ho`MSwyLo@qYHU}6eqme? ziWI``28(#&dRVI6Oz?T=OnJ&D*_c8TUWa(nLhg(5DAkHvac}n7u1cgvc|fOXM|Gv> zedoD*j>;lDEQqD)cXXqMIN7e36y7T+SVzj#*)m9xG8e8wtDF$yVOY~o)ro1M-tUp? zSIeVNG}Yn3YEAd^d-2lb-L1Ah4AlpcabADCWnx@6!X>Np zRgr@Ge6@Hlbs>>}O(S^3HCn3lV_H{XM&Mxs=s=CP3sOgWp)OW6m{q7SN z4c?qCgk5UloBK8dDnr__;n8>K4erA!9bQK?*5;q{YJD804*I9(&&KC`_9|mbm8*aE zB|&GVLF?I@#bJ!QFonxVFsR49UrGfVg#u|_n~1IS-w3YE zpZh(j|2U-oG@$%BrT;OV`8A>aFr4^4s{b;c`Z}inK&<~fsQ){s|2CrjFPrx*ne{H3 z_Cc-xE0^;>tN$vN@+p<^ESU5{uKz``|3k0;CzJ0+vj0oB|4Fs~M6mxTl<*{w>_@Zz zOt}9gk?l&h{~(O$NVNY>y8j-E=25->CX((WkLw?c=TE!;QojFCy#J0}Rki>C0xwBK zK~#8N70flFZASpWFby1LxD1a!h4;U?BraV@m!iALMF6K4My2AIWW^5N3^UEg0cMA$ z(>j$=#CjTBK;a;qWkOL7QT^I=#j7(P(yb0he!*zG*SYpqFiz;JrcOVqC2A+#(0Ka| zQ0mQs(*YTBH2Qx1N={EmL$&LmsgId0lr!z{Uzfs!zQ@Ed2|7J=N#*fv%)uK*`^{?| zE1xvw_DuGBIek;z&bw3T#E6!<($5dpm$Y07RWON8F1>3B&DM$wYo*V*UUnYg_gTBx z?}qh*13ZN8+3eMBX{YNaA8cL!ozJ|CB%-ux-_PyZ{Z#U6$RsDVF_j#C*0a;53R5bL zIzgmd_k2U~pv^NrhqNVskhVFYyNQ<9a6I28h$OEtZpEQI4!DF~BbRL+tF9}y3&%y! z%-6fld$of@dsh?|`z#{d=fcOfA3}@J_gc4UQWu5lBvF>)-2Umox>Al7`Zt5;UwJ(6 zLsCI!-~NtnwUow~eu#`vb=CFaq5$W$^c5b>*_2x_jEeixpR%Ho7ekb&enO|_IH_Cb zXj069az1}Avi|k+s)s$7{{bkz3Gq-_o9L31|L}yB-n0R8V`BCH8Qq%{6in+;GZu%7 zFft$*EsM8cQ_|-nGUXT&L<rB+zPBjB3fjMPMi(L*@+7ptEl-F<$1#Q*>R07*qo IM6N<$f~fzH1ONa4 literal 0 HcmV?d00001 diff --git a/games/default/files/player/pep/textures/pep_manaregen2.png b/games/default/files/player/pep/textures/pep_manaregen2.png new file mode 100644 index 0000000000000000000000000000000000000000..114f39465b8ef41780feccc713df365690bf9ba5 GIT binary patch literal 772 zcmV+f1N;1mP)j>N|1>`QK1lyKLjN^C{V_ZFGCcY-J^MRF|3ORtIYa+FNB=rR|1CH5D>d^hHuNt! z_eD?tFgo}yIQBzL|0*={L{9%eO8-bw|369pM^XPLG4Dc5|3*;%NmKtQGVo1T|0Xc* zB`@tvR{tq8@l##@BrfbxTmMT{|4LNs1Vr%|ywnfjw}2fTJsAmzf*iW+|wiKH5eTw2HA*i!O= z@^pLb4SheH_B=~Nm5!iEy5Q-S4EDDUlVKL2(kjZU#4OvlUb%Lnlf2Coju!OQbeW}R zdWBE4z86|+zBDujt{nLmHh;h<8Jo`s-#m?m3;CC98Ox+*MV>bwCl>v3OZxl_8S_gC z72HGm(W@M|p4>MLycfm2Z^g#4O4XG_i1j=K@o)Xh808nOSd*2NNsTM~xOTj6yXRX~ zmfdC9$(^9 z6GpY`4EpMy(gX{HJ3}4A8kebi7u9C6&iK zvn0xaLuQQiwH>h%mDKa)obzi*i+j?9Y%0d=mGOU8E+V+09=Kru00009?dFr$1it%f_Uhdio-IHi6wpm{E=g*u;jEuD5NuZTUfj6t!A zKdXc}oOLR&i9VNbC7N?6m~keacPz4tK$&tUw2eZxk3_YOL%5Mfw~$4fbSb%#N0e_)mTx4GX&#YkAG?%Ek7yl;VHU!hP{5f^yp>A6mrRUh8o!uLJC1qV z0006ONklH2EzkWpJYvhrJxstp=%{248aVVep!xJEUrz4Hpe z8F9)iY%1!35RcN5y5(WPo#)UKNysp6TD zC`Q&$|GtMkl_)NX(47e~Zt0_FnSH|+6cmf&k5;-xi zfXhQ=+TZIwzsRLke;R2F0qUtM?}8%%sfSOStWS&`U>YA~^jdXEEomQ`GjyWWx}&Az z6~}pW62~uHD{>9JhZzy^v?>*i%@e{~H2dj<Tg;IyGBLqBFEiMbSRRm9|winECec@2t(~X7^TF py1_CtEW#yP1w!7eTq9OQ-GBHQAYoc~nGXN}002ovPDHLkV1j=uTuT4| literal 0 HcmV?d00001 diff --git a/games/default/files/player/pep/textures/pep_regen.png b/games/default/files/player/pep/textures/pep_regen.png new file mode 100644 index 0000000000000000000000000000000000000000..8aad7ad919a41699e59a1c95ed967756dd1a828d GIT binary patch literal 783 zcmV+q1MvKbP)mwuoLqq>ZN9P|O z|4B*a9vkPr-xnAEPf!0wM%)w>|4U2% zMMZ`yiN*i`0w_sDK~#7F1;K@ZBsTy6FxehvT!zEvaMFKkk&tA6-g?#5u4pb$lu0k(K?(ds(gKwDu=)^N6(hW`S5GUS^73ZL)$sFpN1#3qvF@h074!-Rs3+KIc=_I9^xu$9DPnUDjAFOR|sI%~+TQe|V8!V`=%` zi7Ax2gFe2X`1MGM1(B*K-3O5Chhca&mDA1YLc=DsMOcSWs^6~R;fIzhl?&s^Kvng3 z0T^6x#;ys&DDavj;6zh~m<<-pO^Ym2-kSk(J8GsU@|XuRFvMVi3VQ8%soED)nd!-s zp^zoW>a)3Ghu@waqpyucRi1&B7#NP%P1&kX=J(_1%4&q4(L`5Q-;Mef2l#N=4sS`8 zP&0TpTI~)GMkQZ_kuS`DEg0oEX1%}3#QYx_{NQPt88uy)vRV+8{a$Hq8~S>hVr0Q=gWotv}CpwtAW{r%?*f=I6maj)34>Av#~1)H(E zFzMPQm71bFI#nc2IFEEog-FbNl#=PjJPDH7(|jtjN#~WemBV2q{tvWZBCQy1F?s+1 N002ovPDHLkV1lPsa#{cY literal 0 HcmV?d00001 diff --git a/games/default/files/player/pep/textures/pep_regen2.png b/games/default/files/player/pep/textures/pep_regen2.png new file mode 100644 index 0000000000000000000000000000000000000000..43126845a57a3bb987b0e0aba2e452d1c45db6d7 GIT binary patch literal 791 zcmV+y1L*vTP)gX>y<79%BDPhv^+*|3-@cM2P=Pkmed*|4NSJ7+n8FiRc_)MTK`Xz|3Zf6 z8($X5{AK_E0x(HLK~#8N1;7KgZ8rb_(4FMiyu>5EO3Z(1U5>IkPPl6-wM$gM*g+yO z(v1}lfwI*(XXaY|Pe5(hP2m((>*-eDp7!S6%2lI1`claO`YBk~PC0_^YL}JdD0Idr zf7R9Lp$M2t`5)$pUEyBD@-5ddD8oCkep10B8x+#vsj-ENOuBXJ!qdIa)7TGMJRcOY z4|Bd8yls7mqfABPsf@W)>=iP|!tlU{V=NWfA>TY_Nm;a_r7&EyhO3sQR=f6zbMn@9eD~^Rg+z;fCUc$h-R2_m0zSP!$Gv&-$`d5ayCF!-A>N@IO4R VB8b4;(DwiU002ovPDHLkV1nH>ktqNG literal 0 HcmV?d00001 diff --git a/games/default/files/player/pep/textures/pep_speedminus.png b/games/default/files/player/pep/textures/pep_speedminus.png new file mode 100644 index 0000000000000000000000000000000000000000..99c3ffd92c5d69b270b209ae1077d96eb759048c GIT binary patch literal 757 zcmVC;N*i{ER96jWGX|E&q`w`ie9Emn8UzGXIt(`H3U=_l9`b@4?|&flgg5`2I{%&+?0h``pd9dkKL4T}@qsx1oIC%Y zJ^!H@?R^^VenbDK7V3IH|D;6!s2A&d6zF(C|D{I%suAUNOaHGw|Dz0U4^jXC0vbs~ zK~#8N4a!BL+*SYpFg-G}2jMd$Dfj-DYxhzdtvAiEG#`$A7^fw6Qz`K;ki8^rOC{$1 z@Qyp`cm4LOtDoy{9AL_P&F5PquUsIUzM#Yo`U(&2-2Cm>UHGHyuF&T8q(o)mH`%H; zcu}$+o%AN>N{BZlCg)eL!$7_>hKDmGFsNEjj?f<-ZjCy4%gvKUsIT$Enm)sgu}Nxn zvwKB8+fq-#R9g$q`@p3RqpmiCnMC7e`V-^B?o#I_0rTA3)_CM!jl1RjMdZViRarQe zL(|&Boa5(}4JR0Ty&9*f3B1fhr|%vGm*Q>yXw6=)yf8G=5E3B;-_M!mCzl{{t{6qh z;#zlgSC1-d5%vYNMlI;gFW6oo*6hyQdJ1tpqhK z&zPsrPyjloh(SlMhng)H;M^U`@a%+21&_>8$f#z(p{ncCGR6uezNyCXy$K!vY$QMZ z+We5WnzpHwnKs1z#3l_Y521>#ugUaXcV|c~y>ww%y^@A{y0LaDgX#iyak^P#n>duV z{o-2Th~gelxwrP1-roj<@H9hgMl?-u>MXpgGS}$5uu#;PM#16t3c5SuLBDW&HeyEu nPyK{5Dv! zMX#V`?$4;=^?B3m1pCD)O^K6^wlO#M>bSH7bR&i;IxL)iyG3QhF|MUJlX7XU91Z`oS<0}&Z6Np2FEGS;%;qY23~)UIsy`+?>u^>m`yO_CU=_qMZK-iC2` z<$ld3SZ&CSE1`HAuif~4O;;%xs&CrDr7ZeeOFMV_d(>&vYaTX0@W8Jm-yc+2C?Wj0 zP*~Ag)VB1-3{KPI>x@560un&t&AXc1!a+sWLG)K{vk(4{i2QF<#Vrs2^u5 zMF_s^d~h4;PBNL)p;%`MZFjNJ$5P>SUwi8ElR^-n-TI~qgq?+{m)Aj2YQ^<(17a#? zlKV7NrA}=Ak^I#gK)Stg&IiFo<j#!?mEgQFM9JINv0y5G;O%8mj-TOX>eeq#x1`WZp|Q3oc%pEA{8=IoTGOKZz6 ztA5Pr9$fayFA!ULTwl=-i7hPWjmdZN!J)x3NpE<;JOpv5qXE<6RF#dPXufp%7yY1W z9z7sF$s$@P)23G=AzozQNvS$htp=8>T6m!9J6hB^s*n<8HN{U0Ex~e}O!ltiG8g1F zdoPQD)@ZKow|=nFC{{mT&vmQQ*Movu@hz2l3jL6omjX6}9H33Jy0xtfyN!vB+DY#t zof!k-Bzm8%CCkt$_JBXGkGvRoE}lztxQsVVIYQv;I28BfNiy@g=X5MhDgVA3Te z=Hbn}{MMkG-!u>ztDrHOhiNPOy-yJwq3s$9Qc_YNAC(k{4p+^1QwsWyn0oJpz1qK? z0j87X2oF70MYyG*dPejJaHm<7U)AG^@36*su++n_gA2ofF`1n(O1)`M_-%%~x;#4CiW~&~sFHScr1cjqti zNLPRPC~iU7b%1s{wLB{5R#QCDWQ$F{v&8Z0bjKu=k4+4qlA8VrOwB+jJy@21{io?x x?GNRa4@SoM<208Fo06BOnbtIoSD)&f{|EZsAtz6$+miqQ002ovPDHLkV1hI+aajNW literal 0 HcmV?d00001 diff --git a/games/default/files/player/playereffects/README.md b/games/default/files/player/playereffects/README.md new file mode 100644 index 000000000..808c2c30f --- /dev/null +++ b/games/default/files/player/playereffects/README.md @@ -0,0 +1,228 @@ +# Player Effects +## Summary +This is an framework for assigning temporary status effects to players. This mod is aimed to modders and maybe interested people. This framework is a work in progress and not finished. + +## Profile +* Name: Player Effects +* Short name: `playereffects` +* Current version: 1.2.0 (This is a [SemVer](http://semver.org/).) +* Dependencies: None! +* License of everything: MIT License +* Discussion page: [here](https://forum.minetest.net/viewtopic.php?f=11&t=9689) + +## Information for players +This mod alone is not aimed directly at players. Briefly, the point of this mod is to help other mods to implement temporary status effects for players in a clean and consistant way. +Here is the information which may be relevant to you: Your current status effects are shown on the HUD on the right side, along with a timer which shows the time until the effect gets disabled. It is possible for the server to disable this feature entirely. Some status effects may also be hidden and are never exposed to the HUD. + +You only have to install this mod iff you have a mod which implements Player Effects. Here is a list of known mods which do: + +* Magic Beans—Wuzzy’s Fork [`magicbeans_w`] + +## Information for server operators +By default, this mod stores the effects into the file `playereffects.mt` in the current world path every 10 seconds. On a regular server shutdown, this file is also written to. The data in this file is read when the mod is started. + +It is save to delete `playereffects.mt` when the mod does currently not run. This simply erases all active and inactive effects when the server starts again. + +You can disable the automatic saving in `settings.lua`. + +### Configuration +Player Effects can be configured. Just edit the file `settings.lua`. You find everything you need to know in that file. Be careful to not delete the lines, just edit them. + +## Information for modders +This is a framework for other mods to depend on. It provides means to define, apply and remove temporary status effects to players in a (hopefully) unobstrusive way. +A status effect is an effect for a player which changes some property of the player. This property can be practically everything. Currently, the framework supports one kind of effect, which I call “exclusive effects”. For each property (speed, gravity, whatver), there can be only one effect in place at the same time. Here are some examples for possible status effects: + +* high walking speed (`speed` property) +* high jump height (`jump` property) +* low player gravity (`gravity` property) +* high player gravity (`gravity` property) +* having the X privilege granted (binary “do I have the property?” property) (yes, this is weird, but it works!) + +The framework aims to provide means to define effect types and to apply and cancel effects to players. The framework aims to be a stable foundation stone. This means it needs a lot of testing. + +## Known bugs +### Effect timers don’t stop when game gets paused +When you paused the game in singleplayer mode, the effect timers just continue as if nothing happened. Of course, all effect timers should be stopped while the game is paused, like everything else. Apparently this bug cannot be fixed with the current Lua API. + +## API documentation +### Data types +#### Effect type (`effect_type`) +An effect type is a description of what is later to be concretely applied as an effect to a player. An effect type, however, is *not* assigned to a player. There are two kinds of effect types: Repeating and non-repeating. See the section on `effect` for more information. + +`effect_type` is a table with these fields: + +* `description`: Human-readable short description of the effect. Will be exposed to the HUD, iff `hidden` is `false`. +* `groups`: A table of groups to which this effect type belongs to. +* `apply`: Function to be called when effect is applied. See `playereffects.register_effect_type`. +* `cancel`: Function to be called when effect is cancelled. See `playereffects.register_effect_type`. +* `icon`: This is optional. It can be the file name of a texture. Should have a size of 16px×16px. Will be exposed to the HUD, iff `hidden` is `false`. +* `hidden`: Iff this is false, it will not be exposed to the HUD when this effect is active. +* `cancel_on_death`: Iff this is true, the effect will be cancelled automatically when the player dies. +* `repeat_interval` is an optional number. When specified, the effects of this type becomes a repeating effect. Repeating effects call `apply` an arbitrary number of times; non-repeating effects just call it once when the effect is created. The number specifies the interval in seconds between each call. Iff this parameter is `nil`, the effect type is a non-repeating effect. + +Normally you don’t need to read or edit fields of this table. Use `playereffects.register_effect_type` to add a new effect type to Player Effects. + +#### Effect group +An effect group is basically a concept. Any effect type can be member of any number of effect groups. The main point of effect groups is to find effects which affect the same property. For example, an effect which makes you faster and another effect which makes you slower both affect the same property: speed. The group for that then would be the string `"speed"`. See also `examples.lua`, which includes the effects `high_speed` and `low_speed`. + +Currently, the main rule of Player Effects requires that there can only be one effect in place. Don’t worry, Player Effects already does that job for you. Back to the example: it is possible to be fast and it is possible to be slow. But it is not possible to be fast `and` slow at the same time. Player Effects ensures that by cancelling all conflicting concepts before applying a new one. + +The concept of groups may be changed or extended in the future. + +You can invent effect groups (like the groups in Minetest) on the fly. A group is just a string. Practically, you should use groups which other people use. + +#### Effect (`effect`) +An effect is an current change of a player property (like speed, jump height, and so on). It is the realization of an effect type. All effects are temporary. There are currently two types of effects: Repeating and non-repeating. Non-repeating effects call their `apply` callback once when they are created. Repeating effects call their apply callback multiple times with a specified interval. By default, effects are non-repeating. + +`effect` is a table with the following modding-relevant fields: + +* `playername`: The name of the player to which the effect belongs to. +* `effect_id`: A globally unique identifier of the effect. It is a number and assigned automatically by Player Effects. +* `effect_type_id`: The identifier of the effect’s effect type. It is a string and assigned by `playereffects.register_effect_type`. +* `metadata`: An optional field which may contain a table with additional, modder-defined data to be “remembered” for later. The `apply` callback can set this field. + +Internally, Player Effects also uses these fields: + +* `start_time`: The operating system time (from `os.time()`) of when the effect has been started. +* `time_left`: The number of seconds left before the effect runs out. This number is only set when the effect starts or the effect is unfrozen because i.e. a player re-joins. You can’t use this field to blindly get the remaining time of the effect. +* `repeat_interval_start_time` and `repeat_interval_time_left`: Same as `start_time` and `time_left`, but for repeating effects. + +You should normally not need to care about these internally used fields. + + +### Functions +#### `playereffects.register_effect_type(effect_type_id, description, icon, groups, apply, cancel, hidden, cancel_on_death, repeat_interval)` +Adds a new effect type for the Player Effects mods, so it can be later be applied to players. + +##### Parameters +* `effect_type_id` is the identifier (a string) which is internally used by the mod. Later known as `effect_type_id`. You may choose the identifier at will, but please use only alphanumeric ASCII characters. The identifier must be unique along all mods. +* `description` is the text which is exposed to the HUD and visible to the player. +* `icon`: This is optional an can be `nil`. It can be the file name of a texture. Should have a size of 16px×16px. In this case, this is the icon for the HUD. Basically this is just eye-candy. If this is `nil`, no icon is shown. The icon will be exposed to the HUD, iff `hidden` is `false`. +* `groups` is a table of strings to which the effect type is assigned to. +* `apply`: See below. +* `cancel`: See below. +* `hidden` is an optional boolean value. Iff `true`, the effect description and icon will not be exposed to the player HUD. Otherwise, the effect is exposed. Default: `false` +* `cancel_on_death` is an optional boolean value. Iff true, the effect will be cancelled automatically when the player dies. Default: `true`. +* `repeat_interval` is an optional number. When specified, the effects of this type becomes a repeating effect. Repeating effects call `apply` an arbitrary number of times; non-repeating effects just call it once when the effect is created. The number specifies the interval in seconds between each call. Iff this parameter is `nil`, the effect type is a non-repeating effect. + + +###### `apply` function +The `apply` function is a callback function which is called by Player Effects. Here the modder can put all the gameplay-relevant code. + +`apply` takes a player object as its only argument. This is the player to which the effect is applied to. + +The function may return a table. This table will be added as the field `metadata` to the resulting `effect`. + +The function may return `false`. This is used to tell Player Effects that the effect could, for whatever reason, not be successfully applied. Currently, this feature is experimental and possibly broken. + +The function may also return just `nil` on a normal success without metadata. + +###### `cancel` function +The `cancel` function is called by Player Effects when the effect is to be cancelled. Here the modder can do all the code which is needed to revert the changes an earlier `apply` call made. + +`cancel` takes an `effect` as its first argument and a player object as its second argument. Remember, this `effect` may also contain a field called `metadata`, which may have been added by an earlier `apply` call. `player` is the player to which the effect is/was applied. This argument is just there for convenience reasons. + +Player Effects does not care about the return value of this function. + +##### Return value +Always `nil`. + +#### `playereffects.apply_effect_type(effect_type_id, duration, player, repeat_interval_time_left)` +Attempts to apply a new effect of a certain type for a certain duration to a certain player. This function can fail, although this should rarely happen. This function handles non-repeating effects and repeating effects as well. + +##### Parameters +* `effect_type_id`: The identifier of the effect type. This is the name which was used in `playereffects.register_effect_type` and always a string. +* `duration`: How long the effect. Please use only positive values and only integers. If a repeating effect type is specified, this number specifies the number of repetitions; for non-repeating effects this number specifies the effect duration in seconds. +* `player`: The player object to which the new effect should be applied to. +* `repeat_interval_time_left`: This parameter is optional and only for repeating effects. If it is a number, it specifies the time until the first call of the `apply` callback fires. By default, a full repeat interval is waited until the first call. + +##### Return value +The function either returns `false` or a number. Iff the function returns `false`, the effect was not successfully applied. The function may return `false` on these occasions: + +* `player` is not a valid player object +* The `apply` function of the effect type returned `false` + +On success, the function returns a number. This number is the effect ID of the effect which has been just created. This effect ID can be used later, for `playereffects.cancel_effect`, for example. + +#### `playereffects.cancel_effect(effect_id)` +Cancels a single effect. + +##### Parameter +* `effect_id`: The effect ID of the effect which shall be cancelled. + +##### Return value +Always `nil`. + +#### `playereffects.cancel_effect_group(groupname, playername)` +Cancels all a player’s effects which belong to a certain group. + +##### Parameters +* `groupname`: The name of the effect group (string) of which all active effects of the player shall be cancelled. +* `playername`: The name of the player to which the effects which are about to be cancelled belong to. + +##### Return value +Always `nil`. + +#### `playereffects.cancel_effect_type(effect_type_id, cancel_all, playername)` +Cancels one or all player effect with a certain effect type +Careful! This function has *not* been tested yet! + +##### Parameters +* `effect_type_id`: Identifier of the effect type. +* `cancel_all`: Iff true, cancels all active effects with this effect type +* `playername`: Name of the player to which the effects belong to + +##### Return value +Always `nil`. + +#### `playereffects.get_remaining_effect_time(effect_id)` +Returns the remaining time of an effect. + +##### Parameter +* `effect_id`: The effect identifier of the effect in question + +##### Return value +Iff the effect exists, the remaining effect time is returned in full seconds. Iff the effect does not exist, `nil` is returned. + +#### `playereffects.get_player_effects(playername)` +Returns all active effects of a player. + +##### Parameter +`playername`: The name of the player from which the effects are requested. + +##### Return value +A table of all `effect`s which belong to the player. If the player does not exist, this function returns an empty table. + +#### `playereffects.has_effect_type(playername, effect_type_id)` +Returns `true` iff the provided player has an effect of the specified effect type, `false` otherwise. + +##### Parameters +* `playername`: Name of the player to check the existance of the effect type for +* `effect_type_id`: Identifier of the effect type. + +## Examples +This mod comes with extensive examples. The examples are disabled by default. Edit `settings.lua` to enable the examples. See `examples.lua` to find out how they are programmed. The examples are only for demonstration purposes. They are not intended to be used in an actual game. + +### Chat commands +The examples are mainly accessible with chat commands. Since this is just an example, everyone can use these examples. + +#### Apply effect +These commands apply (or try to) apply an effect to you. You will get a response in the chat which give you the `effect_id` on success. On failure, the example will tell you that it failed. + +* `fast`: Makes you faster for 10 seconds. +* `slow`: Makes you slower for 120s. +* `hfast`: Makes you faster for 10s. This is a hidden effect and is not exposed to the HUD. +* `highjump`: Increases your jump height for 20s. +* `fly`: Gives you the `fly` privilege for a minute. You keep the privilege even when you die. Better don’t mess around with this privilege manually when you use this. +* `regen`: Gives you a half heart per second 10 times (5 hearts overall healing). This is an example of a repeating effect. +* `slowregen`: Gives you a half heart every 15 seconds, 10 times (5 hearts overall healing). This is an example of a repeating effect. +* `blind`: Tints the whole screen black for 5 seconds. This is highly experimental and will be drawn over many existing HUD elements. In other words, prepare your HUD to be messed up. +* `null`: Tries to apply an effect which always fails. This demonstrates the failure of effects. + +#### Cancel effects +* `cancelall`: Cancels all your active effects. + +#### Testing +* `stresstest [number]`: Applies `number` dummy effects which don’t do anything to you. Iff omitted, `number` is assumed to be 100. This command is there to test the performance of this mod for absurdly large effect numbers. + + diff --git a/games/default/files/player/playereffects/init.lua b/games/default/files/player/playereffects/init.lua new file mode 100644 index 000000000..12b2bb391 --- /dev/null +++ b/games/default/files/player/playereffects/init.lua @@ -0,0 +1,522 @@ +--[=[ Main tables ]=] + +playereffects = {} + +--[[ table containing the groups (experimental) ]] +playereffects.groups = {} + +--[[ table containing all the HUD info tables, indexed by player names. +A single HUD info table is formatted like this: { text_id = 1, icon_id=2, pos = 0 } +Where: text_id: HUD ID of the textual effect description + icon_id: HUD ID of the effect icon (optional) + pos: Y offset factor (starts with 0) +Example of full table: +{ ["player1"] = {{ text_id = 1, icon_id=4, pos = 0 }}, ["player2] = { { text_id = 5, icon_id=6, pos = 0 }, { text_id = 7, icon_id=8, pos = 1 } } } +]] +playereffects.hudinfos = {} + +--[[ table containing all the effect types ]] +playereffects.effect_types = {} + +--[[ table containing all the active effects ]] +playereffects.effects = {} + +--[[ table containing all the inactive effects. +Effects become inactive if a player leaves an become active again if they join again. ]] +playereffects.inactive_effects = {} + +-- Variable for counting the effect_id +playereffects.last_effect_id = 0 + + +--[[ + Settings for Player Effects +]] + +-- Wheather to use the HUD to expose the active effects to players (true or false) +playereffects.use_hud = true + +-- Wheather to use autosave (true or false) +playereffects.use_autosave = true + +-- The time interval between autosaves, in seconds (only used when use_autosave is true) +playereffects.autosave_time = 10 + + +--[=[ Load inactive_effects and last_effect_id from playereffects, if this file exists ]=] +do + local filepath = minetest.get_worldpath().."/playereffects" + local file = io.open(filepath, "r") + if file then + minetest.log("action", "[playereffects] playereffects opened.") + local string = file:read() + io.close(file) + if(string ~= nil) then + local savetable = minetest.deserialize(string) + playereffects.inactive_effects = savetable.inactive_effects + minetest.debug("[playereffects] playereffects successfully read.") + minetest.debug("[playereffects] inactive_effects = "..dump(playereffects.inactive_effects)) + playereffects.last_effect_id = savetable.last_effect_id + minetest.debug("[playereffects] last_effect_id = "..dump(playereffects.last_effect_id)) + + end + end +end + +function playereffects.next_effect_id() + playereffects.last_effect_id = playereffects.last_effect_id + 1 + return playereffects.last_effect_id +end + +--[=[ API functions ]=] +function playereffects.register_effect_type(effect_type_id, description, icon, groups, apply, cancel, hidden, cancel_on_death, repeat_interval) + local effect_type = {} + effect_type.description = description + effect_type.apply = apply + effect_type.groups = groups + effect_type.icon = icon + if cancel ~= nil then + effect_type.cancel = cancel + else + effect_type.cancel = function() end + end + if hidden ~= nil then + effect_type.hidden = hidden + else + effect_type.hidden = false + end + if cancel_on_death ~= nil then + effect_type.cancel_on_death = cancel_on_death + else + effect_type.cancel_on_death = true + end + effect_type.repeat_interval = repeat_interval + + playereffects.effect_types[effect_type_id] = effect_type + minetest.log("action", "[playereffects] Effect type "..effect_type_id.." registered!") +end + +function playereffects.apply_effect_type(effect_type_id, duration, player, repeat_interval_time_left) + local start_time = os.time() + local is_player = false + if(type(player)=="userdata") then + if(player.is_player ~= nil) then + if(player:is_player() == true) then + is_player = true + end + end + end + if(is_player == false) then + minetest.log("error", "[playereffects] Attempted to apply effect type "..effect_type_id.." to a non-player!") + return false + end + + local playername = player:get_player_name() + local groups = playereffects.effect_types[effect_type_id].groups + for k,v in pairs(groups) do + playereffects.cancel_effect_group(v, playername) + end + + local metadata + if(playereffects.effect_types[effect_type_id].repeat_interval == nil) then + local status = playereffects.effect_types[effect_type_id].apply(player) + if(status == false) then + minetest.log("action", "[playereffects] Attempt to apply effect type "..effect_type_id.." to player "..playername.." failed!") + return false + else + metadata = status + end + end + + + local effect_id = playereffects.next_effect_id() + local smallest_hudpos + local biggest_hudpos = -1 + local free_hudpos + if(playereffects.hudinfos[playername] == nil) then + playereffects.hudinfos[playername] = {} + end + local hudinfos = playereffects.hudinfos[playername] + for effect_id, hudinfo in pairs(hudinfos) do + local hudpos = hudinfo.pos + if(hudpos > biggest_hudpos) then + biggest_hudpos = hudpos + end + if(smallest_hudpos == nil) then + smallest_hudpos = hudpos + elseif(hudpos < smallest_hudpos) then + smallest_hudpos = hudpos + end + end + if(smallest_hudpos == nil) then + free_hudpos = 0 + elseif(smallest_hudpos >= 0) then + free_hudpos = smallest_hudpos - 1 + else + free_hudpos = biggest_hudpos + 1 + end + + local repeat_interval = playereffects.effect_types[effect_type_id].repeat_interval + if(repeat_interval ~= nil) then + if(repeat_interval_time_left == nil) then + repeat_interval_time_left = repeat_interval + end + end + + --[[ show no more than 20 effects on the screen, so that hud_update does not need to be called so often ]] + local text_id, icon_id + if(free_hudpos <= 20) then + text_id, icon_id = playereffects.hud_effect(effect_type_id, player, free_hudpos, duration, repeat_interval_time_left) + local hudinfo = { + text_id = text_id, + icon_id = icon_id, + pos = free_hudpos, + } + playereffects.hudinfos[playername][effect_id] = hudinfo + else + text_id, icon_id = nil, nil + end + + local effect = { + playername = playername, + effect_id = effect_id, + effect_type_id = effect_type_id, + start_time = start_time, + repeat_interval_start_time = start_time, + time_left = duration, + repeat_interval_time_left = repeat_interval_time_left, + metadata = metadata, + } + + playereffects.effects[effect_id] = effect + + if(repeat_interval ~= nil) then + minetest.after(repeat_interval_time_left, playereffects.repeater, effect_id, duration, player, playereffects.effect_types[effect_type_id].apply) + else + minetest.after(duration, function(effect_id) playereffects.cancel_effect(effect_id) end, effect_id) + end + + return effect_id +end + +function playereffects.repeater(effect_id, repetitions, player, apply) + local effect = playereffects.effects[effect_id] + if(effect ~= nil) then + local repetitions = effect.time_left + apply(player) + repetitions = repetitions - 1 + effect.time_left = repetitions + if(repetitions <= 0) then + playereffects.cancel_effect(effect_id) + else + local repeat_interval = playereffects.effect_types[effect.effect_type_id].repeat_interval + effect.repeat_interval_time_left = repeat_interval + effect.repeat_interval_start_time = os.time() + minetest.after( + repeat_interval, + playereffects.repeater, + effect_id, + repetitions, + player, + apply + ) + end + end +end + +function playereffects.cancel_effect_type(effect_type_id, cancel_all, playername) + local effects = playereffects.get_player_effects(playername) + if(cancel_all==nil) then cancel_all = false end + for e=1, #effects do + if(effects[e].effect_type_id == effect_type_id) then + playereffects.cancel_effect(effects[e].effect_id) + if(cancel_all==false) then + return + end + end + end +end + +function playereffects.cancel_effect_group(groupname, playername) + local effects = playereffects.get_player_effects(playername) + for e=1,#effects do + local effect = effects[e] + local thesegroups = playereffects.effect_types[effect.effect_type_id].groups + local delete = false + for g=1,#thesegroups do + if(thesegroups[g] == groupname) then + playereffects.cancel_effect(effect.effect_id) + break + end + end + end +end + +function playereffects.get_remaining_effect_time(effect_id) + local now = os.time() + local effect = playereffects.effects[effect_id] + if(effect ~= nil) then + return (effect.time_left - os.difftime(now, effect.start_time)) + else + return nil + end +end + +function playereffects.cancel_effect(effect_id) + local effect = playereffects.effects[effect_id] + if(effect ~= nil) then + local player = minetest.get_player_by_name(effect.playername) + local hudinfo = playereffects.hudinfos[effect.playername][effect_id] + if(hudinfo ~= nil) then + if(hudinfo.text_id~=nil) then + player:hud_remove(hudinfo.text_id) + end + if(hudinfo.icon_id~=nil) then + player:hud_remove(hudinfo.icon_id) + end + playereffects.hudinfos[effect.playername][effect_id] = nil + end + playereffects.effect_types[effect.effect_type_id].cancel(effect, player) + playereffects.effects[effect_id] = nil + end +end + +function playereffects.get_player_effects(playername) + if(minetest.get_player_by_name(playername) ~= nil) then + local effects = {} + for k,v in pairs(playereffects.effects) do + if(v.playername == playername) then + table.insert(effects, v) + end + end + return effects + else + return {} + end +end + +function playereffects.has_effect_type(playername, effect_type_id) + local pe = playereffects.get_player_effects(playername) + for i=1,#pe do + if pe[i].effect_type_id == effect_type_id then + return true + end + end + return false +end + +--[=[ Saving all data to file ]=] +function playereffects.save_to_file() + local save_time = os.time() + local savetable = {} + local inactive_effects = {} + for id,effecttable in pairs(playereffects.inactive_effects) do + local playername = id + if(inactive_effects[playername] == nil) then + inactive_effects[playername] = {} + end + for i=1,#effecttable do + table.insert(inactive_effects[playername], effecttable[i]) + end + end + for id,effect in pairs(playereffects.effects) do + local new_duration, new_repeat_duration + if(playereffects.effect_types[effect.effect_type_id].repeat_interval ~= nil) then + new_duration = effect.time_left + new_repeat_duration = effect.repeat_interval_time_left - os.difftime(save_time, effect.repeat_interval_start_time) + else + new_duration = effect.time_left - os.difftime(save_time, effect.start_time) + end + local new_effect = { + effect_id = effect.effect_id, + effect_type_id = effect.effect_type_id, + time_left = new_duration, + repeat_interval_time_left = new_repeat_duration, + start_time = effect.start_time, + repeat_interval_start_time = effect.repeat_interval_start_time, + playername = effect.playername, + metadata = effect.metadata + } + if(inactive_effects[effect.playername] == nil) then + inactive_effects[effect.playername] = {} + end + table.insert(inactive_effects[effect.playername], new_effect) + end + + savetable.inactive_effects = inactive_effects + savetable.last_effect_id = playereffects.last_effect_id + + local savestring = minetest.serialize(savetable) + + local filepath = minetest.get_worldpath().."/playereffects" + local file = io.open(filepath, "w") + if file then + file:write(savestring) + io.close(file) + minetest.log("action", "[playereffects] Wrote playereffects data into "..filepath..".") + else + minetest.log("error", "[playereffects] Failed to write playereffects data into "..filepath..".") + end +end + +--[=[ Callbacks ]=] +--[[ Cancel all effects on player death ]] +minetest.register_on_dieplayer(function(player) + local effects = playereffects.get_player_effects(player:get_player_name()) + for e=1,#effects do + if(playereffects.effect_types[effects[e].effect_type_id].cancel_on_death == true) then + playereffects.cancel_effect(effects[e].effect_id) + end + end +end) + + +minetest.register_on_leaveplayer(function(player) + local leave_time = os.time() + local playername = player:get_player_name() + local effects = playereffects.get_player_effects(playername) + + playereffects.hud_clear(player) + + if(playereffects.inactive_effects[playername] == nil) then + playereffects.inactive_effects[playername] = {} + end + for e=1,#effects do + local new_duration = effects[e].time_left - os.difftime(leave_time, effects[e].start_time) + local new_effect = effects[e] + new_effect.time_left = new_duration + table.insert(playereffects.inactive_effects[playername], new_effect) + playereffects.cancel_effect(effects[e].effect_id) + end +end) + +minetest.register_on_shutdown(function() + minetest.log("action", "[playereffects] Server shuts down. Rescuing data into playereffects") + playereffects.save_to_file() +end) + +minetest.register_on_joinplayer(function(player) + local playername = player:get_player_name() + + -- load all the effects again (if any) + if(playereffects.inactive_effects[playername] ~= nil) then + for i=1,#playereffects.inactive_effects[playername] do + local effect = playereffects.inactive_effects[playername][i] + playereffects.apply_effect_type(effect.effect_type_id, effect.time_left, player, effect.repeat_interval_time_left) + end + playereffects.inactive_effects[playername] = nil + end +end) + +playereffects.globalstep_timer = 0 +playereffects.autosave_timer = 0 +minetest.register_globalstep(function(dtime) + playereffects.globalstep_timer = playereffects.globalstep_timer + dtime + playereffects.autosave_timer = playereffects.autosave_timer + dtime + -- Update HUDs of all players + if(playereffects.globalstep_timer >= 1) then + playereffects.globalstep_timer = 0 + + local players = minetest.get_connected_players() + for p=1,#players do + playereffects.hud_update(players[p]) + end + end + -- Autosave into file + if(playereffects.use_autosave == true and playereffects.autosave_timer >= playereffects.autosave_time) then + playereffects.autosave_timer = 0 + minetest.log("action", "[playereffects] Autosaving mod data to playereffects ...") + playereffects.save_to_file() + end +end) + +--[=[ HUD ]=] +function playereffects.hud_update(player) + if(playereffects.use_hud == true) then + local now = os.time() + local playername = player:get_player_name() + local hudinfos = playereffects.hudinfos[playername] + if(hudinfos ~= nil) then + for effect_id, hudinfo in pairs(hudinfos) do + local effect = playereffects.effects[effect_id] + if(effect ~= nil and hudinfo.text_id ~= nil) then + local description = playereffects.effect_types[effect.effect_type_id].description + local repeat_interval = playereffects.effect_types[effect.effect_type_id].repeat_interval + if(repeat_interval ~= nil) then + local repeat_interval_time_left = os.difftime(effect.repeat_interval_start_time + effect.repeat_interval_time_left, now) + player:hud_change(hudinfo.text_id, "text", description .. " ("..tostring(effect.time_left).."/"..tostring(repeat_interval_time_left) .. "s)") + else + local time_left = os.difftime(effect.start_time + effect.time_left, now) + player:hud_change(hudinfo.text_id, "text", description .. " ("..tostring(time_left).." s)") + end + end + end + end + end +end + +function playereffects.hud_clear(player) + if(playereffects.use_hud == true) then + local playername = player:get_player_name() + local hudinfos = playereffects.hudinfos[playername] + if(hudinfos ~= nil) then + for effect_id, hudinfo in pairs(hudinfos) do + local effect = playereffects.effects[effect_id] + if(hudinfo.text_id ~= nil) then + player:hud_remove(hudinfo.text_id) + end + if(hudinfo.icon_id ~= nil) then + player:hud_remove(hudinfo.icon_id) + end + playereffects.hudinfos[playername][effect_id] = nil + end + end + end +end + +function playereffects.hud_effect(effect_type_id, player, pos, time_left, repeat_interval_time_left) + local text_id, icon_id + local effect_type = playereffects.effect_types[effect_type_id] + if(playereffects.use_hud == true and effect_type.hidden == false) then + local color + if(playereffects.effect_types[effect_type_id].cancel_on_death == true) then + color = 0xFFFFFF + else + color = 0xF0BAFF + end + local description = playereffects.effect_types[effect_type_id].description + local text + if(repeat_interval_time_left ~= nil) then + text = description .. " ("..tostring(time_left).."/"..tostring(repeat_interval_time_left) .. "s )" + else + text = description .. " ("..tostring(time_left).." s)" + end + text_id = player:hud_add({ + hud_elem_type = "text", + position = { x = 1, y = 0.3 }, + name = "effect_"..effect_type_id, + text = text, + scale = { x = 170, y = 20}, + alignment = { x = -1, y = 0 }, + direction = 1, + number = color, + offset = { x = -5, y = pos*20 } + }) + if(playereffects.effect_types[effect_type_id].icon ~= nil) then + icon_id = player:hud_add({ + hud_elem_type = "image", + scale = { x = 1, y = 1 }, + position = { x = 1, y = 0.3 }, + name = "effect_icon_"..effect_type_id, + text = playereffects.effect_types[effect_type_id].icon.."^[mask:pep_glass_bottle_overlay.png", + alignment = { x = -1, y=0 }, + direction = 0, + offset = { x = -186, y = pos*20 }, + }) + end + else + text_id = nil + icon_id = nil + end + return text_id, icon_id +end diff --git a/games/default/files/player/playerphysics/README.md b/games/default/files/player/playerphysics/README.md new file mode 100644 index 000000000..fa7b68f52 --- /dev/null +++ b/games/default/files/player/playerphysics/README.md @@ -0,0 +1,123 @@ +# Player Physics API. + +Version: 1.0.0 + +This mod makes it possible for multiple mods to modify player physics (speed, jumping strength, gravity) without conflict. + +## Introduction +### For players +Mods and games in Minetest can set physical attributes of players, such as speed and jump strength. For example, player speed could be set to 200%. But the way this works makes it difficult for multiple mods to *modify* physical attributes without leading to conflicts, problems and hilarious bugs, like speed that changes often to nonsense values. + +The Player Physics API aims to resolve this conflict by providing a “common ground” for mods to work together in this regard. + +This mod does nothing on its own, you will only need to install it as dependency of other mods. + +When you browse for mods that somehow mess with player physics (namely: speed, jump strength or gravity) and want to use more than one of them, check out if they support the Player Physics API. If they don't, it's very likely these mods will break as soon you activate more than one of them, for example, if two mods try to set the player speed. If you found such a “hilarious bug”, please report it to the developers of the mods (or games) and point them to the Player Physics API. + +Of course, not all mods need the Player Physics API. Mods that don't touch player physics at all won't need this mod. + +The rest of this document is directed at developers. + +### For developers +The function `set_physics_override` from the Minetest Lua API allows mod authors to override physical attributes of players, such as speed or jump strength. + +This function works fine as long there is only one mod that sets a particular physical attribute at a time. However, as soon as at least two different mods (that do not know each other) try to change the same player physics attribute using only this function, there will be conflicts as each mod will undo the change of the other mod, as the function sets a raw value. A classic race condition occurs. This is the case because the mods fail to communicate with each other. + +This mod solves the problem of conflicts. It bans the concept of “setting the raw value directly” and replaces it with the concept of factors that mods can add and remove for each attribute. The real physical player attribute will be the product of all active factors. + +## Quick start +Let's say you have a mod `example` and want to double the speed of the player (i.e. multiply it by a factor of 2), but you also don't want to break other mods that might touch the speed. + +Previously, you might have written something like this: + +`player:set_physics_override({speed=2})` + +However, your mod broke down as soon the mod `example2` came along, which wanted to increase the speed by 50%. In the real game, the player speed randomly switched from 50% and 200% which was a very annoying bug. + +In your `example` mod, you can replace the code with this: + +`playerphysics.add_physics_factor(player, "speed", "my_double_speed", 2)` + +Where `"my_double_speed` is an unique ID for your speed factor. + +Now your `example` mod is interoperable! And now, of course, the `example2` mod has to be updated in a similar fashion. + +## Precondition +There is only one precondition to using this mod, but it is important: + +Mods *MUST NOT* call `set_physics_override` directly for numerical values. Instead, to modify player physics, all mods that touch player physics have to use this API. + +## Functions +### `playerphysics.add_physics_factor(player, attribute, id, value)` +Adds a factor for a player physic and updates the player physics immediately. + +#### Parameters +* `player`: Player object +* `attribute`: Which of the physical attributes to change. Any of the numeric values of `set_physics_override` (e.g. `"speed"`, `"jump"`, `"gravity"`) +* `id`: Unique identifier for this factor. Identifiers are stored on a per-player per-attribute type basis +* `value`: The factor to add to the list of products + +If a factor for the same player, attribute and `id` already existed, it will be overwritten. + +### `playerphysics.remove_physics_factor(player, attribute, id)` +Removes the physics factor of the given ID and updates the player's physics. + +#### Parameters +Same as in `playerphysics.add_physics_factor`, except there is no `value` argument. + +## Examples +### Speed changes +Let's assume this mod is used by 3 different mods all trying to change the speed: +Potions, Exhaustion and Electrocution. +Here's what it could look like: + +Potions mod: +``` +playerphysics.add_physics_factor(player, "speed", "run_potion", 2) +``` + +Exhaustion mod: +``` +playerphysics.add_physics_factor(player, "jump", "exhausted", 0.75) +``` + +Electrocution mod: +``` +playerphysics.add_physics_factor(player, "jump", "shocked", 0.9) +``` + +When the 3 mods have done their change, the real player speed is simply the product of all factors, that is: + +2 * 0.75 * 0.9 = 1.35 + +The final player speed is thus 135%. + +### Speed changes, part 2 + +Let's take the example above. +Now if the Electrocution mod is done with shocking the player, it just needs to call: + +``` +playerphysics.remove_physics_factor(player, "jump", "shocked") +``` + +The effect is now gone, so the new player speed will be: + +2 * 0.75 = 1.5 + +### Sleeping +To simulate sleeping by preventing all player movement, this can be done with this easy trick: + +``` +playerphysics.add_physics_factor(player, "speed", "sleeping", 0) +playerphysics.add_physics_factor(player, "jump", "sleeping", 0) +``` + +This works regardless of the other factors because 0 times anything equals 0. + + + + + +## License +This mod is free software, released under the MIT License. diff --git a/games/default/files/player/playerphysics/init.lua b/games/default/files/player/playerphysics/init.lua new file mode 100644 index 000000000..2b7d7df02 --- /dev/null +++ b/games/default/files/player/playerphysics/init.lua @@ -0,0 +1,43 @@ +playerphysics = {} + +local function calculate_attribute_product(player, attribute) + local a = minetest.deserialize(player:get_attribute("playerphysics:physics")) + local product = 1 + if a == nil or a[attribute] == nil then + return product + end + local factors = a[attribute] + if type(factors) == "table" then + for _, factor in pairs(factors) do + product = product * factor + end + end + return product +end + +function playerphysics.add_physics_factor(player, attribute, id, value) + local a = minetest.deserialize(player:get_attribute("playerphysics:physics")) + if a == nil then + a = { [attribute] = { [id] = value } } + elseif a[attribute] == nil then + a[attribute] = { [id] = value } + else + a[attribute][id] = value + end + player:set_attribute("playerphysics:physics", minetest.serialize(a)) + local raw_value = calculate_attribute_product(player, attribute) + player:set_physics_override({[attribute] = raw_value}) +end + +function playerphysics.remove_physics_factor(player, attribute, id) + local a = minetest.deserialize(player:get_attribute("playerphysics:physics")) + if a == nil or a[attribute] == nil then + -- Nothing to remove + return + else + a[attribute][id] = nil + end + player:set_attribute("playerphysics:physics", minetest.serialize(a)) + local raw_value = calculate_attribute_product(player, attribute) + player:set_physics_override({[attribute] = raw_value}) +end diff --git a/games/default/files/player/playerplus/README.md b/games/default/files/player/playerplus/README.md new file mode 100644 index 000000000..626de21f2 --- /dev/null +++ b/games/default/files/player/playerplus/README.md @@ -0,0 +1,20 @@ +MultiCraft Game mod: PlayerPlus + +This mod lets the player move faster when walking on ice, slows down the player +when walking on snow, makes touching a cactus hurt and suffocates player when +their head is inside a solid node... enjoy! + +https://forum.minetest.net/viewtopic.php?t=10090&p=153667 + + +The mod has been rewritten and optimized to work with Player Physics API: +https://forum.minetest.net/viewtopic.php?f=9&t=22172 +Removed POVA, monoids support, knock-back, glitch. + +API: +Every second the mod checks which node the player is standing on, which node is +at foot and head level and stores inside a global table to be used by mods: + +- playerplus[name].nod_stand +- playerplus[name].nod_foot +- playerplus[name].nod_head diff --git a/games/default/files/player/playerplus/depends.txt b/games/default/files/player/playerplus/depends.txt new file mode 100644 index 000000000..e32aa361d --- /dev/null +++ b/games/default/files/player/playerplus/depends.txt @@ -0,0 +1,2 @@ +default +playerphysics diff --git a/games/default/files/playerplus/init.lua b/games/default/files/player/playerplus/init.lua similarity index 72% rename from games/default/files/playerplus/init.lua rename to games/default/files/player/playerplus/init.lua index f2a81a626..13aef74d8 100644 --- a/games/default/files/playerplus/init.lua +++ b/games/default/files/player/playerplus/init.lua @@ -1,59 +1,35 @@ ---[[ - walking on ice makes player walk faster, - stepping through snow or water slows player down, - touching a cactus hurts player, - and suffocation when head is inside solid node,. - - PlayerPlus by TenPlus1 -]] - playerplus = {} -- get node but use fallback for nil or unknown local node_ok = function(pos, fallback) - fallback = fallback or "air" - local node = minetest.get_node_or_nil(pos) - if node and minetest.registered_nodes[node.name] then return node.name end - return fallback end -local armor_mod = minetest.get_modpath("3d_armor") ---local def = {} local time = 0 - +-- check speed +local check = 0.5 minetest.register_globalstep(function(dtime) - time = time + dtime - - -- every 1 second - if time < 1 then + if time < check then return end - -- reset time for next check time = 0 - -- define locals outside loop local name, pos, ndef, def, nslow, nfast -- loop through players for _,player in ipairs(minetest.get_connected_players()) do - -- who am I? name = player:get_player_name() - - -- where am I? pos = player:get_pos() - - -- what is around me? pos.y = pos.y - 0.1 -- standing on playerplus[name].nod_stand = node_ok(pos) @@ -65,66 +41,52 @@ minetest.register_globalstep(function(dtime) pos.y = pos.y + 1.5 -- head level playerplus[name].nod_head = node_ok(pos) - + pos.y = pos.y - 1.2 -- feet level playerplus[name].nod_feet = node_ok(pos) pos.y = pos.y - 0.2 -- reset pos - -- get player physics - def = player:get_physics_override() - - if armor_mod and armor and armor.def then - -- get player physics from armor - def.speed = armor.def[name].speed or def.speed - def.jump = armor.def[name].jump or def.jump - def.gravity = armor.def[name].gravity or def.gravity - end +-- [ Physics ] -- are we standing on any nodes that speed player up? nfast = nil - if playerplus[name].nod_stand == "default:ice" then + if playerplus[name].nod_stand == "default:ice" + or playerplus[name].nod_stand == "default:packedice" then nfast = true end -- are we standing on any nodes that slow player down? nslow = nil if playerplus[name].nod_stand == "default:snow" - or playerplus[name].nod_stand == "default:snowblock" then + or playerplus[name].nod_stand == "default:snowblock" + or playerplus[name].nod_stand == "default:bedrock" + or playerplus[name].nod_stand == "default:slimeblock" + or playerplus[name].nod_stand == "mobs:cobweb" then nslow = true end -- apply speed changes if nfast and not playerplus[name].nfast then - def.speed = def.speed + 0.4 - + playerphysics.add_physics_factor(player, "speed", "playerplusspeed", 1.5) playerplus[name].nfast = true - - elseif not nfast and playerplus[name].nfast then - def.speed = def.speed - 0.4 + elseif not nfast and playerplus[name].nfast then + playerphysics.remove_physics_factor(player, "speed", "playerplusspeed") playerplus[name].nfast = nil end - -- apply slowdown changes if nslow and not playerplus[name].nslow then - def.speed = def.speed - 0.3 - + playerphysics.add_physics_factor(player, "speed", "playerplusslow", 0.7) playerplus[name].nslow = true elseif not nslow and playerplus[name].nslow then - def.speed = def.speed + 0.3 - + playerphysics.remove_physics_factor(player, "speed", "playerplusslow") playerplus[name].nslow = nil end - - -- set player physics - player:set_physics_override(def.speed, def.jump, def.gravity) ---[[ - print ("Speed: " .. def.speed - .. " / Jump: " .. def.jump - .. " / Gravity: " .. def.gravity) -]] + +-- [ HP ] + -- Is player suffocating inside a normal node without no_clip privs? local ndef = minetest.registered_nodes[playerplus[name].nod_head] @@ -144,7 +106,6 @@ minetest.register_globalstep(function(dtime) local near = minetest.find_node_near(pos, 1, "default:cactus") if near then - -- am I touching the cactus? if so it hurts for _,object in pairs(minetest.get_objects_inside_radius(near, 1.1)) do @@ -152,17 +113,13 @@ minetest.register_globalstep(function(dtime) object:set_hp(object:get_hp() - 2) end end - end - end - end) -- set to blank on join (for 3rd party mods) minetest.register_on_joinplayer(function(player) - local name = player:get_player_name() playerplus[name] = {} @@ -171,9 +128,7 @@ minetest.register_on_joinplayer(function(player) playerplus[name].nod_stand = "" end) - -- clear when player leaves minetest.register_on_leaveplayer(function(player) - playerplus[ player:get_player_name() ] = nil end) diff --git a/games/default/files/playerplus/license.txt b/games/default/files/player/playerplus/license.txt similarity index 100% rename from games/default/files/playerplus/license.txt rename to games/default/files/player/playerplus/license.txt diff --git a/games/default/files/player_api/api.lua b/games/default/files/player_api/api.lua index 15242711b..bc1bda603 100644 --- a/games/default/files/player_api/api.lua +++ b/games/default/files/player_api/api.lua @@ -1,6 +1,3 @@ --- MultiCraft game mod: player --- See README.txt for licensing and other information. - player_api = {} -- Player animation blending @@ -45,7 +42,7 @@ function player_api.set_model(player, model_name) textures = player_textures[name] or model.textures, visual = "mesh", visual_size = model.visual_size or {x = 1, y = 1}, - collisionbox = model.collisionbox or {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3}, + collisionbox = model.collisionbox, -- or {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3}, stepheight = model.stepheight or 0.6, eye_height = model.eye_height or 1.47, }) @@ -53,7 +50,7 @@ function player_api.set_model(player, model_name) else player:set_properties({ visual = "upright_sprite", - collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.75, 0.3}, + -- collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.75, 0.3}, stepheight = 0.6, eye_height = 1.625, }) diff --git a/games/default/files/playerplus/README.md b/games/default/files/playerplus/README.md deleted file mode 100644 index 2d97c5c1a..000000000 --- a/games/default/files/playerplus/README.md +++ /dev/null @@ -1,31 +0,0 @@ -MultiCraft game mod: PlayerPlus -Removed POVA, monoids support, knock-back, glitch. - -This mod lets the player move faster when walking on ice, slows down the player -when walking on snow, makes touching a cactus hurt and suffocates player when -their head is inside a solid node... enjoy! - -https://forum.minetest.net/viewtopic.php?t=10090&p=153667 - -- 0.1 - Initial release -- 0.2 - 3d_armor mod compatibility -- 0.3 - Optimized code -- 0.4 - Added suffocation when inside nodes -- 0.5 - Slow down when walking in water -- 0.6 - Code tidy and tweak, increased damage by cactus and suffocation -- 0.7 - Added global 'playerplus' table to hold node names gathered around player -- 0.8 - Player knock-back added -- 0.9 - 'on_walk_over' function support added for nodes -- 1.0 - Update to newer functions, requires Minetest 0.4.16 and above to run -- 1.1 - Added support for player_monoids mod (thanks tacotexmex) -- 1.2 - Added POVA support, tweaked code slightly -- 1.3 - Add setting under Advances to enable older sneak glitch movement - -API: - -Every second the mod checks which node the player is standing on, which node is -at foot and head level and stores inside a global table to be used by mods: - -- playerplus[name].nod_stand -- playerplus[name].nod_foot -- playerplus[name].nod_head diff --git a/games/default/files/playerplus/depends.txt b/games/default/files/playerplus/depends.txt deleted file mode 100644 index c12cc51ba..000000000 --- a/games/default/files/playerplus/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -default -3d_armor? diff --git a/games/default/files/potions/potions/README.txt b/games/default/files/potions/potions/README.txt deleted file mode 100644 index 46df19e1e..000000000 --- a/games/default/files/potions/potions/README.txt +++ /dev/null @@ -1,33 +0,0 @@ ---Potions by Traxie21-- ---This mod provides no default potions. If you would like some, download potionspack at github.com/Traxie21/potionspack-- - - ---API DOCUMENTATION-- - -Potion Registering Format: - -potions.register_potion(NAME, COLOR, EXPIRE TIME, ACTIVATION FUNCTION, EXPIRE FUNCTION) - -NAME: Name of potion. Invalid characeters are automagically stripped from it. - -COLOR: Color of potion image in-game, available colors: black, brown, cyan, darkblue, darkgrey, lightgrey, darkred, dull, green, orange, pink, purple, red, white, and yellow. - -EXPIRE TIME: Number in seconds. - -ACTIVATION FUNCTION: The function that is run when the ground is right-clicked with the potion. - -EXPIRE FUNCTION: The function that is run when the expire time runs out. - - ---EXAMPLE-- - -potions.register_potion("Anti Gravity", "purple", 60, -function(itemstack, user, pointed_thing) - user:set_physics_override(3, 1.5, 0.5) - minetest.chat_send_player(user:get_player_name(), "You have been blessed with Anti Gravity for 60 seconds!") -end, - -function(itemstack, user, pointed_thing) - user:set_physics_override(1,1,1) - minetest.chat_send_player(user:get_player_name(), "Anti Gravity has worn off.") -end) diff --git a/games/default/files/potions/potions/init.lua b/games/default/files/potions/potions/init.lua deleted file mode 100644 index 1e6de3b8e..000000000 --- a/games/default/files/potions/potions/init.lua +++ /dev/null @@ -1,71 +0,0 @@ - - -local MOD_NAME = minetest.get_current_modname() - local MOD_PATH = minetest.get_modpath(MOD_NAME) - local Vec3 = dofile(MOD_PATH.."/lib/Vec3_1-0.lua") - -potions = {} - - - -function potions.register_potion(iname, color, exptime, action, expaction) - iname = string.gsub(iname, "[-%[%]()1023456789 ]", "") - minetest.register_craftitem(minetest.get_current_modname()..":"..iname:lower(), { - description = iname.." Potion", - inventory_image = "potions_bottle.png^potions_"..color..".png", - groups = {brewing = 1}, - - on_place = function(itemstack, user, pointed_thing) - action(itemstack, user, pointed_thing) - minetest.after(exptime, expaction, itemstack, user, pointed_thing) - itemstack:take_item() - --Particle Code - --Potions Particles - minetest.add_particlespawner(30, 0.2, - pointed_thing.above, pointed_thing.above, - {x=1, y= 2, z=1}, {x=-1, y= 2, z=-1}, - {x=0.2, y=0.2, z=0.2}, {x=-0.2, y=0.5, z=-0.2}, - 5, 10, - 1, 3, - false, "potions_"..color..".png") - - --Shatter Particles - minetest.add_particlespawner(40, 0.1, - pointed_thing.above, pointed_thing.above, - {x=2, y=0.2, z=2}, {x=-2, y=0.5, z=-2}, - {x=0, y=-6, z=0}, {x=0, y=-10, z=0}, - 0.5, 2, - 0.2, 5, - true, "potions_shatter.png") - - local dir = Vec3(user:get_look_dir()) *20 - minetest.add_particle( - {x=user:getpos().x, y=user:getpos().y+1.5, z=user:getpos().z}, {x=dir.x, y=dir.y, z=dir.z}, {x=0, y=-10, z=0}, 0.2, - 6, false, "potions_bottle.png^potions_"..color..".png") - return itemstack - - end, - }) -end - - -minetest.register_craftitem("potions:glass_bottle", { - description = "Glass Bottle", - inventory_image = "potions_bottle.png", - groups = {brewing = 1}, - on_place = function(itemstack, user, pointed_thing) - itemstack:take_item() - --Shatter Particles - minetest.add_particlespawner(40, 0.1, - pointed_thing.above, pointed_thing.above, - {x=2, y=0.2, z=2}, {x=-2, y=0.5, z=-2}, - {x=0, y=-6, z=0}, {x=0, y=-10, z=0}, - 0.5, 2, - 0.2, 5, - true, "potions_shatter.png") - return itemstack - end, -}) - -minetest.register_alias("vessels:glass_bottle", "potions:glass_bottle") - diff --git a/games/default/files/potions/potions/lib/Vec3_1-0.lua b/games/default/files/potions/potions/lib/Vec3_1-0.lua deleted file mode 100644 index 85d91ae5f..000000000 --- a/games/default/files/potions/potions/lib/Vec3_1-0.lua +++ /dev/null @@ -1,398 +0,0 @@ -local THIS_VERSION = "1.0" - ---- 3D vector class/operations. - -- - -- Note that methods can be called in either an object-oriented way: - -- v1 = Vec3(1, 2, 3) - -- v2 = v1:add({ x = 2, y = 2, z = 0 }) - -- or as simple functions: - -- Vec3.add({ x = 1, y = 2, z = 3 }, { x = 2, y = 2, z = 0 }) - -- - -- All methods that can be called on a Vec3 using ":" may be called on a table - -- using the second functional syntax, but the first parameter MUST have the - -- expected components "x", "y", and "z". If a vector is used as the second - -- paramter, it may instead be a list/array with numeric indices, like - -- { 1.0, 2.0, 3.0 } in place of { x = 1.0, y = 2.0, z = 3.0 }. - -- - -- @author prestidigitator (as registered at forum.minetest.net) - -- @copyright 2013, licensed under WTFPL - -- -local Vec3 = {} -local Vec3_meta = {} -local Vec3_inst_meta = {} - -Vec3.VERSION = THIS_VERSION - -setmetatable(Vec3, Vec3_meta) -Vec3_inst_meta.__index = Vec3 - ---- Constructs a Vec3 from three numbers. - -- - -- Call with one of: - -- Vec3.new(x, y, z) - -- Vec3(x, y, z) - -- - -- @return a new Vec3 object -local function Vec3_new(x, y, z) - local obj = { x = x or 0.0, y = y or 0.0, z = z or 0.0 } - setmetatable(obj, Vec3_inst_meta) - return obj -end -Vec3.new = Vec3_new - ---- Constructs a new copy of a Vec3. - -- - -- Call with one of: - -- vec:new_copy() - -- Vec3.new_copy(vec) - -- Vec3(vec) - -- - -- @return a new Vec3 object that is a copy of the parameter -local function Vec3_new_copy(v) - local obj = { x = v.x or v[1] or 0.0, - y = v.y or v[2] or 0.0, - z = v.z or v[3] or 0.0 } - setmetatable(obj, Vec3_inst_meta) - return obj -end -Vec3.new_copy = Vec3_new_copy - -Vec3_meta.__call = function(class, a, b, c) - if type(a) == "table" then - return Vec3.new_copy(a) - else - return Vec3.new(a, b, c) - end -end - ---- Computes the square of the length of a Vec3. - -- - -- Call with one of: - -- vec:len_sq() - -- Vec3.len_sq(vec) - -- - -- @return a number -local function Vec3_len_sq(v) - return v.x^2 + v.y^2 + v.z^2 -end -Vec3.len_sq = Vec3_len_sq - ---- Computes the length of a Vec3. - -- - -- Call with one of: - -- vec:len() - -- Vec3.len(vec) - -- - -- @return a number -local function Vec3_len(v) - return math.sqrt(v.x^2 + v.y^2 + v.z^2) -end -Vec3.len = Vec3_len - ---- Computes a unit vector pointing in the same direction as a Vec3. - -- Undefined for a zero-vector and may throw an error. - -- - -- Call with one of: - -- vec:unit() - -- Vec3.unit(vec) - -- - -- @return a new Vec3 with length 1.0 -local function Vec3_unit(v) - local len = math.sqrt(v.x^2 + v.y^2 + v.z^2) - return Vec3.new(v.x/len, v.y/len, v.z/len) -end -Vec3.unit = Vec3_unit - ---- Multiplies a Vec3 by a number. - -- - -- Call with one of: - -- vec:mul(m) - -- Vec3.mul(vec, m) - -- vec*m - -- m*vec - -- - -- @return a new Vec3 object with the result of the operation -local function Vec3_mul(v, m) - local mn = tonumber(m) - if not mn then error("Can't multiply vector by non-scalar") end - return Vec3.new(v.x*mn, v.y*mn, v.z*mn) -end -Vec3.mul = Vec3_mul -Vec3_inst_meta.__mul = function(a, b) - if type(a) == "table" then - return Vec3_mul(a, b) - else - return Vec3_mul(b, a) - end -end - ---- Divides a Vec3 by a number. - -- - -- Call with one of: - -- vec:div(m) - -- Vec3.div(vec, m) - -- vec/m - -- - -- @return a new Vec3 object with the result of the operation -local function Vec3_div(v, m) - return Vec3.new(v.x/m, v.y/m, v.z/m) -end -Vec3.div = Vec3_div -Vec3_inst_meta.__div = Vec3_div - ---- Negates a Vec3 (signs of all components are inverted). - -- - -- Call with one of: - -- vec:unm() - -- Vec3.unm(vec) - -- -vec - -- - -- @return a new Vec3 object with the result of the operation -local function Vec3_unm(v) - return Vec3.new(-v.x, -v.y, -v.z) -end -Vec3.unm = Vec3_unm -Vec3_inst_meta.__unm = Vec3_unm - ---- Adds two Vec3s or a Vec3 composed of three given components. - -- - -- Call with one of: - -- vec1:add(vec2) - -- vec1:add(x, y, z) - -- Vec3.add(vec1, vec2) - -- Vec3.add(vec1, x, y, z) - -- vec1 + vec2 - -- - -- @return a new Vec3 object with the result of the operation -local function Vec3_add(v, a, b, c) - if type(a) == "table" then - return Vec3.new(v.x + (a.x or a[1] or 0.0), - v.y + (a.y or a[2] or 0.0), - v.z + (a.z or a[3] or 0.0)) - else - return Vec3.new(v.x + a, v.y + b, v.z + c) - end -end -Vec3.add = Vec3_add - ---- Subtracts two Vec3s or a Vec3 composed of three given components. - -- - -- Call with one of: - -- vec1:sub(vec2) - -- vec1:sub(x, y, z) - -- Vec3.sub(vec1, vec2) - -- Vec3.sub(vec1, x, y, z) - -- vec1 - vec2 - -- - -- @return a new Vec3 object with the result of the operation -local function Vec3_sub(v, a, b, c) - if type(a) == "table" then - return Vec3.new(v.x - (a.x or a[1] or 0.0), - v.y - (a.y or a[2] or 0.0), - v.z - (a.z or a[3] or 0.0)) - else - return Vec3.new(v.x - a, v.y - b, v.z - c) - end -end -Vec3.sub = Vec3_sub - ---- Tests two Vec3s or a Vec3 composed of three given components for - -- exact component-wise equality. - -- - -- Call with one of: - -- vec1:eq(vec2) - -- vec1:eq(x, y, z) - -- Vec3.eq(vec1, vec2) - -- Vec3.eq(vec1, x, y, z) - -- vec1 == vec2 - -- vec1 ~= vec2 - -- Note that because of built-in Lua logic "==" and "~=" work ONLY if - -- vec1 and vec2 are actually Vec3s (not tables). - -- - -- @return a new Vec3 object with the result of the operation -local function Vec3_eq(v, a, b, c) - if type(a) == "table" then - return v.x == (a.x or a[1] or 0.0) and - v.y == (a.y or a[2] or 0.0) and - v.z == (a.z or a[3] or 0.0) - else - return v.x == a and v.y == b and v.z == c - end -end -Vec3.eq = Vec3_eq - ---- Takes the dot product of a Vec3 and a Vec3s or a Vec3 composed of - -- three given components. - -- - -- Call with one of: - -- vec1:dot(vec2) - -- vec1:dot(x, y, z) - -- Vec3.dot(vec1, vec2) - -- Vec3.dot(vec1, x, y, z) - -- - -- @return a number -local function Vec3_dot(v, a, b, c) - if type(a) == "table" then - return v.x * (a.x or a[1] or 0.0) + - v.y * (a.y or a[2] or 0.0) + - v.z * (a.z or a[3] or 0.0) - else - return v.x * a + v.y * b + v.z * c - end -end -Vec3.dot = Vec3_dot - ---- Takes the cross product of a Vec3 and a Vec3s or a Vec3 composed of - -- three given components. - -- - -- Call with one of: - -- vec1:cross(vec2) - -- vec1:cross(x, y, z) - -- Vec3.cross(vec1, vec2) - -- Vec3.cross(vec1, x, y, z) - -- - -- @return a new Vec3 with the result of the operation -local function Vec3_cross(v, a, b, c) - local ux, uy, uz - if type(a) == "table" then - ux = a.x or a[1] or 0.0 - uy = a.y or a[2] or 0.0 - uz = a.z or a[3] or 0.0 - else - ux = a or 0.0 - uy = b or 0.0 - uz = c or 0.0 - end - - return Vec3.new(v.y*uz - v.z*uy, v.z*ux - v.x*uz, v.x*uy - v.y*ux) -end -Vec3.cross = Vec3_cross - ---- Rotates this (the first) vector around the second vector by the - -- given angle. - -- - -- Call with one of: - -- vec:rot_around(axis, angle) - -- Vec3.rot_around(vec, axis, angle) - -- - -- @param axis - -- The axis about which to rotate. - -- @param angle - -- The angle by which to rotate this vector, in radians. - -- @return - -- a new Vec3 with the result of the operation. -local function Vec3_rot_around(v, axis, angle) - local uaxis = Vec3.new_copy(axis):unit() - - local alen = uaxis:dotvec(v) - local avec = uaxis:mul(alen) - - local pvec = Vec3.subvec(v, avec) - local rvec = uaxis:crossvec(v) - - local v1 = pvec:mul(math.cos(angle)) - local v2 = rvec:mul(math.sin(angle)) - - return avec:addvec(v1):addvec(v2) -end -Vec3.rot_around = Vec3_rot_around - ---- Adds two Vec3s. Optimized for pure Vec3/table operations by removing - -- type checking and conditionals. If called with Vec3-likes table(s), - -- ensure all expected components "x", "y", and "z" exist. - -- - -- Call with one of: - -- vec1:addvec(vec2) - -- Vec3.addvec(vec1, vec2) - -- - -- @return a new Vec3 object with the result of the operation -local function Vec3_addvec(v1, v2) - return Vec3.new(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z) -end -Vec3.addvec = Vec3_addvec -Vec3_inst_meta.__add = Vec3_addvec - ---- Subtracts two Vec3s. Optimized for pure Vec3/table operations by - -- removing type checking and conditionals. If called with Vec3-likes - -- table(s), ensure all expected components "x", "y", and "z" exist. - -- - -- Call with one of: - -- vec1:subvec(vec2) - -- Vec3.subvec(vec1, vec2) - -- - -- @return a new Vec3 object with the result of the operation -local function Vec3_subvec(v1, v2) - return Vec3.new(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z) -end -Vec3.subvec = Vec3_subvec -Vec3_inst_meta.__sub = Vec3_subvec - ---- Tests two Vec3s for exact component-wise equality. Optimized for pure - -- Vec3/table operations by removing type checking and conditionals. - -- If called with Vec3-likes table(s), ensure all expected components - -- "x", "y", and "z" exist. - -- - -- Call with one of: - -- vec1:eqvec(vec2) - -- Vec3.eqvec(vec1, vec2) - -- - -- @return a new Vec3 object with the result of the operation -local function Vec3_eqvec(v1, v2) - return v1.x == v2.x and v1.y == v2.y and v1.z == v2.z -end -Vec3.eqvec = Vec3_eqvec -Vec3_inst_meta.__eq = Vec3_eqvec - ---- Takes the dot product of two Vec3s. Optimized for pure Vec3/table - -- operations by removing type checking and conditionals. If called - -- with Vec3-likes table(s), ensure all expected components "x", "y", - -- and "z" exist. - -- - -- Call with one of: - -- vec1:dotvec(vec2) - -- Vec3.dotvec(vec1, vec2) - -- - -- @return a number -local function Vec3_dotvec(v1, v2) - return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z -end -Vec3.dotvec = Vec3_dotvec - ---- Takes the cross product of two Vec3s. Optimized for pure Vec3/table - -- operations by removing type checking and conditionals. If called - -- with Vec3-likes table(s), ensure all expected components "x", "y", - -- and "z" exist. - -- - -- Call with one of: - -- vec1:crossvec(vec2) - -- Vec3.crossvec(vec1, vec2) - -- - -- @return a new Vec3 with the result of the operation -local function Vec3_crossvec(v1, v2) - return Vec3.new(v1.y*v2.z - v1.z*v2.y, - v1.z*v2.x - v1.x*v2.z, - v1.x*v2.y - v1.y*v2.x) -end -Vec3.crossvec = Vec3_crossvec - ---- Converts Vec3 to a string with format "(x,y,z)". - -- - -- Call with one of: - -- vec:tostring() - -- Vec3.tostring(vec) - -- tostring(vec) - -- - -- @return a string -local function Vec3_tostring(v) - return "(".. - (v.x or v[1] or "0") - ..",".. - (v.y or v[2] or "0") - ..",".. - (v.z or v[3] or "0") - ..")" -end -Vec3.tostring = Vec3_tostring -Vec3_inst_meta.__tostring = Vec3_tostring - -return Vec3 diff --git a/games/default/files/potions/potionspack/depends.txt b/games/default/files/potions/potionspack/depends.txt deleted file mode 100644 index 4a56efaee..000000000 --- a/games/default/files/potions/potionspack/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ - -potions -default diff --git a/games/default/files/potions/potionspack/init.lua b/games/default/files/potions/potionspack/init.lua deleted file mode 100644 index 63c4ebd12..000000000 --- a/games/default/files/potions/potionspack/init.lua +++ /dev/null @@ -1,164 +0,0 @@ - - -potions.register_potion("Anti Gravity", "purple", 60, -function(itemstack, user, pointed_thing) - user:set_physics_override(nil, 1.5, 0.5) - minetest.chat_send_player(user:get_player_name(), "You have been blessed with Anti Gravity for 60 seconds!") -end, - -function(itemstack, user, pointed_thing) - user:set_physics_override(nil,1,1) - minetest.chat_send_player(user:get_player_name(), "Anti Gravity has worn off.") -end) - -potions.register_potion("Anti Gravity II", "pink", 60, -function(itemstack, user, pointed_thing) - user:set_physics_override(3, nil, 0.1) - minetest.chat_send_player(user:get_player_name(), "You have been blessed with Anti Gravity II for 60 seconds!") -end, - -function(itemstack, user, pointed_thing) - user:set_physics_override(1,nil,1) - minetest.chat_send_player(user:get_player_name(), "Anti Gravity II has worn off.") -end) - -potions.register_potion("Speed", "lightgrey", 60, -function(itemstack, user, pointed_thing) - user:set_physics_override(3, 1, 1) - minetest.chat_send_player(user:get_player_name(), "You have been blessed with Speed for 60 seconds!") -end, - -function(itemstack, user, pointed_thing) - user:set_physics_override(1,nil,nil) - minetest.chat_send_player(user:get_player_name(), "Speed has worn off.") -end) - -potions.register_potion("Speed II", "cyan", 60, -function(itemstack, user, pointed_thing) - user:set_physics_override(5, 1, 1) - minetest.chat_send_player(user:get_player_name(), "You have been blessed with Speed II for 60 seconds!") -end, - -function(itemstack, user, pointed_thing) - user:set_physics_override(1,nil,nil) - minetest.chat_send_player(user:get_player_name(), "Speed II has worn off.") -end) - -potions.register_potion("Inversion", "dull", 60, -function(itemstack, user, pointed_thing) - user:set_physics_override(1, -1, -0.2) - minetest.chat_send_player(user:get_player_name(), "You have been cursed with Inversion for 60 seconds!") -end, - -function(itemstack, user, pointed_thing) - user:set_physics_override(1,1,1) - minetest.chat_send_player(user:get_player_name(), "Inversion has worn off.") -end) - -potions.register_potion("Confusion", "dull", 60, -function(itemstack, user, pointed_thing) - user:set_physics_override(-1, nil, nil) - minetest.chat_send_player(user:get_player_name(), "You have been cursed with Confusion for 60 seconds!") -end, - -function(itemstack, user, pointed_thing) - user:set_physics_override(1,1,1) - minetest.chat_send_player(user:get_player_name(), "Confusion has worn off.") -end) - -potions.register_potion("What will this do", "white", 60, -function(itemstack, user, pointed_thing) - user:set_physics_override(math.random(1, 20), math.random(1, 20), math.random(-4, 2)) - minetest.chat_send_player(user:get_player_name(), "You have been given unknown powers for good or evil! (60 seconds)") -end, - -function(itemstack, user, pointed_thing) - user:set_physics_override(1,1,1) - minetest.chat_send_player(user:get_player_name(), "Unknown powers lost.") -end) - -potions.register_potion("Instant Health", "pink", 1, -function(itemstack, user, pointed_thing) - local hp = user:get_hp() - user:set_hp(hp + 6) -end, - -function(itemstack, user, pointed_thing) -end) - -potions.register_potion("Instant Health II", "pink", 1, -function(itemstack, user, pointed_thing) - local hp = user:get_hp() - local hp_raise = hp + 12 - user:set_hp(hp_raise) -end, - -function(itemstack, user, pointed_thing) -end) - -potions.register_potion("Regen", "purple", 35, -function(itemstack, user, pointed_thing) - local regen_I = true - minetest.chat_send_player(user:get_player_name(), "Regeneration I for 35 seconds") - local regen_II - if regen_II == true then - local regen - regen = function ( ) - local hp = user:get_hp() - if hp >= 20 then - minetest.after(1, regen) - elseif hp < 20 then - user:set_hp(hp + 1) - minetest.after(1, regen) - end - end - minetest.after(1, regen) - end -end, - -function(itemstack, user, pointed_thing) - local regen_I = false -end) - -potions.register_potion("Regen II", "purple", 30, -function(itemstack, user, pointed_thing) - local regen_II = true - minetest.chat_send_player(user:get_player_name(), "Regeneration II for 30 seconds") - if regen_II == true then - local regen - regen = function ( ) - local hp = user:get_hp() - if hp >= 20 then - minetest.after(.5, regen) - elseif hp < 20 then - user:set_hp(hp + 1) - minetest.after(.5, regen) - end - end - minetest.after(.5, regen) - end -end, - -function(itemstack, user, pointed_thing) - local regen_II = false -end) - -potions.register_potion("Harming", "red", 1, -function(itemstack, user, pointed_thing) - local hp = user:get_hp() - local lower = hp - 3 - user:set_hp(lower) -end, - -function(itemstack, user, pointed_thing) -end) - -potions.register_potion("Harming II", "red", 1, -function(itemstack, user, pointed_thing) - local hp = user:get_hp() - local lower = hp - 6 - user:set_hp(lower) -end, - -function(itemstack, user, pointed_thing) -end) diff --git a/games/default/files/potions/potionspack/textures/potions_black.png b/games/default/files/potions/potionspack/textures/potions_black.png deleted file mode 100644 index 2e813bbfbb0607046b9dcfd74a5b29642305db8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4S0F7UBqS^>EFvNzDk^%j zYDq0nh_NKdFPOpM*^M+H$KKP$F{C2y>Ip-^1_uF_gBuOR&K-)1_&;lf(*NHL9elIz z&%CoJ?$84%t;a%_wVuhSzMtc~Mm5@@lr!h?h9lYar3Mj!?666=m;PC858j$1S>Eakt5qI^3A>#o99_E9~6S$TsfY2lUg&dD~ z<`zBvIOn5o(DVrxr9zXo98nQ^Tg>9#drr|xb`R^4tt@jR4h#LS;eRCB`cv}68lZU$ Mp00i_>zopr0Bnjfl>h($ diff --git a/games/default/files/potions/potionspack/textures/potions_cyan.png b/games/default/files/potions/potionspack/textures/potions_cyan.png deleted file mode 100644 index 992f48875dcea82183c170224ce986bc2cc354e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfvl>na*S0HV^Y@x-<#g?m=TCQ1U zxo(Bk`jyrjR$FgcW3zR=?e-0}J2sWRJL(8j$5;~N7tG-B>_!@p7@{%p>Ip-} z0|p!n2e&t{>Lf67M;vg{NmwYBr1)$VgHg$=UiNz7%5L518;%?oFg(=Wp;cb;HSmey s(O(5yN+#Dzd|1KXI4??!=i^!KyBso_moF5)02FVdQ&MBb@08br98UO$Q diff --git a/games/default/files/potions/potionspack/textures/potions_darkblue.png b/games/default/files/potions/potionspack/textures/potions_darkblue.png deleted file mode 100644 index e975c7696b8a1e832277872c64fbb6989b1074e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv#Q>iWS0JsY-lwlI*-&eyk=ATu zo%tp@i_P?wo9nMK*I#2{uzuRy@7h2`j3q&S!3+-1ZlnP@zMd|QAsQ2}o-kxQV8G#e zFrAS*;=rNp4Xio|3&oNYwN@*nytpFG|4;3;*l9h%)?)_TLCz`LTdrHqy7lmgWy^N` mS2Bz?>l8oS6+J0%f6v)?sfpXa8T$bZX7F_Nb6Mw<&;$V4e?Kz- diff --git a/games/default/files/potions/potionspack/textures/potions_darkgrey.png b/games/default/files/potions/potionspack/textures/potions_darkgrey.png deleted file mode 100644 index a01dc77b7bf806e5c445129ce4326a3470dce451..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@o&cW^S0L@;;^OA!=I-upIY(C) z$Y(4G@(X5gcy=QV$g%cxaSW-5OJ1P);8(-B2mB7{M>a1qjBwt`6d?I}KiiSTMs|Pr wQ(aS8jvW8I*id5MvBgFa|LbEL5(HQoD)&g7Z(U=z6KD*Br>mdKI;Vst07V8a*#H0l diff --git a/games/default/files/potions/potionspack/textures/potions_darkred.png b/games/default/files/potions/potionspack/textures/potions_darkred.png deleted file mode 100644 index 2dd936b468c0b8d198f3fcb4fd83765b9b1cb1ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfvi2$DvS0FuELt}=f=1eWEE>+cu z8XCQ7YO}Spz6VbK2b5zh3GxeOaCmkj4ajlxba4!+V7z+5knw;453^&S0c)^8Yd{6p zB7tAJjTX+!?^XPo`zpF3wn;2`O>39pDYm8O6ThlGlF>M~JJ^HIS>v{EW=FoBNu_VYZn8D%MjWi&~$s6}O zYgBF4s@bkrbN#ygCs2;DB*-tA!Qt7BG$6;#)5S5QBJS!5L&gIJJj@4|D{w7J0HI|8 zzgz{Eakt5tqC`^TDr%a}W3((vNIjWEkPRlPN&*^?tS^i;e95 x@Ta<_vK%@7d9k6yzGI7xBL3IMHY5nJGF0x7IN!R)ZYR(f22WQ%mvv4FO#r)&GIRg{ diff --git a/games/default/files/potions/potionspack/textures/potions_orange.png b/games/default/files/potions/potionspack/textures/potions_orange.png deleted file mode 100644 index 50f000fce44bad6d4ee7859b8a7366c145447cd3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfvxd5LKS0H`A&+FlophwfgAI*q- zJUi~myyT|~GoCKWdb%Vh(xl}NPz7U2kY6x^!?PP{K#sSki(`n!#H%L^84nn6FdW?8 zz^aqL$Q^NjNo<3__D}{%tEb1Bue;n^^i*it4=E+LA3}jo`<}_T$_3}}xqHu^bGRWa hp2>Eqn9j%Z?3qucINf5dKL#4h;OXk;vd$@?2>>RzLI?l= diff --git a/games/default/files/potions/potionspack/textures/potions_particle.png b/games/default/files/potions/potionspack/textures/potions_particle.png deleted file mode 100644 index c44784c8671de37ed452dd5004dd0ff6b51a2a05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 540 zcmV+%0^|LOP)Pu0CM?e2JnJ7jo)UkzUzzmyS|=S_iX{#@l(6w=LR5s73q@_02_W7raGOvM~MAJvre;_N)SU# z26r2Atx?w->swsdZ2?*_-zh7}Dlyh*_h_P{O(ufHpu>ga^se@3n!eToV4;Y))J!x6 zuNGw_#Yj~zW3=>wF4Wmd+i6ek7~gII3KJ=&!{8;15Dx~!MtKZFv>}snHFcMQy=fnH zEkF_Dl&NHjvYPU6Cyw?Os_g4II^?+`X0cP$%g{pg^MIJ7%n;)kq&%2xQ3e22UMVb+ zxzBss&;t8cQ=KMfaSv<6WROK}7qN~p@?7dJhTH)t>7OCZG-Y3Jlo-Lj!ZW?mUe~+Z zyVkozz0lj*_Vqlp)cM{J703qn@JPs`=?NXmaxcctn!`a80}=`ON&J?JmLM5i>NzEsqAf@NZaQhPJR?N0Z1Rd0mcihen4 zT_`s11psXODH?St#7mSXh*3(H+^p)klvj(m9O{{3Yp?jYx<8$tqVsdp`E{)NZKT%% e^tJHcs0{#!quvDifmwzC0000L2&680x;TbZ zFuuLmoOi51#Np%bn;gr&_e-7Gw)Xgpy;m(lcT}wKt8@KveCnb_i)x;RZChw|ZNeqi zU+ER1teMddRxWhN&2?<*xnz22!-2(T9yvctILY>?asBQIwkoBKzt3r1d1p4~nBkRI zdNMbgS!$=2C76Dju!r@|HN{2$ZyCk8PycXXMw71b1chj`iF;UOES-P+4~T8K8r!DD zZP5O@Lu`e f=vz0p${r1ZX9t#!(!AWwR_`njxgN@xNA1$}oa diff --git a/games/default/files/potions/potionspack/textures/potions_purple.png b/games/default/files/potions/potionspack/textures/potions_purple.png deleted file mode 100644 index 4d9fe01b0e2fe305784aa65a5f4ca06eae36c57e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfvtpJ}8S0J6PzA95=ZI;IRY|RZh znwxSpx8!MU&DYvqptZA5dsmV6o?@N7B|7`{Lyx`$s%9(+@(X5gcy=QV$O-mzaSYLz zc=g0Vh64sX4j0!8v}(90as_rciLMH0)$~c^DwTA+bl9)@ID5TtWtTf&B6Gg;5srMN zXC?0LvfX!iWS0H`Y%Ico2?R_Vw`z|gI z+}$5|dOq;=eHak%FevCzaB#+lU%Ws?j3q&S!3+-1ZlnP@zMd|QAsQ2}o-kxQV8G#e zFrAS*;=rNp4Xio|3&oNYwN@*nytpFG|4;3;*l9h%)?)_TLCz`LTdrHqy7lmgWy^N` mS2Bz?>l8oS6+J0%f6v)?sfpXa8T$bZX7F_Nb6Mw<&;$T47DJl= diff --git a/games/default/files/potions/potionspack/textures/potions_shatter.png b/games/default/files/potions/potionspack/textures/potions_shatter.png deleted file mode 100644 index c68353a35a4c99a0b674ce95e89f734ffb4e5ba0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 115 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1SGw4HSYi^wvr&fU?2?ydCS-*0x1no7srqa z#$<_r5C8wy&k>5>U*A}~|L>2E3BNyo=b!TNwf>QY_wn`&42N%vS9k4=0_kD!boFyt I=akR{09Z35i~s-t diff --git a/games/default/files/potions/potionspack/textures/potions_white.png b/games/default/files/potions/potionspack/textures/potions_white.png deleted file mode 100644 index 4d7b0fcfa50bb9354cec456b3243df343d5fc8b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@o&cW^S0Mf3#fz6OU%q=7V1i=N|Aoq#xP5$S}frCsTmr>-}s;78}|9 x;ZJoiWS0KG}t=7Ix+K0F69NnRF zVz=(;eR}5)8C*DQc;T?|#Uo}sUM0LhMT{jue!&b5&u*jvIli7Qjv*QoubwbuJYc}# zdN7@lJL15h?G3Ct2@A!N6tz|>q`bHy&HqpBwb*Gr!Pa92+(FJM+gq+%&bsyRh-J%m n{Z}%KHtQ5W+!Z}3aDUI)c&UlozZv@h4QB9k^>bP0l+XkK*hoaL diff --git a/games/default/files/vessels/README.txt b/games/default/files/vessels/README.txt new file mode 100644 index 000000000..c758b8caf --- /dev/null +++ b/games/default/files/vessels/README.txt @@ -0,0 +1,9 @@ +MultiCraft Game mod: vessels +========================== +See license.txt for license information. + +Authors of source code +---------------------- +Originally by Vanessa Ezekowitz (LGPLv3.0+) +Modified by Perttu Ahola (LGPLv3.0+) +Various Minetest developers and contributors (LGPLv3.0+) diff --git a/games/default/files/vessels/depends.txt b/games/default/files/vessels/depends.txt new file mode 100644 index 000000000..4ad96d515 --- /dev/null +++ b/games/default/files/vessels/depends.txt @@ -0,0 +1 @@ +default diff --git a/games/default/files/vessels/init.lua b/games/default/files/vessels/init.lua new file mode 100644 index 000000000..fe2e6a4f1 --- /dev/null +++ b/games/default/files/vessels/init.lua @@ -0,0 +1,108 @@ +local vessels_shelf_formspec = + "size[9,7;]" .. + "list[context;vessels;0,0.3;9,2;]" .. + "list[current_player;main;0,2.85;9,1;]" .. + "list[current_player;main;0,4.08;9,3;9]" .. + "listring[context;vessels]" .. + "listring[current_player;main]" + +local function get_vessels_shelf_formspec(inv) + local formspec = vessels_shelf_formspec + local invlist = inv and inv:get_list("vessels") + return formspec +end + +minetest.register_node("vessels:shelf", { + description = "Potion Shelf", + tiles = {"default_wood.png", "default_wood.png", "default_wood.png", + "default_wood.png", "vessels_shelf.png", "vessels_shelf.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = default.node_sound_wood_defaults(), + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_vessels_shelf_formspec(nil)) + local inv = meta:get_inventory() + inv:set_size("vessels", 9 * 2) + end, + can_dig = function(pos,player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("vessels") + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if minetest.get_item_group(stack:get_name(), "vessel") ~= 0 then + return stack:get_count() + end + return 0 + 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 vessels shelf at ".. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_vessels_shelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " moves stuff to vessels shelf at ".. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_vessels_shelf_formspec(meta:get_inventory())) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes stuff from vessels shelf at ".. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_vessels_shelf_formspec(meta:get_inventory())) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "vessels", drops) + drops[#drops + 1] = "vessels:shelf" + minetest.remove_node(pos) + return drops + end, +}) + +minetest.register_craft({ + output = "vessels:shelf", + recipe = { + {"group:wood", "group:wood", "group:wood"}, + {"group:vessel", "group:vessel", "group:vessel"}, + {"group:wood", "group:wood", "group:wood"}, + } +}) + +minetest.register_node("vessels:glass_bottle", { + description = "Empty Glass Bottle", + drawtype = "plantlike", + tiles = {"vessels_glass_bottle.png"}, + inventory_image = "vessels_glass_bottle.png", + wield_image = "vessels_glass_bottle.png", + paramtype = "light", + is_ground_content = false, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} + }, + groups = {vessel = 1, dig_immediate = 3, attached_node = 1}, + sounds = default.node_sound_glass_defaults(), +}) + +minetest.register_alias("potions:glass_bottle", "vessels:glass_bottle") + +minetest.register_craft( { + output = "vessels:glass_bottle 4", + recipe = { + {"", "", ""}, + {"default:glass", "", "default:glass"}, + {"", "default:glass", ""} + } +}) + +minetest.register_craft({ + type = "fuel", + recipe = "vessels:shelf", + burntime = 30, +}) diff --git a/games/default/files/vessels/license.txt b/games/default/files/vessels/license.txt new file mode 100644 index 000000000..ca16e28c0 --- /dev/null +++ b/games/default/files/vessels/license.txt @@ -0,0 +1,16 @@ +License of source code +---------------------- + +GNU Lesser General Public License, version 3.0 +Copyright (C) 2012-2016 Vanessa Ezekowitz +Copyright (C) 2012-2016 celeron55, Perttu Ahola +Copyright (C) 2012-2016 Various Minetest developers and contributors + +This program is free software; you can redistribute it and/or modify it under the terms +of the GNU Lesser General Public License as published by the Free Software Foundation; +either version 3.0 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU Lesser General Public License for more details: +https://www.gnu.org/licenses/lgpl-3.0.html diff --git a/games/default/files/potions/potionspack/textures/potions_bottle.png b/games/default/files/vessels/textures/vessels_glass_bottle.png similarity index 100% rename from games/default/files/potions/potionspack/textures/potions_bottle.png rename to games/default/files/vessels/textures/vessels_glass_bottle.png diff --git a/games/default/files/vessels/textures/vessels_shelf.png b/games/default/files/vessels/textures/vessels_shelf.png new file mode 100644 index 0000000000000000000000000000000000000000..157ae85b7026577d5f310604494fdf89273a9e68 GIT binary patch literal 349 zcmV-j0iyniP)A(tWlbr4VK#15D+&h#9uy3Lc6oJaZ(c|!VqR!OEgpq> zd|Fs!g=ac@b9i-GEt8CsSVJTm5)7}e#*c!6iE2DNklE1V3QJ=p=pF9tB8X0YCqfYYbsvhK