VoxeLibre/mods/ENTITIES/mobs_mc/slime+magma_cube.lua

476 lines
12 KiB
Lua
Raw Permalink Normal View History

2017-07-05 03:15:46 +02:00
--License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc")
2017-07-05 03:15:46 +02:00
local MAPBLOCK_SIZE = 16 -- size for slime chunk logic
local SEED_OFFSET = 362 -- module specific seed
local world_seed = (minetest.get_mapgen_setting("seed") + SEED_OFFSET) % 4294967296
-- slime density, where default N=10 is every 10th chunk
local slime_ratio = tonumber(minetest.settings:get("slime_ratio")) or 10
-- use 3D chunking instead of 2d chunks
local slime_3d_chunks = minetest.settings:get_bool("slime_3d_chunks", false)
-- maximum light level, for slimes in caves only, not magma/swamps
local slime_max_light = (tonumber(minetest.settings:get("slime_max_light")) or minetest.LIGHT_MAX) + 1
-- maximum light level for swamp spawning
local swamp_light_max = 7
-- maximum height to spawn in slime chunks
local slime_chunk_spawn_max = mcl_worlds.layer_to_y(40)
2023-03-16 19:04:56 +01:00
local floor = math.floor
local max = math.max
2023-03-16 19:04:56 +01:00
local function is_slime_chunk(pos)
if not pos then return end -- no position given
if slime_ratio == 0 then return end -- no slime chunks
if slime_ratio <= 1 then return true end -- slime everywhere
local bpos = vector.new(floor(pos.x / MAPBLOCK_SIZE), slime_3d_chunks and floor(pos.y / MAPBLOCK_SIZE) or 0, floor(pos.z / MAPBLOCK_SIZE))
return PcgRandom(minetest.hash_node_position(bpos) + world_seed):next(0,1e9)/1e9 * slime_ratio < 1
2023-03-16 22:38:27 +01:00
end
2023-03-16 19:04:56 +01:00
2023-03-16 22:38:27 +01:00
-- Returns a function that spawns children in a circle around pos.
-- To be used as on_die callback.
-- self: mob reference
-- pos: position of "mother" mob
-- child_mod: Mob to spawn
-- spawn_distance: Spawn distance from "mother" mob
-- eject_speed: Initial speed of child mob away from "mother" mob
local spawn_children_on_die = function(child_mob, spawn_distance, eject_speed)
return function(self, pos)
eject_speed = eject_speed or 1
2023-03-16 22:38:27 +01:00
local mndef = minetest.registered_nodes[minetest.get_node(pos).name]
local mother_stuck = mndef and mndef.walkable
local angle = math.random() * math.pi * 2
2023-03-16 22:38:27 +01:00
local children = {}
local spawn_count = math.random(2, 4)
for i = 1, spawn_count do
local dir = vector.new(math.cos(angle), 0, math.sin(angle))
local newpos = pos + dir * spawn_distance
2023-03-16 22:38:27 +01:00
-- If child would end up in a wall, use position of the "mother", unless
-- the "mother" was stuck as well
if not mother_stuck then
local cndef = minetest.registered_nodes[minetest.get_node(newpos).name]
if cndef and cndef.walkable then
newpos = pos
eject_speed = eject_speed * 0.5
end
end
local mob = mcl_mobs.spawn(newpos, child_mob)
if mob then
if not mother_stuck then
mob:set_velocity(dir * eject_speed)
end
mob:set_yaw(angle - math.pi/2)
table.insert(children, mob)
2023-03-16 22:38:27 +01:00
end
angle = angle + (math.pi*2) / spawn_count
end
-- If mother was murdered, children attack the killer after 1 second
if self.state == "attack" then
minetest.after(1.0, function(children, enemy)
local le
for c = 1, #children do
le = children[c]:get_luaentity()
if le then
le.state = "attack"
le.attack = enemy
end
end
end, children, self.attack)
end
end
2023-03-16 19:04:56 +01:00
end
-- two different rules, underground slime chunks and regular swamp spawning
2023-09-21 06:53:32 +02:00
local function slime_spawn_check(pos, environmental_light, artificial_light, sky_light)
if pos.y <= slime_chunk_spawn_max and is_slime_chunk(pos) then
return max(artificial_light, sky_light) <= slime_max_light
2023-09-21 06:53:32 +02:00
end
return max(artificial_light, sky_light) <= swamp_light_max
2023-09-21 06:53:32 +02:00
end
2017-07-05 03:15:46 +02:00
-- Slime
local slime_big = {
description = S("Slime - big"),
2017-07-05 03:15:46 +02:00
type = "monster",
2020-04-11 02:46:03 +02:00
spawn_class = "hostile",
group_attack = { "mobs_mc:slime_big", "mobs_mc:slime_small", "mobs_mc:slime_tiny" },
2017-07-05 03:15:46 +02:00
hp_min = 16,
hp_max = 16,
2020-12-06 15:46:42 +01:00
xp_min = 4,
xp_max = 4,
collisionbox = {-1.02, -0.01, -1.02, 1.02, 2.03, 1.02, rotate = true},
2017-07-05 03:15:46 +02:00
visual_size = {x=12.5, y=12.5},
textures = {{"mobs_mc_slime.png", "mobs_mc_slime.png"}},
2017-07-05 03:15:46 +02:00
visual = "mesh",
mesh = "mobs_mc_slime.b3d",
makes_footstep_sound = true,
sounds = {
jump = "green_slime_jump",
death = "green_slime_death",
damage = "green_slime_damage",
attack = "green_slime_attack",
distance = 16,
},
damage = 4,
reach = 2.5,
2017-07-05 03:15:46 +02:00
armor = 100,
drops = {},
-- TODO: Fix animations
animation = {
jump_speed = 17,
stand_speed = 17,
walk_speed = 17,
jump_start = 1,
jump_end = 20,
stand_start = 1,
stand_end = 20,
walk_start = 1,
walk_end = 20,
2017-07-05 03:15:46 +02:00
},
fall_damage = 0,
view_range = 16,
attack_type = "dogfight",
2017-07-05 03:15:46 +02:00
passive = false,
jump = true,
2023-03-21 22:47:20 +01:00
walk_velocity = 1.9,
run_velocity = 1.9,
2017-07-05 03:15:46 +02:00
walk_chance = 0,
jump_height = 5.2,
2019-03-09 00:54:49 +01:00
fear_height = 0,
spawn_small_alternative = "mobs_mc:slime_small",
on_die = spawn_children_on_die("mobs_mc:slime_small", 1.0, 1.5),
use_texture_alpha = true,
2023-09-21 06:53:32 +02:00
spawn_check = slime_spawn_check,
2017-07-05 03:15:46 +02:00
}
mcl_mobs.register_mob("mobs_mc:slime_big", slime_big)
2017-07-05 03:15:46 +02:00
local slime_small = table.copy(slime_big)
slime_small.description = S("Slime - small")
slime_small.sounds.base_pitch = 1.15
2017-07-05 03:15:46 +02:00
slime_small.hp_min = 4
slime_small.hp_max = 4
2020-12-06 15:46:42 +01:00
slime_small.xp_min = 2
slime_small.xp_max = 2
slime_small.collisionbox = {-0.51, -0.01, -0.51, 0.51, 1.00, 0.51, rotate = true}
2017-07-05 03:15:46 +02:00
slime_small.visual_size = {x=6.25, y=6.25}
slime_small.damage = 3
slime_small.reach = 2.25
2023-03-21 22:47:20 +01:00
slime_small.walk_velocity = 1.8
slime_small.run_velocity = 1.8
2017-07-05 03:15:46 +02:00
slime_small.jump_height = 4.3
slime_small.spawn_small_alternative = "mobs_mc:slime_tiny"
slime_small.on_die = spawn_children_on_die("mobs_mc:slime_tiny", 0.6, 1.0)
mcl_mobs.register_mob("mobs_mc:slime_small", slime_small)
2017-07-05 03:15:46 +02:00
local slime_tiny = table.copy(slime_big)
slime_tiny.description = S("Slime - tiny")
slime_tiny.sounds.base_pitch = 1.3
2017-07-05 03:15:46 +02:00
slime_tiny.hp_min = 1
slime_tiny.hp_max = 1
2020-12-06 15:46:42 +01:00
slime_tiny.xp_min = 1
slime_tiny.xp_max = 1
slime_tiny.collisionbox = {-0.2505, -0.01, -0.2505, 0.2505, 0.50, 0.2505, rotate = true}
2017-07-05 03:15:46 +02:00
slime_tiny.visual_size = {x=3.125, y=3.125}
slime_tiny.damage = 1
slime_tiny.reach = 2
2017-07-05 03:15:46 +02:00
slime_tiny.drops = {
-- slimeball
2022-05-25 23:25:15 +02:00
{name = "mcl_mobitems:slimeball",
2017-07-05 03:15:46 +02:00
chance = 1,
min = 0,
max = 2,},
}
2023-03-21 22:47:20 +01:00
slime_tiny.walk_velocity = 1.7
slime_tiny.run_velocity = 1.7
2017-07-05 03:15:46 +02:00
slime_tiny.jump_height = 3
slime_tiny.spawn_small_alternative = nil
2017-07-05 03:15:46 +02:00
slime_tiny.on_die = nil
mcl_mobs.register_mob("mobs_mc:slime_tiny", slime_tiny)
2017-07-05 03:15:46 +02:00
local water_level = mobs_mc.water_level
local cave_biomes = {
"FlowerForest_underground",
"JungleEdge_underground",
"StoneBeach_underground",
"MesaBryce_underground",
"Mesa_underground",
"RoofedForest_underground",
"Jungle_underground",
"Swampland_underground",
"BirchForest_underground",
"Plains_underground",
"MesaPlateauF_underground",
"ExtremeHills_underground",
"MegaSpruceTaiga_underground",
"BirchForestM_underground",
"SavannaM_underground",
"MesaPlateauFM_underground",
"Desert_underground",
"Savanna_underground",
"Forest_underground",
"SunflowerPlains_underground",
"ColdTaiga_underground",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
"MangroveSwamp_underground"
}
local cave_min = mcl_vars.mg_overworld_min
local cave_max = water_level - 23
local swampy_biomes = {"Swampland", "MangroveSwamp"}
local swamp_min = water_level
local swamp_max = water_level + 27
2017-07-05 03:15:46 +02:00
2022-05-25 14:44:49 +02:00
mcl_mobs:spawn_specific(
2021-04-25 17:30:15 +02:00
"mobs_mc:slime_tiny",
"overworld",
2021-04-08 13:39:18 +02:00
"ground",
cave_biomes,
2021-04-25 17:30:15 +02:00
0,
slime_max_light,
2021-04-25 17:30:15 +02:00
30,
1000,
2021-04-25 17:30:15 +02:00
4,
cave_min,
2023-03-16 19:04:56 +01:00
cave_max,
nil, nil, is_slime_chunk)
2021-04-08 13:39:18 +02:00
mcl_mobs:spawn_specific(
"mobs_mc:slime_tiny",
"overworld",
"ground",
swampy_biomes,
0,
swamp_light_max,
30,
1000,
4,
swamp_min,
swamp_max)
2022-05-25 14:44:49 +02:00
mcl_mobs:spawn_specific(
2021-04-25 17:30:15 +02:00
"mobs_mc:slime_small",
"overworld",
2021-04-08 13:39:18 +02:00
"ground",
cave_biomes,
2021-04-25 17:30:15 +02:00
0,
slime_max_light,
2021-04-25 17:30:15 +02:00
30,
1000,
2021-04-25 17:30:15 +02:00
4,
cave_min,
2023-03-16 19:04:56 +01:00
cave_max,
nil, nil, is_slime_chunk)
2021-04-08 13:39:18 +02:00
mcl_mobs:spawn_specific(
"mobs_mc:slime_small",
"overworld",
"ground",
swampy_biomes,
0,
swamp_light_max,
30,
1000,
4,
swamp_min,
swamp_max)
2022-05-25 14:44:49 +02:00
mcl_mobs:spawn_specific(
2021-04-25 17:30:15 +02:00
"mobs_mc:slime_big",
"overworld",
"ground",
cave_biomes,
2021-04-25 17:30:15 +02:00
0,
slime_max_light,
2021-04-25 17:30:15 +02:00
30,
1000,
2021-04-25 17:30:15 +02:00
4,
cave_min,
2023-03-16 19:04:56 +01:00
cave_max,
nil, nil, is_slime_chunk)
2017-07-05 03:15:46 +02:00
mcl_mobs:spawn_specific(
"mobs_mc:slime_big",
"overworld",
"ground",
swampy_biomes,
0,
swamp_light_max,
30,
1000,
4,
swamp_min,
swamp_max)
2023-03-16 19:04:56 +01:00
2017-07-05 03:15:46 +02:00
-- Magma cube
local magma_cube_big = {
description = S("Magma Cube - big"),
2017-07-05 03:15:46 +02:00
type = "monster",
2020-04-11 02:46:03 +02:00
spawn_class = "hostile",
2017-07-05 03:15:46 +02:00
hp_min = 16,
hp_max = 16,
2020-12-06 15:46:42 +01:00
xp_min = 4,
xp_max = 4,
collisionbox = {-1.02, -0.01, -1.02, 1.02, 2.03, 1.02, rotate = true},
2017-07-05 03:15:46 +02:00
visual_size = {x=12.5, y=12.5},
textures = {{ "mobs_mc_magmacube.png", "mobs_mc_magmacube.png" }},
2017-07-05 03:15:46 +02:00
visual = "mesh",
mesh = "mobs_mc_magmacube.b3d",
makes_footstep_sound = true,
sounds = {
2019-02-01 08:13:45 +01:00
jump = "mobs_mc_magma_cube_big",
death = "mobs_mc_magma_cube_big",
attack = "mobs_mc_magma_cube_attack",
2017-07-05 03:15:46 +02:00
distance = 16,
},
2023-03-21 22:47:20 +01:00
walk_velocity = 2.5,
run_velocity = 2.5,
2017-07-05 03:15:46 +02:00
damage = 6,
reach = 2.35,
armor = 53,
2017-07-05 03:15:46 +02:00
drops = {
2022-05-25 23:25:15 +02:00
{name = "mcl_mobitems:magma_cream",
2017-07-05 03:15:46 +02:00
chance = 4,
min = 1,
max = 1,},
},
-- TODO: Fix animations
animation = {
jump_speed = 20,
stand_speed = 20,
walk_speed = 20,
jump_start = 1,
jump_end = 40,
stand_start = 1,
stand_end = 1,
walk_start = 1,
walk_end = 40,
2017-07-05 03:15:46 +02:00
},
water_damage = 0,
lava_damage = 0,
fire_damage = 0,
2017-07-05 03:15:46 +02:00
light_damage = 0,
fall_damage = 0,
view_range = 16,
attack_type = "dogfight",
2017-07-05 03:15:46 +02:00
passive = false,
jump = true,
jump_height = 8,
walk_chance = 0,
2019-03-09 00:54:49 +01:00
fear_height = 0,
spawn_small_alternative = "mobs_mc:magma_cube_small",
on_die = spawn_children_on_die("mobs_mc:magma_cube_small", 0.8, 1.5),
2021-01-08 14:43:49 +01:00
fire_resistant = true,
2017-07-05 03:15:46 +02:00
}
mcl_mobs.register_mob("mobs_mc:magma_cube_big", magma_cube_big)
2017-07-05 03:15:46 +02:00
local magma_cube_small = table.copy(magma_cube_big)
magma_cube_small.description = S("Magma Cube - small")
2019-02-01 08:13:45 +01:00
magma_cube_small.sounds.jump = "mobs_mc_magma_cube_small"
magma_cube_small.sounds.death = "mobs_mc_magma_cube_small"
2017-07-05 03:15:46 +02:00
magma_cube_small.hp_min = 4
magma_cube_small.hp_max = 4
2020-12-06 15:46:42 +01:00
magma_cube_small.xp_min = 2
magma_cube_small.xp_max = 2
magma_cube_small.collisionbox = {-0.51, -0.01, -0.51, 0.51, 1.00, 0.51, rotate = true}
2017-07-05 03:15:46 +02:00
magma_cube_small.visual_size = {x=6.25, y=6.25}
magma_cube_small.damage = 3
magma_cube_small.reach = 2.1
2017-07-05 03:15:46 +02:00
magma_cube_small.walk_velocity = .8
2023-03-21 22:47:20 +01:00
magma_cube_small.run_velocity = 2.0
2017-07-05 03:15:46 +02:00
magma_cube_small.jump_height = 6
magma_cube_small.damage = 4
magma_cube_small.reach = 2.75
magma_cube_small.armor = 66
magma_cube_small.spawn_small_alternative = "mobs_mc:magma_cube_tiny"
magma_cube_small.on_die = spawn_children_on_die("mobs_mc:magma_cube_tiny", 0.6, 1.0)
mcl_mobs.register_mob("mobs_mc:magma_cube_small", magma_cube_small)
2017-07-05 03:15:46 +02:00
local magma_cube_tiny = table.copy(magma_cube_big)
magma_cube_tiny.description = S("Magma Cube - tiny")
2019-02-01 08:13:45 +01:00
magma_cube_tiny.sounds.jump = "mobs_mc_magma_cube_small"
magma_cube_tiny.sounds.death = "mobs_mc_magma_cube_small"
magma_cube_tiny.sounds.base_pitch = 1.25
2017-07-05 03:15:46 +02:00
magma_cube_tiny.hp_min = 1
magma_cube_tiny.hp_max = 1
2020-12-06 15:46:42 +01:00
magma_cube_tiny.xp_min = 1
magma_cube_tiny.xp_max = 1
magma_cube_tiny.collisionbox = {-0.2505, -0.01, -0.2505, 0.2505, 0.50, 0.2505, rotate = true}
2017-07-05 03:15:46 +02:00
magma_cube_tiny.visual_size = {x=3.125, y=3.125}
magma_cube_tiny.walk_velocity = 1.02
magma_cube_tiny.run_velocity = 1.02
magma_cube_tiny.jump_height = 4
magma_cube_tiny.damage = 3
magma_cube_tiny.reach = 2
magma_cube_tiny.armor = 50
2017-07-05 03:15:46 +02:00
magma_cube_tiny.drops = {}
magma_cube_tiny.spawn_small_alternative = nil
2017-07-05 03:15:46 +02:00
magma_cube_tiny.on_die = nil
mcl_mobs.register_mob("mobs_mc:magma_cube_tiny", magma_cube_tiny)
2017-07-05 03:15:46 +02:00
local magma_cube_biomes = {"Nether", "BasaltDelta"}
local nether_min = mcl_vars.mg_nether_min
local nether_max = mcl_vars.mg_nether_max
2022-05-25 14:44:49 +02:00
mcl_mobs:spawn_specific(
2021-04-25 17:30:15 +02:00
"mobs_mc:magma_cube_tiny",
"nether",
2021-04-08 13:39:18 +02:00
"ground",
magma_cube_biomes,
2021-04-25 17:30:15 +02:00
0,
minetest.LIGHT_MAX+1,
30,
100,
2021-04-25 17:30:15 +02:00
4,
nether_min,
nether_max)
2021-04-08 13:39:18 +02:00
2022-05-25 14:44:49 +02:00
mcl_mobs:spawn_specific(
2021-04-25 17:30:15 +02:00
"mobs_mc:magma_cube_small",
"nether",
2021-04-08 13:39:18 +02:00
"ground",
magma_cube_biomes,
2021-04-25 17:30:15 +02:00
0,
minetest.LIGHT_MAX+1,
30,
100,
2021-04-25 17:30:15 +02:00
4,
nether_min,
nether_max)
2021-04-08 13:39:18 +02:00
2022-05-25 14:44:49 +02:00
mcl_mobs:spawn_specific(
2021-04-25 17:30:15 +02:00
"mobs_mc:magma_cube_big",
"nether",
2021-04-08 13:39:18 +02:00
"ground",
magma_cube_biomes,
2021-04-25 17:30:15 +02:00
0,
minetest.LIGHT_MAX+1,
30,
100,
2021-04-25 17:30:15 +02:00
4,
nether_min,
nether_max)
2017-07-05 03:15:46 +02:00
-- spawn eggs
mcl_mobs.register_egg("mobs_mc:magma_cube_big", S("Magma Cube"), "#350000", "#fcfc00")
-- non_spawn_specific is typically for mobs who don't spawn in the overworld, or mobs that don't spawn
-- naturally. However, slimes are a particular case where they spawn under different conditions in the same
-- dimension.
mcl_mobs:non_spawn_specific("mobs_mc:slime_big","overworld",0,minetest.LIGHT_MAX+1)
mcl_mobs:non_spawn_specific("mobs_mc:magma_cube_big","overworld",0, minetest.LIGHT_MAX+1)
mcl_mobs.register_egg("mobs_mc:slime_big", S("Slime"), "#52a03e", "#7ebf6d")
-- FIXME: add spawn eggs for small and tiny slimes and magma cubes