develop #30

Merged
milan merged 8 commits from develop into master 2021-01-27 21:59:08 +01:00
100 changed files with 1752 additions and 284 deletions
Showing only changes of commit f54c45abcd - Show all commits

View file

@ -92,13 +92,14 @@ git clone --depth 1 --branch master https://notabug.org/TenPlus1/stairs.git
git clone --depth 1 --branch master https://notabug.org/TenPlus1/anvils.git
git clone --depth 1 --branch master https://notabug.org/TenPlus1/carts.git
git clone --depth 1 --branch master https://notabug.org/TenPlus1/doors.git
#Temporary fix for mistake in repo in mod.conf
rm -f doors/mod.conf
git clone --depth 1 --branch master https://notabug.org/TenPlus1/pie.git
git clone --depth 1 --branch master https://notabug.org/TenPlus1/castle.git
git clone --depth 1 --branch master https://notabug.org/TenPlus1/mobs_sky.git
git clone --depth 1 --branch master https://github.com/Uberi/Minetest-WorldEdit.git
git clone --depth 1 --branch master https://github.com/minetest-mods/realchess.git
git clone --depth 1 --branch master https://github.com/Grizzly-Adam/BBQ.git
git clone --depth 1 --branch master git://cheapiesystems.com/mail
git clone --depth 1 --branch master https://github.com/minetest-mods/mydoors.git
git clone --depth 1 --branch master https://github.com/TumeniNodes/angledwalls.git
git clone --depth 1 --branch master https://github.com/pyrollo/display_modpack.git
@ -111,7 +112,6 @@ git clone --depth 1 --branch master https://github.com/Extex101/christmas.git
git clone --depth 1 --branch master https://gitlab.com/VanessaE/gloopblocks.git
git clone --depth 1 --branch master https://github.com/minetest-mods/mylandscaping.git
git clone --depth 1 --branch master https://gitlab.com/VanessaE/minislots.git
git clone --depth 1 --branch master git://cheapiesystems.com/prefab_redo
git clone --depth 1 --branch master https://github.com/v-rob/bridger.git
git clone --depth 1 --branch master https://github.com/AiTechEye/smartshop.git
git clone --depth 1 --branch master https://repo.or.cz/minetest_colorcubes.git
@ -130,6 +130,9 @@ git clone --depth 1 --branch master https://github.com/qwrwed/lightsplus.git
git clone --depth 1 --branch master https://github.com/khonkhortisan/rubiks.git
git clone --branch master https://git.bananach.space/advtrains.git
git clone --depth 1 --branch master https://github.com/Dragonop/claycrafter
git clone --depth 1 --branch master https://notabug.org/NetherEran/hot_air_balloons.git
git clone --branch master https://cheapiesystems.com/git/prefab_redo
git clone --branch master https://cheapiesystems.com/git/mail
#Clean git stuff

View file

@ -216,7 +216,7 @@ load_mod_font_api = true
load_mod_poisonivy = true
load_mod_xdecor = true
load_mod_trunks = true
load_mod_mobs_bat = true
load_mod_mobs_bat = false
load_mod_playeranim = true
load_mod_playerplus = true
load_mod_prefab_redo = true
@ -268,3 +268,5 @@ load_mod_assets = true
load_mod_advtrains_signals_ks = true
load_mod_claycrafter = true
load_mod_serialize_lib = true
load_mod_mobs_sky = false
load_mod_hot_air_balloons = true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 B

After

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 714 B

After

Width:  |  Height:  |  Size: 528 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 718 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 618 B

After

Width:  |  Height:  |  Size: 398 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 376 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 793 B

After

Width:  |  Height:  |  Size: 476 B

View file

@ -104,10 +104,10 @@ function advtrains.set_trainhud(name, text, driver)
local driverhud = {
hud_elem_type = "image",
name = "ADVTRAINS_DRIVER",
position = {x=0.5, y=0.7},
offset = {x=0,y=5},
position = {x=0.5, y=1},
offset = {x=0,y=-170},
text = driver or "",
alignment = {x=0,y=1},
alignment = {x=0,y=-1},
scale = {x=1,y=1},}
if not hud then
hud = {["driver"]={}}
@ -116,8 +116,8 @@ function advtrains.set_trainhud(name, text, driver)
hud_elem_type = "text",
name = "ADVTRAINS",
number = 0xFFFFFF,
position = {x=0.5, y=0.7},
offset = {x=0, y=-5},
position = {x=0.5, y=1},
offset = {x=0, y=-300},
text = text,
scale = {x=200, y=60},
alignment = {x=0, y=-1},
@ -184,32 +184,14 @@ function advtrains.hud_train_format(train, flip)
local vel = advtrains.abs_ceil(train.velocity)
local vel_kmh=advtrains.abs_ceil(advtrains.ms_to_kmh(train.velocity))
local levers = {[0] = "emg","b","r","n","p"}
local lvrcolor = {[0] = "red", "orange", "orange", "cyan", "cyan"}
local tlev=train.lever or 1
if train.velocity==0 and not train.active_control then tlev=1 end
local ht = {"[combine:440x110:0,0=(advtrains_hud_bg.png^[resize\\:440x110)"}
local st = {}
if train.debug then st = {train.debug} end
local ht = {"[combine:300x150:0,0=(advtrains_hud_bg.png^[resize\\:300x150)"}
ht[#ht+1] = "100,0=(advtrains_hud_" .. (flip and "reverse" or "forward") .. ".png^[resize\\:100x20^[makealpha\\:#000000)"
ht[#ht+1] = "200,0=(advtrains_hud_" .. (levers[tlev] or "bg") .. ".png^[resize\\:100x20^[multiply\\:" .. (lvrcolor[tlev] or "#000000") .. "^[makealpha\\:#000000)"
if train.tarvelocity or train.atc_command then
ht[#ht+1] = "100,20=(advtrains_hud_atc.png^[resize\\:100x20^[makealpha\\:#000000)"
end
if train.ctrl.lzb then
ht[#ht+1] = "200,20=(advtrains_hud_lzb.png^[resize\\:100x20^[multiply\\:red^[makealpha\\:#000000)"
end
if train.is_shunt then
ht[#ht+1] = "100,40=(advtrains_hud_shunt.png^[resize\\:100x20^[makealpha\\:#000000)"
end
if train.door_open == -1 then
ht[#ht+1] = "100,60=(advtrains_hud_left_door.png^[resize\\:100x20^[makealpha\\:#000000)"
elseif train.door_open == 1 then
ht[#ht+1] = "200,60=(advtrains_hud_right_door.png^[resize\\:100x24^[makealpha\\:#000000)"
end
-- speed indication(s)
-- seven-segment display
local function sevenseg(digit, x, y, w, h, m)
--[[
-1-
@ -246,34 +228,71 @@ function advtrains.hud_train_format(train, flip)
end
end
end
sevenseg(math.floor(vel/10), 5, 5, 20, 10, "[colorize\\:red\\:255")
sevenseg(vel%10, 55, 5, 20, 10, "[colorize\\:red\\:255")
-- lever
ht[#ht+1] = "275,10=(advtrains_hud_bg.png^[colorize\\:cyan^[resize\\:5x18)"
ht[#ht+1] = "275,28=(advtrains_hud_bg.png^[colorize\\:white^[resize\\:5x18)"
ht[#ht+1] = "275,46=(advtrains_hud_bg.png^[colorize\\:orange^[resize\\:5x36)"
ht[#ht+1] = "275,82=(advtrains_hud_bg.png^[colorize\\:red^[resize\\:5x18)"
ht[#ht+1] = "292,16=(advtrains_hud_bg.png^[colorize\\:darkslategray^[resize\\:6x78)"
ht[#ht+1] = sformat("280,%s=(advtrains_hud_bg.png^[colorize\\:gray^[resize\\:30x18)",18*(4-tlev)+10)
-- reverser
ht[#ht+1] = sformat("245,10=(advtrains_hud_arrow.png^[transformFY%s)", flip and "" or "^[multiply\\:cyan")
ht[#ht+1] = sformat("245,85=(advtrains_hud_arrow.png%s)", flip and "^[multiply\\:orange" or "")
ht[#ht+1] = "250,35=(advtrains_hud_bg.png^[colorize\\:darkslategray^[resize\\:5x40)"
ht[#ht+1] = sformat("240,%s=(advtrains_hud_bg.png^[resize\\:25x15^[colorize\\:gray)", flip and 65 or 30)
-- train control/safety indication
if train.tarvelocity or train.atc_command then
ht[#ht+1] = "10,10=(advtrains_hud_atc.png^[resize\\:30x30^[multiply\\:cyan)"
end
if train.ctrl.lzb then
ht[#ht+1] = "50,10=(advtrains_hud_lzb.png^[resize\\:30x30^[multiply\\:red)"
end
if train.is_shunt then
ht[#ht+1] = "90,10=(advtrains_hud_shunt.png^[resize\\:30x30^[multiply\\:orange)"
end
-- door
ht[#ht+1] = "187,10=(advtrains_hud_bg.png^[resize\\:26x30^[colorize\\:white)"
ht[#ht+1] = "189,12=(advtrains_hud_bg.png^[resize\\:22x11)"
ht[#ht+1] = sformat("170,10=(advtrains_hud_bg.png^[resize\\:15x30^[colorize\\:%s)", train.door_open==-1 and "white" or "darkslategray")
ht[#ht+1] = "172,12=(advtrains_hud_bg.png^[resize\\:11x11)"
ht[#ht+1] = sformat("215,10=(advtrains_hud_bg.png^[resize\\:15x30^[colorize\\:%s)", train.door_open==1 and "white" or "darkslategray")
ht[#ht+1] = "217,12=(advtrains_hud_bg.png^[resize\\:11x11)"
-- speed indication(s)
sevenseg(math.floor(vel/10), 320, 10, 30, 10, "[colorize\\:red\\:255")
sevenseg(vel%10, 380, 10, 30, 10, "[colorize\\:red\\:255")
for i = 1, vel, 1 do
ht[#ht+1] = sformat("%d,100=(advtrains_hud_bg.png^[resize\\:11x30^[colorize\\:white)", i*14-3)
ht[#ht+1] = sformat("%d,65=(advtrains_hud_bg.png^[resize\\:8x20^[colorize\\:white)", i*11-1)
end
for i = max+1, 20, 1 do
ht[#ht+1] = sformat("%d,100=(advtrains_hud_bg.png^[resize\\:11x30^[colorize\\:darkslategray)", i*14-3)
ht[#ht+1] = sformat("%d,65=(advtrains_hud_bg.png^[resize\\:8x20^[colorize\\:darkslategray)", i*11-1)
end
if res and res > 0 then
ht[#ht+1] = sformat("%d,95=(advtrains_hud_bg.png^[resize\\:3x40^[colorize\\:red\\:255)", 8+res*14)
ht[#ht+1] = sformat("%d,60=(advtrains_hud_bg.png^[resize\\:3x30^[colorize\\:red\\:255)", 7+res*11)
end
if train.tarvelocity then
ht[#ht+1] = sformat("%d,130=(advtrains_hud_arrow.png^[multiply\\:cyan^[transformFY^[makealpha\\:#000000)", 2+train.tarvelocity*14)
ht[#ht+1] = sformat("%d,85=(advtrains_hud_arrow.png^[multiply\\:cyan^[transformFY^[makealpha\\:#000000)", 1+train.tarvelocity*11)
end
local lzb = train.lzb
if lzb and lzb.oncoming then
local oc = lzb.oncoming
for i = 1, #oc do
local spd = oc[i].spd
if not spd then
ht[#ht+1] = "203,43=(advtrains_hud_bg.png^[resize\\:14x14^[colorize\\:lime\\:255)"
elseif spd == 0 then
ht[#ht+1] = "283,43=(advtrains_hud_bg.png^[resize\\:14x14^[colorize\\:red\\:255)"
elseif tonumber(spd) then
ht[#ht+1] = "243,43=(advtrains_hud_bg.png^[resize\\:14x14^[colorize\\:orange\\:255)"
ht[#ht+1] = sformat("%d,85=(advtrains_hud_arrow.png^[multiply\\:red^[makealpha\\:#000000)", 2+spd*14)
local c = not spd and "lime" or (type(spd) == "number" and (spd == 0) and "red" or "orange") or nil
if c then
ht[#ht+1] = sformat("130,10=(advtrains_hud_bg.png^[resize\\:30x5^[colorize\\:%s)",c)
ht[#ht+1] = sformat("130,35=(advtrains_hud_bg.png^[resize\\:30x5^[colorize\\:%s)",c)
if spd and spd~=0 then
ht[#ht+1] = sformat("%d,50=(advtrains_hud_arrow.png^[multiply\\:red^[makealpha\\:#000000)", 1+spd*11)
end
local floor = math.floor
local dist = floor(((oc[i].idx or train.index)-train.index))
dist = math.max(0, math.min(999, dist))
for j = 1, 3, 1 do
sevenseg(floor((dist/10^(3-j))%10), 119+j*11, 18, 4, 2, "[colorize\\:"..c)
end
break
end
break
end
end
@ -291,7 +310,7 @@ end
local _, texture = advtrains.hud_train_format { -- dummy train object to demonstrate the train hud
max_speed = 15, speed_restriction = 15, velocity = 15, tarvelocity = 12,
active_control = true, lever = 3, ctrl = {lzb = true}, is_shunt = true,
door_open = 1, lzb = {oncoming = {{spd=6}}}
door_open = 1, lzb = {oncoming = {{spd=6, idx=125.7}}}, index = 0,
}
minetest.register_node("advtrains:hud_demo",{

View file

@ -190,6 +190,7 @@ local function write_to_fd(root_table, file, config)
file:write("LUA_SER v=1\n")
write_table(root_table, file, config)
file:write("E\nEND_SER\n")
file:close()
end
-- Reads the file contents from the passed file descriptor and returns the table on success

View file

@ -1 +1,4 @@
name = ambience
depends = default
optional_depends = fire, playerplus
description = Adds realistic sound effects into your world.

View file

@ -1 +1,4 @@
name = bakedclay
depends = default
optional_depends = stairs, moreblocks, lucky_block, technic_cnc
description = Adds the ability to bake clay into blocks and colour them with dye.

View file

@ -1 +1 @@
This mod adds bees and hives to Minetest
Adds bees and hives to Minetest.

View file

@ -1 +1,4 @@
name = bees
depends = default
optional_depends = intllib, lucky_block
description = Adds bees and hives to Minetest.

View file

@ -1 +1,4 @@
name = bonemeal
depends = default
optional_depends = intllib, lucky_block, farming, ethereal, moretrees, technic_worldgen, flowers, dye
description = Adds bone and bonemeal giving the ability to quickly grow plants and saplings.

View file

@ -1 +1,4 @@
name = bows
depends = default
optional_depends = mobs, lucky_block
description = Adds a selection of bows and arrows for players to use in-game.

View file

@ -1 +1,4 @@
name = builtin_item
depends = default
optional_depends =
description = Dropped items can now be pushed by water and have their own custom functions.

View file

@ -33,8 +33,12 @@ Have any questions/comments? Submit an [issue](https://github.com/minetest-mods/
This "ore", doesn't spawn underground!\
Instead, it spawns at the sky; that's why it's called "cloud".
An ore will be spawned inside the schematic.\
You have less chances to find an ore, than not to find an ore.
An ore will be spawned somewhere in the schematic!\
You'll have certain probabilities to have an ore or not!
- For small clouds: 2.5% of getting an ore per node.
- For medium clouds: 5% of getting an ore per node.
- For big clouds: 7.5% of getting an ore per node.
Small schematic
![Small schematic](https://user-images.githubusercontent.com/51391473/69098689-af9fbf00-0a1e-11ea-9e88-c74a6b74baa3.png)

View file

@ -78,6 +78,50 @@ minetest.register_node("cloud_items:decorative_cloud", {
sounds = default.node_sound_stone_defaults(),
})
-- On-generation nodes. These nodes are used
-- immediately right after generation.
minetest.register_node("cloud_items:ongen_small", {
description = S("On-generation cloud"),
tiles = {"default_cloud.png"},
light_source = 2,
is_ground_content = false,
groups = {cracky = 1, level = 3, not_in_creative_inventory = 1},
drop = "",
sounds = default.node_sound_stone_defaults(),
on_place = function(itemstack, user, pointed_thing)
minetest.chat_send_player(user:get_player_name(), "You're not allowed to place on-generation cloud blocks!")
return itemstack
end,
})
minetest.register_node("cloud_items:ongen_medium", {
description = S("On-generation cloud"),
tiles = {"default_cloud.png"},
light_source = 2,
is_ground_content = false,
groups = {cracky = 1, level = 3, not_in_creative_inventory = 1},
drop = "",
sounds = default.node_sound_stone_defaults(),
on_place = function(itemstack, user, pointed_thing)
minetest.chat_send_player(user:get_player_name(), "You're not allowed to place on-generation cloud blocks!")
return itemstack
end,
})
minetest.register_node("cloud_items:ongen_big", {
description = S("On-generation cloud"),
tiles = {"default_cloud.png"},
light_source = 2,
is_ground_content = false,
groups = {cracky = 1, level = 3, not_in_creative_inventory = 1},
drop = "",
sounds = default.node_sound_stone_defaults(),
on_place = function(itemstack, user, pointed_thing)
minetest.chat_send_player(user:get_player_name(), "You're not allowed to place on-generation cloud blocks!")
return itemstack
end,
})
------------
-- Stairs --
------------
@ -202,6 +246,53 @@ local function place_schem_metadata(origin, filename)
minetest.log("action", "Successfully placed schematic with " .. nodes .. " nodes (metadata)")
end
-- When an schematic is generated, it'll have a special node
-- which will have certain chance to convert to an ore or normal cloud.
local chance = math.random(1, 100)
minetest.register_lbm({
label = "Replace cloud nodes with ore if succeeded",
name = "cloud_items:chance_add_ore",
nodenames = {"cloud_items:ongen_small", "cloud_items:ongen_medium", "cloud_items:ongen_big"},
run_at_every_load = true,
action = function(pos, node)
chance = math.random(1, 100)
if node.name == "cloud_items:ongen_small" then
if chance < 2.5 then
minetest.remove_node(pos)
minetest.add_node(pos, {name="cloud_items:cloud_ore"})
minetest.log("action", "cloud_items: Replaced on-generation cloud with cloud ore.")
else
minetest.remove_node(pos)
minetest.add_node(pos, {name="cloud_items:cloud"})
minetest.log("action", "cloud_items: Replaced on-generation cloud with normal cloud.")
end
elseif node.name == "cloud_items:ongen_medium" then
if chance < 5 then
minetest.remove_node(pos)
minetest.add_node(pos, {name="cloud_items:cloud_ore"})
minetest.log("action", "cloud_items: Replaced on-generation cloud with cloud ore.")
else
minetest.remove_node(pos)
minetest.add_node(pos, {name="cloud_items:cloud"})
minetest.log("action", "cloud_items: Replaced on-generation cloud with normal cloud.")
end
elseif node.name == "cloud_items:ongen_big" then
if chance < 7.5 then
minetest.remove_node(pos)
minetest.add_node(pos, {name="cloud_items:cloud_ore"})
minetest.log("action", "cloud_items: Replaced on-generation cloud with cloud ore.")
else
minetest.remove_node(pos)
minetest.add_node(pos, {name="cloud_items:cloud"})
minetest.log("action", "cloud_items: Replaced on-generation cloud with normal cloud.")
end
end
end,
})
--[[
Functions from Minetest Game's nyancat (LGPLv2.1+).
@ -231,30 +322,6 @@ local function generate_small(minp, maxp, seed)
end
end
-- Generate the small schematic without the ore. 🤭
-- There are more chances to find an small schematic without an ore.
local function generate_small_without_ore(minp, maxp, seed)
local height_min = 200
local height_max = 1500
if maxp.y < height_min or minp.y > height_max then
return
end
local y_min = math.max(minp.y, height_min)
local y_max = math.min(maxp.y, height_max)
local volume = (maxp.x - minp.x + 1) * (y_max - y_min + 1) * (maxp.z - minp.z + 1)
local pr = PseudoRandom(seed + 9324342)
local max_num_schematics = math.floor(volume / (30 * 30 * 30))
for i = 1, max_num_schematics do
if pr:next(0, 1000) == 0 then
local x0 = pr:next(minp.x, maxp.x)
local y0 = pr:next(minp.y, maxp.y)
local z0 = pr:next(minp.z, maxp.z)
local p0 = {x = x0, y = y0, z = z0}
place_schem(p0, "cloud_small_2.we")
end
end
end
-- Medium.
local function generate_medium(minp, maxp, seed)
local height_min = 380
@ -278,29 +345,6 @@ local function generate_medium(minp, maxp, seed)
end
end
-- Medium (without ore).
local function generate_medium_without_ore(minp, maxp, seed)
local height_min = 380
local height_max = 1680
if maxp.y < height_min or minp.y > height_max then
return
end
local y_min = math.max(minp.y, height_min)
local y_max = math.min(maxp.y, height_max)
local volume = (maxp.x - minp.x + 1) * (y_max - y_min + 1) * (maxp.z - minp.z + 1)
local pr = PseudoRandom(seed + 9324342)
local max_num_schematics = math.floor(volume / (38 * 38 * 38))
for i = 1, max_num_schematics do
if pr:next(0, 1000) == 0 then
local x0 = pr:next(minp.x, maxp.x)
local y0 = pr:next(minp.y, maxp.y)
local z0 = pr:next(minp.z, maxp.z)
local p0 = {x = x0, y = y0, z = z0}
place_schem(p0, "cloud_medium_2.we")
end
end
end
-- Big.
local function generate_big(minp, maxp, seed)
local height_min = 580
@ -324,30 +368,7 @@ local function generate_big(minp, maxp, seed)
end
end
-- Big (without ore).
local function generate_big_without_ore(minp, maxp, seed)
local height_min = 580
local height_max = 1880
if maxp.y < height_min or minp.y > height_max then
return
end
local y_min = math.max(minp.y, height_min)
local y_max = math.min(maxp.y, height_max)
local volume = (maxp.x - minp.x + 1) * (y_max - y_min + 1) * (maxp.z - minp.z + 1)
local pr = PseudoRandom(seed + 9324342)
local max_num_schematics = math.floor(volume / (46 * 46 * 46))
for i = 1, max_num_schematics do
if pr:next(0, 1000) == 0 then
local x0 = pr:next(minp.x, maxp.x)
local y0 = pr:next(minp.y, maxp.y)
local z0 = pr:next(minp.z, maxp.z)
local p0 = {x = x0, y = y0, z = z0}
place_schem(p0, "cloud_big_2.we")
end
end
end
-- Cloud house
-- Cloud house.
local function generate_cloud_house(minp, maxp, seed)
local height_min = 1500
local height_max = 3750
@ -377,11 +398,8 @@ end
-- Generate/place the schematics.
minetest.register_on_generated(function(minp, maxp, seed)
generate_small(minp, maxp, seed)
generate_small_without_ore(minp, maxp, seed)
generate_medium(minp, maxp, seed)
generate_medium_without_ore(minp, maxp, seed)
generate_big(minp, maxp, seed)
generate_big_without_ore(minp, maxp, seed)
generate_cloud_house(minp, maxp, seed)
end)
@ -571,6 +589,8 @@ local car_def = {
passenger3_attach_at = {x=-4,y=3.7,z=-3.5},
passenger3_eye_offset = {x=4, y=3, z=0},
enable_crash = false,
drop_on_destroy = {"vehicle_mash:tire 2", "vehicle_mash:windshield",
"vehicle_mash:battery", "vehicle_mash:motor"},
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 577 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

View file

@ -0,0 +1,54 @@
This mod adds craftable and ridable hot air balloons to minetest.
Controls:
right click with fuel item: increase heat and buoyancy (*)
right click without coal: enter or leave balloon
left, right, up, down (default WASD): accelerate the balloon
sneak (default shift): decrease heat, lowering buoyancy
jump (default space): turn the balloon towards where the player is looking
optional dependencies:
default, bucket (enable crafting recipe 1 if installed together)
mcl_core, mcl_mobitems, mcl_buckets (enable crafting recipe 2 if installed together)
Crafting recipe 1 (Minetest Game and most derivatives):
[P] := paper
[W] := wood
[L] := lava bucket
[ ] := nothing
[P][P][P]
[P][L][P]
[ ][W][ ]
Crafting recipe 2 (MineClone 2):
[L] := leather
[W] := wood
[V] := lava bucket
[S] := string
[L][L][L]
[L][V][L]
[S][W][S]
See license.txt for proper license information.
Author of code
----------------------------------------
NetherEran (LGPL v2.1)
Authors of media (models, textures)
----------------------------------------
Textures
--------
NetherEran (CC BY-SA 3.0):
hot_air_balloons_balloon.png
hot_air_balloons_balloon_flame.png
hot_air_balloons_balloon_model.png --Contains default_wood.png (by BlockMen) and default_aspen_wood.png (by sofar) (derived from default_pine_wood by paramat)
Models
--------
NetherEran (CC BY-SA 3.0):
ballon.blend (= hot_air_balloons_balloon.obj)

View file

@ -0,0 +1,101 @@
--localize things for better performance
local serialize = minetest.serialize
local add_entity = minetest.add_entity
local after = minetest.after
--for storing which players left while in a balloon
local storage = minetest.get_mod_storage()
local absent_ballooners = minetest.deserialize(storage:get_string("absent_ballooners")) or {}
--putting leaving people into storage
local leave_while_ballooning = function(player)
local parent = player:get_attach()
if parent and not parent:is_player()
then
local balloon_type = parent:get_luaentity().balloon_type
if balloon_type
then
--remove() only works if someone else is in the area,
--hence the need for mark_for_deletion
parent:remove()
absent_ballooners[player:get_player_name()] = balloon_type
end
end
end
--same as on_leave but for all players at once
local on_shutdown = function()
local connected_players = minetest.get_connected_players()
for i, p in ipairs(connected_players)
do
leave_while_ballooning(p)
end
storage:set_string("absent_ballooners", serialize(absent_ballooners))
end
--putting leaving people into storage and saving storage
local on_leave = function(player)
leave_while_ballooning(player)
storage:set_string("absent_ballooners", serialize(absent_ballooners))
end
minetest.register_on_leaveplayer(on_leave)
minetest.register_on_shutdown(on_shutdown)
--checking if player who joined was ballooning when they left
--if so spawn a new balloon and set them as attachment
local on_join = function(player)
if player
then
local name = player:get_player_name()
if absent_ballooners[name]
then
local pos = player:get_pos()
--for compatibility with version 1.1 of the mod
if absent_ballooners[name] == true
then
absent_ballooners[name] = "hot_air_balloons:balloon"
end
--minetest doesn't seem to like add_entity on init so a minetest.after is used
--player is set as pilot in on_activate
after(2,
function()
--concatenating "P" with name signals that player should be set as attach
add_entity(pos, absent_ballooners[name], "P" .. name)
end)
end
end
end
minetest.register_on_joinplayer(on_join)
--called in on_activate if balloon was spawned to rescue an absent ballooner
local set_rescue = function(self, playername)
local player = minetest.get_player_by_name(playername)
self.pilot = playername
if not player --player logged off right away
then
self.object:remove()
return
end
player:set_attach(self.object, "",
{x = 0, y = 1, z = 0}, {x = 0, y = 0, z = 0})
absent_ballooners[playername] = nil
end
--set as get_staticdata
local mark_for_deletion = function(self)
if self.pilot
then
--pilot logged off while ballooning, deleting balloon on next activation
return "R"
else
--normally save and load balloon
return ""
end
end
return set_rescue, mark_for_deletion

View file

@ -0,0 +1,30 @@
API functions:
hot_air_balloons.get_entity(name, mesh_name, texture_name)
arguments:
'name': string in the format "modname:entityname"
'mesh_name': string in the format "modname_meshFileName"
'texture_name': string in the format "modname_textureFileName"
Example usage: minetest.register_entity(hot_air_balloons.get_entity(foo, raa, see))
you can also store the values in a local variable and change the fields of the entity definition table before registering the entity.
passing the entity name to the function is used when a balloon pilot logs off
hot_air_balloons.get_item(name, description, texture, object_name)
arguments:
'name': string in the format "modname:itemname"
'description': string that appears in the tooltip. Use minetest.translate with this.
'texture': string in the format "modname_textureFileName"
'object_name' is the name specified in hot_air_balloons.get_entity
Example usage: minetest.register_craftitem(hot_air_balloons.get_item(foo, raa, see, mon))
returns an item name and an item definition table
as with get_entity you can store the item definition table and change its fields before registering the item.
explanation of the custom fields of the entitiy definition table:
pilot: stores the player name of the pilot or nil if there is no pilot
heat: integer in the interval [0, 12000)
Decides wether to fly up or down
balloon_type: entity name of the balloon, e.g."hot_air_balloons:balloon".
used to make the balloon log off and log back in together with its pilot

View file

@ -0,0 +1,50 @@
--This file adds crafting recipes depending on which dependencies are installed
if minetest.get_modpath("default") and
minetest.get_modpath("bucket")
then
minetest.register_craft(
{
output = "hot_air_balloons:item",
recipe =
{
{"default:paper", "default:paper", "default:paper"},
{"default:paper", "bucket:bucket_lava", "default:paper"},
{"", "group:wood", "" },
},
})
return
end
if minetest.get_modpath("mcl_buckets") and
minetest.get_modpath("mcl_mobitems") and
minetest.get_modpath("mcl_core")
then
minetest.register_craft(
{
output = "hot_air_balloons:item",
recipe =
{
{"mcl_mobitems:leather", "mcl_mobitems:leather", "mcl_mobitems:leather"},
{"mcl_mobitems:leather", "bucket:bucket_lava", "mcl_mobitems:leather"},
{"mcl_mobitems:string", "group:wood", "mcl_mobitems:string" },
},
})
return
end
--[[
minetest.register_craft(
{
type = "aircraft"
}
]]
--make balloon work with mcl2 creative mode
--announce in chat if no crafting recipe was added.
minetest.after(2,
function()
minetest.chat_send_all("Optional dependencies for hot_air_balloons are missing so no crafting recipe was added.\n"..
"Install either 'default' and 'bucket' or 'mcl_core', 'mcl_mobitems' 'and mcl_buckets' if this bothers you.\n"..
"All other functions of the mod should be unaffected by this.")
end)

View file

@ -0,0 +1,5 @@
default?
bucket?
mcl_buckets?
mcl_mobitems?
mcl_core?

View file

@ -0,0 +1,226 @@
--localize functions for better performance
local string_byte = string.byte
local string_sub = string.sub
local get_item_group = minetest.get_item_group
local add_particlespawner = minetest.add_particlespawner
local add_item = minetest.add_item
local get_node = minetest.get_node
local add_entity = minetest.add_entity
local modpath = minetest.get_modpath("hot_air_balloons")
local set_rescue, mark_for_deletion_if_piloted = dofile(modpath .. "/absent_ballooner_rescuing.lua")
local handle_movement = dofile(modpath .. "/movement.lua")
local is_in_creative = function(name)
return creative and creative.is_enabled_for
and creative.is_enabled_for(name)
end
local get_fire_particle = function (pos)
pos.y = pos.y + 3
return {
amount = 3,
time = 1,
minpos = pos,
maxpos = pos,
minvel = {x = 0, y = 1, z = 0},
maxvel = {x = 0, y = 1, z = 0},
minexptime = 1,
maxexptime = 1,
minsize = 10,
maxsize = 5,
collisiondetection = false,
vertical = false,
texture = "hot_air_balloons_flame.png"
}
end
local function get_fuel_value(item)
input = {
method = "fuel",
items = {item},
}
return minetest.get_craft_result(input).time or 0
end
local add_heat = function(self, player)
local item_stack = player:get_wielded_item()
local fuelval = get_fuel_value(item_stack)
if not fuelval or fuelval == 0 then
return false
end
local heat = self.heat
heat = heat + 30 * fuelval --for coal lump 1 min until heat is back to original
if heat < 12000 --cap heat at 12000 (10 min)
then
self.heat = heat
--adding particle effect
local pos = self.object:get_pos()
add_particlespawner(get_fire_particle(pos))
if not is_in_creative(player:get_player_name())
then
item_stack:take_item()
player:set_wielded_item(item_stack)
end
end
return true
end
--global table, has fields get_entity_def and get_item_def
--custom balloons right now turn into normal ones when the pilot leaves
hot_air_balloons = {}
hot_air_balloons.get_entity = function(name, mesh_name, texture_name)
return
name,
{
initial_properties =
{
hp_max = 1,
physical = true,
weight = 5,
collisionbox = {-0.65, -0.01, -0.65, 0.65, 1.11, 0.65},
visual = "mesh",
mesh = "hot_air_balloons_balloon.obj",
textures = {"hot_air_balloons_balloon_model.png"},
is_visible = true,
makes_footstep_sound = false,
backface_culling = false,
},
heat = 0,
balloon_type = name,
on_step = function(self, dtime)
--decrease heat, move
if self.heat > 0
then
self.heat = self.heat - 1
end
handle_movement(self)
end,
on_rightclick = function (self, clicker)
--if hoding coal, increase heat, else mount/dismount
if not clicker or not clicker:is_player()
then
return
end
--checking if clicker is holding coal
--heating balloon and returning if yes
if add_heat(self, clicker)
then
return
end
--if not holding coal:
local playername = clicker:get_player_name()
if self.pilot and self.pilot == playername
then
self.pilot = nil
clicker:set_detach()
elseif not self.pilot
then
--attach
self.pilot = playername
clicker:set_attach(self.object, "",
{x = 0, y = 1, z = 0}, {x = 0, y = 0, z = 0})
end
end,
--if pilot leaves start sinking and prepare for next pilot
on_detach_child = function(self, child)
self.heat = 0
self.object:setvelocity({x = 0, y = 0, z = 0})
end,
on_activate = function(self, staticdata, dtime_s)
self.object:set_armor_groups({punch_operable = 1})
--so balloons don't get lost
self.object:setvelocity({x = 0, y = 0, z = 0})
--checking if balloon was spawned from item or unloaded without pilot
if staticdata == ""
then
return
end
--checking if balloon should despawn when pilot logged off
local first_char = string_byte(staticdata)
--ballooner logged off, balloon will respawn when ballooner logs back in
if first_char == 82 --chr 82 = R
then
self.object:remove()
return
--absent ballooner logged back in
elseif first_char == 80 --chr 80 = P
then
set_rescue(self, string_sub(staticdata, 2))
end
end,
get_staticdata = mark_for_deletion_if_piloted,
on_punch = function(self, puncher) --drop balloon item
if self.pilot
then
return
elseif not (puncher and puncher:is_player())
then
return
else
self.object:remove()
local inv = puncher:get_inventory()
if not is_in_creative(puncher:get_player_name())
or not inv:contains_item("main", "hot_air_balloons:item")
then
local leftover = inv:add_item("main", "hot_air_balloons:item")
if not leftover:is_empty()
then
add_item(self.object:get_pos(), leftover)
end
end
end
end,
}
end
hot_air_balloons.get_item = function(name, description, texture, object_name)
return
name,
{
description = description,
inventory_image = texture,
stack_max = 1,
liquids_pointable = true,
groups = {flammable = 2},
on_place =
function (itemstack, placer, pointed_thing)
--places balloon if the clicked thing is a node and the above node is air
if pointed_thing.type == "node"
and get_node (pointed_thing.above).name == "air"
then
if not is_in_creative(placer:get_player_name())
then
itemstack:take_item()
end
local pos_to_place = pointed_thing.above
pos_to_place.y = pos_to_place.y - 0.5 --subtracting 0.5 to place on ground
add_entity(pointed_thing.above, object_name)
end
--add remaining items to inventory
return itemstack
end
}
end
--registering the balloon entity, item and recepies
minetest.register_entity(hot_air_balloons.get_entity(
"hot_air_balloons:balloon",
"hot_air_balloons_balloon.obj",
"hot_air_balloons_balloon_model.png"))
minetest.register_craftitem(hot_air_balloons.get_item(
"hot_air_balloons:item",
minetest.translate("hot_air_balloons", "Hot Air Balloon"),
"hot_air_balloons_balloon.png",
"hot_air_balloons:balloon"))
dofile(modpath .. "/craft.lua")

View file

@ -0,0 +1,54 @@
License of source code
----------------------
GNU Lesser General Public License, version 2.1
Copyright (C) 2019 NetherEran
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 2.1 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/old-licenses/lgpl-2.1.html
Licenses of media (textures, models and sounds)
-----------------------------------------------
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
Copyright (C) 2010-2018:
NetherEran
BlockMen
sofar
paramat
You are free to:
Share — copy and redistribute the material in any medium or format.
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
The licensor cannot revoke these freedoms as long as you follow the license terms.
Under the following terms:
Attribution — You must give appropriate credit, provide a link to the license, and
indicate if changes were made. You may do so in any reasonable manner, but not in any way
that suggests the licensor endorses you or your use.
ShareAlike — If you remix, transform, or build upon the material, you must distribute
your contributions under the same license as the original.
No additional restrictions — You may not apply legal terms or technological measures that
legally restrict others from doing anything the license permits.
Notices:
You do not have to comply with the license for elements of the material in the public
domain or where your use is permitted by an applicable exception or limitation.
No warranties are given. The license may not give you all of the permissions necessary
for your intended use. For example, other rights such as publicity, privacy, or moral
rights may limit how you use the material.
For more details:
http://creativecommons.org/licenses/by-sa/3.0/

View file

@ -0,0 +1,2 @@
# textdomain:hot_air_balloons
Hot Air Balloon=Heißluftballon

View file

@ -0,0 +1,2 @@
# textdomain:hot_air_balloons
Hot Air Balloon=Globo Aerostático

View file

@ -0,0 +1,2 @@
# textdomain:hot_air_balloons
Hot Air Balloon=Balon cu aer cald

View file

@ -0,0 +1,4 @@
name = hot_air_balloons
author = Eran
description = Adds craftable and controllable hot air balloons.
optional_depends = default, bucket, mcl_buckets, mcl_mobitems, mcl_core

Binary file not shown.

View file

@ -0,0 +1,485 @@
# Blender v2.79 (sub 0) OBJ File: 'balloon.blend'
# www.blender.org
mtllib hot_air_balloons_balloon.mtl
o Cube.001
v -19.500000 44.216793 19.500000
v -19.500000 83.216797 19.500000
v -19.500000 44.216793 -19.500000
v -19.500000 83.216797 -19.500000
v 19.500000 44.216793 19.500000
v 19.500000 83.216797 19.500000
v 19.500000 44.216793 -19.500000
v 19.500000 83.216797 -19.500000
v -6.500000 0.016788 6.500000
v 6.500000 0.016788 6.500000
v -6.500000 0.016788 -6.500000
v 6.500000 0.016788 -6.500000
v -6.500000 1.441189 6.500000
v 6.500000 1.441189 6.500000
v -6.500000 1.441189 -6.500000
v 6.500000 1.441189 -6.500000
v -6.500000 0.016788 -4.550000
v -6.500000 0.016788 4.550000
v 6.500000 0.016788 4.550000
v 6.500000 0.016788 -4.550000
v -6.500000 1.441189 -4.550000
v -6.500000 1.441189 4.550000
v 6.500000 1.441189 4.550000
v 6.500000 1.441189 -4.550000
v -4.550000 0.016788 6.500000
v 4.550000 0.016788 6.500000
v 4.550000 0.016788 -6.500000
v -4.550000 0.016788 -6.500000
v -4.550000 1.441189 6.500000
v 4.550000 1.441189 6.500000
v 4.550000 1.441189 -6.500000
v -4.550000 1.441189 -6.500000
v 4.550000 1.441189 4.550000
v -4.550000 1.441189 4.550000
v -4.550000 1.441189 -4.550000
v -4.550000 0.016788 4.550000
v 4.550000 0.016788 4.550000
v -4.550000 0.016788 -4.550000
v 4.550000 0.016788 -4.550000
v 6.500000 11.077995 6.500000
v -6.500000 11.077995 6.500000
v 6.500000 11.077995 6.500000
v -6.500000 11.077995 -6.500000
v -6.500000 11.077995 6.500000
v 6.500000 11.077995 -6.500000
v 4.550000 11.077995 4.550000
v 4.550000 11.077995 -4.550000
v -4.550000 11.077995 -4.550000
v -4.550000 11.077995 -4.550000
v -4.550000 1.441189 -4.550000
v 4.550000 1.441189 -4.550000
v 4.550000 11.077995 -4.550000
v -4.550000 11.077995 4.550000
v 4.550000 1.441189 4.550000
v 6.500000 1.441189 -6.500000
v 4.550000 11.077995 4.550000
v -4.550000 11.077995 -6.500000
v -6.500000 1.441189 -6.500000
v 4.550000 11.077995 -6.500000
v 4.550000 11.077995 6.500000
v -4.550000 11.077995 6.500000
v 6.500000 11.077995 -4.550000
v 6.500000 1.441189 6.500000
v 6.500000 11.077995 4.550000
v -6.500000 11.077995 4.550000
v -6.500000 11.077995 -4.550000
v -6.500000 1.441189 6.500000
v 6.500000 11.077995 -6.500000
v -6.500000 11.077995 -6.500000
v 5.586319 8.609333 -5.559702
v 11.988016 44.915165 -12.060156
v 5.537368 8.331722 -7.158404
v 11.939065 44.637550 -13.658857
v 7.185020 8.327442 -5.559702
v 13.586718 44.633270 -12.060156
v 7.136070 8.049831 -7.158404
v 13.537767 44.355656 -13.658857
v -5.586318 8.609333 -5.559702
v -11.988014 44.915165 -12.060155
v -5.537367 8.331722 -7.158404
v -11.939065 44.637554 -13.658857
v -7.185020 8.327442 -5.559702
v -13.586717 44.633270 -12.060155
v -7.136071 8.049831 -7.158404
v -13.537764 44.355656 -13.658857
v 5.586319 8.609337 5.559702
v 11.988015 44.915161 12.060157
v 5.537368 8.331722 7.158404
v 11.939065 44.637547 13.658860
v 7.185020 8.327442 5.559702
v 13.586717 44.633270 12.060157
v 7.136070 8.049831 7.158404
v 13.537766 44.355652 13.658860
v -5.586318 8.609337 5.559702
v -11.988016 44.915161 12.060155
v -5.537367 8.331722 7.158405
v -11.939065 44.637550 13.658857
v -7.185019 8.327442 5.559704
v -13.586717 44.633266 12.060157
v -7.136071 8.049831 7.158405
v -13.537766 44.355652 13.658860
vt 0.666667 0.666667
vt 0.333333 0.666667
vt 0.333333 0.333333
vt 0.666667 0.333333
vt 0.000000 1.000000
vt 0.000000 0.666667
vt 0.333333 0.666667
vt 0.333333 1.000000
vt 0.333333 0.333333
vt 0.000000 0.333333
vt 0.000000 0.000000
vt 0.333333 0.000000
vt 0.333333 0.333333
vt 0.333333 0.000000
vt 0.666667 0.000000
vt 0.666667 0.333333
vt 0.000000 0.666667
vt 0.000000 0.333333
vt 0.333333 0.666667
vt 0.666667 0.000000
vt 1.000000 0.000000
vt 1.000000 0.333333
vt 0.666667 0.333333
vt 0.350615 0.683822
vt 0.333949 0.683822
vt 0.333949 0.667155
vt 0.350615 0.667155
vt 0.761207 0.649225
vt 0.761207 0.665892
vt 0.749033 0.665892
vt 0.749033 0.649225
vt 0.761207 0.427778
vt 0.761207 0.444444
vt 0.749033 0.444444
vt 0.749033 0.427778
vt 0.538985 0.761111
vt 0.538985 0.777778
vt 0.526810 0.777778
vt 0.526810 0.761111
vt 0.667442 0.461111
vt 0.667442 0.444444
vt 0.679616 0.444444
vt 0.679616 0.461111
vt 0.667442 0.555556
vt 0.667442 0.538889
vt 0.679616 0.538889
vt 0.679616 0.555556
vt 0.761207 0.555556
vt 0.761207 0.572222
vt 0.749033 0.572222
vt 0.749033 0.555556
vt 0.761207 0.650000
vt 0.749033 0.650000
vt 0.749420 0.427778
vt 0.749420 0.444444
vt 0.667054 0.444444
vt 0.667054 0.427778
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.445060 0.683822
vt 0.428393 0.683822
vt 0.428393 0.667155
vt 0.445060 0.667155
vt 0.428393 0.777778
vt 0.350615 0.777778
vt 0.350615 0.761111
vt 0.428393 0.761111
vt 0.350615 0.683333
vt 0.428393 0.683333
vt 0.445060 0.777778
vt 0.445060 0.761111
vt 0.445060 0.683333
vt 0.749420 0.555556
vt 0.749420 0.572222
vt 0.667054 0.572222
vt 0.667054 0.555556
vt 0.616763 0.749521
vt 0.538985 0.749521
vt 0.538985 0.667155
vt 0.616763 0.667155
vt 0.750035 0.334724
vt 0.750035 0.351390
vt 0.667669 0.351390
vt 0.667669 0.334724
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.538985 0.667362
vt 0.538985 0.684029
vt 0.526810 0.684029
vt 0.526810 0.667362
vt 0.538985 0.683333
vt 0.526810 0.683333
vt 0.761822 0.334724
vt 0.761822 0.351390
vt 0.749648 0.351390
vt 0.749648 0.334724
vt 0.761207 0.350000
vt 0.749033 0.350000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.333949 0.777778
vt 0.333949 0.761111
vt 0.333949 0.683333
vt 0.744444 0.749033
vt 0.666667 0.749033
vt 0.666667 0.666667
vt 0.744444 0.666667
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.744444 0.666667
vt 0.822222 0.666667
vt 0.822222 0.749033
vt 0.744444 0.749033
vt 0.444445 0.777778
vt 0.444445 0.761111
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.616763 0.777778
vt 0.616763 0.666667
vt 0.633429 0.666667
vt 0.633429 0.777778
vt 0.616763 0.831398
vt 0.538985 0.831398
vt 0.538985 0.749033
vt 0.616763 0.749033
vt 0.444445 0.683333
vt 0.749420 0.650000
vt 0.667054 0.650000
vt 0.678841 0.538889
vt 0.678841 0.461111
vt 0.761207 0.461111
vt 0.761207 0.538889
vt 0.749420 0.649225
vt 0.749420 0.665892
vt 0.667054 0.665892
vt 0.667054 0.649225
vt 0.678841 0.555556
vt 0.761207 0.555556
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.678841 0.444444
vt 0.761207 0.444444
vt 0.749420 0.350000
vt 0.667054 0.350000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.444445 0.684029
vt 0.444445 0.667362
vt 0.633429 0.666667
vt 0.650096 0.666667
vt 0.650096 0.777778
vt 0.633429 0.777778
vt 0.744444 0.749033
vt 0.761111 0.749033
vt 0.761111 0.826810
vt 0.744444 0.826810
vt 0.777778 0.749033
vt 0.777778 0.826810
vt 0.761111 0.826810
vt 0.761111 0.749033
vt 0.666667 0.749033
vt 0.744444 0.749033
vt 0.744444 0.826810
vt 0.666667 0.826810
vt 0.858286 0.648647
vt 0.858286 0.333406
vt 0.872154 0.333333
vt 0.872154 0.648574
vt 0.941529 0.333333
vt 0.941529 0.648427
vt 0.927654 0.648427
vt 0.927654 0.333333
vt 0.844417 0.333406
vt 0.844417 0.648647
vt 0.830549 0.648574
vt 0.830549 0.333333
vt 0.955404 0.333333
vt 0.955404 0.648427
vt 0.941529 0.648427
vt 0.941529 0.333333
vt 0.650096 0.694844
vt 0.663754 0.695262
vt 0.663754 0.708933
vt 0.650096 0.708515
vt 0.663754 0.722603
vt 0.650096 0.723022
vt 0.650096 0.709351
vt 0.663754 0.708933
vt 0.844417 0.333333
vt 0.858286 0.333406
vt 0.858286 0.648647
vt 0.844417 0.648574
vt 0.913779 0.333333
vt 0.927654 0.333333
vt 0.927654 0.648427
vt 0.913779 0.648427
vt 0.830549 0.648574
vt 0.816681 0.648647
vt 0.816681 0.333406
vt 0.830549 0.333333
vt 0.886029 0.648427
vt 0.872154 0.648427
vt 0.872154 0.333333
vt 0.886029 0.333333
vt 0.650096 0.694844
vt 0.650096 0.681174
vt 0.663754 0.680755
vt 0.663754 0.694426
vt 0.650096 0.750781
vt 0.650096 0.737110
vt 0.663754 0.737528
vt 0.663754 0.751199
vt 0.802812 0.648647
vt 0.788944 0.648574
vt 0.788944 0.333333
vt 0.802812 0.333406
vt 0.886029 0.648427
vt 0.899904 0.648427
vt 0.899904 0.963520
vt 0.886029 0.963520
vt 0.762184 0.333406
vt 0.776052 0.333333
vt 0.776052 0.648574
vt 0.762183 0.648647
vt 0.913779 0.648426
vt 0.899904 0.648427
vt 0.899904 0.333333
vt 0.913779 0.333333
vt 0.650096 0.765288
vt 0.650096 0.751617
vt 0.663754 0.751199
vt 0.663754 0.764869
vt 0.650096 0.680337
vt 0.650096 0.666667
vt 0.663754 0.667085
vt 0.663754 0.680755
vt 0.816681 0.333333
vt 0.816681 0.648574
vt 0.802812 0.648647
vt 0.802812 0.333406
vt 0.886029 0.648427
vt 0.886029 0.333333
vt 0.899904 0.333333
vt 0.899904 0.648426
vt 0.788944 0.333406
vt 0.788944 0.648647
vt 0.775075 0.648574
vt 0.775075 0.333333
vt 0.872154 0.963520
vt 0.872154 0.648427
vt 0.886029 0.648427
vt 0.886029 0.963520
vt 0.650096 0.723022
vt 0.663754 0.723440
vt 0.663754 0.737110
vt 0.650096 0.736692
vt 0.774865 0.662317
vt 0.761207 0.662735
vt 0.761207 0.649065
vt 0.774865 0.648647
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -0.9848 0.1736 0.0000
vn -0.0302 -0.1710 -0.9848
vn 0.9848 -0.1736 0.0000
vn 0.0302 0.1710 0.9848
vn -0.1710 -0.9698 0.1736
vn 0.1710 0.9698 -0.1736
vn 0.9848 0.1736 -0.0000
vn 0.0302 -0.1710 -0.9848
vn -0.9848 -0.1736 -0.0000
vn -0.0302 0.1710 0.9848
vn 0.1710 -0.9698 0.1736
vn -0.1710 0.9698 -0.1737
vn -0.0302 -0.1710 0.9848
vn 0.0302 0.1710 -0.9848
vn -0.1710 -0.9698 -0.1736
vn 0.1710 0.9698 0.1737
vn 0.0302 -0.1710 0.9848
vn -0.0302 0.1710 -0.9848
vn 0.1710 -0.9698 -0.1736
vn -0.1710 0.9698 0.1736
usemtl None
s off
f 1/1/1 2/2/1 4/3/1 3/4/1
f 3/5/2 4/6/2 8/7/2 7/8/2
f 7/9/3 8/10/3 6/11/3 5/12/3
f 5/13/4 6/14/4 2/15/4 1/16/4
f 3/17/5 7/18/5 5/13/5 1/19/5
f 8/20/6 4/21/6 2/22/6 6/23/6
f 39/24/5 27/25/5 12/26/5 20/27/5
f 18/28/1 9/29/1 13/30/1 22/31/1
f 28/32/2 11/33/2 15/34/2 32/35/2
f 26/36/4 10/37/4 14/38/4 30/39/4
f 20/40/3 12/41/3 16/42/3 24/43/3
f 10/44/3 19/45/3 23/46/3 14/47/3
f 19/45/3 20/40/3 24/43/3 23/46/3
f 11/48/1 17/49/1 21/50/1 15/51/1
f 17/49/1 18/52/1 22/53/1 21/50/1
f 32/54/2 15/55/2 69/56/2 57/57/2
f 15/58/4 58/59/4 43/60/4 69/61/4
f 26/62/5 37/63/5 19/64/5 10/65/5
f 37/63/5 39/24/5 20/27/5 19/64/5
f 18/66/5 17/67/5 38/68/5 36/69/5
f 36/69/5 38/68/5 39/70/5 37/71/5
f 9/72/5 18/66/5 36/69/5 25/73/5
f 25/73/5 36/69/5 37/71/5 26/74/5
f 15/75/1 21/76/1 66/77/1 69/78/1
f 51/79/2 50/80/2 48/81/2 47/82/2
f 16/83/2 31/84/2 59/85/2 68/86/2
f 52/87/4 56/88/4 46/89/4 47/90/4
f 9/91/4 25/92/4 29/93/4 13/94/4
f 25/95/4 26/36/4 30/39/4 29/96/4
f 12/97/2 27/98/2 31/99/2 16/100/2
f 27/101/2 28/32/2 32/35/2 31/102/2
f 49/103/4 52/87/4 47/90/4 48/104/4
f 17/67/5 11/105/5 28/106/5 38/68/5
f 38/68/5 28/106/5 27/107/5 39/70/5
f 34/108/4 33/109/4 56/110/4 53/111/4
f 13/112/4 67/113/4 41/114/4 44/115/4
f 16/116/4 55/117/4 45/118/4 68/119/4
f 54/120/3 51/121/3 47/122/3 46/123/3
f 30/39/4 14/38/4 40/124/4 60/125/4
f 14/126/4 63/127/4 42/128/4 40/129/4
f 44/130/6 42/131/6 64/132/6 65/133/6
f 35/134/1 34/135/1 53/136/1 49/137/1
f 29/96/4 30/39/4 60/125/4 61/138/4
f 21/76/1 22/139/1 65/140/1 66/77/1
f 23/141/3 24/142/3 62/143/3 64/144/3
f 22/145/1 13/146/1 44/147/1 65/148/1
f 14/149/3 23/141/3 64/144/3 40/150/3
f 50/151/4 35/152/4 49/103/4 48/104/4
f 24/142/3 16/153/3 68/154/3 62/143/3
f 31/155/2 32/54/2 57/57/2 59/156/2
f 33/157/4 54/158/4 46/89/4 56/88/4
f 13/94/4 29/93/4 61/159/4 44/160/4
f 62/161/6 68/162/6 69/163/6 66/164/6
f 62/165/6 52/166/6 56/167/6 64/168/6
f 66/169/6 65/170/6 53/171/6 49/172/6
f 51/173/5 54/174/5 34/175/5 50/176/5
f 70/177/7 71/178/7 73/179/7 72/180/7
f 72/181/8 73/182/8 77/183/8 76/184/8
f 76/185/9 77/186/9 75/187/9 74/188/9
f 74/189/10 75/190/10 71/191/10 70/192/10
f 72/193/11 76/194/11 74/195/11 70/196/11
f 77/197/12 73/198/12 71/199/12 75/200/12
f 78/201/13 80/202/13 81/203/13 79/204/13
f 80/205/14 84/206/14 85/207/14 81/208/14
f 84/209/15 82/210/15 83/211/15 85/212/15
f 82/213/16 78/214/16 79/215/16 83/216/16
f 80/217/17 78/218/17 82/219/17 84/220/17
f 85/221/18 83/222/18 79/223/18 81/224/18
f 86/225/7 88/226/7 89/227/7 87/228/7
f 88/229/19 92/230/19 93/231/19 89/232/19
f 92/233/9 90/234/9 91/235/9 93/236/9
f 90/237/20 86/238/20 87/239/20 91/240/20
f 88/241/21 86/242/21 90/243/21 92/244/21
f 93/245/22 91/246/22 87/247/22 89/248/22
f 94/249/13 95/250/13 97/251/13 96/252/13
f 96/253/23 97/254/23 101/255/23 100/256/23
f 100/257/15 101/258/15 99/259/15 98/260/15
f 98/261/24 99/262/24 95/263/24 94/264/24
f 96/265/25 100/266/25 98/267/25 94/268/25
f 101/269/26 97/270/26 95/271/26 99/272/26

View file

@ -0,0 +1,209 @@
--localize global functions
local vector_new = vector.new
local math_hypot = math.hypot
local atan = math.atan
local cos = math.cos
local sin = math.sin
local abs = math.abs
local pi = math.pi
local min = math.min
--max speed settings
local max_ballooning_vertical_speed = 1
local max_ballooning_horizontal_speed = 3
local function is_water_is_air(pos)
local node_name = minetest.get_node(pos).name
return minetest.get_item_group(node_name, "water") > 0,
node_name == "air"
end
local function get_vertical_acceleration(self)
local heat = self.heat
local vel_y = self.object:getvelocity().y
local acc_candidate = heat / 1000 - 0.5
--enforce max speed
if vel_y > max_ballooning_vertical_speed
and acc_candidate * vel_y > 0
then
return 0
else
return acc_candidate
end
end
--if balloon is submerged
local function float_up(self, vel)
self.submerged = true
vel.y = 1
return vel
end
local function swim(self, vel)
--allow controls, allow up
local pos = self.object:get_pos()
--keep y constant or rising
local acc_y = get_vertical_acceleration(self)
if self.submerged or acc_y < 0
then
self.submerged = false
vel.y = 0
return 0, vel
else
return acc_y, vel
end
end
local tau = pi * 2
--returns the radian equivalent of a in the range [0, tau)
local function to_radian(a)
if a < 0
then
return to_radian(a + tau)
elseif a >= tau
then
return to_radian(a - tau)
else
return a
end
end
--decides which is the shortest way to rotate towards where the player is looking
local function get_rotate_direction(a, b)
return to_radian(a - b) < to_radian(b - a)
end
--rotates the balloon towards where the player is looking
local pi_192ths = pi / 192 --radians to turn each step
local function rotate(self, player)
-- + pi so it finishes rotating when looking towards where the player is looking
local player_yaw = player:get_look_horizontal() + pi
local self_yaw = self.object:getyaw()
if get_rotate_direction(player_yaw, self_yaw)
then
self.object:setyaw(to_radian(self_yaw - pi_192ths))
else
self.object:setyaw(to_radian(self_yaw + pi_192ths))
end
end
--takes wasd and turns it into a 2d vector
local pi_halves = pi / 2
function get_direction(right, left, up, down)
local inline, cross = 0, 0
local move = right or left or up or down
if left then cross = 1 end
if right then cross = cross - 1 end
if up then inline = 1 end
if down then inline = inline - 1 end
local arg
if inline < 0
then
return atan(cross / inline) + pi, move
elseif inline > 0
then
return atan(cross / inline), move
else
return pi_halves * cross, move
end
end
--[[
space to rotate where the player is looking
wasd to apply acceleration
shift to let out hot air, cooling the balloon
]]
local function handle_control(self, vel)
if not self.pilot
then
return 0, 0
end
local player = minetest.get_player_by_name(self.pilot)
if not player --player left, balloon should get deleted
then
return 0, 0
end
local control = player:get_player_control()
if control.sneak --lowering heat quickly
then
local heat = self.heat - 30
if heat < 0
then
self.heat = 0
else
self.heat = heat
end
end
if control.jump --rotate towards player yaw
then
rotate(self, player)
end
--taking direction from get_direction
--and turning it into radians.
--if max speed is reached, only acceleration in the opposite direction is applied.
local dir_radians, move = get_direction(control.right, control.left, control.up, control.down)
if move and math_hypot(vel.x, vel.z)
then
dir_radians = dir_radians + player:get_look_horizontal()
local x, z = -sin(dir_radians), cos(dir_radians)
if math_hypot(vel.x, vel.z) > max_ballooning_horizontal_speed
then
if x * vel.x > 0
then
x = 0
end
if z * vel.z > 0
then
z = 0
end
end
return x, z
end
return 0, 0
end
--[[handle movement in different cases
movement restrictions:
-on ground: only vertical movement
-on water: free movement, though vertical only if up
-submerged: free movement, vertical goes up automatically
-in air: completely free movement
]]
return function(self)
local pos_in = self.object:get_pos()
local pos_under = vector_new(pos_in.x, pos_in.y - 0.1, pos_in.z)
local on_water, in_air = is_water_is_air(pos_under)
local acc = vector_new(0, 0, 0)
local vel = self.object:getvelocity()
if is_water_is_air(pos_in) --if submerged
then
vel = float_up(self, vel)
acc.x, acc.z = handle_control(self, vel)
self.object:setvelocity(vel)
elseif on_water --if on water
then
acc.y, vel = swim(self, vel)
self.object:setvelocity(vel)
acc.x, acc.z = handle_control(self, vel)
elseif in_air
then
--allow controls and height change
acc.y = get_vertical_acceleration(self)
acc.x, acc.z = handle_control(self, vel)
else --if on ground
--only allow height change
acc.y = get_vertical_acceleration(self)
vel.x = 0
vel.z = 0
self.object:setvelocity(vel)
end
self.object:setacceleration(acc)
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 678 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

4
mods/mob_horse/mod.conf Normal file
View file

@ -0,0 +1,4 @@
name = mob_horse
depends = mobs
optional_depends = lucky_block, intllib
description = Adds a rideable horse into game with horse shoe upgrades.

View file

@ -161,7 +161,7 @@ minetest.register_craft({
minetest.register_craftitem(":mobs:rabbit_hide", {
description = S("Rabbit Hide"),
inventory_image = "mobs_rabbit_hide.png",
groups = {flammable = 2, leather = 1},
groups = {flammable = 2, pelt = 1},
})
minetest.register_craft({

View file

@ -1 +1,4 @@
name = mobs_animal
depends = default, mobs
optional_depends = lucky_block, intllib
description = Adds farm animals.

View file

@ -1 +1,4 @@
name = mobs_monster
depends = default, mobs
optional depends = lucky_block, toolranks, intllib
description = Adds many types of monster.

View file

@ -1 +1,4 @@
name = mobs_npc
depends = default, mobs
optional_depends = lucky_block, intllib
description = Adds simple NPC and Trader.

View file

@ -563,7 +563,7 @@ function mob_class:attempt_flight_correction(override)
-- We are not flying in what we are supposed to.
-- See if we can find intended flight medium and return to it
local pos = self.object:get_pos()
local pos = self.object:get_pos() ; if not pos then return true end
local searchnodes = self.fly_in
if type(searchnodes) == "string" then

View file

@ -1 +1,4 @@
name = mobs
depends = default
optional_depends = tnt, dye, farming, invisibility, intllib, lucky_block, cmi, toolranks
description = Adds a mob api for mods to add animals or monsters etc.

View file

@ -1,9 +1,7 @@
-- lib_mount by Blert2112 (edited by TenPlus1)
local enable_crash = false
local crash_threshold = 6.5 -- ignored if enable_crash=false
local abs, cos, floor, sin, sqrt, pi =
math.abs, math.cos, math.floor, math.sin, math.sqrt, math.pi
------------------------------------------------------------------------------
--
@ -11,7 +9,6 @@ local crash_threshold = 6.5 -- ignored if enable_crash=false
--
local node_ok = function(pos, fallback)
fallback = fallback or mobs.fallback_node
local node = minetest.get_node_or_nil(pos)
@ -25,7 +22,6 @@ end
local function node_is(pos)
local node = node_ok(pos)
if node.name == "air" then
@ -49,33 +45,30 @@ end
local function get_sign(i)
i = i or 0
if i == 0 then
return 0
else
return i / math.abs(i)
return i / abs(i)
end
end
local function get_velocity(v, yaw, y)
local x = -math.sin(yaw) * v
local z = math.cos(yaw) * v
local x = -sin(yaw) * v
local z = cos(yaw) * v
return {x = x, y = y, z = z}
end
local function get_v(v)
return math.sqrt(v.x * v.x + v.z * v.z)
return sqrt(v.x * v.x + v.z * v.z)
end
local function force_detach(player)
local attached_to = player:get_attach()
if not attached_to then
@ -86,21 +79,19 @@ local function force_detach(player)
if entity and entity.driver
and entity.driver == player then
entity.driver = nil
end
player:set_detach()
default.player_attached[player:get_player_name()] = false
player_api.player_attached[player:get_player_name()] = false
player:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
default.player_set_animation(player, "stand" , 30)
player:set_properties({visual_size = {x = 1, y = 1} })
player_api.set_animation(player, "stand", 30)
player:set_properties({visual_size = {x = 1, y = 1}})
end
-------------------------------------------------------------------------------
minetest.register_on_leaveplayer(function(player)
force_detach(player)
end)
@ -119,10 +110,37 @@ end)
-------------------------------------------------------------------------------
-- Just for correct detaching
local function find_free_pos(pos)
local check = {
{x = 1, y = 0, z = 0},
{x = 1, y = 1, z = 0},
{x = -1, y = 0, z = 0},
{x = -1, y = 1, z = 0},
{x = 0, y = 0, z = 1},
{x = 0, y = 1, z = 1},
{x = 0, y = 0, z = -1},
{x = 0, y = 1, z = -1}
}
for _, c in pairs(check) do
local npos = {x = pos.x + c.x, y = pos.y + c.y, z = pos.z + c.z}
local node = minetest.get_node_or_nil(npos)
if node and node.name then
local def = minetest.registered_nodes[node.name]
if def and not def.walkable and
def.liquidtype == "none" then
return npos
end
end
end
return pos
end
-------------------------------------------------------------------------------
function mobs.attach(entity, player)
local attach_at, eye_offset = {}, {}
entity.player_rotation = entity.player_rotation or {x = 0, y = 0, z = 0}
entity.driver_attach_at = entity.driver_attach_at or {x = 0, y = 0, z = 0}
entity.driver_eye_offset = entity.driver_eye_offset or {x = 0, y = 0, z = 0}
@ -131,17 +149,17 @@ function mobs.attach(entity, player)
local rot_view = 0
if entity.player_rotation.y == 90 then
rot_view = math.pi / 2
rot_view = pi / 2
end
attach_at = entity.driver_attach_at
eye_offset = entity.driver_eye_offset
local attach_at = entity.driver_attach_at
local eye_offset = entity.driver_eye_offset
entity.driver = player
force_detach(player)
player:set_attach(entity.object, "", attach_at, entity.player_rotation)
default.player_attached[player:get_player_name()] = true
player_api.player_attached[player:get_player_name()] = true
player:set_eye_offset(eye_offset, {x = 0, y = 0, z = 0})
player:set_properties({
@ -151,46 +169,36 @@ function mobs.attach(entity, player)
}
})
minetest.after(0.2, function(name)
local player = minetest.get_player_by_name(name)
if player then
default.player_set_animation(player, "sit" , 30)
minetest.after(0.2, function()
if player and player:is_player() then
player_api.set_animation(player, "sit", 30)
end
end, player:get_player_name())
end)
player:set_look_horizontal(entity.object:get_yaw() - rot_view)
end
function mobs.detach(player, offset)
function mobs.detach(player)
force_detach(player)
default.player_set_animation(player, "stand" , 30)
local pos = player:get_pos()
pos = {
x = pos.x + offset.x,
y = pos.y + 0.2 + offset.y,
z = pos.z + offset.z
}
minetest.after(0.1, function(name, pos)
local player = minetest.get_player_by_name(name)
if player then
minetest.after(0.1, function()
if player and player:is_player() then
local pos = find_free_pos(player:get_pos())
pos.y = pos.y + 0.5
player:set_pos(pos)
end
end, player:get_player_name(), pos)
end)
end
function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
local yaw = entity.object:get_yaw() or 0
local rot_steer, rot_view = math.pi/2, 0
local rot_view = 0
if entity.player_rotation.y == 90 then
rot_steer, rot_view = 0, math.pi/2
rot_view = pi / 2
end
local acce_y = 0
@ -200,19 +208,14 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
-- process controls
if entity.driver then
--print ("---velo", get_v(velo))
local ctrl = entity.driver:get_player_control()
-- move forwards
if ctrl.up then
entity.v = entity.v + entity.accel / 10
-- move backwards
elseif ctrl.down then
if entity.max_speed_reverse == 0 and entity.v == 0 then
return
end
@ -220,12 +223,24 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
entity.v = entity.v - entity.accel / 10
end
-- fix mob rotation
local horz = entity.driver:get_look_horizontal() or 0
-- mob rotation
local horz
if entity.alt_turn == true then
horz = yaw
if ctrl.left then
horz = horz + 0.05
elseif ctrl.right then
horz = horz - 0.05
end
else
horz = entity.driver:get_look_horizontal() or 0
end
entity.object:set_yaw(horz - entity.rotate)
if can_fly then
-- fly up
if ctrl.jump then
velo.y = velo.y + 1
@ -245,9 +260,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
velo.y = velo.y + 0.1
if velo.y > 0 then velo.y = 0 end
end
else
-- jump
if ctrl.jump then
@ -261,7 +274,6 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
-- if not moving then set animation and return
if entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then
if stand_anim then
mobs:set_animation(entity, stand_anim)
end
@ -280,7 +292,6 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
entity.v = entity.v - 0.02 * s
if s ~= get_sign(entity.v) then
entity.object:set_velocity({x = 0, y = 0, z = 0})
entity.v = 0
return
@ -293,14 +304,15 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
max_spd = entity.max_speed_forward
end
if math.abs(entity.v) > max_spd then
if abs(entity.v) > max_spd then
entity.v = entity.v - get_sign(entity.v)
end
-- Set position, velocity and acceleration
local p = entity.object:get_pos()
local new_velo
local new_acce = {x = 0, y = -9.8, z = 0}
if not p then return end
local new_acce = {x = 0, y = -9.81, z = 0}
p.y = p.y - 0.5
@ -308,23 +320,18 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
local v = entity.v
if ni == "air" then
if can_fly == true then
new_acce.y = 0
end
elseif ni == "liquid" or ni == "lava" then
if ni == "lava" and entity.lava_damage ~= 0 then
entity.lava_counter = (entity.lava_counter or 0) + dtime
if entity.lava_counter > 1 then
minetest.sound_play("default_punch", {
object = entity.object,
max_hear_distance = 5
}, true)
})
entity.object:punch(entity.object, 1.0, {
full_punch_interval = 1.0,
@ -335,14 +342,12 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
end
end
if entity.terrain_type == 2
or entity.terrain_type == 3 then
local terrain_type = entity.terrain_type
if terrain_type == 2 or terrain_type == 3 then
new_acce.y = 0
p.y = p.y + 1
if node_is(p) == "liquid" then
if velo.y >= 5 then
velo.y = 5
elseif velo.y < 0 then
@ -351,9 +356,11 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
new_acce.y = 5
end
else
if math.abs(velo.y) < 1 then
if abs(velo.y) < 1 then
local pos = entity.object:get_pos()
pos.y = math.floor(pos.y) + 0.5
if not pos then return end
pos.y = floor(pos.y) + 0.5
entity.object:set_pos(pos)
velo.y = 0
end
@ -363,46 +370,22 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
end
end
new_velo = get_velocity(v, entity.object:get_yaw() - rot_view, velo.y)
local new_velo = get_velocity(v, yaw - rot_view, velo.y)
new_acce.y = new_acce.y + acce_y
entity.object:set_velocity(new_velo)
entity.object:set_acceleration(new_acce)
-- CRASH!
if enable_crash then
local intensity = entity.v2 - v
if intensity >= crash_threshold then
--print("----------- crash", intensity)
entity.object:punch(entity.object, 1.0, {
full_punch_interval = 1.0,
damage_groups = {fleshy = intensity}
}, nil)
end
end
entity.v2 = v
end
-- directional flying routine by D00Med (edited by TenPlus1)
function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim)
local ctrl = entity.driver:get_player_control()
local velo = entity.object:get_velocity()
local dir = entity.driver:get_look_dir()
local yaw = entity.driver:get_look_horizontal() + 1.57 -- offset fix between old and new commands
local rot_steer, rot_view = math.pi / 2, 0
if entity.player_rotation.y == 90 then
rot_steer, rot_view = 0, math.pi / 2
end
if ctrl.up then
entity.object:set_velocity({
@ -414,7 +397,7 @@ function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
elseif ctrl.down then
entity.object:set_velocity({
x = -dir.x * speed,
y = dir.y * speed + 2,
y = dir.y * speed + 2,
z = -dir.z * speed
})
@ -422,11 +405,10 @@ function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
entity.object:set_velocity({x = 0, y = -2, z = 0})
end
entity.object:set_yaw(yaw + math.pi + math.pi / 2 - entity.rotate)
entity.object:set_yaw(yaw + pi + pi / 2 - entity.rotate)
-- firing arrows
if ctrl.LMB and ctrl.sneak and shoots then
local pos = entity.object:get_pos()
local obj = minetest.add_entity({
x = pos.x + 0 + dir.x * 2.5,
@ -438,8 +420,8 @@ function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
ent.switch = 1 -- for mob specific arrows
ent.owner_id = tostring(entity.object) -- so arrows dont hurt entity you are riding
local vec = {x = dir.x * 6, y = dir.y * 6, z = dir.z * 6}
local yaw = entity.driver:get_look_horizontal()
obj:set_yaw(yaw + math.pi / 2)
yaw = entity.driver:get_look_horizontal()
obj:set_yaw(yaw + pi / 2)
obj:set_velocity(vec)
else
obj:remove()
@ -448,7 +430,6 @@ function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
-- change animation if stopped
if velo.x == 0 and velo.y == 0 and velo.z == 0 then
mobs:set_animation(entity, stand_anim)
else
-- moving animation

View file

@ -23,9 +23,9 @@ minetest.register_node("mobs:spawner", {
-- text entry formspec
meta:set_string("formspec",
"size[9,3.5]"
"size[10,3.5]"
.. "label[0.15,0.5;" .. minetest.formspec_escape(head) .. "]"
.. "field[1,2.5;7.5,0.8;text;" .. S("Command:")
.. "field[1,2.5;8.5,0.8;text;" .. S("Command:")
.. ";${command}]")
meta:set_string("infotext", S("Spawner Not Active (enter settings)"))
@ -162,10 +162,17 @@ minetest.register_abm({
end
end
-- set medium mob usually spawns in (defaults to air)
local reg = minetest.registered_entities[mob].fly_in
if not reg or type(reg) == "string" then
reg = {(reg or "air")}
end
-- find air blocks within 5 nodes of spawner
local air = minetest.find_nodes_in_area(
{x = pos.x - 5, y = pos.y + yof, z = pos.z - 5},
{x = pos.x + 5, y = pos.y + yof, z = pos.z + 5}, {"air"})
{x = pos.x + 5, y = pos.y + yof, z = pos.z + 5}, reg)
-- spawn in random air block
if air and #air > 0 then

View file

@ -0,0 +1,4 @@
name = mobs_sky
depends = default, mobs
optional_depends =
description = Adds bats into your world.

View file

@ -0,0 +1,4 @@
name = mobs_birds
depends = default, mobs
optional_depends =
description = Adds birds into your world.

View file

@ -0,0 +1,4 @@
name = mobs_butterfly
depends = default, mobs
optional_depends =
description = Adds butterflies into your world.

View file

@ -0,0 +1,4 @@
name = mobs_crocs
depends = default, mobs
optional_depends =
description = Adds crocodiles into your world.

View file

@ -0,0 +1,4 @@
name = mobs_fish
depends = default, mobs
optional_depends =
description = Adds fish into your world.

View file

@ -0,0 +1,4 @@
name = mobs_jellyfish
depends = default, mobs
optional_depends =
description = Adds jellyfish into your world.

View file

@ -0,0 +1,4 @@
name = mobs_sharks
depends = default, mobs
optional_depends =
description = Adds sharks into your world.

View file

@ -0,0 +1,4 @@
name = mobs_turtles
depends = default, mobs
optional_depends =
description = Adds turtles into your world.

View file

@ -1 +1,4 @@
name = pie
depends = default
optional_depends = hunger, hbhunger, stamina, lucky_block
description = Add a selection of tasty Pie/Cakes to eat.

View file

@ -1 +1,4 @@
name = playerplus
depends =
optional_depends = default, 3d_armor, player_monoids, pova
description = Add speed effects, suffocation and cactus damage to players.

View file

@ -1 +1,4 @@
name = regrow
depends =
optional_depends =
description = This mod helps to regrow tree fruits instead of replanting saplings.

View file

@ -1151,7 +1151,7 @@ function get_sign_formspec(pos, nodename)
local formspec = {
"size[6,4]",
"textarea[0,-0.3;6.5,3;text;;" .. txt .. "]",
"textarea[0,-0.3;6.5,3;text;;" .. minetest.formspec_escape(txt) .. "]",
"background[-0.5,-0.5;7,5;signs_lib_sign_bg.jpg]",
"button_exit[2,3.4;2,1;ok;" .. S("Write") .. "]"
}
@ -1195,14 +1195,15 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
meta:set_int("widefont", 1)
change = true
end
if change then
minetest.log("action", S("@1 flipped the wide-font switch to \"@2\" at @3",
(playername or ""),
(fields.on and "off" or "on"),
minetest.pos_to_string(pos)
))
minetest.show_formspec(playername, "signs_lib:sign", get_sign_formspec(pos, node.name))
signs_lib.update_sign(pos, fields)
minetest.show_formspec(playername, "signs_lib:sign", get_sign_formspec(pos, node.name))
end
end
end)

View file

@ -1 +1,4 @@
name = stairs
depends = default
optional_depends =
description = Adds stairs, slabs, inner and outer corners and slopes.

View file

@ -1 +1 @@
Adds stamina and hunger effects.
Adds stamina, hunger and drunk effects.

View file

@ -1 +1,4 @@
name = stamina
depends = default
optional_depends = 3d_armor, player_monoids, pova
description = Adds stamina, hunger and drunk effects.

View file

@ -0,0 +1,56 @@
g top
v 0.498000 0.498000 0.498000
v -0.498000 0.498000 0.498000
v -0.498000 -0.498000 -0.498000
v 0.498000 -0.498000 -0.498000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vn 0.0000 0.7071 -0.7071
s off
f 2/1/1 1/2/1 4/3/1 3/4/1
g bottom
v -0.498000 -0.498000 0.498000
v 0.498000 -0.498000 0.498000
v -0.498000 -0.498000 -0.498000
v 0.498000 -0.498000 -0.498000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vn 0.0000 -1.0000 -0.0000
s off
f 6/5/2 5/6/2 7/7/2 8/8/2
g right
v -0.498000 0.498000 0.498000
v -0.498000 -0.498000 0.498000
v -0.498000 -0.498000 -0.498000
vt 1.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vn -1.0000 0.0000 0.0000
s off
f 9/9/3 11/10/3 10/11/3
g left
v 0.498000 0.498000 0.498000
v 0.498000 -0.498000 0.498000
v 0.498000 -0.498000 -0.498000
vt 0.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vn 1.0000 0.0000 0.0000
s off
f 12/12/4 13/13/4 14/14/4
g back
v 0.498000 0.498000 0.498000
v -0.498000 0.498000 0.498000
v -0.498000 -0.498000 0.498000
v 0.498000 -0.498000 0.498000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vn 0.0000 -0.0000 1.0000
s off
f 15/15/5 16/16/5 17/17/5 18/18/5

View file

@ -88,6 +88,9 @@ minetest.register_node(NODE_NAME.."_active", {
allow_metadata_inventory_take = wh.allow_metadata_inventory_take,
allow_metadata_inventory_move = wh.allow_metadata_inventory_move,
diggable = false,
can_dig = function() return false end,
on_rotate = screwdriver.disallow,
paramtype = "light",
sunlight_propagates = true,

View file

@ -88,6 +88,9 @@ minetest.register_node(NODE_NAME.."_active", {
allow_metadata_inventory_take = wh.allow_metadata_inventory_take,
allow_metadata_inventory_move = wh.allow_metadata_inventory_move,
diggable = false,
can_dig = function() return false end,
on_rotate = screwdriver.disallow,
paramtype = "light",
sunlight_propagates = true,

View file

@ -88,6 +88,9 @@ minetest.register_node(NODE_NAME.."_active", {
allow_metadata_inventory_take = wh.allow_metadata_inventory_take,
allow_metadata_inventory_move = wh.allow_metadata_inventory_move,
diggable = false,
can_dig = function() return false end,
on_rotate = screwdriver.disallow,
paramtype = "light",
sunlight_propagates = true,

View file

@ -444,6 +444,9 @@ minetest.register_node("tubelib:distributor_active", {
on_timer = keep_running,
on_rotate = screwdriver.disallow,
diggable = false,
can_dig = function() return false end,
paramtype = "light",
sunlight_propagates = true,
paramtype2 = "facedir",

View file

@ -175,6 +175,9 @@ minetest.register_node("tubelib:pusher_active", {
on_timer = keep_running,
on_rotate = screwdriver.disallow,
diggable = false,
can_dig = function() return false end,
paramtype = "light",
sunlight_propagates = true,
paramtype2 = "facedir",

View file

@ -354,6 +354,9 @@ minetest.register_node("tubelib_addons1:autocrafter_active", {
},
},
diggable = false,
can_dig = function() return false end,
on_rotate = screwdriver.disallow,
on_timer = keep_running,
on_receive_fields = on_receive_fields,

View file

@ -193,6 +193,9 @@ minetest.register_node("tubelib_addons1:grinder_active", {
"tubelib_front.png",
},
diggable = false,
can_dig = function() return false end,
on_rotate = screwdriver.disallow,
on_timer = keep_running,
on_receive_fields = on_receive_fields,

View file

@ -202,6 +202,9 @@ minetest.register_node("tubelib_addons1:liquidsampler_active", {
'tubelib_addons1_liquidsampler.png',
},
diggable = false,
can_dig = function() return false end,
on_rotate = screwdriver.disallow,
on_timer = keep_running,
on_receive_fields = on_receive_fields,

View file

@ -175,6 +175,9 @@ minetest.register_node("tubelib_addons1:pusher_fast_active", {
on_timer = keep_running,
on_rotate = screwdriver.disallow,
diggable = false,
can_dig = function() return false end,
paramtype = "light",
sunlight_propagates = true,
paramtype2 = "facedir",

View file

@ -372,6 +372,9 @@ minetest.register_node("tubelib_addons1:quarry_active", {
on_timer = keep_running,
on_rotate = screwdriver.disallow,
diggable = false,
can_dig = function() return false end,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_take = allow_metadata_inventory_take,

View file

@ -151,7 +151,7 @@ tubelib.register_node("tubelib_addons2:mesecons_converter", {}, {
meta:set_string("infotext", S("Tubelib Mesecons Converter").." "..own_number..S(": connected with").." "..payload)
meta:set_string("numbers", payload)
meta:set_string("formspec", formspec(meta))
return true
end
return true
end,
})

View file

@ -413,6 +413,9 @@ minetest.register_node("tubelib_addons3:distributor_active", {
on_timer = keep_running,
on_rotate = screwdriver.disallow,
diggable = false,
can_dig = function() return false end,
paramtype = "light",
sunlight_propagates = true,
paramtype2 = "facedir",

View file

@ -160,6 +160,9 @@ minetest.register_node("tubelib_addons3:pusher_active", {
on_timer = keep_running,
on_rotate = screwdriver.disallow,
diggable = false,
can_dig = function() return false end,
paramtype = "light",
sunlight_propagates = true,
paramtype2 = "facedir",

View file

@ -55,7 +55,7 @@ optional: intllib
# License
Copyright (C) 2017-2021 Joachim Stolberg
Copyright (C) 2017-2020 Joachim Stolberg
Code: Licensed under the GNU LGPL version 2.1 or later.
See LICENSE.txt and http://www.gnu.org/licenses/lgpl-2.1.txt
Textures: CC0
@ -81,6 +81,5 @@ Textures: CC0
- 2020-01-03 v1.7 * max_tube_length bugfix
- 2020-02-02 v1.8 * 'special nodes' as alternative to 'secondary nodes' introduced
- 2020-05-31 v1.9 * Generator function 'get_tube_line' added, storage improvements
- 2021-01-17 v2.0 * Update cache on node removal (#7) and refuse to connect with faces of a node which are not marked valid (#3)

View file

@ -78,8 +78,12 @@ function Tube:del_from_cache(pos, dir)
local key2 = S(pos2)
if self.connCache[key2] and self.connCache[key2][dir2] then
self.connCache[key2][dir2] = nil
if self.debug_info then self.debug_info(pos2, "del") end
end
self.connCache[key][dir] = nil
if self.debug_info then self.debug_info(pos, "del") end
else
if self.debug_info then self.debug_info(pos, "noc") end
end
end
@ -90,6 +94,7 @@ function Tube:add_to_cache(pos1, dir1, pos2, dir2)
self.connCache[key] = {}
end
self.connCache[key][dir1] = {pos2 = pos2, dir2 = dir2}
if self.debug_info then self.debug_info(pos1, "add") end
end
-- pos/dir are the pos of the secondary nodes pointing to the head tube nodes.

View file

@ -84,14 +84,12 @@ function Tube:get_node_lvm(pos)
local data = vm:get_data()
local param2_data = vm:get_param2_data()
local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge})
local idx = area:indexp(pos)
if data[idx] and param2_data[idx] then
return {
name = minetest.get_name_from_content_id(data[idx]),
param2 = param2_data[idx]
}
end
return {name="ignore", param2=0}
local idx = area:index(pos.x, pos.y, pos.z)
node = {
name = minetest.get_name_from_content_id(data[idx]),
param2 = param2_data[idx]
}
return node
end
-- Read param2 from a primary node at the given position.
@ -121,12 +119,7 @@ function Tube:get_secondary_node(pos, dir)
local npos = vector.add(pos, Dir6dToVector[dir or 0])
local node = self:get_node_lvm(npos)
if self.secondary_node_names[node.name] then
local valid_dir_string = minetest.get_meta(npos):get_string('valid_dirs')
local valid_dirs = self.valid_dirs
if valid_dir_string and valid_dir_string ~= "" then
valid_dirs = minetest.deserialize(valid_dir_string)
end
return node, npos, valid_dirs[Turn180Deg[dir]] or false
return node, npos
end
end
@ -291,17 +284,13 @@ function Tube:determine_tube_dirs(pos, preferred_pos, fdir)
-- Check for secondary nodes (chests and so on)
for dir = 1,6 do
if allowed[dir] then
local _,npos,allow = self:get_secondary_node(pos, dir)
local _,npos = self:get_secondary_node(pos, dir)
if npos then
if not allow then
allowed[dir] = false
if preferred_pos and vector.equals(npos, preferred_pos) then
preferred_pos = nil
table.insert(tbl, 2, dir)
else
if preferred_pos and vector.equals(npos, preferred_pos) then
preferred_pos = nil
table.insert(tbl, 2, dir)
else
table.insert(tbl, dir)
end
table.insert(tbl, dir)
end
end
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

View file

@ -13,7 +13,7 @@
]]--
-- Version for compatibility checks, see readme.md/history
tubelib2.version = 2.0
tubelib2.version = 1.9
-- for lazy programmers
local S = function(pos) if pos then return minetest.pos_to_string(pos) end end
@ -59,13 +59,11 @@ function tubelib2.get_node_lvm(pos)
local param2_data = vm:get_param2_data()
local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge})
local idx = area:indexp(pos)
if data[idx] and param2_data[idx] then
return {
name = minetest.get_name_from_content_id(data[idx]),
param2 = param2_data[idx]
}
end
return {name="ignore", param2=0}
node = {
name = minetest.get_name_from_content_id(data[idx]),
param2 = param2_data[idx]
}
return node
end
local function update1(self, pos, dir)
@ -161,8 +159,6 @@ local function update_secondary_nodes_after_node_dug(self, pos, dirs)
tmp, npos = self:get_secondary_node(pos, dir)
end
if npos then
self:del_from_cache(npos, Turn180Deg[dir])
self:del_from_cache(pos, dir)
self:update_secondary_node(npos, Turn180Deg[dir])
self:update_secondary_node(pos, dir)
end
@ -186,6 +182,7 @@ function Tube:new(attr)
pairingList = {}, -- teleporting nodes
connCache = {}, -- connection cache {pos1 = {dir1 = {pos2 = pos2, dir2 = dir2},...}
special_node_names = {}, -- use add_special_node_names() to register nodes
debug_info = attr.debug_info, -- debug_info(pos, text)
}
o.valid_dirs = Tbl(o.dirs_to_check)
setmetatable(o, self)
@ -369,7 +366,7 @@ function Tube:stop_pairing(pos, oldmetadata, sFormspec)
local tele_pos = minetest.string_to_pos(oldmetadata.fields.tele_pos)
local peer_meta = M(tele_pos)
if peer_meta then
self:after_place_node(tele_pos, {peer_meta:get_int("tube_dir")})
self:after_dig_node(tele_pos, {peer_meta:get_int("tube_dir")})
peer_meta:set_string("channel", nil)
peer_meta:set_string("tele_pos", nil)
peer_meta:set_string("formspec", sFormspec)

View file

@ -19,6 +19,44 @@ local S = function(pos) if pos then return minetest.pos_to_string(pos) end end
local P = minetest.string_to_pos
local M = minetest.get_meta
-- Marker entities for debugging purposes
local function debug_info(pos, text)
local marker = minetest.add_entity(pos, "tubelib2:marker_cube")
if marker ~= nil then
if text == "add" then
marker:set_nametag_attributes({color = "#FF0000", text = "add__________"})
elseif text == "del" then
marker:set_nametag_attributes({color = "#00FF00", text = "_____del_____"})
elseif text == "noc" then
marker:set_nametag_attributes({color = "#0000FF", text = "__________noc"})
end
minetest.after(6, marker.remove, marker)
end
end
minetest.register_entity(":tubelib2:marker_cube", {
initial_properties = {
visual = "cube",
textures = {
"tubelib2_marker_cube.png",
"tubelib2_marker_cube.png",
"tubelib2_marker_cube.png",
"tubelib2_marker_cube.png",
"tubelib2_marker_cube.png",
"tubelib2_marker_cube.png",
},
physical = false,
visual_size = {x = 1.1, y = 1.1},
collisionbox = {-0.55,-0.55,-0.55, 0.55,0.55,0.55},
glow = 8,
},
on_punch = function(self)
self.object:remove()
end,
})
-- Test tubes
local Tube = tubelib2.Tube:new({
@ -34,6 +72,7 @@ local Tube = tubelib2.Tube:new({
after_place_tube = function(pos, param2, tube_type, num_tubes, tbl)
minetest.swap_node(pos, {name = "tubelib2:tube"..tube_type, param2 = param2})
end,
debug_info = debug_info,
})
Tube:register_on_tube_update(function(node, pos, out_dir, peer_pos, peer_in_dir)

View file

@ -54,7 +54,7 @@ See [`LICENSE.md`](LICENSE.md) for more information.
## Dependencies
- `default` (included in [Minetest Game](https://github.com/minetest/minetest_game))
- [`lib_mount`](https://github.com/Panquesito7/lib_mount)
- [`lib_mount`](https://github.com/minetest-mods/lib_mount)
## Requirements

4
mods/wine/mod.conf Normal file
View file

@ -0,0 +1,4 @@
name = wine
depends =
optional_depends = default, intllib, lucky_block, pipeworks, bonemeal, mcl_core, mcl_sounds, mcl_loot, doc, unified_inventory, thirsty, farming
description = Adds many alcoholic beverages and barrel to ferment them in.

3
mods/wool/mod.conf Normal file
View file

@ -0,0 +1,3 @@
name = wool
depends = default
description = Adds wool blocks into game.