develop #30
|
@ -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/anvils.git
|
||||||
git clone --depth 1 --branch master https://notabug.org/TenPlus1/carts.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
|
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/pie.git
|
||||||
git clone --depth 1 --branch master https://notabug.org/TenPlus1/castle.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://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/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/minetest-mods/realchess.git
|
||||||
git clone --depth 1 --branch master https://github.com/Grizzly-Adam/BBQ.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/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/TumeniNodes/angledwalls.git
|
||||||
git clone --depth 1 --branch master https://github.com/pyrollo/display_modpack.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://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://github.com/minetest-mods/mylandscaping.git
|
||||||
git clone --depth 1 --branch master https://gitlab.com/VanessaE/minislots.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/v-rob/bridger.git
|
||||||
git clone --depth 1 --branch master https://github.com/AiTechEye/smartshop.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
|
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 --depth 1 --branch master https://github.com/khonkhortisan/rubiks.git
|
||||||
git clone --branch master https://git.bananach.space/advtrains.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://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
|
#Clean git stuff
|
||||||
|
|
|
@ -216,7 +216,7 @@ load_mod_font_api = true
|
||||||
load_mod_poisonivy = true
|
load_mod_poisonivy = true
|
||||||
load_mod_xdecor = true
|
load_mod_xdecor = true
|
||||||
load_mod_trunks = true
|
load_mod_trunks = true
|
||||||
load_mod_mobs_bat = true
|
load_mod_mobs_bat = false
|
||||||
load_mod_playeranim = true
|
load_mod_playeranim = true
|
||||||
load_mod_playerplus = true
|
load_mod_playerplus = true
|
||||||
load_mod_prefab_redo = true
|
load_mod_prefab_redo = true
|
||||||
|
@ -268,3 +268,5 @@ load_mod_assets = true
|
||||||
load_mod_advtrains_signals_ks = true
|
load_mod_advtrains_signals_ks = true
|
||||||
load_mod_claycrafter = true
|
load_mod_claycrafter = true
|
||||||
load_mod_serialize_lib = true
|
load_mod_serialize_lib = true
|
||||||
|
load_mod_mobs_sky = false
|
||||||
|
load_mod_hot_air_balloons = true
|
||||||
|
|
Before Width: | Height: | Size: 92 B After Width: | Height: | Size: 91 B |
Before Width: | Height: | Size: 714 B After Width: | Height: | Size: 528 B |
Before Width: | Height: | Size: 355 B |
Before Width: | Height: | Size: 718 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 618 B After Width: | Height: | Size: 398 B |
Before Width: | Height: | Size: 376 B |
Before Width: | Height: | Size: 274 B |
Before Width: | Height: | Size: 322 B |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 793 B After Width: | Height: | Size: 476 B |
|
@ -104,10 +104,10 @@ function advtrains.set_trainhud(name, text, driver)
|
||||||
local driverhud = {
|
local driverhud = {
|
||||||
hud_elem_type = "image",
|
hud_elem_type = "image",
|
||||||
name = "ADVTRAINS_DRIVER",
|
name = "ADVTRAINS_DRIVER",
|
||||||
position = {x=0.5, y=0.7},
|
position = {x=0.5, y=1},
|
||||||
offset = {x=0,y=5},
|
offset = {x=0,y=-170},
|
||||||
text = driver or "",
|
text = driver or "",
|
||||||
alignment = {x=0,y=1},
|
alignment = {x=0,y=-1},
|
||||||
scale = {x=1,y=1},}
|
scale = {x=1,y=1},}
|
||||||
if not hud then
|
if not hud then
|
||||||
hud = {["driver"]={}}
|
hud = {["driver"]={}}
|
||||||
|
@ -116,8 +116,8 @@ function advtrains.set_trainhud(name, text, driver)
|
||||||
hud_elem_type = "text",
|
hud_elem_type = "text",
|
||||||
name = "ADVTRAINS",
|
name = "ADVTRAINS",
|
||||||
number = 0xFFFFFF,
|
number = 0xFFFFFF,
|
||||||
position = {x=0.5, y=0.7},
|
position = {x=0.5, y=1},
|
||||||
offset = {x=0, y=-5},
|
offset = {x=0, y=-300},
|
||||||
text = text,
|
text = text,
|
||||||
scale = {x=200, y=60},
|
scale = {x=200, y=60},
|
||||||
alignment = {x=0, y=-1},
|
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 = advtrains.abs_ceil(train.velocity)
|
||||||
local vel_kmh=advtrains.abs_ceil(advtrains.ms_to_kmh(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
|
local tlev=train.lever or 1
|
||||||
if train.velocity==0 and not train.active_control then tlev=1 end
|
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 = {}
|
local st = {}
|
||||||
if train.debug then st = {train.debug} end
|
if train.debug then st = {train.debug} end
|
||||||
|
|
||||||
local ht = {"[combine:300x150:0,0=(advtrains_hud_bg.png^[resize\\:300x150)"}
|
-- seven-segment display
|
||||||
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)
|
|
||||||
local function sevenseg(digit, x, y, w, h, m)
|
local function sevenseg(digit, x, y, w, h, m)
|
||||||
--[[
|
--[[
|
||||||
-1-
|
-1-
|
||||||
|
@ -246,34 +228,71 @@ function advtrains.hud_train_format(train, flip)
|
||||||
end
|
end
|
||||||
end
|
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
|
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
|
end
|
||||||
for i = max+1, 20, 1 do
|
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
|
end
|
||||||
if res and res > 0 then
|
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
|
end
|
||||||
if train.tarvelocity then
|
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
|
end
|
||||||
local lzb = train.lzb
|
local lzb = train.lzb
|
||||||
if lzb and lzb.oncoming then
|
if lzb and lzb.oncoming then
|
||||||
local oc = lzb.oncoming
|
local oc = lzb.oncoming
|
||||||
for i = 1, #oc do
|
for i = 1, #oc do
|
||||||
local spd = oc[i].spd
|
local spd = oc[i].spd
|
||||||
if not spd then
|
local c = not spd and "lime" or (type(spd) == "number" and (spd == 0) and "red" or "orange") or nil
|
||||||
ht[#ht+1] = "203,43=(advtrains_hud_bg.png^[resize\\:14x14^[colorize\\:lime\\:255)"
|
if c then
|
||||||
elseif spd == 0 then
|
ht[#ht+1] = sformat("130,10=(advtrains_hud_bg.png^[resize\\:30x5^[colorize\\:%s)",c)
|
||||||
ht[#ht+1] = "283,43=(advtrains_hud_bg.png^[resize\\:14x14^[colorize\\:red\\:255)"
|
ht[#ht+1] = sformat("130,35=(advtrains_hud_bg.png^[resize\\:30x5^[colorize\\:%s)",c)
|
||||||
elseif tonumber(spd) then
|
if spd and spd~=0 then
|
||||||
ht[#ht+1] = "243,43=(advtrains_hud_bg.png^[resize\\:14x14^[colorize\\:orange\\:255)"
|
ht[#ht+1] = sformat("%d,50=(advtrains_hud_arrow.png^[multiply\\:red^[makealpha\\:#000000)", 1+spd*11)
|
||||||
ht[#ht+1] = sformat("%d,85=(advtrains_hud_arrow.png^[multiply\\:red^[makealpha\\:#000000)", 2+spd*14)
|
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
|
end
|
||||||
break
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -291,7 +310,7 @@ end
|
||||||
local _, texture = advtrains.hud_train_format { -- dummy train object to demonstrate the train hud
|
local _, texture = advtrains.hud_train_format { -- dummy train object to demonstrate the train hud
|
||||||
max_speed = 15, speed_restriction = 15, velocity = 15, tarvelocity = 12,
|
max_speed = 15, speed_restriction = 15, velocity = 15, tarvelocity = 12,
|
||||||
active_control = true, lever = 3, ctrl = {lzb = true}, is_shunt = true,
|
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",{
|
minetest.register_node("advtrains:hud_demo",{
|
||||||
|
|
|
@ -190,6 +190,7 @@ local function write_to_fd(root_table, file, config)
|
||||||
file:write("LUA_SER v=1\n")
|
file:write("LUA_SER v=1\n")
|
||||||
write_table(root_table, file, config)
|
write_table(root_table, file, config)
|
||||||
file:write("E\nEND_SER\n")
|
file:write("E\nEND_SER\n")
|
||||||
|
file:close()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Reads the file contents from the passed file descriptor and returns the table on success
|
-- Reads the file contents from the passed file descriptor and returns the table on success
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
name = ambience
|
name = ambience
|
||||||
|
depends = default
|
||||||
|
optional_depends = fire, playerplus
|
||||||
|
description = Adds realistic sound effects into your world.
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
name = bakedclay
|
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.
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
This mod adds bees and hives to Minetest
|
Adds bees and hives to Minetest.
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
name = bees
|
name = bees
|
||||||
|
depends = default
|
||||||
|
optional_depends = intllib, lucky_block
|
||||||
|
description = Adds bees and hives to Minetest.
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
name = bonemeal
|
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.
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
name = bows
|
name = bows
|
||||||
|
depends = default
|
||||||
|
optional_depends = mobs, lucky_block
|
||||||
|
description = Adds a selection of bows and arrows for players to use in-game.
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
name = builtin_item
|
name = builtin_item
|
||||||
|
depends = default
|
||||||
|
optional_depends =
|
||||||
|
description = Dropped items can now be pushed by water and have their own custom functions.
|
||||||
|
|
|
@ -33,8 +33,12 @@ Have any questions/comments? Submit an [issue](https://github.com/minetest-mods/
|
||||||
This "ore", doesn't spawn underground!\
|
This "ore", doesn't spawn underground!\
|
||||||
Instead, it spawns at the sky; that's why it's called "cloud".
|
Instead, it spawns at the sky; that's why it's called "cloud".
|
||||||
|
|
||||||
An ore will be spawned inside the schematic.\
|
An ore will be spawned somewhere in the schematic!\
|
||||||
You have less chances to find an ore, than not to find an ore.
|
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
|
||||||
![Small schematic](https://user-images.githubusercontent.com/51391473/69098689-af9fbf00-0a1e-11ea-9e88-c74a6b74baa3.png)
|
![Small schematic](https://user-images.githubusercontent.com/51391473/69098689-af9fbf00-0a1e-11ea-9e88-c74a6b74baa3.png)
|
||||||
|
|
|
@ -78,6 +78,50 @@ minetest.register_node("cloud_items:decorative_cloud", {
|
||||||
sounds = default.node_sound_stone_defaults(),
|
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 --
|
-- Stairs --
|
||||||
------------
|
------------
|
||||||
|
@ -202,6 +246,53 @@ local function place_schem_metadata(origin, filename)
|
||||||
minetest.log("action", "Successfully placed schematic with " .. nodes .. " nodes (metadata)")
|
minetest.log("action", "Successfully placed schematic with " .. nodes .. " nodes (metadata)")
|
||||||
end
|
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+).
|
Functions from Minetest Game's nyancat (LGPLv2.1+).
|
||||||
|
|
||||||
|
@ -231,30 +322,6 @@ local function generate_small(minp, maxp, seed)
|
||||||
end
|
end
|
||||||
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.
|
-- Medium.
|
||||||
local function generate_medium(minp, maxp, seed)
|
local function generate_medium(minp, maxp, seed)
|
||||||
local height_min = 380
|
local height_min = 380
|
||||||
|
@ -278,29 +345,6 @@ local function generate_medium(minp, maxp, seed)
|
||||||
end
|
end
|
||||||
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.
|
-- Big.
|
||||||
local function generate_big(minp, maxp, seed)
|
local function generate_big(minp, maxp, seed)
|
||||||
local height_min = 580
|
local height_min = 580
|
||||||
|
@ -324,30 +368,7 @@ local function generate_big(minp, maxp, seed)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Big (without ore).
|
-- Cloud house.
|
||||||
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
|
|
||||||
local function generate_cloud_house(minp, maxp, seed)
|
local function generate_cloud_house(minp, maxp, seed)
|
||||||
local height_min = 1500
|
local height_min = 1500
|
||||||
local height_max = 3750
|
local height_max = 3750
|
||||||
|
@ -377,11 +398,8 @@ end
|
||||||
-- Generate/place the schematics.
|
-- Generate/place the schematics.
|
||||||
minetest.register_on_generated(function(minp, maxp, seed)
|
minetest.register_on_generated(function(minp, maxp, seed)
|
||||||
generate_small(minp, maxp, seed)
|
generate_small(minp, maxp, seed)
|
||||||
generate_small_without_ore(minp, maxp, seed)
|
|
||||||
generate_medium(minp, maxp, seed)
|
generate_medium(minp, maxp, seed)
|
||||||
generate_medium_without_ore(minp, maxp, seed)
|
|
||||||
generate_big(minp, maxp, seed)
|
generate_big(minp, maxp, seed)
|
||||||
generate_big_without_ore(minp, maxp, seed)
|
|
||||||
generate_cloud_house(minp, maxp, seed)
|
generate_cloud_house(minp, maxp, seed)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
@ -571,6 +589,8 @@ local car_def = {
|
||||||
passenger3_attach_at = {x=-4,y=3.7,z=-3.5},
|
passenger3_attach_at = {x=-4,y=3.7,z=-3.5},
|
||||||
passenger3_eye_offset = {x=4, y=3, z=0},
|
passenger3_eye_offset = {x=4, y=3, z=0},
|
||||||
|
|
||||||
|
enable_crash = false,
|
||||||
|
|
||||||
drop_on_destroy = {"vehicle_mash:tire 2", "vehicle_mash:windshield",
|
drop_on_destroy = {"vehicle_mash:tire 2", "vehicle_mash:windshield",
|
||||||
"vehicle_mash:battery", "vehicle_mash:motor"},
|
"vehicle_mash:battery", "vehicle_mash:motor"},
|
||||||
}
|
}
|
||||||
|
|
BIN
mods/cloud_items/textures/cloud_items_gloves_cloud.png
Normal file
After Width: | Height: | Size: 577 B |
BIN
mods/cloud_items/textures/cloud_items_gloves_cloud_preview.png
Normal file
After Width: | Height: | Size: 432 B |
BIN
mods/cloud_items/textures/cloud_items_inv_gloves_cloud.png
Normal file
After Width: | Height: | Size: 397 B |
54
mods/hot_air_balloons/README.txt
Normal 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)
|
101
mods/hot_air_balloons/absent_ballooner_rescuing.lua
Normal 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
|
||||||
|
|
||||||
|
|
30
mods/hot_air_balloons/api.txt
Normal 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
|
50
mods/hot_air_balloons/craft.lua
Normal 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)
|
5
mods/hot_air_balloons/depends.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
default?
|
||||||
|
bucket?
|
||||||
|
mcl_buckets?
|
||||||
|
mcl_mobitems?
|
||||||
|
mcl_core?
|
226
mods/hot_air_balloons/init.lua
Normal 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")
|
54
mods/hot_air_balloons/license.txt
Normal 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/
|
2
mods/hot_air_balloons/locale/hot_air_balloons.de.tr
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# textdomain:hot_air_balloons
|
||||||
|
Hot Air Balloon=Heißluftballon
|
2
mods/hot_air_balloons/locale/hot_air_balloons.es.tr
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# textdomain:hot_air_balloons
|
||||||
|
Hot Air Balloon=Globo Aerostático
|
2
mods/hot_air_balloons/locale/hot_air_balloons.ro.tr
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# textdomain:hot_air_balloons
|
||||||
|
Hot Air Balloon=Balon cu aer cald
|
4
mods/hot_air_balloons/mod.conf
Normal 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
|
BIN
mods/hot_air_balloons/models/balloon.blend
Normal file
485
mods/hot_air_balloons/models/hot_air_balloons_balloon.obj
Normal 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
|
209
mods/hot_air_balloons/movement.lua
Normal 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
|
BIN
mods/hot_air_balloons/screenshot.png
Normal file
After Width: | Height: | Size: 678 KiB |
BIN
mods/hot_air_balloons/textures/hot_air_balloons_balloon.png
Normal file
After Width: | Height: | Size: 299 B |
After Width: | Height: | Size: 114 KiB |
BIN
mods/hot_air_balloons/textures/hot_air_balloons_flame.png
Normal file
After Width: | Height: | Size: 248 B |
4
mods/mob_horse/mod.conf
Normal 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.
|
|
@ -161,7 +161,7 @@ minetest.register_craft({
|
||||||
minetest.register_craftitem(":mobs:rabbit_hide", {
|
minetest.register_craftitem(":mobs:rabbit_hide", {
|
||||||
description = S("Rabbit Hide"),
|
description = S("Rabbit Hide"),
|
||||||
inventory_image = "mobs_rabbit_hide.png",
|
inventory_image = "mobs_rabbit_hide.png",
|
||||||
groups = {flammable = 2, leather = 1},
|
groups = {flammable = 2, pelt = 1},
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
name = mobs_animal
|
name = mobs_animal
|
||||||
|
depends = default, mobs
|
||||||
|
optional_depends = lucky_block, intllib
|
||||||
|
description = Adds farm animals.
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
name = mobs_monster
|
name = mobs_monster
|
||||||
|
depends = default, mobs
|
||||||
|
optional depends = lucky_block, toolranks, intllib
|
||||||
|
description = Adds many types of monster.
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
name = mobs_npc
|
name = mobs_npc
|
||||||
|
depends = default, mobs
|
||||||
|
optional_depends = lucky_block, intllib
|
||||||
|
description = Adds simple NPC and Trader.
|
||||||
|
|
|
@ -563,7 +563,7 @@ function mob_class:attempt_flight_correction(override)
|
||||||
|
|
||||||
-- We are not flying in what we are supposed to.
|
-- We are not flying in what we are supposed to.
|
||||||
-- See if we can find intended flight medium and return to it
|
-- 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
|
local searchnodes = self.fly_in
|
||||||
|
|
||||||
if type(searchnodes) == "string" then
|
if type(searchnodes) == "string" then
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
name = mobs
|
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.
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
|
|
||||||
-- lib_mount by Blert2112 (edited by TenPlus1)
|
-- lib_mount by Blert2112 (edited by TenPlus1)
|
||||||
|
|
||||||
local enable_crash = false
|
local abs, cos, floor, sin, sqrt, pi =
|
||||||
local crash_threshold = 6.5 -- ignored if enable_crash=false
|
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)
|
local node_ok = function(pos, fallback)
|
||||||
|
|
||||||
fallback = fallback or mobs.fallback_node
|
fallback = fallback or mobs.fallback_node
|
||||||
|
|
||||||
local node = minetest.get_node_or_nil(pos)
|
local node = minetest.get_node_or_nil(pos)
|
||||||
|
@ -25,7 +22,6 @@ end
|
||||||
|
|
||||||
|
|
||||||
local function node_is(pos)
|
local function node_is(pos)
|
||||||
|
|
||||||
local node = node_ok(pos)
|
local node = node_ok(pos)
|
||||||
|
|
||||||
if node.name == "air" then
|
if node.name == "air" then
|
||||||
|
@ -49,33 +45,30 @@ end
|
||||||
|
|
||||||
|
|
||||||
local function get_sign(i)
|
local function get_sign(i)
|
||||||
|
|
||||||
i = i or 0
|
i = i or 0
|
||||||
|
|
||||||
if i == 0 then
|
if i == 0 then
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
return i / math.abs(i)
|
return i / abs(i)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function get_velocity(v, yaw, y)
|
local function get_velocity(v, yaw, y)
|
||||||
|
local x = -sin(yaw) * v
|
||||||
local x = -math.sin(yaw) * v
|
local z = cos(yaw) * v
|
||||||
local z = math.cos(yaw) * v
|
|
||||||
|
|
||||||
return {x = x, y = y, z = z}
|
return {x = x, y = y, z = z}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function get_v(v)
|
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
|
end
|
||||||
|
|
||||||
|
|
||||||
local function force_detach(player)
|
local function force_detach(player)
|
||||||
|
|
||||||
local attached_to = player:get_attach()
|
local attached_to = player:get_attach()
|
||||||
|
|
||||||
if not attached_to then
|
if not attached_to then
|
||||||
|
@ -86,21 +79,19 @@ local function force_detach(player)
|
||||||
|
|
||||||
if entity and entity.driver
|
if entity and entity.driver
|
||||||
and entity.driver == player then
|
and entity.driver == player then
|
||||||
|
|
||||||
entity.driver = nil
|
entity.driver = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
player:set_detach()
|
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})
|
player:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
|
||||||
default.player_set_animation(player, "stand" , 30)
|
player_api.set_animation(player, "stand", 30)
|
||||||
player:set_properties({visual_size = {x = 1, y = 1} })
|
player:set_properties({visual_size = {x = 1, y = 1}})
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
minetest.register_on_leaveplayer(function(player)
|
minetest.register_on_leaveplayer(function(player)
|
||||||
force_detach(player)
|
force_detach(player)
|
||||||
end)
|
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)
|
function mobs.attach(entity, player)
|
||||||
|
|
||||||
local attach_at, eye_offset = {}, {}
|
|
||||||
|
|
||||||
entity.player_rotation = entity.player_rotation or {x = 0, y = 0, z = 0}
|
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_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}
|
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
|
local rot_view = 0
|
||||||
|
|
||||||
if entity.player_rotation.y == 90 then
|
if entity.player_rotation.y == 90 then
|
||||||
rot_view = math.pi / 2
|
rot_view = pi / 2
|
||||||
end
|
end
|
||||||
|
|
||||||
attach_at = entity.driver_attach_at
|
local attach_at = entity.driver_attach_at
|
||||||
eye_offset = entity.driver_eye_offset
|
local eye_offset = entity.driver_eye_offset
|
||||||
entity.driver = player
|
entity.driver = player
|
||||||
|
|
||||||
force_detach(player)
|
force_detach(player)
|
||||||
|
|
||||||
player:set_attach(entity.object, "", attach_at, entity.player_rotation)
|
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_eye_offset(eye_offset, {x = 0, y = 0, z = 0})
|
||||||
|
|
||||||
player:set_properties({
|
player:set_properties({
|
||||||
|
@ -151,46 +169,36 @@ function mobs.attach(entity, player)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.after(0.2, function(name)
|
minetest.after(0.2, function()
|
||||||
local player = minetest.get_player_by_name(name)
|
if player and player:is_player() then
|
||||||
if player then
|
player_api.set_animation(player, "sit", 30)
|
||||||
default.player_set_animation(player, "sit" , 30)
|
|
||||||
end
|
end
|
||||||
end, player:get_player_name())
|
end)
|
||||||
|
|
||||||
player:set_look_horizontal(entity.object:get_yaw() - rot_view)
|
player:set_look_horizontal(entity.object:get_yaw() - rot_view)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function mobs.detach(player, offset)
|
function mobs.detach(player)
|
||||||
|
|
||||||
force_detach(player)
|
force_detach(player)
|
||||||
|
|
||||||
default.player_set_animation(player, "stand" , 30)
|
minetest.after(0.1, function()
|
||||||
|
if player and player:is_player() then
|
||||||
local pos = player:get_pos()
|
local pos = find_free_pos(player:get_pos())
|
||||||
|
pos.y = pos.y + 0.5
|
||||||
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
|
|
||||||
player:set_pos(pos)
|
player:set_pos(pos)
|
||||||
end
|
end
|
||||||
end, player:get_player_name(), pos)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
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
|
if entity.player_rotation.y == 90 then
|
||||||
rot_steer, rot_view = 0, math.pi/2
|
rot_view = pi / 2
|
||||||
end
|
end
|
||||||
|
|
||||||
local acce_y = 0
|
local acce_y = 0
|
||||||
|
@ -200,19 +208,14 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||||
|
|
||||||
-- process controls
|
-- process controls
|
||||||
if entity.driver then
|
if entity.driver then
|
||||||
|
|
||||||
--print ("---velo", get_v(velo))
|
|
||||||
|
|
||||||
local ctrl = entity.driver:get_player_control()
|
local ctrl = entity.driver:get_player_control()
|
||||||
|
|
||||||
-- move forwards
|
-- move forwards
|
||||||
if ctrl.up then
|
if ctrl.up then
|
||||||
|
|
||||||
entity.v = entity.v + entity.accel / 10
|
entity.v = entity.v + entity.accel / 10
|
||||||
|
|
||||||
-- move backwards
|
-- move backwards
|
||||||
elseif ctrl.down then
|
elseif ctrl.down then
|
||||||
|
|
||||||
if entity.max_speed_reverse == 0 and entity.v == 0 then
|
if entity.max_speed_reverse == 0 and entity.v == 0 then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -220,12 +223,24 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||||
entity.v = entity.v - entity.accel / 10
|
entity.v = entity.v - entity.accel / 10
|
||||||
end
|
end
|
||||||
|
|
||||||
-- fix mob rotation
|
-- mob rotation
|
||||||
local horz = entity.driver:get_look_horizontal() or 0
|
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)
|
entity.object:set_yaw(horz - entity.rotate)
|
||||||
|
|
||||||
if can_fly then
|
if can_fly then
|
||||||
|
|
||||||
-- fly up
|
-- fly up
|
||||||
if ctrl.jump then
|
if ctrl.jump then
|
||||||
velo.y = velo.y + 1
|
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
|
velo.y = velo.y + 0.1
|
||||||
if velo.y > 0 then velo.y = 0 end
|
if velo.y > 0 then velo.y = 0 end
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
-- jump
|
-- jump
|
||||||
if ctrl.jump then
|
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 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 entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then
|
||||||
|
|
||||||
if stand_anim then
|
if stand_anim then
|
||||||
mobs:set_animation(entity, stand_anim)
|
mobs:set_animation(entity, stand_anim)
|
||||||
end
|
end
|
||||||
|
@ -280,7 +292,6 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||||
entity.v = entity.v - 0.02 * s
|
entity.v = entity.v - 0.02 * s
|
||||||
|
|
||||||
if s ~= get_sign(entity.v) then
|
if s ~= get_sign(entity.v) then
|
||||||
|
|
||||||
entity.object:set_velocity({x = 0, y = 0, z = 0})
|
entity.object:set_velocity({x = 0, y = 0, z = 0})
|
||||||
entity.v = 0
|
entity.v = 0
|
||||||
return
|
return
|
||||||
|
@ -293,14 +304,15 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||||
max_spd = entity.max_speed_forward
|
max_spd = entity.max_speed_forward
|
||||||
end
|
end
|
||||||
|
|
||||||
if math.abs(entity.v) > max_spd then
|
if abs(entity.v) > max_spd then
|
||||||
entity.v = entity.v - get_sign(entity.v)
|
entity.v = entity.v - get_sign(entity.v)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Set position, velocity and acceleration
|
-- Set position, velocity and acceleration
|
||||||
local p = entity.object:get_pos()
|
local p = entity.object:get_pos()
|
||||||
local new_velo
|
if not p then return end
|
||||||
local new_acce = {x = 0, y = -9.8, z = 0}
|
|
||||||
|
local new_acce = {x = 0, y = -9.81, z = 0}
|
||||||
|
|
||||||
p.y = p.y - 0.5
|
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
|
local v = entity.v
|
||||||
|
|
||||||
if ni == "air" then
|
if ni == "air" then
|
||||||
|
|
||||||
if can_fly == true then
|
if can_fly == true then
|
||||||
new_acce.y = 0
|
new_acce.y = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif ni == "liquid" or ni == "lava" then
|
elseif ni == "liquid" or ni == "lava" then
|
||||||
|
|
||||||
if ni == "lava" and entity.lava_damage ~= 0 then
|
if ni == "lava" and entity.lava_damage ~= 0 then
|
||||||
|
|
||||||
entity.lava_counter = (entity.lava_counter or 0) + dtime
|
entity.lava_counter = (entity.lava_counter or 0) + dtime
|
||||||
|
|
||||||
if entity.lava_counter > 1 then
|
if entity.lava_counter > 1 then
|
||||||
|
|
||||||
minetest.sound_play("default_punch", {
|
minetest.sound_play("default_punch", {
|
||||||
object = entity.object,
|
object = entity.object,
|
||||||
max_hear_distance = 5
|
max_hear_distance = 5
|
||||||
}, true)
|
})
|
||||||
|
|
||||||
entity.object:punch(entity.object, 1.0, {
|
entity.object:punch(entity.object, 1.0, {
|
||||||
full_punch_interval = 1.0,
|
full_punch_interval = 1.0,
|
||||||
|
@ -335,14 +342,12 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if entity.terrain_type == 2
|
local terrain_type = entity.terrain_type
|
||||||
or entity.terrain_type == 3 then
|
if terrain_type == 2 or terrain_type == 3 then
|
||||||
|
|
||||||
new_acce.y = 0
|
new_acce.y = 0
|
||||||
p.y = p.y + 1
|
p.y = p.y + 1
|
||||||
|
|
||||||
if node_is(p) == "liquid" then
|
if node_is(p) == "liquid" then
|
||||||
|
|
||||||
if velo.y >= 5 then
|
if velo.y >= 5 then
|
||||||
velo.y = 5
|
velo.y = 5
|
||||||
elseif velo.y < 0 then
|
elseif velo.y < 0 then
|
||||||
|
@ -351,9 +356,11 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||||
new_acce.y = 5
|
new_acce.y = 5
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if math.abs(velo.y) < 1 then
|
if abs(velo.y) < 1 then
|
||||||
local pos = entity.object:get_pos()
|
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)
|
entity.object:set_pos(pos)
|
||||||
velo.y = 0
|
velo.y = 0
|
||||||
end
|
end
|
||||||
|
@ -363,46 +370,22 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||||
end
|
end
|
||||||
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
|
new_acce.y = new_acce.y + acce_y
|
||||||
|
|
||||||
entity.object:set_velocity(new_velo)
|
entity.object:set_velocity(new_velo)
|
||||||
entity.object:set_acceleration(new_acce)
|
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
|
entity.v2 = v
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- directional flying routine by D00Med (edited by TenPlus1)
|
-- directional flying routine by D00Med (edited by TenPlus1)
|
||||||
|
function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim)
|
||||||
function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
|
|
||||||
|
|
||||||
local ctrl = entity.driver:get_player_control()
|
local ctrl = entity.driver:get_player_control()
|
||||||
local velo = entity.object:get_velocity()
|
local velo = entity.object:get_velocity()
|
||||||
local dir = entity.driver:get_look_dir()
|
local dir = entity.driver:get_look_dir()
|
||||||
local yaw = entity.driver:get_look_horizontal() + 1.57 -- offset fix between old and new commands
|
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
|
if ctrl.up then
|
||||||
entity.object:set_velocity({
|
entity.object:set_velocity({
|
||||||
|
@ -414,7 +397,7 @@ function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
|
||||||
elseif ctrl.down then
|
elseif ctrl.down then
|
||||||
entity.object:set_velocity({
|
entity.object:set_velocity({
|
||||||
x = -dir.x * speed,
|
x = -dir.x * speed,
|
||||||
y = dir.y * speed + 2,
|
y = dir.y * speed + 2,
|
||||||
z = -dir.z * speed
|
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})
|
entity.object:set_velocity({x = 0, y = -2, z = 0})
|
||||||
end
|
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
|
-- firing arrows
|
||||||
if ctrl.LMB and ctrl.sneak and shoots then
|
if ctrl.LMB and ctrl.sneak and shoots then
|
||||||
|
|
||||||
local pos = entity.object:get_pos()
|
local pos = entity.object:get_pos()
|
||||||
local obj = minetest.add_entity({
|
local obj = minetest.add_entity({
|
||||||
x = pos.x + 0 + dir.x * 2.5,
|
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.switch = 1 -- for mob specific arrows
|
||||||
ent.owner_id = tostring(entity.object) -- so arrows dont hurt entity you are riding
|
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 vec = {x = dir.x * 6, y = dir.y * 6, z = dir.z * 6}
|
||||||
local yaw = entity.driver:get_look_horizontal()
|
yaw = entity.driver:get_look_horizontal()
|
||||||
obj:set_yaw(yaw + math.pi / 2)
|
obj:set_yaw(yaw + pi / 2)
|
||||||
obj:set_velocity(vec)
|
obj:set_velocity(vec)
|
||||||
else
|
else
|
||||||
obj:remove()
|
obj:remove()
|
||||||
|
@ -448,7 +430,6 @@ function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
|
||||||
|
|
||||||
-- change animation if stopped
|
-- change animation if stopped
|
||||||
if velo.x == 0 and velo.y == 0 and velo.z == 0 then
|
if velo.x == 0 and velo.y == 0 and velo.z == 0 then
|
||||||
|
|
||||||
mobs:set_animation(entity, stand_anim)
|
mobs:set_animation(entity, stand_anim)
|
||||||
else
|
else
|
||||||
-- moving animation
|
-- moving animation
|
||||||
|
|
|
@ -23,9 +23,9 @@ minetest.register_node("mobs:spawner", {
|
||||||
|
|
||||||
-- text entry formspec
|
-- text entry formspec
|
||||||
meta:set_string("formspec",
|
meta:set_string("formspec",
|
||||||
"size[9,3.5]"
|
"size[10,3.5]"
|
||||||
.. "label[0.15,0.5;" .. minetest.formspec_escape(head) .. "]"
|
.. "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}]")
|
.. ";${command}]")
|
||||||
|
|
||||||
meta:set_string("infotext", S("Spawner Not Active (enter settings)"))
|
meta:set_string("infotext", S("Spawner Not Active (enter settings)"))
|
||||||
|
@ -162,10 +162,17 @@ minetest.register_abm({
|
||||||
end
|
end
|
||||||
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
|
-- find air blocks within 5 nodes of spawner
|
||||||
local air = minetest.find_nodes_in_area(
|
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},
|
||||||
{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
|
-- spawn in random air block
|
||||||
if air and #air > 0 then
|
if air and #air > 0 then
|
||||||
|
|
4
mods/mobs_sky/mobs_bat/mod.conf
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
name = mobs_sky
|
||||||
|
depends = default, mobs
|
||||||
|
optional_depends =
|
||||||
|
description = Adds bats into your world.
|
4
mods/mobs_sky/mobs_birds/mod.conf
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
name = mobs_birds
|
||||||
|
depends = default, mobs
|
||||||
|
optional_depends =
|
||||||
|
description = Adds birds into your world.
|
4
mods/mobs_sky/mobs_butterfly/mod.conf
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
name = mobs_butterfly
|
||||||
|
depends = default, mobs
|
||||||
|
optional_depends =
|
||||||
|
description = Adds butterflies into your world.
|
4
mods/mobs_water/mobs_crocs/mod.conf
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
name = mobs_crocs
|
||||||
|
depends = default, mobs
|
||||||
|
optional_depends =
|
||||||
|
description = Adds crocodiles into your world.
|
4
mods/mobs_water/mobs_fish/mod.conf
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
name = mobs_fish
|
||||||
|
depends = default, mobs
|
||||||
|
optional_depends =
|
||||||
|
description = Adds fish into your world.
|
4
mods/mobs_water/mobs_jellyfish/mod.conf
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
name = mobs_jellyfish
|
||||||
|
depends = default, mobs
|
||||||
|
optional_depends =
|
||||||
|
description = Adds jellyfish into your world.
|
4
mods/mobs_water/mobs_sharks/mod.conf
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
name = mobs_sharks
|
||||||
|
depends = default, mobs
|
||||||
|
optional_depends =
|
||||||
|
description = Adds sharks into your world.
|
4
mods/mobs_water/mobs_turtles/mod.conf
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
name = mobs_turtles
|
||||||
|
depends = default, mobs
|
||||||
|
optional_depends =
|
||||||
|
description = Adds turtles into your world.
|
|
@ -1 +1,4 @@
|
||||||
name = pie
|
name = pie
|
||||||
|
depends = default
|
||||||
|
optional_depends = hunger, hbhunger, stamina, lucky_block
|
||||||
|
description = Add a selection of tasty Pie/Cakes to eat.
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
name = playerplus
|
name = playerplus
|
||||||
|
depends =
|
||||||
|
optional_depends = default, 3d_armor, player_monoids, pova
|
||||||
|
description = Add speed effects, suffocation and cactus damage to players.
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
name = regrow
|
name = regrow
|
||||||
|
depends =
|
||||||
|
optional_depends =
|
||||||
|
description = This mod helps to regrow tree fruits instead of replanting saplings.
|
||||||
|
|
|
@ -1151,7 +1151,7 @@ function get_sign_formspec(pos, nodename)
|
||||||
|
|
||||||
local formspec = {
|
local formspec = {
|
||||||
"size[6,4]",
|
"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]",
|
"background[-0.5,-0.5;7,5;signs_lib_sign_bg.jpg]",
|
||||||
"button_exit[2,3.4;2,1;ok;" .. S("Write") .. "]"
|
"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)
|
meta:set_int("widefont", 1)
|
||||||
change = true
|
change = true
|
||||||
end
|
end
|
||||||
|
|
||||||
if change then
|
if change then
|
||||||
minetest.log("action", S("@1 flipped the wide-font switch to \"@2\" at @3",
|
minetest.log("action", S("@1 flipped the wide-font switch to \"@2\" at @3",
|
||||||
(playername or ""),
|
(playername or ""),
|
||||||
(fields.on and "off" or "on"),
|
(fields.on and "off" or "on"),
|
||||||
minetest.pos_to_string(pos)
|
minetest.pos_to_string(pos)
|
||||||
))
|
))
|
||||||
minetest.show_formspec(playername, "signs_lib:sign", get_sign_formspec(pos, node.name))
|
|
||||||
signs_lib.update_sign(pos, fields)
|
signs_lib.update_sign(pos, fields)
|
||||||
|
minetest.show_formspec(playername, "signs_lib:sign", get_sign_formspec(pos, node.name))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
name = stairs
|
name = stairs
|
||||||
|
depends = default
|
||||||
|
optional_depends =
|
||||||
|
description = Adds stairs, slabs, inner and outer corners and slopes.
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Adds stamina and hunger effects.
|
Adds stamina, hunger and drunk effects.
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
name = stamina
|
name = stamina
|
||||||
|
depends = default
|
||||||
|
optional_depends = 3d_armor, player_monoids, pova
|
||||||
|
description = Adds stamina, hunger and drunk effects.
|
||||||
|
|
|
@ -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
|
|
@ -87,6 +87,9 @@ minetest.register_node(NODE_NAME.."_active", {
|
||||||
on_metadata_inventory_put = wh.on_metadata_inventory_put,
|
on_metadata_inventory_put = wh.on_metadata_inventory_put,
|
||||||
allow_metadata_inventory_take = wh.allow_metadata_inventory_take,
|
allow_metadata_inventory_take = wh.allow_metadata_inventory_take,
|
||||||
allow_metadata_inventory_move = wh.allow_metadata_inventory_move,
|
allow_metadata_inventory_move = wh.allow_metadata_inventory_move,
|
||||||
|
|
||||||
|
diggable = false,
|
||||||
|
can_dig = function() return false end,
|
||||||
|
|
||||||
on_rotate = screwdriver.disallow,
|
on_rotate = screwdriver.disallow,
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
|
|
|
@ -88,6 +88,9 @@ minetest.register_node(NODE_NAME.."_active", {
|
||||||
allow_metadata_inventory_take = wh.allow_metadata_inventory_take,
|
allow_metadata_inventory_take = wh.allow_metadata_inventory_take,
|
||||||
allow_metadata_inventory_move = wh.allow_metadata_inventory_move,
|
allow_metadata_inventory_move = wh.allow_metadata_inventory_move,
|
||||||
|
|
||||||
|
diggable = false,
|
||||||
|
can_dig = function() return false end,
|
||||||
|
|
||||||
on_rotate = screwdriver.disallow,
|
on_rotate = screwdriver.disallow,
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
sunlight_propagates = true,
|
sunlight_propagates = true,
|
||||||
|
|
|
@ -87,6 +87,9 @@ minetest.register_node(NODE_NAME.."_active", {
|
||||||
on_metadata_inventory_put = wh.on_metadata_inventory_put,
|
on_metadata_inventory_put = wh.on_metadata_inventory_put,
|
||||||
allow_metadata_inventory_take = wh.allow_metadata_inventory_take,
|
allow_metadata_inventory_take = wh.allow_metadata_inventory_take,
|
||||||
allow_metadata_inventory_move = wh.allow_metadata_inventory_move,
|
allow_metadata_inventory_move = wh.allow_metadata_inventory_move,
|
||||||
|
|
||||||
|
diggable = false,
|
||||||
|
can_dig = function() return false end,
|
||||||
|
|
||||||
on_rotate = screwdriver.disallow,
|
on_rotate = screwdriver.disallow,
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
|
|
|
@ -444,6 +444,9 @@ minetest.register_node("tubelib:distributor_active", {
|
||||||
on_timer = keep_running,
|
on_timer = keep_running,
|
||||||
on_rotate = screwdriver.disallow,
|
on_rotate = screwdriver.disallow,
|
||||||
|
|
||||||
|
diggable = false,
|
||||||
|
can_dig = function() return false end,
|
||||||
|
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
sunlight_propagates = true,
|
sunlight_propagates = true,
|
||||||
paramtype2 = "facedir",
|
paramtype2 = "facedir",
|
||||||
|
|
|
@ -174,7 +174,10 @@ minetest.register_node("tubelib:pusher_active", {
|
||||||
|
|
||||||
on_timer = keep_running,
|
on_timer = keep_running,
|
||||||
on_rotate = screwdriver.disallow,
|
on_rotate = screwdriver.disallow,
|
||||||
|
|
||||||
|
diggable = false,
|
||||||
|
can_dig = function() return false end,
|
||||||
|
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
sunlight_propagates = true,
|
sunlight_propagates = true,
|
||||||
paramtype2 = "facedir",
|
paramtype2 = "facedir",
|
||||||
|
|
|
@ -353,6 +353,9 @@ minetest.register_node("tubelib_addons1:autocrafter_active", {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
diggable = false,
|
||||||
|
can_dig = function() return false end,
|
||||||
|
|
||||||
on_rotate = screwdriver.disallow,
|
on_rotate = screwdriver.disallow,
|
||||||
on_timer = keep_running,
|
on_timer = keep_running,
|
||||||
|
|
|
@ -193,6 +193,9 @@ minetest.register_node("tubelib_addons1:grinder_active", {
|
||||||
"tubelib_front.png",
|
"tubelib_front.png",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
diggable = false,
|
||||||
|
can_dig = function() return false end,
|
||||||
|
|
||||||
on_rotate = screwdriver.disallow,
|
on_rotate = screwdriver.disallow,
|
||||||
on_timer = keep_running,
|
on_timer = keep_running,
|
||||||
on_receive_fields = on_receive_fields,
|
on_receive_fields = on_receive_fields,
|
||||||
|
|
|
@ -202,6 +202,9 @@ minetest.register_node("tubelib_addons1:liquidsampler_active", {
|
||||||
'tubelib_addons1_liquidsampler.png',
|
'tubelib_addons1_liquidsampler.png',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
diggable = false,
|
||||||
|
can_dig = function() return false end,
|
||||||
|
|
||||||
on_rotate = screwdriver.disallow,
|
on_rotate = screwdriver.disallow,
|
||||||
on_timer = keep_running,
|
on_timer = keep_running,
|
||||||
on_receive_fields = on_receive_fields,
|
on_receive_fields = on_receive_fields,
|
||||||
|
|
|
@ -174,6 +174,9 @@ minetest.register_node("tubelib_addons1:pusher_fast_active", {
|
||||||
|
|
||||||
on_timer = keep_running,
|
on_timer = keep_running,
|
||||||
on_rotate = screwdriver.disallow,
|
on_rotate = screwdriver.disallow,
|
||||||
|
|
||||||
|
diggable = false,
|
||||||
|
can_dig = function() return false end,
|
||||||
|
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
sunlight_propagates = true,
|
sunlight_propagates = true,
|
||||||
|
|
|
@ -372,6 +372,9 @@ minetest.register_node("tubelib_addons1:quarry_active", {
|
||||||
on_timer = keep_running,
|
on_timer = keep_running,
|
||||||
on_rotate = screwdriver.disallow,
|
on_rotate = screwdriver.disallow,
|
||||||
|
|
||||||
|
diggable = false,
|
||||||
|
can_dig = function() return false end,
|
||||||
|
|
||||||
allow_metadata_inventory_put = allow_metadata_inventory_put,
|
allow_metadata_inventory_put = allow_metadata_inventory_put,
|
||||||
allow_metadata_inventory_take = allow_metadata_inventory_take,
|
allow_metadata_inventory_take = allow_metadata_inventory_take,
|
||||||
|
|
||||||
|
|
|
@ -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("infotext", S("Tubelib Mesecons Converter").." "..own_number..S(": connected with").." "..payload)
|
||||||
meta:set_string("numbers", payload)
|
meta:set_string("numbers", payload)
|
||||||
meta:set_string("formspec", formspec(meta))
|
meta:set_string("formspec", formspec(meta))
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
return true
|
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
|
@ -413,6 +413,9 @@ minetest.register_node("tubelib_addons3:distributor_active", {
|
||||||
on_timer = keep_running,
|
on_timer = keep_running,
|
||||||
on_rotate = screwdriver.disallow,
|
on_rotate = screwdriver.disallow,
|
||||||
|
|
||||||
|
diggable = false,
|
||||||
|
can_dig = function() return false end,
|
||||||
|
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
sunlight_propagates = true,
|
sunlight_propagates = true,
|
||||||
paramtype2 = "facedir",
|
paramtype2 = "facedir",
|
||||||
|
|
|
@ -159,7 +159,10 @@ minetest.register_node("tubelib_addons3:pusher_active", {
|
||||||
|
|
||||||
on_timer = keep_running,
|
on_timer = keep_running,
|
||||||
on_rotate = screwdriver.disallow,
|
on_rotate = screwdriver.disallow,
|
||||||
|
|
||||||
|
diggable = false,
|
||||||
|
can_dig = function() return false end,
|
||||||
|
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
sunlight_propagates = true,
|
sunlight_propagates = true,
|
||||||
paramtype2 = "facedir",
|
paramtype2 = "facedir",
|
||||||
|
|
|
@ -55,7 +55,7 @@ optional: intllib
|
||||||
|
|
||||||
|
|
||||||
# License
|
# License
|
||||||
Copyright (C) 2017-2021 Joachim Stolberg
|
Copyright (C) 2017-2020 Joachim Stolberg
|
||||||
Code: Licensed under the GNU LGPL version 2.1 or later.
|
Code: Licensed under the GNU LGPL version 2.1 or later.
|
||||||
See LICENSE.txt and http://www.gnu.org/licenses/lgpl-2.1.txt
|
See LICENSE.txt and http://www.gnu.org/licenses/lgpl-2.1.txt
|
||||||
Textures: CC0
|
Textures: CC0
|
||||||
|
@ -81,6 +81,5 @@ Textures: CC0
|
||||||
- 2020-01-03 v1.7 * max_tube_length bugfix
|
- 2020-01-03 v1.7 * max_tube_length bugfix
|
||||||
- 2020-02-02 v1.8 * 'special nodes' as alternative to 'secondary nodes' introduced
|
- 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
|
- 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)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -78,8 +78,12 @@ function Tube:del_from_cache(pos, dir)
|
||||||
local key2 = S(pos2)
|
local key2 = S(pos2)
|
||||||
if self.connCache[key2] and self.connCache[key2][dir2] then
|
if self.connCache[key2] and self.connCache[key2][dir2] then
|
||||||
self.connCache[key2][dir2] = nil
|
self.connCache[key2][dir2] = nil
|
||||||
|
if self.debug_info then self.debug_info(pos2, "del") end
|
||||||
end
|
end
|
||||||
self.connCache[key][dir] = nil
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -90,6 +94,7 @@ function Tube:add_to_cache(pos1, dir1, pos2, dir2)
|
||||||
self.connCache[key] = {}
|
self.connCache[key] = {}
|
||||||
end
|
end
|
||||||
self.connCache[key][dir1] = {pos2 = pos2, dir2 = dir2}
|
self.connCache[key][dir1] = {pos2 = pos2, dir2 = dir2}
|
||||||
|
if self.debug_info then self.debug_info(pos1, "add") end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- pos/dir are the pos of the secondary nodes pointing to the head tube nodes.
|
-- pos/dir are the pos of the secondary nodes pointing to the head tube nodes.
|
||||||
|
|
|
@ -84,14 +84,12 @@ function Tube:get_node_lvm(pos)
|
||||||
local data = vm:get_data()
|
local data = vm:get_data()
|
||||||
local param2_data = vm:get_param2_data()
|
local param2_data = vm:get_param2_data()
|
||||||
local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge})
|
local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge})
|
||||||
local idx = area:indexp(pos)
|
local idx = area:index(pos.x, pos.y, pos.z)
|
||||||
if data[idx] and param2_data[idx] then
|
node = {
|
||||||
return {
|
name = minetest.get_name_from_content_id(data[idx]),
|
||||||
name = minetest.get_name_from_content_id(data[idx]),
|
param2 = param2_data[idx]
|
||||||
param2 = param2_data[idx]
|
}
|
||||||
}
|
return node
|
||||||
end
|
|
||||||
return {name="ignore", param2=0}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Read param2 from a primary node at the given position.
|
-- 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 npos = vector.add(pos, Dir6dToVector[dir or 0])
|
||||||
local node = self:get_node_lvm(npos)
|
local node = self:get_node_lvm(npos)
|
||||||
if self.secondary_node_names[node.name] then
|
if self.secondary_node_names[node.name] then
|
||||||
local valid_dir_string = minetest.get_meta(npos):get_string('valid_dirs')
|
return node, npos
|
||||||
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
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -291,17 +284,13 @@ function Tube:determine_tube_dirs(pos, preferred_pos, fdir)
|
||||||
-- Check for secondary nodes (chests and so on)
|
-- Check for secondary nodes (chests and so on)
|
||||||
for dir = 1,6 do
|
for dir = 1,6 do
|
||||||
if allowed[dir] then
|
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 npos then
|
||||||
if not allow then
|
if preferred_pos and vector.equals(npos, preferred_pos) then
|
||||||
allowed[dir] = false
|
preferred_pos = nil
|
||||||
|
table.insert(tbl, 2, dir)
|
||||||
else
|
else
|
||||||
if preferred_pos and vector.equals(npos, preferred_pos) then
|
table.insert(tbl, dir)
|
||||||
preferred_pos = nil
|
|
||||||
table.insert(tbl, 2, dir)
|
|
||||||
else
|
|
||||||
table.insert(tbl, dir)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
BIN
mods/tubelib2/textures/tubelib2_marker_cube.png
Normal file
After Width: | Height: | Size: 195 B |
|
@ -13,7 +13,7 @@
|
||||||
]]--
|
]]--
|
||||||
|
|
||||||
-- Version for compatibility checks, see readme.md/history
|
-- Version for compatibility checks, see readme.md/history
|
||||||
tubelib2.version = 2.0
|
tubelib2.version = 1.9
|
||||||
|
|
||||||
-- for lazy programmers
|
-- for lazy programmers
|
||||||
local S = function(pos) if pos then return minetest.pos_to_string(pos) end end
|
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 param2_data = vm:get_param2_data()
|
||||||
local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge})
|
local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge})
|
||||||
local idx = area:indexp(pos)
|
local idx = area:indexp(pos)
|
||||||
if data[idx] and param2_data[idx] then
|
node = {
|
||||||
return {
|
name = minetest.get_name_from_content_id(data[idx]),
|
||||||
name = minetest.get_name_from_content_id(data[idx]),
|
param2 = param2_data[idx]
|
||||||
param2 = param2_data[idx]
|
}
|
||||||
}
|
return node
|
||||||
end
|
|
||||||
return {name="ignore", param2=0}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function update1(self, pos, dir)
|
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)
|
tmp, npos = self:get_secondary_node(pos, dir)
|
||||||
end
|
end
|
||||||
if npos then
|
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(npos, Turn180Deg[dir])
|
||||||
self:update_secondary_node(pos, dir)
|
self:update_secondary_node(pos, dir)
|
||||||
end
|
end
|
||||||
|
@ -186,6 +182,7 @@ function Tube:new(attr)
|
||||||
pairingList = {}, -- teleporting nodes
|
pairingList = {}, -- teleporting nodes
|
||||||
connCache = {}, -- connection cache {pos1 = {dir1 = {pos2 = pos2, dir2 = dir2},...}
|
connCache = {}, -- connection cache {pos1 = {dir1 = {pos2 = pos2, dir2 = dir2},...}
|
||||||
special_node_names = {}, -- use add_special_node_names() to register nodes
|
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)
|
o.valid_dirs = Tbl(o.dirs_to_check)
|
||||||
setmetatable(o, self)
|
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 tele_pos = minetest.string_to_pos(oldmetadata.fields.tele_pos)
|
||||||
local peer_meta = M(tele_pos)
|
local peer_meta = M(tele_pos)
|
||||||
if peer_meta then
|
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("channel", nil)
|
||||||
peer_meta:set_string("tele_pos", nil)
|
peer_meta:set_string("tele_pos", nil)
|
||||||
peer_meta:set_string("formspec", sFormspec)
|
peer_meta:set_string("formspec", sFormspec)
|
||||||
|
|
|
@ -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 P = minetest.string_to_pos
|
||||||
local M = minetest.get_meta
|
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
|
-- Test tubes
|
||||||
|
|
||||||
local Tube = tubelib2.Tube:new({
|
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)
|
after_place_tube = function(pos, param2, tube_type, num_tubes, tbl)
|
||||||
minetest.swap_node(pos, {name = "tubelib2:tube"..tube_type, param2 = param2})
|
minetest.swap_node(pos, {name = "tubelib2:tube"..tube_type, param2 = param2})
|
||||||
end,
|
end,
|
||||||
|
debug_info = debug_info,
|
||||||
})
|
})
|
||||||
|
|
||||||
Tube:register_on_tube_update(function(node, pos, out_dir, peer_pos, peer_in_dir)
|
Tube:register_on_tube_update(function(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||||
|
|
|
@ -54,7 +54,7 @@ See [`LICENSE.md`](LICENSE.md) for more information.
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
- `default` (included in [Minetest Game](https://github.com/minetest/minetest_game))
|
- `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
|
## Requirements
|
||||||
|
|
||||||
|
|
4
mods/wine/mod.conf
Normal 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
|
@ -0,0 +1,3 @@
|
||||||
|
name = wool
|
||||||
|
depends = default
|
||||||
|
description = Adds wool blocks into game.
|