Gonna just push it and see what happens.

master
James Stevenson 2019-01-17 02:34:38 -05:00
parent de9e769972
commit 8b075ec314
5 changed files with 181 additions and 144 deletions

View File

@ -9,13 +9,9 @@
local MP = minetest.get_modpath(minetest.get_current_modname())
local S, NS = dofile(MP .. "/intllib.lua")
local use_cmi = minetest.global_exists("cmi")
mobs = {
mod = "redo",
version = "20180915",
intllib = S,
invis = minetest.global_exists("invisibility") and invisibility or {},
}
local undercrowd = mobs.undercrowd
mobs.intllib = S
mobs.invis = {}
-- creative check
local creative_cache = minetest.settings:get_bool("creative_mode")
@ -23,7 +19,6 @@ function mobs.is_creative(name)
return creative_cache or minetest.check_player_privs(name, {creative = true})
end
-- localize math functions
local pi = math.pi
local square = math.sqrt
@ -34,7 +29,7 @@ local min = math.min
local max = math.max
local atann = math.atan
local random = math.random
print(random(20))
print(random(10) + random(10))
local floor = math.floor
local atan = function(x)
if not x or x ~= x then
@ -2934,6 +2929,7 @@ local mob_step = function(self, dtime)
self.stepper = random()
end
local t = 0
--[[
for k, v in pairs(minetest.get_objects_inside_radius(pos, 24)) do
local s = v:get_luaentity()
if s and s.health then
@ -2947,6 +2943,8 @@ local mob_step = function(self, dtime)
end
end
end
--]]
undercrowd(pos, 8)
if minetest.find_node_near(pos, 8, "mobs:spawner") then
return
end

View File

@ -1,4 +1,9 @@
local S = mobs.intllib
local boom = function(pos, radius)
radius = radius or 2
tnt.boom(pos, {radius = radius,
damage_radius = radius,})
end
-- Dungeon Master by PilzAdam
mobs:register_mob("mobs:dungeon_master", {
type = "monster",
@ -25,13 +30,16 @@ mobs:register_mob("mobs:dungeon_master", {
},
makes_footstep_sound = true,
sounds = {
warcry = "mobs_dungeonmaster",
attack = "mobs_dungeonmaster",
die = "mobs_dungeonmaster",
random = "mobs_dungeonmaster",
shoot_attack = "mobs_fireball",
},
walk_velocity = 1,
--run_velocity = 1,
--jump = true,
--view_range = 15,
view_range = 7,
drops = {
{name = "default:mese_crystal", chance = 1, min = 1, max = 2},
{name = "default:diamond", chance = 2, min = 0, max = 1},
@ -52,6 +60,9 @@ mobs:register_mob("mobs:dungeon_master", {
speed_normal = 15,
speed_run = 15,
},
on_die = function(self, pos)
boom(pos)
end,
})
mobs:register_egg("mobs:dungeon_master", S("Dungeon Master"), "fire_basic_flame.png", 1, true)
@ -59,54 +70,23 @@ mobs:register_egg("mobs:dungeon_master", S("Dungeon Master"), "fire_basic_flame.
-- fireball (weapon)
mobs:register_arrow("mobs:fireball", {
visual = "sprite",
visual_size = {x = 1, y = 1},
visual_size = {x = 1.5, y = 1.5},
textures = {"mobs_fireball.png"},
collisionbox = {-0.1, -0.1, -0.1, 0.1, 0.1, 0.1},
velocity = 7,
--tail = 1,
--tail_texture = "mobs_fireball.png",
--tail_size = 10,
velocity = 9,
glow = 14,
expire = 0.1,
on_activate = function(self, staticdata, dtime_s)
-- make fireball indestructable
self.object:set_armor_groups({immortal = 1, fleshy = 100})
end,
-- if player has a good weapon with 7+ damage it can deflect fireball
on_punch = function(self, hitter, tflp, tool_capabilities, dir)
if hitter and hitter:is_player() and
tool_capabilities and dir then
local damage = tool_capabilities.damage_groups and
tool_capabilities.damage_groups.fleshy or 1
local tmp = tflp / (tool_capabilities.full_punch_interval or 1.4)
if damage > 6 and tmp < 4 then
self.object:set_velocity({
x = dir.x * self.velocity,
y = dir.y * self.velocity,
z = dir.z * self.velocity,
})
end
end
end,
-- direct hit, no fire... just plenty of pain
hit_player = function(self, player)
player:punch(self.object, 1.0, {
full_punch_interval = 1.0,
damage_groups = {fleshy = 8},
}, nil)
tnt.boom(self.object:get_pos(), {radius = 3})
boom(self.object:get_pos())
end,
hit_mob = function(self, player)
player:punch(self.object, 1.0, {
full_punch_interval = 1.0,
damage_groups = {fleshy = 8},
}, nil)
tnt.boom(self.object:get_pos(), {radius = 3})
boom(self.object:get_pos())
end,
-- node hit
hit_node = function(self, pos, node)
tnt.boom(self.object:get_pos(), {radius = 3})
boom(self.object:get_pos())
end
})

View File

@ -1,51 +1,7 @@
local path = minetest.get_modpath(minetest.get_current_modname())
local stepper = 0
minetest.register_globalstep(function(dtime)
if stepper < 10 then
stepper = stepper + dtime
return
else
stepper = 0
end
local players = minetest.get_connected_players()
for i = 1, #players do
if players[i] == "" then
break
end
local pos = players[i]:get_pos()
if not pos then
break
end
local t = 0
for k, v in pairs(minetest.get_objects_inside_radius(pos, 16)) do
local s = v:get_luaentity()
if s and s.health then
t = t + 1
end
if t >= 6 then
return v:remove()
end
end
if minetest.find_node_near(pos, 8, "mobs:spawner") then
break
end
if not minetest.get_node_or_nil(pos) then
break
end
if minetest.get_node_or_nil(pos).name ~= "air" then
pos.y = pos.y + 1
end
if minetest.get_node_or_nil(pos).name ~= "air" then
break
end
local added = minetest.add_node(pos, {name = "mobs:spawner"})
if not added then
break
end
minetest.get_node_timer(pos):start(0)
end
end)
mobs = {}
local path = minetest.get_modpath(minetest.get_current_modname())
dofile(path .. "/players.lua")
dofile(path .. "/api.lua")
dofile(path .. "/crafts.lua")
dofile(path .. "/nodes.lua")

View File

@ -1,7 +1,11 @@
-- mobs/nodes.lua is part of Glitchtest
-- Copyright 2018 James Stevenson
-- GNU GPL 3
local random = math.random
local redo = mobs.redo
local limiter = mobs.limiter
minetest.register_node("mobs:spawner", {
description = "I spawn things!",
drawtype = "airlike",
@ -24,35 +28,16 @@ minetest.register_node("mobs:spawner", {
local node = minetest.get_node_or_nil({
x = pos.x,
y = pos.y - 1,
z = pos.z
z = pos.z,
})
if node and node.name then
local node_below = minetest.registered_nodes[node.name]
if node_below and not node_below.walkable then
return minetest.set_node(pos, {name = "air"})
end
end
local immediate_surrounding = minetest.get_objects_inside_radius(pos, 2.67)
if #immediate_surrounding > 0 then
return minetest.set_node(pos, {name = "air"})
end
local surrounding = minetest.get_objects_inside_radius(pos, 24)
if #surrounding > 6 then
local h = 0
for i = 1, #surrounding do
local s = surrounding[i]
local sl = s:get_luaentity()
if sl and sl.health then
h = h + 1
end
if s:is_player() then
h = h + 2
end
end
if h > 10 then
return minetest.set_node(pos, {name = "air"})
return redo(pos)
end
end
local light = minetest.get_node_light(pos)
limiter(pos)
local mobs = {
"mobs:rat",
"mobs:npc",
@ -63,7 +48,7 @@ minetest.register_node("mobs:spawner", {
local protection = minetest.find_node_near(pos, 13,
{"protector:protect", "protector:protect2"}, true)
if not protection and (biome == "underground" or night) and
minetest.get_node_light(pos) < 9 then
light < 3 then
local mobs_to_insert = {
"mobs:dungeon_master",
"mobs:oerkki",
@ -100,51 +85,32 @@ minetest.register_node("mobs:spawner", {
y = spawn_pos.y + colbox[5],
z = spawn_pos.z + colbox[6],
}
-- Check mob's collisionbox for adequate space to spawn.
local d = vector.distance(p1, p2)
local r, s = minetest.find_nodes_in_area(p1, p2, "air", true)
if s["air"] < d then
return minetest.set_node(pos, {name = "air"})
return redo(pos)
end
minetest.add_entity(spawn_pos, mob)
minetest.set_node(r[random(#r)], {name = "mobs:spawner"})
return minetest.set_node(pos, {name = "air"})
redo(pos)
else
minetest.get_node_timer(pos):set(elapsed + 1, elapsed)
end
end,
})
minetest.register_abm({
label = "Spawner Limiter",
nodenames = {"mobs:spawner"},
--neighbors = {},
interval = 1,
interval = 5,
chance = 1,
catch_up = false,
action = function(pos, node, active_object_count, active_object_count_wider)
local i = active_object_count
local s = active_object_count_wider
local t = minetest.get_node_timer(pos)
if not t or not t:is_started() then
return minetest.set_node(pos, {name = "air"})
end
if s > 9 or i > 3 then
local things = minetest.get_objects_inside_radius(pos, 24)
local ttl = 0
for k, v in pairs(things) do
local h = v:get_luaentity()
if h and h.health and h.health > 0 then
ttl = ttl + 1
end
local p = v:is_player()
if p then
ttl = ttl + 2
end
end
if ttl > 12 then
minetest.set_node(pos, {name = "air"})
end
end
print(active_object_count, active_object_count_wider)
limiter(pos)
end,
})
--minetest.register_lbm()
--minetest.register_on_mapgen()

137
mods/mobs/players.lua Normal file
View File

@ -0,0 +1,137 @@
local random = math.random
mobs.undercrowd = function(pos, radius)
radius = radius or 3
local r = minetest.get_objects_inside_radius(pos, radius)
local t = 0
for _, v in pairs(r) do
local s = v:get_luaentity()
if not s then
break
end
if s.owner ~= "" then
break
end
if s.health > 0 then
t = t + 1
end
if t > 5 then
print("Overcrowded.")
return v:remove()
end
end
end
local undercrowd = mobs.undercrowd
minetest.register_on_mods_loaded(function()
for node, def in pairs(minetest.registered_nodes) do
if def.walkable then
local g = def.groups
g.reliable = 1
minetest.override_item(node, {
groups = g,
})
end
end
end)
mobs.redo = function(pos, radius)
radius = radius or 1
local p1 = {
x = pos.x - radius,
y = pos.y - radius,
z = pos.z - radius,
}
local p2 = {
x = pos.x + radius,
y = pos.y + radius,
z = pos.z + radius,
}
local n = minetest.find_node_near(pos, radius, "mobs:spawner")
if n then
local t = minetest.get_node_timer(n)
if not t:is_started() then
print("Restarting timer.")
t:start(1)
end
end
local a = minetest.find_nodes_in_area_under_air(p1, p2, "group:reliable")
if a and a[1] then
print("Setting spawner.")
local an = a[random(#a)]
local np = {
x = an.x,
y = an.y + 1,
z = an.z,
}
minetest.set_node(np, {name = "mobs:spawner"})
end
end
local redo = mobs.redo
mobs.limiter = function(pos, radius, limit, immediate_surrounding, surrounding)
radius = radius or 6.67
limit = limit or radius * 3
immediate_surrounding = immediate_surrounding or
minetest.get_objects_inside_radius(pos, radius)
if #immediate_surrounding > 6 then
print("Limiting.")
return redo(pos)
end
local surrounding = surrounding or
minetest.get_objects_inside_radius(pos, radius * 3)
if #surrounding > 18 then
local h = 0
for i = 1, #surrounding do
local s = surrounding[i]
local sl = s:get_luaentity()
if sl and sl.health then
h = h + 1
end
if s:is_player() then
h = h + 4
end
end
if h > limit then
print("Limiting.")
return redo(pos)
end
end
end
local stepper = 0
minetest.register_globalstep(function(dtime)
if stepper < 10 then
stepper = stepper + dtime
return
else
stepper = 0
end
local players = minetest.get_connected_players()
for i = 1, #players do
if players[i] == "" then
break
end
local pos = players[i]:get_pos()
if not pos then
break
end
undercrowd(pos, 8)
if minetest.find_node_near(pos, 8, "mobs:spawner") then
break
end
if not minetest.get_node_or_nil(pos) then
break
end
if minetest.get_node_or_nil(pos).name ~= "air" then
pos.y = pos.y + 1
end
if minetest.get_node_or_nil(pos).name ~= "air" then
break
end
local added = minetest.add_node(pos, {name = "mobs:spawner"})
if not added then
break
end
minetest.get_node_timer(pos):start(0)
end
end)