Improve variations logic. Add sand zombie
parent
4bdd5a33e7
commit
eddaeda1f5
281
init.lua
281
init.lua
|
@ -53,7 +53,9 @@ mobs:register_mob("natspawner:zombie", {
|
|||
if self.spawn and self.spawn.pos then
|
||||
local meta = minetest.get_meta(self.spawn.pos)
|
||||
meta:set_int("entity_killed_count", meta:get_int("entity_killed_count") + 1)
|
||||
if self.variation then meta:set_int("spawned_variation_count", 0) end
|
||||
if self.variation then
|
||||
meta:set_int("spawned_variation_count", meta:get_int("spawned_variation_count") - 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
|
@ -66,11 +68,12 @@ local function spawn(pos, force)
|
|||
if spawner_name then
|
||||
local spawner = spawners[spawner_name]
|
||||
local replacement_node_name = meta:get_string("replaced_node_name")
|
||||
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
local interval = math.random(spawner.min_spawn_interval, spawner.max_spawn_interval)
|
||||
|
||||
-- Check for players nearby
|
||||
local objects = minetest.get_objects_inside_radius(pos, spawner.min_player_distance)
|
||||
local objects = minetest.get_objects_inside_radius(pos, 25)
|
||||
|
||||
--local entity_spawn_count = meta:get_int("entity_spawn_count")
|
||||
|
||||
|
@ -91,82 +94,142 @@ local function spawn(pos, force)
|
|||
end
|
||||
end
|
||||
|
||||
-- Check for amount nearby
|
||||
if force or (entity_count <= spawner.max_mob_count) then
|
||||
-- Spawn
|
||||
local spawn_pos = {x=pos.x + math.random(0, spawner.spawn_radius), y=pos.y+3, z=pos.z + math.random(0, spawner.spawn_radius)}
|
||||
-- Check spawn position - if not air, then spawn just above the spawner
|
||||
local spawn_node = minetest.get_node_or_nil(spawn_pos)
|
||||
if spawn_node and spawn_node.name ~= "air" then
|
||||
spawn_pos = pos
|
||||
if replacement_node_name and replacement_node_name ~= "" then
|
||||
local max_mob_count = spawner.max_mob_count
|
||||
-- Force variations only
|
||||
local force_variation = false
|
||||
minetest.log("Spawner data: "..dump(spawners[spawner_name].replacement_nodes[replacement_node_name]))
|
||||
if spawners[spawner_name].replacement_nodes[replacement_node_name].variations_only == true then
|
||||
force_variation = true
|
||||
end
|
||||
minetest.log("Spawning "..spawner.entity_name.." at pos "..minetest.pos_to_string(spawn_pos))
|
||||
local entity = minetest.add_entity(spawn_pos, spawner.entity_name)
|
||||
if entity then
|
||||
entity:get_luaentity().entity_name = spawner.entity_name
|
||||
entity:get_luaentity().spawn = {
|
||||
pos = pos
|
||||
}
|
||||
|
||||
if force_variation
|
||||
and spawners[spawner_name].replacement_nodes[replacement_node_name].max_count then
|
||||
max_mob_count = spawners[spawner_name].replacement_nodes[replacement_node_name].max_count
|
||||
minetest.log("The max count: "..dump(max_mob_count))
|
||||
entity_count = meta:get_int("spawned_variation_count")
|
||||
end
|
||||
|
||||
minetest.log("Entity count: "..dump(entity_count))
|
||||
minetest.log("Max mob count: "..dump(max_mob_count))
|
||||
minetest.log("Force: "..dump(force))
|
||||
|
||||
-- Check for amount nearby
|
||||
if force or (entity_count <= max_mob_count) then
|
||||
-- Spawn
|
||||
local spawn_pos = {x=pos.x + math.random(0, spawner.spawn_radius), y=pos.y+3, z=pos.z + math.random(0, spawner.spawn_radius)}
|
||||
-- Check spawn position - if not air, then spawn just above the spawner
|
||||
local spawn_node = minetest.get_node_or_nil(spawn_pos)
|
||||
if spawn_node and spawn_node.name ~= "air" then
|
||||
spawn_pos = pos
|
||||
end
|
||||
minetest.log("Spawning "..spawner.entity_name.." at pos "..minetest.pos_to_string(spawn_pos))
|
||||
local entity = minetest.add_entity(spawn_pos, spawner.entity_name)
|
||||
if entity then
|
||||
entity:get_luaentity().entity_name = spawner.entity_name
|
||||
entity:get_luaentity().spawn = {
|
||||
pos = pos
|
||||
}
|
||||
|
||||
-- Set textures if requested
|
||||
minetest.log(replacement_node_name)
|
||||
if replacement_node_name and replacement_node_name ~= "" then
|
||||
if spawners[spawner_name].replacement_nodes[replacement_node_name].textures then
|
||||
entity:set_properties({
|
||||
textures = spawners[spawner_name].replacement_nodes[replacement_node_name].textures
|
||||
})
|
||||
local max_variation_count = meta:get_int("max_variation_count")
|
||||
local spawned_variation_count = meta:get_int("spawned_variation_count")
|
||||
|
||||
-- Spawn a variation with 30% chance
|
||||
local variation_chance = math.random(1, 10)
|
||||
local variations = spawners[spawner_name].replacement_nodes[replacement_node_name].variations
|
||||
|
||||
minetest.log("")
|
||||
|
||||
if (variations
|
||||
and spawned_variation_count < max_variation_count
|
||||
and variation_chance > 7) or force_variation == true then
|
||||
|
||||
-- Choose a variation
|
||||
local index = math.random(1, #variations)
|
||||
if spawners[spawner_name].variations.data[variations[index]] ~= nil then
|
||||
local registered_variation = spawners[spawner_name].variations.data[variations[index]]
|
||||
|
||||
minetest.log("Spawning variation "..dump(variations[index]))
|
||||
|
||||
entity:get_luaentity().variation = true
|
||||
-- Velocity
|
||||
if registered_variation.walk_velocity then
|
||||
entity:get_luaentity().walk_velocity =
|
||||
registered_variation.walk_velocity
|
||||
end
|
||||
|
||||
if registered_variation.run_velocity then
|
||||
entity:get_luaentity().run_velocity =
|
||||
registered_variation.run_velocity
|
||||
end
|
||||
|
||||
-- View range
|
||||
if registered_variation.view_range then
|
||||
entity:get_luaentity().view_range =
|
||||
registered_variation.view_range
|
||||
end
|
||||
|
||||
-- HP
|
||||
if registered_variation.hp_min and registered_variation.hp_max then
|
||||
local hp =
|
||||
math.random(registered_variation.hp_min, registered_variation.hp_max)
|
||||
entity:get_luaentity().hp_max = hp
|
||||
entity:get_luaentity().health = hp
|
||||
entity:get_luaentity().old_health = hp
|
||||
end
|
||||
|
||||
-- Damage
|
||||
if registered_variation.damage then
|
||||
entity:get_luaentity().damage = registered_variation.damage
|
||||
end
|
||||
|
||||
if registered_variation.reach then
|
||||
entity:get_luaentity().reach = registered_variation.reach
|
||||
end
|
||||
|
||||
-- Armor
|
||||
if registered_variation.armor then
|
||||
entity:set_armor_groups({immortal = 1, fleshy = registered_variation.armor})
|
||||
end
|
||||
|
||||
if registered_variation.knock_back then
|
||||
entity:get_luaentity().knock_back = registered_variation.knock_back
|
||||
end
|
||||
|
||||
if registered_variation.visual_size then
|
||||
-- Size properties
|
||||
entity:set_properties({
|
||||
visual_size = registered_variation.visual_size,
|
||||
collisionbox = registered_variation.collisionbox,
|
||||
stepheight = registered_variation.stepheight
|
||||
})
|
||||
end
|
||||
|
||||
-- Textures
|
||||
if registered_variation.textures then
|
||||
entity:set_properties({
|
||||
textures = registered_variation.textures
|
||||
})
|
||||
end
|
||||
|
||||
-- Increase variation count
|
||||
meta:set_int("spawned_variation_count", meta:get_int("spawned_variation_count") + 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Spawn a variation with 30% chance
|
||||
local variation_chance = math.random(1, 10)
|
||||
if variation_chance > 7
|
||||
and meta:get_int("spawned_variation_count") == 0
|
||||
and spawners[spawner_name].variations then
|
||||
|
||||
-- Choose a variation
|
||||
local variations = spawners[spawner_name].variations
|
||||
local index = math.random(1, #variations)
|
||||
|
||||
entity:get_luaentity().variation = true
|
||||
-- Velocity
|
||||
entity:get_luaentity().walk_velocity = variations[index].walk_velocity
|
||||
entity:get_luaentity().run_velocity = variations[index].run_velocity
|
||||
-- View range
|
||||
entity:get_luaentity().view_range = variations[index].view_range
|
||||
-- HP
|
||||
local hp = math.random(variations[index].hp_min, variations[index].hp_max)
|
||||
entity:get_luaentity().hp_max = hp
|
||||
entity:get_luaentity().health = hp
|
||||
entity:get_luaentity().old_health = hp
|
||||
-- Damage
|
||||
entity:get_luaentity().damage = variations[index].damage
|
||||
entity:get_luaentity().reach = variations[index].reach
|
||||
-- Armor
|
||||
entity:set_armor_groups({immortal = 1, fleshy = variations[index].armor})
|
||||
entity:get_luaentity().knock_back = variations[index].knock_back
|
||||
-- Other properties
|
||||
entity:set_properties({
|
||||
visual_size = variations[index].visual_size,
|
||||
collisionbox = variations[index].collisionbox,
|
||||
stepheight = variations[index].stepheight
|
||||
})
|
||||
-- Increase variation count
|
||||
meta:set_int("spawned_variation_count", meta:get_int("spawned_variation_count") + 1)
|
||||
|
||||
end
|
||||
minetest.log("Spawned variation count: "..meta:get_int("spawned_variation_count"))
|
||||
minetest.log("Next spawning scheduled in "..interval.." seconds")
|
||||
|
||||
else
|
||||
minetest.log("Max spawn limit reached")
|
||||
-- Re-calulate interval using deactivation times
|
||||
interval = math.random(spawner.min_deactivation_time, spawner.max_deactivation_time)
|
||||
minetest.log("Deactivating spawner for "..interval.." seconds")
|
||||
end
|
||||
else
|
||||
minetest.log("Max spawn limit reached")
|
||||
-- Re-calulate interval using deactivation times
|
||||
interval = math.random(spawner.min_deactivation_time, spawner.max_deactivation_time)
|
||||
minetest.log("Deactivating spawner for "..interval.." seconds")
|
||||
end
|
||||
|
||||
-- Re-schedule
|
||||
timer:start(interval)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -174,7 +237,9 @@ natspawner.register_spawner = function(spawner_name, def)
|
|||
|
||||
spawners[spawner_name] = {
|
||||
entity_name = def.entity_name,
|
||||
variations = def.entity_variations,
|
||||
variations = {
|
||||
data = def.entity_variations
|
||||
},
|
||||
replacement_nodes = def.node_replacement_map,
|
||||
min_player_distance = def.min_player_distance or 10,
|
||||
max_spawn_interval = def.max_spawn_interval or 300, --300
|
||||
|
@ -184,7 +249,7 @@ natspawner.register_spawner = function(spawner_name, def)
|
|||
max_kill_count = def.max_kill_count or 35,
|
||||
min_deactivation_time = def.min_deactivation_time or 60,
|
||||
max_deactivation_time = def.max_deactivation_time or 120,
|
||||
max_mob_count = def.max_mob_count or 40,
|
||||
max_mob_count = def.max_mob_count or 15,
|
||||
spawn_on_dig = def.spawn_on_dig
|
||||
}
|
||||
spawner_count = spawner_count + 1
|
||||
|
@ -204,8 +269,12 @@ natspawner.register_spawner = function(spawner_name, def)
|
|||
meta:set_int("entity_spawn_count", 0)
|
||||
meta:set_int("entity_killed_count", 0)
|
||||
meta:set_int("spawned_variation_count", 0)
|
||||
meta:set_int("next_deactivation_count", math.random(def.min_kill_count, def.max_kill_count))
|
||||
meta:set_int("next_deactivation_time", math.random(def.min_deactivation_time, def.max_deactivation_time))
|
||||
meta:set_int("max_variation_count",
|
||||
math.random(def.min_variation_count or 0, def.max_variation_count or 0))
|
||||
meta:set_int("next_deactivation_count",
|
||||
math.random(def.min_kill_count, def.max_kill_count))
|
||||
meta:set_int("next_deactivation_time",
|
||||
math.random(def.min_deactivation_time, def.max_deactivation_time))
|
||||
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
timer:start(def.min_spawn_interval)
|
||||
|
@ -218,7 +287,7 @@ natspawner.register_spawner = function(spawner_name, def)
|
|||
local entity_killed_count = meta:get_int("entity_killed_count")
|
||||
local next_deactivation_count = meta:get_int("next_deactivation_count")
|
||||
if (entity_killed_count < next_deactivation_count) then
|
||||
if spawn_on_dig then
|
||||
if def.spawn_on_dig then
|
||||
spawn(pos, true)
|
||||
end
|
||||
minetest.chat_send_player(digger:get_player_name(), "You have killed "..entity_killed_count.." enemies!")
|
||||
|
@ -235,7 +304,7 @@ end
|
|||
natspawner.register_spawner("zombie", {
|
||||
entity_name = "natspawner:zombie",
|
||||
entity_variations = {
|
||||
-- Giant zombie
|
||||
["giant_zombie"] =
|
||||
{
|
||||
visual_size = {x=2.75, y=2.5, z=2.75},
|
||||
collisionbox = {-0.63, -2.5, -0.75, 0.63, 1.88, 0.75},
|
||||
|
@ -249,17 +318,55 @@ natspawner.register_spawner("zombie", {
|
|||
reach = 4,
|
||||
armor = 325,
|
||||
knock_back = false,
|
||||
},
|
||||
["ice_zombie"] = {
|
||||
textures = {"mobs_zombie_ice.png"}
|
||||
},
|
||||
["sand_zombie_small"] = {
|
||||
textures = {"mobs_zombie_sand.png"},
|
||||
visual_size = {x=0.5, y=0.5, z=0.5},
|
||||
}
|
||||
},
|
||||
node_replacement_map = {
|
||||
["default:stone"] = {name = "stone_spawner", tiles = {"default_stone.png^[cracko:1:2", "default_stone.png", {name = "default_stone.png"}}},
|
||||
["default:sand"] = {name = "sand_spawner", tiles = {"default_sand.png^[cracko:1:2", "default_sand.png", {name = "default_sand.png"}}},
|
||||
["default:desert_sand"] = {name = "desert_sand_spawner", tiles = {"default_desert_sand.png^[cracko:1:2", "default_desert_sand.png", {name = "default_desert_sand.png"}}},
|
||||
["default:ice"] = {name = "ice_spawner", tiles = {"default_ice.png^[cracko:1:2", "default_ice.png", {name = "default_ice.png"}}},
|
||||
["default:snowblock"] = {name = "snowblock_spawner", tiles = {"default_snow.png^[cracko:1:2", "default_snow.png", {name = "default_snow.png"}}},
|
||||
["default:stone"] = {
|
||||
name = "stone_spawner",
|
||||
tiles = {"default_stone.png^[cracko:1:2", "default_stone.png", {name = "default_stone.png"}}
|
||||
},
|
||||
["default:sand"] = {
|
||||
name = "sand_spawner",
|
||||
tiles = {"default_sand.png^[cracko:1:2", "default_sand.png", {name = "default_sand.png"}},
|
||||
variations = {"sand_zombie_small"}
|
||||
},
|
||||
["default:desert_sand"] = {
|
||||
name = "desert_sand_spawner",
|
||||
tiles = {"default_desert_sand.png^[cracko:1:2", "default_desert_sand.png", {name = "default_desert_sand.png"}}
|
||||
},
|
||||
["default:ice"] = {
|
||||
name = "ice_spawner",
|
||||
tiles = {"default_ice.png^[cracko:1:2", "default_ice.png", {name = "default_ice.png"}},
|
||||
variations = {"ice_zombie"},
|
||||
variations_only = true,
|
||||
max_count = 15,
|
||||
min_count = 10
|
||||
},
|
||||
["default:snowblock"] = {
|
||||
name = "snowblock_spawner",
|
||||
tiles = {"default_snow.png^[cracko:1:2", "default_snow.png", {name = "default_snow.png"}},
|
||||
variations = {"ice_zombie"},
|
||||
variations_only = true,
|
||||
max_count = 15,
|
||||
min_count = 10
|
||||
},
|
||||
["default:dirt_with_grass"] = {name = "dirt_with_grass_spawner", tiles = {"default_grass.png^[cracko:1:2", "default_dirt.png", {name = "default_dirt.png^default_grass_side.png"}}},
|
||||
["default:dirt_with_dry_grass"] = {name = "dirt_with_dry_grass_spawner", tiles = {"default_dry_grass.png^[cracko:1:2", "default_dirt.png", {name = "default_dirt.png^default_dry_grass_side.png"}}},
|
||||
["default:dirt_with_snow"] = {name = "dirt_with_snow_spawner", tiles = {"default_snow.png^[cracko:1:2", "default_dirt.png", {name = "default_dirt.png^default_snow_side.png"}}, textures = {"mobs_zombie_ice.png"}},
|
||||
["default:dirt_with_snow"] = {
|
||||
name = "dirt_with_snow_spawner",
|
||||
tiles = {"default_snow.png^[cracko:1:2", "default_dirt.png", {name = "default_dirt.png^default_snow_side.png"}},
|
||||
variations = {"ice_zombie"},
|
||||
variations_only = true,
|
||||
max_count = 15,
|
||||
min_count = 10
|
||||
},
|
||||
["default:dirt_with_rainforest_litter"] = {name = "dirt_with_rainforest_litter_spawner", tiles = {"default_rainforest_litter.png^[cracko:1:2", "default_dirt.png", {name = "default_dirt.png^default_rainforest_litter_side.png"}}},
|
||||
["default:dirt_with_coniferous_litter"] = {name = "dirt_with_coniferous_litter_spawner", tiles = {"default_coniferous_litter.png^[cracko:1:2", "default_dirt.png", {name = "default_dirt.png^default_coniferous_litter_side.png"}}},
|
||||
["default:permafrost"] = {name = "permafrost_spawner", tiles = {"default_permafrost.png^[cracko:1:2", "default_permafrost.png", {name = "default_permafrost.png"}}},
|
||||
|
@ -325,7 +432,12 @@ minetest.register_on_generated(function(minp, maxp, seed)
|
|||
local p2 = minetest.find_node_near(mpos, 25, {
|
||||
"default:dirt_with_grass",
|
||||
"default:dirt_with_snow",
|
||||
"default:dirt_with_coniferous_litter"
|
||||
"default:dirt_with_coniferous_litter",
|
||||
"default:permafrost",
|
||||
"default:permafrost_with_moss",
|
||||
"default:permafrost_with_stones",
|
||||
"default:sand",
|
||||
"default:desert_sand"
|
||||
})
|
||||
while p2 == nil and cnt < 10 do
|
||||
cnt = cnt+1
|
||||
|
@ -333,7 +445,12 @@ minetest.register_on_generated(function(minp, maxp, seed)
|
|||
p2 = minetest.find_node_near(mpos, 25, {
|
||||
"default:dirt_with_grass",
|
||||
"default:dirt_with_snow",
|
||||
"default:dirt_with_coniferous_litter"
|
||||
"default:dirt_with_coniferous_litter",
|
||||
"default:permafrost",
|
||||
"default:permafrost_with_moss",
|
||||
"default:permafrost_with_stones",
|
||||
"default:sand",
|
||||
"default:desert_sand"
|
||||
})
|
||||
end
|
||||
if p2 == nil then return end
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
Loading…
Reference in New Issue