Millions of changes and bugfixes

master
LoneWolfHT 2019-12-27 17:07:30 -08:00
parent 28bca3bd95
commit 859c9ce27f
29 changed files with 568 additions and 33 deletions

View File

@ -2,7 +2,7 @@ creative_mode = false
enable_pvp = true
enable_damage = true
server_name = Block Combat
server_name = Voxel Combat
server_description = Light PvP server with multiple mods.
server_address = <>
port = 30000
@ -20,4 +20,4 @@ default_privs = shout, interact, zoom
max_block_send_distance = 6
max_simultaneous_block_sends_per_client = 1
max_simultaneous_block_sends_server_total = 20
active_block_range = 1
active_block_range = 1

View File

@ -7,7 +7,7 @@ minetest.register_tool("combat:knife", {
tool_capabilities = {
full_punch_interval = 0.9,
max_drop_level=1,
damage_groups = {fleshy=1},
damage_groups = {fleshy=1.5},
},
})
@ -20,7 +20,7 @@ minetest.register_tool("combat:sword", {
tool_capabilities = {
full_punch_interval = 0.8,
max_drop_level=1,
damage_groups = {fleshy=3},
damage_groups = {fleshy=2},
},
sound = {breaks = "default_tool_breaks"},
})

View File

@ -1,10 +1,10 @@
function main.spawn_rand_drop()
function main.spawn_rand_drop(pos)
local drops = main.current_mode.mode.drops
if not drops then return end
local itemspawns = main.current_mode.itemspawns
local spawnpos = itemspawns[math.random(1, #itemspawns)]
local spawnpos = pos or itemspawns[math.random(1, #itemspawns)]
for item, chance in pairs(drops) do
if item ~= "default" then
@ -23,12 +23,12 @@ end
local dropstep = 0
minetest.register_globalstep(function(dtime)
if not main.current_mode or not main.current_mode.mode then return end
if not vc_info.mode_running then return end
local dropint = main.current_mode.mode.drop_interval
local online_players = #minetest.get_connected_players()
if dropint and dropstep >= dropint/online_players and online_players >= 1 and main.current_mode.mode.itemspawns then
if dropint and dropstep >= dropint - (online_players * 5) and online_players >= 1 then
dropstep = 0
main.spawn_rand_drop()

View File

@ -2,7 +2,7 @@ main = {
current_mode = {},
modes = {},
playing = {}, -- main.playing[playername] = true/false
mode_interval = 60 * 5,
mode_interval = 60 * 8,
default_drops = {
default = "shooter_guns:ammo",
["combat:medkit"] = 20,
@ -12,7 +12,7 @@ main = {
["combat:sword"] = 60,
},
default_starter_items = {"combat:knife", "shooter_guns:pistol_loaded", "shooter_guns:ammo 2"},
default_drop_interval = 20,
default_drop_interval = 25,
}
vc_info = {
@ -37,7 +37,7 @@ end
function main.start_mode(name)
if vc_info.mode_running and main.current_mode.mode.on_end then
local _ = main.current_mode.mode.on_end()
main.current_mode.mode.on_end()
end
vc_info.mode_running = false
@ -60,6 +60,8 @@ function main.start_mode(name)
main.current_mode.itemspawns = mapdef.itemspawns
main.current_mode.playerspawns = mapdef.playerspawns
vc_info.mode_running = true
for _, p in ipairs(minetest.get_connected_players()) do
if main.playing[p:get_player_name()] then
main.join_player(p)
@ -67,20 +69,24 @@ function main.start_mode(name)
end
if main.modes[name].on_start then
local _ = main.modes[name].on_start()
main.modes[name].on_start()
end
main.sethud_all("Current mode: "..main.modes[name].full_name..". Current map: "..mapdef.name, 7)
vc_info.mode_running = true
end
function main.join_player(player)
local inv = player:get_inventory()
local name = player:get_player_name()
if not vc_info.mode_running then
main.log("No mode running. Can't join player", "error")
return
end
main.give_starter_items(inv)
skybox.set(player, main.get_sky(main.current_mode.map.skybox))
local one, two, three = player:get_sky()
player:set_sky(one, two, three, false)
@ -110,14 +116,17 @@ minetest.register_on_joinplayer(function(p)
p:set_hp(20, {type = "set_hp"})
if not vc_info.mode_running then
main.start_mode("default")
main.start_mode(main.rand_mode())
else
main.join_player(p)
end
end)
function main.on_respawn(p)
if not main.current_mode.playerspawns then return false end
if not vc_info.mode_running or not main.current_mode.playerspawns then
minetest.after(5, main.on_respawn, p)
return
end
p:set_pos(main.current_mode.playerspawns[math.random(1, #main.current_mode.playerspawns)])
@ -127,6 +136,9 @@ end
minetest.register_on_player_hpchange(function(_, hp_change, reason)
if reason.type == "fall" then
return 0
elseif reason.type == "punch" and reason.object and reason.object:is_player() and
vc_info.mode_running and main.current_mode.mode.pvp ~= true then
return 0
else
return hp_change
end

View File

@ -6,6 +6,7 @@ main.register_mode("modename", {
drops = main.default_drops, <required>
starter_items = main.default_starter_items, <required>
drop_interval = main.default_drop_interval, <required>
pvp = <bool>, <default is false>
on_start = function(), <optional>
on_end = function(), <optional>
on_step = function(dtime), <optional>
@ -15,15 +16,75 @@ main.register_mode("modename", {
]]--
main.register_mode("default", {
main.register_mode("pvp_party", {
full_name = "PvP Party",
min_players = 1,
min_players = 2,
pvp = true,
drops = main.default_drops,
starter_items = main.default_starter_items,
drop_interval = main.default_drop_interval,
})
local function rand_mode()
local z_s_modestep = 20 * 3
main.register_mode("zombie_survival", {
full_name = "Zombie Survival",
min_players = 1,
drops = main.default_drops,
starter_items = main.default_starter_items,
on_step = function(dtime)
z_s_modestep = z_s_modestep + dtime
if z_s_modestep >= 20 then
z_s_modestep = z_s_modestep - 20
else
return
end
local objects_in_area = minetest.get_objects_inside_radius(vector.new(), 25)
local zombiecount = 0
local sharkcount = 0
local connected_players = #minetest.get_connected_players()
for _, obj in pairs(objects_in_area) do
if not obj:is_player() then
local name = obj:get_luaentity().name
if name == "zombiestrd:zombie" then
zombiecount = zombiecount + 1
elseif name == "zombiestrd:shark" then
sharkcount = sharkcount + 1
end
end
end
local nodes_under_air = minetest.find_nodes_in_area_under_air(
vector.new(-19, 0, -19),
vector.new(19, 16, 19),
"group:zombie_ground" -- See preregistered_edits
)
local water_nodes_in_area = minetest.find_nodes_in_area(
vector.new(-19, 0, -19),
vector.new(19, 16, 19),
"group:water" -- group given to water liquid
)
if zombiecount < 4 + (connected_players * 3) and nodes_under_air and #nodes_under_air > 1 then
local spawnpos = nodes_under_air[math.random(1, #nodes_under_air)]
spawnpos.y = spawnpos.y + 2
minetest.add_entity(spawnpos, "zombiestrd:zombie")
end
if sharkcount < 2 + (connected_players * 1) and water_nodes_in_area and #water_nodes_in_area > 4 then
local spawnpos = water_nodes_in_area[math.random(1, #water_nodes_in_area)]
spawnpos.y = spawnpos.y + 2
minetest.add_entity(spawnpos, "zombiestrd:shark")
end
end,
})
function main.rand_mode()
local online = #minetest.get_connected_players()
local modes = {}
@ -45,7 +106,7 @@ minetest.register_globalstep(function(dtime)
modechangestep = 0
main.sethud_all("Changing mode...")
minetest.after(3, function() main.start_mode(rand_mode()) end)
minetest.after(3, function() main.start_mode(main.rand_mode()) end)
end
if vc_info.mode_running and main.current_mode.mode.on_step then

View File

@ -158,9 +158,7 @@ function maps.edit_map(pname, mname)
editors[pname].action = "editing"
editors[pname].map = mname
editors[pname].settings = {
name = pname.."s Map"
}
editors[pname].settings = {}
minetest.emerge_area(vector.subtract(mpos, vector.new(20, 0, 20)), vector.add(mpos, vector.new(20, 16, 20)))
minetest.place_schematic(mpos, minetest.get_modpath("maps").."/schems/base.mts", 0, {}, true,
@ -240,7 +238,7 @@ function maps.get_rand_map()
main.log("Map "..dump(map).." is corrupted or out of date!", "error")
else
local found = false
for _, mapdef in ipairs(modes) do
for _, mapdef in pairs(modes) do
if mapdef.name == main.current_mode.name and mapdef.enabled then
found = true
break
@ -291,11 +289,9 @@ end
local function get_modes_string(name)
local string = ""
for _, def in ipairs(editors[name].settings.modes) do
for _, def in pairs(editors[name].settings.modes) do
local color = "#00ff32"
minetest.log(dump(def))
if not def.enabled then color = "#ff0000" end
string = string .. color .. def.name .. ","
@ -305,10 +301,6 @@ local function get_modes_string(name)
end
local function tidy_modes(name)
if not editors[name].settings.modes then
editors[name].settings.modes = {}
end
for modename, def in pairs(main.modes) do
local found = false
@ -321,6 +313,10 @@ local function tidy_modes(name)
end
if not found then
if not editors[name].settings.modes then
editors[name].settings.modes = {}
end
table.insert(editors[name].settings.modes, {name = modename, enabled = true})
end
end
@ -375,7 +371,9 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
local name = player:get_player_name()
local modes = minetest.explode_textlist_event(fields.map_modes)
if modes.type == "DCL" and editors[name].settings.modes and #editors[name].settings.modes > 0 then
minetest.log(dump(modes).."\n"..dump(editors[name].settings.modes))
if modes.type == "DCL" and editors[name].settings.modes then
editors[name].settings.modes[modes.index].enabled = not editors[name].settings.modes[modes.index].enabled
end

View File

@ -1,3 +1,5 @@
shooter.config.allow_entities = true
for name, def in pairs(minetest.registered_nodes) do
local newdef = {groups = def.groups}
@ -15,6 +17,10 @@ for name, def in pairs(minetest.registered_nodes) do
newdef.damage_per_second = 100
end
if name:find("dirt") or name:find("sand") then
newdef.groups.zombie_ground = 1
end
minetest.override_item(name, newdef)
end
@ -43,4 +49,5 @@ end
default.can_grow = function() return true end
minetest.registered_entities["__builtin:item"].on_punch = nil
minetest.registered_entities["__builtin:item"].static_save = false
minetest.registered_entities["__builtin:item"].pointable = false

View File

@ -1,2 +1,2 @@
name = unbreakable_nodes
depends = default, wool, xpanes, farming, flowers, fire, doors, beds, shooter_guns
depends = default, wool, xpanes, farming, flowers, fire, doors, beds, shooter_guns

23
mods/zombiestrd/LICENSE Normal file
View File

@ -0,0 +1,23 @@
MIT License
Copyright (c) 2019
- TheTermos (Main mod)
- LoneWolfHT (a few tweaks to make mobs suit game)
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 @@
mobkit

415
mods/zombiestrd/init.lua Normal file
View File

@ -0,0 +1,415 @@
local abr = minetest.get_mapgen_setting('active_block_range')
local nodename_water = minetest.registered_aliases.mapgen_water_source
local node_lava = nil
local zombiestrd = {}
--zombiestrd.spawn_rate = 0.4 -- less is more
local abs = math.abs
local pi = math.pi
local floor = math.floor
local random = math.random
local sqrt = math.sqrt
local max = math.max
local min = math.min
local pow = math.pow
local sign = math.sign
local time = os.time
local spawn_rate = 1 - max(min(minetest.settings:get('zombiestrd_spawn_chance') or 0.6,1),0)
local spawn_reduction = minetest.settings:get('zombiestrd_spawn_reduction') or 0.4
local function dot(v1,v2)
return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z
end
-- find zombie's head center and radius
local function get_head(luaent)
local pos = luaent.object:get_pos()
local off = luaent.collisionbox[6]
local y=pos.y+luaent.collisionbox[5]-off
pos.y = y
return pos, off
end
-- custom behaviour
-- makes them move in stimulus' general direction for limited time
local function hq_attracted(self,prty,tpos)
local timer = time() + random(10,20) -- zombie's attention span
local func = function(self)
if time() > timer then return true end
if mobkit.is_queue_empty_low(self) and self.isonground then
local pos = mobkit.get_stand_pos(self)
if vector.distance(pos,tpos) > 3 then
mobkit.goto_next_waypoint(self,tpos)
else
return true
end
end
end
mobkit.queue_high(self,func,prty)
end
-- override built in behavior to increase idling time
function zombiestrd.hq_roam(self,prty)
local func=function(self)
if mobkit.is_queue_empty_low(self) and self.isonground then
local pos = mobkit.get_stand_pos(self)
local neighbor = random(8)
local height, tpos, liquidflag = mobkit.is_neighbor_node_reachable(self,neighbor)
if height and not liquidflag then mobkit.dumbstep(self,height,tpos,0.3,20) end
end
end
mobkit.queue_high(self,func,prty)
end
local function alert(pos)
objs = minetest.get_objects_inside_radius(pos,abr*16)
for _,obj in ipairs(objs) do
if not obj:is_player() then
local luaent = obj:get_luaentity()
if luaent and luaent.name == 'zombiestrd:zombie' then
hq_attracted(luaent,10,pos)
end
end
end
end
local function lava_dmg(self,dmg)
node_lava = node_lava or minetest.registered_nodes[minetest.registered_aliases.mapgen_lava_source]
if node_lava then
local pos=self.object:get_pos()
local box = self.object:get_properties().collisionbox
local pos1={x=pos.x+box[1],y=pos.y+box[2],z=pos.z+box[3]}
local pos2={x=pos.x+box[4],y=pos.y+box[5],z=pos.z+box[6]}
local nodes=mobkit.get_nodes_in_area(pos1,pos2)
if nodes[node_lava] then mobkit.hurt(self,dmg) end
end
end
local function zombie_brain(self)
-- vitals should be checked every step
if mobkit.timer(self,1) then lava_dmg(self,6) end
if self.hp <= 0 then
mobkit.clear_queue_high(self) -- cease all activity
mobkit.hq_die(self)
if math.random(1, 3) ~= 1 then
main.spawn_rand_drop(self.object:get_pos()) -- kick the bucket
end
-- workaround for models bottom y being -1. Makes them blink white sometimes, why?
local props = self.object:get_properties()
props.collisionbox[2] = props.collisionbox[1]
self.object:set_properties({collisionbox=props.collisionbox})
return
end
if mobkit.timer(self,1) then -- decision making needn't happen every engine step
local prty = mobkit.get_queue_priority(self)
if prty < 50 and self.isinliquid then
mobkit.hq_liquid_recovery(self,50)
return
end
local pos=self.object:get_pos()
if prty < 20 then
local plyr=mobkit.get_nearby_player(self)
if plyr then
local pos2 = plyr:get_pos()
if prty < 10 then -- zombie not alert
if vector.distance(pos,pos2) < self.view_range/3 and
(not mobkit.is_there_yet2d(pos,minetest.yaw_to_dir(self.object:get_yaw()),pos2) or
vector.length(plyr:get_player_velocity()) > 3) then
mobkit.make_sound(self,'misc')
mobkit.hq_hunt(self,20,plyr)
if random()<=0.5 then alert(pos) end
end
else
if vector.distance(pos,pos2) < self.view_range then
mobkit.make_sound(self,'misc')
mobkit.hq_hunt(self,20,plyr)
if random()<=0.5 then alert(pos) end
end
end
end
end
if mobkit.is_queue_empty_high(self) then
zombiestrd.hq_roam(self,0)
end
end
end
local function shark_brain(self)
if mobkit.timer(self,1) then lava_dmg(self,6) end
mobkit.vitals(self)
if self.hp <= 0 then
mobkit.clear_queue_high(self)
mobkit.hq_die(self)
if math.random(1, 3) ~= 1 then
main.spawn_rand_drop(self.object:get_pos())
end
return
end
if mobkit.timer(self,1) then
local prty = mobkit.get_queue_priority(self)
if prty < 20 then
local target = mobkit.get_nearby_player(self)
if target and mobkit.is_alive(target) and mobkit.is_in_deep(target) and target:get_attach() == nil then
mobkit.clear_queue_high(self)
mobkit.hq_aqua_attack(self,20,target,7)
end
end
end
if mobkit.is_queue_empty_high(self) then mobkit.hq_aqua_roam(self,10,5) end
end
-- spawning is too specific to be included in the api, this is an example.
-- a modder will want to refer to specific names according to games/mods they're using
-- in order for mobs not to spawn on treetops, certain biomes etc.
--[[
local function spawnstep(dtime)
for _,plyr in ipairs(minetest.get_connected_players()) do
if random()<dtime*0.2 then -- each player gets a spawn chance every 5s on average
local vel = plyr:get_player_velocity()
local spd = vector.length(vel)
local chance = spawn_rate * 1/(spd*0.75+1) -- chance is quadrupled for speed=4
local yaw
if spd > 1 then
-- spawn in the front arc
yaw = minetest.dir_to_yaw(vel) + random()*0.35 - 0.75
else
-- random yaw
yaw = random()*pi*2 - pi
end
local pos = plyr:get_pos()
local dir = vector.multiply(minetest.yaw_to_dir(yaw),abr*16)
local pos2 = vector.add(pos,dir)
pos2.y=pos2.y-5
local height, liquidflag = mobkit.get_terrain_height(pos2,32)
if height and --height >= 0 and
mobkit.nodeatpos({x=pos2.x,y=height-0.01,z=pos2.z}).is_ground_content then
local objs = minetest.get_objects_inside_radius(pos,abr*16+5)
local wcnt=0
local dcnt=0
local mobname = 'zombiestrd:zombie'
if liquidflag then -- sharks
local spnode = mobkit.nodeatpos({x=pos2.x,y=height+0.01,z=pos2.z})
local spnode2 = mobkit.nodeatpos({x=pos2.x,y=height+1.01,z=pos2.z}) -- node above to make sure won't spawn in shallows
nodename_water = nodename_water or minetest.registered_aliases.mapgen_water_source
if spnode and spnode2 and spnode.name == nodename_water and spnode2.name == nodename_water then
for _,obj in ipairs(objs) do
if not obj:is_player() then
local entity = obj:get_luaentity()
if entity and entity.name=='zombiestrd:shark' then return end
end
end
mobname = 'zombiestrd:shark'
else
return
end
elseif height >= 0 then --zombies
for _,obj in ipairs(objs) do -- count mobs in abrange
if not obj:is_player() then
local entity = obj:get_luaentity()
if entity and entity.name:find('zombiestrd:') then
chance=chance + (1-chance)*spawn_reduction -- chance reduced for every mob in range
end
end
end
end
if chance < random() then
pos2.y = height+1.01
objs = minetest.get_objects_inside_radius(pos2,abr*16-2)
for _,obj in ipairs(objs) do -- do not spawn if another player around
if obj:is_player() then return end
end
local obj=minetest.add_entity(pos2,mobname) -- ok spawn it already damnit
end
end
end
end
end
]]
--minetest.register_globalstep(spawnstep)
-- minetest.register_globalstep(function(dtime)
-- local spos=mobkit.get_spawn_pos_abr(dtime,5,10,0.5,0.4)
-- if spos then minetest.add_entity(spos,'zombiestrd:zombie') end
-- end)
minetest.register_on_punchnode(
function(pos, node, puncher, pointed_thing)
if random()<=0.1 then
alert(pos)
end
end
)
minetest.register_entity("zombiestrd:zombie",{
-- common props
physical = true,
stepheight = 0.5,
collide_with_objects = true,
collisionbox = {-0.25, -1, -0.25, 0.25, 0.75, 0.25},
visual = "mesh",
mesh = "zombie_normal.b3d",
textures = {"mobs_zombie.png","mobs_zombi2.png"},
visual_size = {x = 1, y = 1},
static_save = false,
timeout = 0,
on_step = mobkit.stepfunc, -- required
on_activate = mobkit.actfunc, -- required
get_staticdata = mobkit.statfunc,
-- api props
springiness=0,
buoyancy = 0.75, -- portion of hitbox submerged
max_speed = 4.5,
jump_height = 1.5,
view_range = 500,
lung_capacity = 10, -- seconds
max_hp = 25,
attack={range=1,damage_groups={fleshy=8}},
animation = {
walk={range={x=41,y=101},speed=40,loop=true},
stand={range={x=0,y=40},speed=1,loop=true},
},
sounds = {
misc='zombie',
attack='zombie_bite',
warn = 'angrydog',
hurt = 'splash_hit',
charge = 'zombie_charge',
},
armor_groups={fleshy = 1},
brainfunc = zombie_brain,
on_punch=function(self, puncher, time_from_last_punch, tool_capabilities, dir)
if mobkit.is_alive(self) then
if time_from_last_punch > 2 then time_from_last_punch = 2 end
local hvel = vector.multiply(vector.normalize({x=dir.x,y=0.5,z=dir.z}),time_from_last_punch)
self.object:set_velocity(hvel)
mobkit.hurt(self,tool_capabilities.damage_groups.fleshy or 1)
mobkit.make_sound(self, "hurt")
end
end,
--[[
on_punch=function(self, puncher, time_from_last_punch, tool_caps, dir)
if mobkit.is_alive(self) then
-- head seeking
if type(puncher)=='userdata' and puncher:is_player() then
local pp = puncher:get_pos()
pp.y = pp.y + puncher:get_properties().eye_height -- pp is now camera pos
local pm, radius = get_head(self)
local look_dir = puncher:get_look_dir()
local head_dir = vector.subtract(pm,pp)
local dot = dot(look_dir,head_dir)
local p2 = {x=pp.x+look_dir.x*dot, y=pp.y+look_dir.y*dot, z=pp.z+look_dir.z*dot}
if vector.distance(pp,pm) <=2 then -- a way to decrease punch range without dependences
if mobkit.isnear3d(pm,p2,radius*0.8) and
time_from_last_punch >= tool_caps.full_punch_interval-0.01 and
tool_caps.damage_groups.fleshy > 3 then -- valid headshot
mobkit.make_sound(self,'headhit')
-- self.object:set_hp(99)
self.hp=0
else
mobkit.make_sound(self,'bodyhit')
if random()<=0.3 then alert(pp) end
if mobkit.get_queue_priority(self) < 10 then
mobkit.make_sound(self,'misc')
mobkit.hq_hunt(self,10,puncher)
end
end
-- kickback
local hvel = vector.multiply(look_dir,4)
self.object:set_velocity({x=hvel.x,y=max(hvel.y,1),z=hvel.z})
end
else
local hvel = vector.multiply(vector.normalize({x=dir.x,y=0,z=dir.z}),4)
self.object:set_velocity({x=hvel.x,y=2,z=hvel.z})
end
end
end
]]
})
minetest.register_entity("zombiestrd:shark",{
-- common props
physical = true,
stepheight = 0.1, --EVIL!
collide_with_objects = true,
collisionbox = {-0.5, -0.3, -0.5, 0.5, 0.3, 0.5},
visual = "mesh",
mesh = "shark.b3d",
textures = {"shark3tex.png"},
visual_size = {x = 1.5, y = 1.5},
static_save = false,
makes_footstep_sound = true,
on_step = mobkit.stepfunc, -- required
on_activate = mobkit.actfunc, -- required
get_staticdata = mobkit.statfunc,
-- api props
springiness=0,
buoyancy = 0.98, -- portion of hitbox submerged
max_speed = 5.5,
jump_height = 2,
view_range = 50,
-- lung_capacity = 0, -- seconds
max_hp = 20,
timeout=600,
attack={range=0.8,damage_groups={fleshy=7}},
sounds = {
hurt = "splash_hit"
},
animation = {
def={range={x=1,y=59},speed=40,loop=true},
fast={range={x=1,y=59},speed=80,loop=true},
back={range={x=15,y=1},speed=-15,loop=false},
},
brainfunc = shark_brain,
on_punch=function(self, puncher, time_from_last_punch, tool_capabilities, dir)
if mobkit.is_alive(self) then
if time_from_last_punch > 2 then time_from_last_punch = 2 end
local hvel = vector.multiply(vector.normalize({x=dir.x,y=0.5,z=dir.z}),time_from_last_punch)
self.object:set_velocity(hvel)
mobkit.hurt(self,tool_capabilities.damage_groups.fleshy or 1)
mobkit.make_sound(self, "hurt")
if type(puncher)=='userdata' and puncher:is_player() then -- if hit by a player
mobkit.clear_queue_high(self) -- abandon whatever they've been doing
mobkit.hq_aqua_attack(self,20,puncher,6) -- get revenge
end
end
end,
})
--[[
minetest.register_on_chat_message(
function(name, message)
if message == 'doit' then
minetest.chat_send_all(dump(minetest.registered_aliases.mapgen_water_source))
end
end
) --]]

3
mods/zombiestrd/mod.conf Normal file
View File

@ -0,0 +1,3 @@
name = zombiestrd
description = Zombies - The real Deal - Now With Sharks
depends = mobkit

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,15 @@
# This file contains settings of zombiestrd that can be changed in
# minetest.conf
# Chance of spawning a mob when there are no other
# mobs in active_block_range around player
# must be float from 0 to 1
# 1 is always, 0 is never
zombiestrd_spawn_chance (Spawn chance) float 0.6
# Base spawn chance is reduced by this factor
# for each mob within active_block_range
# must be float from 0 to 1
# greater number is greater reduction
zombiestrd_spawn_reduction (Spawn chance reduction) float 0.4

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 788 B