Noch mehr mods

This commit is contained in:
N-Nachtigal 2025-05-18 04:02:23 +02:00
parent a063db5d3b
commit cf017b2ca1
527 changed files with 21113 additions and 181 deletions

46
mods/sum_airship/.gitignore vendored Normal file
View file

@ -0,0 +1,46 @@
*.blend1
*.blend
# ---> Lua
# Compiled Lua sources
luac.out
# luarocks build files
*.src.rock
*.zip
*.tar.gz
# Object files
*.o
*.os
*.ko
*.obj
*.elf
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
*.def
*.exp
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex

26
mods/sum_airship/.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,26 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Debug Lua Interpreter",
"type": "lua-local",
"request": "launch",
"program": {
"lua": "lua",
"file": "${file}"
}
},
{
"name": "Debug Custom Lua Environment",
"type": "lua-local",
"request": "launch",
"program": {
"command": "command"
},
"args": []
}
]
}

View file

@ -0,0 +1,42 @@
[![ContentDB](https://content.luanti.org/packages/Sumianvoice/sum_airship/shields/downloads/)]
# sum_airship
Mod for [Luanti](https://luanti.org). You can download it from the in-game content manager, or [ContentDB](https://content.luanti.org/packages/Sumianvoice/sum_airship/).
This mod adds an airship to Minetest. It should work in most games, but only Minetest Game, MineClone (VoxeLibre) and RePixture are supported for crafting recipes. Games based on those may still have crafting if they use the same items. Other games are not because the mod doesn't know what each game calls each item or node. Although, it shouldn't crash no matter what game you use, this is only for crafting recipes.
**Controls:** Flies like a boat, WSAD controls with the addition of jump for up, sneak for down, and aux1 (sprint) to dismount. Does not require fuel but will go faster when given any type of coal.
### Crafting
#### MineClon\* (VoxeLibre)
All items: wool: 27, string: 4, wood: 15, iron_ingot: 4
9 Wool -> Canvas
3 Boats & 3 Iron Ingots -> Hull
3 Canvas, 1 Hull, 4 String & 1 Iron ingot -> Airship
![MCL crafting.gif](crafting_mcl.gif)
#### Minetest Game
All items: wool: 27, string: 4, wood: 15, iron_ingot: 4
9 Wool -> Canvas
3 Boats & 3 Iron Ingots -> Hull
3 Canvas, 1 Hull, 4 String & 1 Iron ingot -> Airship
![MTG crafting.gif](crafting_mtg.gif)
#### RePixture
All items: wool: 27, fiber: 8, wood: varies depending on boat type, steel_ingot: 4
9 group:fuzzy (wool or cotton bale) -> Canvas
3 Boats & 3 Steel Ingots -> Hull
3 Canvas, 1 Hull, 8 Fiber, 1 Steel Ingot -> Airship
![RePixture crafting.gif](crafting_rp.gif)
### Air Currents
This optionally uses [sum_air_currents](https://content.luanti.org/packages/Sumianvoice/sum_air_currents/) to apply force based on the weather.

View file

@ -0,0 +1,440 @@
local mod_name = minetest.get_current_modname()
local mod_path = minetest.get_modpath(mod_name)
local me = {
lift = 4,
speed = 4,
fuel_time = 10,
speed_mult = 4,
i = {},
}
local ship = {
initial_properties = {
physical = true,
pointable = true,
collisionbox = {-0.6, -0.2, -0.6, 0.6, 0.4, 0.6},
selectionbox = {-0.7, -0.35, -0.7, 0.7, 0.4, 0.7},
hp_max = 3,
visual = "mesh",
backface_culling = true,
mesh = "sum_airship.b3d",
textures = {"sum_airship_texture.png"},
},
_animations = {
idle = {x= 10, y= 90},
fly = {x= 91, y= 170},
boost = {x= 91, y= 170},
},
_driver = nil,
_removed = false,
_flags = {},
_itemstring = "sum_airship:boat",
_passenger = nil,
_vel = 0,
_regen_timer = 0,
_fuel = 0,
}
local sounds = {
engine_idle = {
sound_name = "sum_airship_lip_trill",
gain = 1.4,
max_hear_distance = 10,
loop = false,
pitch = 0.75,
},
engine_stop = {
sound_name = "sum_airship_lip_trill_end",
gain = 2.2,
max_hear_distance = 10,
loop = false,
pitch = 1,
},
engine_boost = {
sound_name = "sum_airship_lip_trill",
gain = 40,
max_hear_distance = 10,
loop = false,
pitch = 1,
},
}
function me.sound_play(self, sound_obj, sound_instance)
sound_instance.handle = minetest.sound_play(sound_obj.sound_name, {
gain = sound_obj.gain,
max_hear_distance = sound_obj.max_hear_distance,
loop = sound_obj.loop,
pitch = sound_obj.pitch,
object = self.object,
})
sound_instance.playing = true
sound_instance.time_elapsed = 0
end
function me.sound_stop(sound_instance)
if sound_instance.handle then
minetest.sound_stop(sound_instance.handle)
end
sound_instance.playing = false
sound_instance.time_elapsed = 0
sound_instance.handle = nil
end
function me.sound_countdown(self, dtime)
for _, sound in pairs(self._sounds) do
if sound.playing then
sound.time_elapsed = sound.time_elapsed + dtime
end
end
end
function me.update_sound(self, dtime, forward)
me.sound_countdown(self, dtime)
local is_thrust = (forward ~= 0) and self._driver
if self._sounds.engine.time_elapsed > 2.1
and self._sounds.engine.handle
and self._sounds.engine.playing then
me.sound_stop(self._sounds.engine)
end
if not self._sounds.engine.playing then
if self._fuel > 1 then
me.sound_play(self, sounds.engine_boost, self._sounds.engine)
elseif is_thrust then
me.sound_play(self, sounds.engine_idle, self._sounds.engine)
end
if self._fuel > 1 and self._sounds.engine_stop.playing then
me.sound_stop(self._sounds.engine_stop)
end
end
if self._fuel <= 1 and self._sounds.engine.playing then
if self._fuel > 0 and not self._sounds.engine_stop.playing
and self._sounds.engine_stop.time_elapsed == 0 then
me.sound_play(self, sounds.engine_stop, self._sounds.engine_stop)
end
if not is_thrust
or (self._sounds.engine_stop.time_elapsed == 0
and self._sounds.engine_stop.playing) then
me.sound_stop(self._sounds.engine)
end
end
end
function ship.on_activate(self, staticdata, dtime_s)
local data = minetest.deserialize(staticdata)
if type(data) == "table" then
self._vel = data.v
self._itemstring = data.itemstring
self._fuel = data.fuel
self._flags = data._flags
end
self.object:set_armor_groups({
pierce=100,
slash=100,
blunt=100,
magic=100,
poison=100,
fleshy=100,
})
self.object:set_animation(ship._animations.idle, 24)
self._sounds = { -- workaround for copy vs reference issue
engine = {
handle = nil,
gain = 0.1,
playing = false,
time_elapsed = 0,
},
engine_stop = {
handle = nil,
gain = 0.1,
playing = false,
time_elapsed = 0,
},
}
end
function ship.get_staticdata(self)
return minetest.serialize({
itemstring = self._itemstring,
_flags = self._flags,
v = self._vel,
fuel = self._fuel,
})
end
function me.attach(self, player)
if not (player and player:is_player()) then
return false
end
self._driver = player
self._driver:set_attach(self.object, "",
{x = 0, y = -0.0, z = -2}, {x = 0, y = 0, z = 0})
self._driver:set_look_horizontal(self.object:get_yaw())
end
function me.detach(self)
if not self._driver then return false end
self._driver:set_detach()
self._driver = nil
return true
end
function ship.on_death(self, killer)
if killer and killer:is_player()
and not minetest.is_creative_enabled(killer:get_player_name()) then
local inv = killer:get_inventory()
inv:add_item("main", self._itemstring)
else
minetest.add_item(self.object:get_pos(), self._itemstring)
end
me.detach(self)
self._driver = nil
end
function ship.on_rightclick(self, clicker)
local item = clicker:get_wielded_item()
local item_name = item:get_name()
if clicker and (item and item_name)
and (string.find(item_name, ":coal")
or string.find(item_name, ":charcoal")) then
if not minetest.is_creative_enabled(clicker:get_player_name()) then
item:take_item()
clicker:set_wielded_item(item)
end
self._fuel = self._fuel + me.fuel_time
me.sound_stop(self._sounds.engine)
minetest.sound_play("sum_airship_fire", {
gain = 1,
object = self.object,
})
else
me.attach(self, clicker)
end
end
-- 10, 5, 5
-- this system ensures collision kind of works with balloons.
-- does not include entity to entity collisions
local balloon = {}
balloon.offset = 6
balloon.length = 3.5
balloon.height = 2.5
local balloon_nodes = {}
balloon_nodes[0] = { -- top
p = vector.new(0, balloon.offset + balloon.height, 0),
dir = vector.new(0, -5, 0),}
balloon_nodes[1] = { -- front
p = vector.new(0, balloon.offset, balloon.length),
dir = vector.new(0, -0.5, -1),}
balloon_nodes[2] = { -- back
p = vector.new(0, balloon.offset, -balloon.length),
dir = vector.new(0, 0, 1),}
balloon_nodes[3] = { -- left or right
p = vector.new(balloon.length, balloon.offset, 0),
dir = vector.new(-1, 0, 0),}
balloon_nodes[4] = { -- left or right
p = vector.new(-balloon.length, balloon.offset, 0),
dir = vector.new(1, 0, 0),}
-- diagonals
local vdiag = 0.7
balloon_nodes[5] = {
p = vector.new(-balloon.length*vdiag, balloon.offset, -balloon.length*vdiag),
dir = vector.new(vdiag, 0, vdiag),}
balloon_nodes[6] = {
p = vector.new(balloon.length*vdiag, balloon.offset, -balloon.length*vdiag),
dir = vector.new(-vdiag, 0, vdiag),}
balloon_nodes[7] = {
p = vector.new(-balloon.length*vdiag, balloon.offset, balloon.length*vdiag),
dir = vector.new(vdiag, 0, -vdiag),}
balloon_nodes[8] = {
p = vector.new(balloon.length*vdiag, balloon.offset, balloon.length*vdiag),
dir = vector.new(-vdiag, 0, -vdiag),}
function me.get_balloon_collide(self)
local force = vector.new()
local o = self.object:get_pos()
for _, check in pairs(balloon_nodes) do
local n = minetest.get_node(vector.add(check.p, o))
if n and minetest.registered_nodes[n.name]
and (minetest.registered_nodes[n.name] or {}).walkable then
force = vector.add(force, check.dir)
end
end
return force
end
me.chimney_dist = -0.8
me.chimney_yaw = 0.13
me.chimney_height = 1.5
function me.get_chimney_pos(self)
local p = self.object:get_pos()
local yaw = self.object:get_yaw()
local ret = {
x = p.x + (me.chimney_dist * math.sin(-yaw + me.chimney_yaw)),
y = p.y + me.chimney_height,
z = p.z + (me.chimney_dist * math.cos(-yaw + me.chimney_yaw))}
return ret
end
function ship.on_step(self, dtime, moveresult)
local exit = false
local pi = nil
-- allow to exit
if self._driver and self._driver:is_player() then
local name = self._driver:get_player_name()
pi = self._driver:get_player_control()
exit = pi.aux1
end
if exit then
me.detach(self)
return false
end
local climb = 0
local right = 0
local forward = 0
local v = self.object:get_velocity()
local p = self.object:get_pos()
local node_below = minetest.get_node(vector.offset(p, 0, -0.8, 0)).name
local is_on_floor = (minetest.registered_nodes[node_below] or {}).walkable
local in_water = minetest.get_item_group(minetest.get_node(p).name, "liquid") ~= 0
local on_water = (minetest.get_item_group(minetest.get_node(vector.offset(p, 0, -0.2, 0)).name, "liquid") ~= 0 and not in_water)
local speedboost = 1
if self._fuel > 0 then
self._fuel = self._fuel - dtime
speedboost = 3
end
if pi then
if pi.up then forward = 1
elseif pi.down then forward = -1 end
if pi.jump then climb = 1
elseif pi.sneak then climb = -1 end
if pi.right then right = 1
elseif pi.left then right = -1 end
local yaw = self.object:get_yaw()
local dir = minetest.yaw_to_dir(yaw)
self.object:set_yaw(yaw - right * dtime)
local added_vel = vector.multiply(dir, forward * dtime * me.speed * speedboost)
added_vel.y = added_vel.y + (climb * dtime * me.lift)
v = vector.add(v, added_vel)
end
if self._driver then
local collide_force = me.get_balloon_collide(self)
if collide_force ~= vector.new() then
collide_force = vector.multiply(collide_force, 0.1)
v = vector.multiply(v, 0.95)
end
v = vector.add(v, collide_force)
end
if not self._driver then
v.y = v.y - dtime
end
if minetest.get_modpath("sum_air_currents") then
if self._driver or not is_on_floor then
local wind_vel = sum_air_currents.get_wind(p)
wind_vel = vector.multiply(wind_vel, dtime)
v = vector.add(wind_vel, v)
end
end
if in_water then
v.y = 1
elseif on_water and not self._driver then
v.y = 0
end
if (not self._driver) and is_on_floor then
v.x = v.x * 0.8
v.y = v.y * 0.95
v.z = v.z * 0.8
else
v.x = v.x * (0.98)
v.y = v.y * (0.98)
v.z = v.z * (0.98)
end
local wind_vel = vector.new(0,0,0)
if minetest.get_modpath("sum_air_currents") ~= nil then
wind_vel = sum_air_currents.get_wind(p)
if self._driver or not is_on_floor then
v = vector.add(wind_vel, v)
end
end
self.object:set_velocity(v)
me.update_sound(self, dtime, forward)
local is_thrust = self._driver and forward ~= 0
local chimney_pos = me.get_chimney_pos(self)
local spread = 0.06
if self._fuel > 0 or (math.random(0,100) > 80 and is_thrust) or math.random(0,100) > 95 then
minetest.add_particle({
pos = vector.offset(chimney_pos, math.random(-1, 1)*spread, 0, math.random(-1, 1)*spread),
velocity = vector.add(wind_vel, {x=0, y=math.random(0.2*100,0.7*100)/100, z=0}),
expirationtime = math.random(0.5, 2),
size = math.random(0.1, 4),
collisiondetection = false,
vertical = false,
texture = "sum_airship_smoke.png",
})
end
-- animations
if self._fuel > 0 then
self.object:set_animation(self._animations.boost, 25)
elseif is_thrust then
self.object:set_animation(self._animations.fly, 25)
else
self.object:set_animation(self._animations.idle, 25)
end
end
minetest.register_entity("sum_airship:boat", ship)
minetest.register_craftitem("sum_airship:boat", {
description = "Airship",
inventory_image = "sum_airship.png",
groups = { vehicle = 1, airship = 1, transport = 1},
on_place = function(itemstack, placer, pointed_thing)
if pointed_thing.type ~= "node" then
return itemstack
end
local node = minetest.get_node(pointed_thing.under)
if placer and not placer:get_player_control().sneak then
local def = minetest.registered_nodes[node.name]
if def and def.on_rightclick then
return def.on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack
end
end
local pos = vector.offset(pointed_thing.above, 0, 0, 0)
local self = minetest.add_entity(pos, "sum_airship:boat"):get_luaentity()
if not minetest.is_creative_enabled(placer:get_player_name()) then
itemstack:take_item()
end
return itemstack
end,
})
-- Support SilverSandstone's subtitles mod:
if minetest.get_modpath("subtitles") then
subtitles.register_description('sum_airship_lip_trill', 'Engine purring');
subtitles.register_description('sum_airship_lip_trill_end', 'Engine sputtering');
subtitles.register_description('sum_airship_fire', 'Engine stoked');
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View file

@ -0,0 +1,28 @@
local w = "group:wool"
local b = "group:boat"
local m = "mcl_core:iron_ingot"
local s = "mcl_mobitems:string"
minetest.register_craft({
output = "sum_airship:canvas_roll",
recipe = {
{w, w, w},
{w, w, w},
{w, w, w},
},
})
minetest.register_craft({
output = "sum_airship:hull",
recipe = {
{b, b, b},
{m, m, m},
},
})
minetest.register_craft({
output = "sum_airship:boat",
recipe = {
{"sum_airship:canvas_roll","sum_airship:canvas_roll","sum_airship:canvas_roll",},
{s, m, s,},
{s, "sum_airship:hull", s,},
},
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View file

@ -0,0 +1,29 @@
local w = "group:wool"
if not minetest.get_modpath("farming") then w = "default:paper" end
local b = "boats:boat"
local m = "default:steel_ingot"
local s = "farming:string"
minetest.register_craft({
output = "sum_airship:canvas_roll",
recipe = {
{w, w, w},
{w, w, w},
{w, w, w},
},
})
minetest.register_craft({
output = "sum_airship:hull",
recipe = {
{b, b, b},
{m, m, m},
},
})
minetest.register_craft({
output = "sum_airship:boat",
recipe = {
{"sum_airship:canvas_roll","sum_airship:canvas_roll","sum_airship:canvas_roll",},
{s, m, s,},
{s, "sum_airship:hull", s,},
},
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -0,0 +1,23 @@
crafting.register_craft({
output = "sum_airship:canvas_roll",
items = {
"group:fuzzy 9"
}
})
crafting.register_craft({
output = "sum_airship:hull",
items = {
"group:boat 3",
"rp_default:ingot_steel 3"
}
})
crafting.register_craft({
output = "sum_airship:boat",
items = {
"sum_airship:canvas_roll 3",
"rp_default:ingot_steel 8",
"rp_default:ingot_steel",
"sum_airship:hull",
}
})

View file

@ -0,0 +1,33 @@
local mod_name = minetest.get_current_modname()
local mod_path = minetest.get_modpath(mod_name)
local S = minetest.get_translator(minetest.get_current_modname())
minetest.register_craftitem("sum_airship:canvas_roll", {
description = S("Canvas Roll"),
_doc_items_longdesc = S("Used in crafting airships."),
inventory_image = "sum_airship_canvas.png",
stack_max = 64,
groups = { craftitem = 1 },
})
minetest.register_craftitem("sum_airship:hull", {
description = S("Airship Hull"),
_doc_items_longdesc = S("Used in crafting airships."),
inventory_image = "sum_airship_hull.png",
stack_max = 1,
groups = { craftitem = 1 },
})
if minetest.get_modpath("mcl_boats")
and minetest.get_modpath("mcl_wool")
and minetest.get_modpath("mcl_core")
and minetest.get_modpath("mcl_mobitems") then
dofile(mod_path .. "/crafting_mcl.lua")
elseif (minetest.get_modpath("rp_farming")
or minetest.get_modpath("rp_mobs_mobs"))
and minetest.get_modpath("rp_default")
and minetest.get_modpath("rp_crafting") then
dofile(mod_path .. "/crafting_rp.lua")
elseif minetest.get_modpath("default") then
dofile(mod_path .. "/crafting_mtg.lua")
end

View file

@ -0,0 +1,5 @@
local mod_name = minetest.get_current_modname()
local mod_path = minetest.get_modpath(mod_name)
dofile(mod_path .. DIR_DELIM .. "balloon.lua")
dofile(mod_path .. DIR_DELIM .. "crafts.lua")

View file

@ -0,0 +1,23 @@
Media contained within is under CC-BY-4.0. https://creativecommons.org/licenses/by/4.0/
MIT License
Copyright (c) 2022 Sumi (info@sumianvoice.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,7 @@
name = sum_airship
title = Airship (sum)
author = Sumianvoice
description = Adds a simple airship to Minetest Game, MineClone (VoxeLibre) and RePixture.
optional_depends = default, mcl_core, mcl_wool, mcl_mobitems, mcl_player, rp_crafting, rp_default
release = 30601

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 684 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 770 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB