mirror of
https://codeberg.org/tenplus1/mobs_redo.git
synced 2025-07-16 15:20:28 +02:00
Compare commits
70 Commits
d12576f0c8
...
ca34cc2274
Author | SHA1 | Date | |
---|---|---|---|
ca34cc2274 | |||
168014b86f | |||
6f8b6fe3f5 | |||
dd16d63e8e | |||
7bb5e2b382 | |||
7b429df9e9 | |||
0e72f0ca81 | |||
fb42be6b28 | |||
f54c3da9d7 | |||
65e369e5fc | |||
9f74408792 | |||
18c7f0a422 | |||
2fb7bf2c66 | |||
f01e8a61d0 | |||
b756aa50f5 | |||
e83620553d | |||
e5d1958e16 | |||
6a4a02f3fb | |||
5d88766b74 | |||
d31da2d069 | |||
00db86c924 | |||
26ec61ee29 | |||
a8ca00dc56 | |||
4c80a55c04 | |||
deee28fc59 | |||
ab44080ff8 | |||
9f46182bb4 | |||
2535b5636e | |||
2d014a75c4 | |||
db3831dccf | |||
29b2204f7c | |||
7fbfd9d59c | |||
e50d04a6aa | |||
33589ebda0 | |||
6670938c3d | |||
f131806008 | |||
49325c9c8d | |||
8012250258 | |||
ec44aa91c4 | |||
f58841ab3e | |||
350fc3647c | |||
70c68f6ebc | |||
c023ecc36f | |||
9be934ec25 | |||
f6e16a5503 | |||
c06d071220 | |||
ccbfe93f12 | |||
6750d176ee | |||
246b2769f7 | |||
34b06df758 | |||
0f1f3b4fb3 | |||
774ce6671f | |||
11e1d52cfb | |||
c158e84e28 | |||
10e4dd92a0 | |||
10053e05a9 | |||
425cadeb51 | |||
2d1befacb3 | |||
ad2ccc5895 | |||
754321541a | |||
622abd1486 | |||
55eb893a9a | |||
76ee3d0b51 | |||
00ac9efc8c | |||
bf32a09e5e | |||
9489ff6965 | |||
1dfd7e1af1 | |||
4a6518eeba | |||
a4d2918383 | |||
bdea826b7c |
42
api.txt
42
api.txt
@ -56,6 +56,8 @@ functions needed for the mob to work properly which contains the following:
|
||||
'view_range' how many nodes in distance the mob can see a player.
|
||||
'damage' how many health points the mob does to a player or another
|
||||
mob when melee attacking.
|
||||
'damage_group' group in which damage is dealt, dedaults to "fleshy".
|
||||
'damage_texture_modifier' applies texture modifier on hit e.g "^[brighten"
|
||||
'knock_back' when true has mobs falling backwards when hit, the greater
|
||||
the damage the more they move back.
|
||||
'fear_height' is how high a cliff or edge has to be before the mob stops
|
||||
@ -64,8 +66,12 @@ functions needed for the mob to work properly which contains the following:
|
||||
'fall_damage' when true causes falling to inflict damage.
|
||||
'water_damage' holds the damage per second infliced to mobs when standing in
|
||||
water.
|
||||
'air_damage' holds damage per second inflicted to mob when standing in air.
|
||||
'lava_damage' holds the damage per second inflicted to mobs when standing
|
||||
in lava or fire or an ignition source.
|
||||
in lava.
|
||||
'fire_damage' holds the damage per second inflicted to mobs when standing
|
||||
in fire.
|
||||
|
||||
'light_damage' holds the damage per second inflicted to mobs when light
|
||||
level is between the min and max values below
|
||||
'light_damage_min' minimum light value when mob is affected (default: 14)
|
||||
@ -75,7 +81,7 @@ functions needed for the mob to work properly which contains the following:
|
||||
'floats' when set to 1 mob will float in water, 0 has them sink.
|
||||
'follow' mobs follow player when holding any of the items which appear
|
||||
on this table, the same items can be fed to a mob to tame or
|
||||
breed e.g. {"farming:wheat", "default:apple"}
|
||||
breed e.g. {"farming:wheat", "default:apple", "group:fish"}
|
||||
|
||||
'reach' is how far the mob can attack player when standing
|
||||
nearby, default is 3 nodes.
|
||||
@ -117,6 +123,8 @@ functions needed for the mob to work properly which contains the following:
|
||||
continue chasing.
|
||||
'arrow' holds the pre-defined arrow object to shoot when
|
||||
attacking.
|
||||
'arrow_override' function that allows tweaking of arrow entity from
|
||||
inside mob definition (self) passed to function.
|
||||
'dogshoot_switch' allows switching between attack types by using timers
|
||||
(1 for shoot, 2 for dogfight)
|
||||
'dogshoot_count_max' contains how many seconds before switching from
|
||||
@ -130,6 +138,8 @@ functions needed for the mob to work properly which contains the following:
|
||||
e.g. {"player", "mobs_animal:chicken"}.
|
||||
'runaway_from' contains a table with mob names to run away from, add
|
||||
"player" to list to runaway from player also.
|
||||
'ignore_invisibility' When true mob will still be able to see and attack
|
||||
player even if invisible (invisibility mod only).
|
||||
'blood_amount' contains the number of blood droplets to appear when
|
||||
mob is hit.
|
||||
'blood_texture' has the texture name to use for droplets e.g.
|
||||
@ -226,6 +236,7 @@ functions needed for the mob to work properly which contains the following:
|
||||
'die_end'
|
||||
'die_speed'
|
||||
'die_loop' when set to false stops the animation looping.
|
||||
'die_rotate' if true mob spins during death animation.
|
||||
|
||||
Using '_loop = false' setting will stop any of the above animations from
|
||||
looping.
|
||||
@ -298,6 +309,9 @@ enhance mob functionality and have them do many interesting things:
|
||||
is returned normal attack function continued.
|
||||
'on_die' a function that is called when mob is killed (self, pos), also
|
||||
has access to self.cause_of_death table.
|
||||
'on_flop' function called when flying or swimmimng mob is no longer in
|
||||
air/water, (self) paramater and return true to skip the built
|
||||
in api flop feature.
|
||||
'do_custom' a custom function that is called every tick while mob is
|
||||
active and which has access to all of the self.* variables
|
||||
e.g. (self.health for health or self.standing_in for node
|
||||
@ -329,6 +343,14 @@ for each mob.
|
||||
'self.order' set to "follow" or "stand" so that npc will follow owner
|
||||
or stand it's ground
|
||||
'self.nametag' contains the name of the mob which it can show above
|
||||
'self.state' Current mob state.
|
||||
"stand": no movement (except turning around)
|
||||
"walk": walk or move around aimlessly
|
||||
"attack": chase and attack enemy
|
||||
"runaway": flee from target
|
||||
"flop": bounce around aimlessly
|
||||
(for swimming mobs that have stranded)
|
||||
"die": during death
|
||||
|
||||
|
||||
Adding Mobs in World
|
||||
@ -393,7 +415,7 @@ the mobs:spawn, so it is recommended to use the above instead.
|
||||
mobs:register_spawn(name, nodes, max_light, min_light, chance,
|
||||
active_object_count, max_height, day_toggle)
|
||||
|
||||
mobs:spawn_specfic(name, nodes, neighbors, min_light, max_light, interval,
|
||||
mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval,
|
||||
chance, active_object_count, min_height, max_height, day_toggle, on_spawn)
|
||||
|
||||
A simpler way to handle mob spawns has been added with the mobs:spawn(def)
|
||||
@ -447,6 +469,8 @@ This function registers a arrow for mobs with the attack type shoot.
|
||||
'visual' same is in minetest.register_entity()
|
||||
'visual_size' same is in minetest.register_entity()
|
||||
'textures' same is in minetest.register_entity()
|
||||
'physical' same is in minetest.register_entity() [default: false]
|
||||
'collide_with_objects' same as above
|
||||
'velocity' the velocity of the arrow
|
||||
'drop' if set to true any arrows hitting a node will drop as item
|
||||
'hit_player' a function that is called when the arrow hits a player;
|
||||
@ -667,6 +691,12 @@ space to spawn mob [name], if so then a new position is returned for use,
|
||||
otherwise nil is returned.
|
||||
|
||||
|
||||
mobs:is_node_dangerous(mob_object, nodename)
|
||||
|
||||
This function returns true if the node name given is harmful to the mob (mob_object),
|
||||
it is mainly used when a mob is near a node it has to avoid.
|
||||
|
||||
|
||||
External Settings for "minetest.conf"
|
||||
------------------------------------
|
||||
|
||||
@ -677,6 +707,8 @@ External Settings for "minetest.conf"
|
||||
is false)
|
||||
'mobs_spawn_protected' if set to false then mobs will not spawn in protected
|
||||
areas (default is true)
|
||||
'mobs_spawn_monster_protected' if set to false then monsters will not spawn in
|
||||
protected areas (default is true)
|
||||
'remove_far_mobs' if true then untamed mobs that are outside players
|
||||
visual range will be removed (default is true)
|
||||
'mobname' can change specific mob chance rate (0 to disable) and
|
||||
@ -697,6 +729,10 @@ External Settings for "minetest.conf"
|
||||
function.
|
||||
'mob_nospawn_range' Minimum range a mob can spawn near player (def: 12)
|
||||
'mob_active_limit' Number of active mobs in game, 0 for unlimited
|
||||
'mob_area_spawn' When true will check surrounding area the size of the
|
||||
mob for obstructions before spawning, otherwise it
|
||||
defaults to checking the height of the mob only.
|
||||
'mob_smooth_rotate' Enables smooth rotation when mobs turn by default.
|
||||
|
||||
Players can override the spawn chance for each mob registered by adding a line
|
||||
to their minetest.conf file with a new value, the lower the value the more each
|
||||
|
52
crafts.lua
52
crafts.lua
@ -5,14 +5,13 @@ local S = mobs.intllib
|
||||
minetest.register_craftitem("mobs:nametag", {
|
||||
description = S("Name Tag"),
|
||||
inventory_image = "mobs_nametag.png",
|
||||
groups = {flammable = 2}
|
||||
groups = {flammable = 2, nametag = 1}
|
||||
})
|
||||
|
||||
if minetest.get_modpath("dye") and minetest.get_modpath("farming") then
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "mobs:nametag",
|
||||
recipe = {"default:paper", "dye:black", "farming:string"}
|
||||
recipe = {{"default:paper", "dye:black", "farming:string"}}
|
||||
})
|
||||
end
|
||||
|
||||
@ -20,7 +19,7 @@ end
|
||||
minetest.register_craftitem("mobs:leather", {
|
||||
description = S("Leather"),
|
||||
inventory_image = "mobs_leather.png",
|
||||
groups = {flammable = 2}
|
||||
groups = {flammable = 2, leather = 1}
|
||||
})
|
||||
|
||||
-- raw meat
|
||||
@ -115,11 +114,27 @@ minetest.register_craft({
|
||||
}
|
||||
})
|
||||
|
||||
-- level 2 protection rune
|
||||
minetest.register_craftitem("mobs:protector2", {
|
||||
description = S("Mob Protection Rune (Level 2)"),
|
||||
inventory_image = "mobs_protector2.png",
|
||||
groups = {flammable = 2}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "mobs:protector2",
|
||||
recipe = {
|
||||
{"mobs:protector", "default:mese_crystal", "mobs:protector"},
|
||||
{"default:mese_crystal", "default:diamondblock", "default:mese_crystal"},
|
||||
{"mobs:protector", "default:mese_crystal", "mobs:protector"}
|
||||
}
|
||||
})
|
||||
|
||||
-- saddle
|
||||
minetest.register_craftitem("mobs:saddle", {
|
||||
description = S("Saddle"),
|
||||
inventory_image = "mobs_saddle.png",
|
||||
groups = {flammable = 2}
|
||||
groups = {flammable = 2, saddle = 1}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
@ -133,7 +148,7 @@ minetest.register_craft({
|
||||
|
||||
|
||||
-- make sure we can register fences
|
||||
if default.register_fence then
|
||||
if minetest.get_modpath("default") and default.register_fence then
|
||||
|
||||
-- mob fence (looks like normal fence but collision is 2 high)
|
||||
default.register_fence("mobs:fence_wood", {
|
||||
@ -149,6 +164,7 @@ default.register_fence("mobs:fence_wood", {
|
||||
}
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
-- mob fence top (has enlarged collisionbox to stop mobs getting over)
|
||||
minetest.register_node("mobs:fence_top", {
|
||||
@ -181,8 +197,6 @@ minetest.register_craft({
|
||||
}
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
|
||||
-- items that can be used as fuel
|
||||
minetest.register_craft({
|
||||
@ -283,12 +297,18 @@ minetest.register_tool(":mobs:mob_reset_stick", {
|
||||
|
||||
tex_obj = obj
|
||||
|
||||
-- get base texture
|
||||
local bt = tex_obj:get_luaentity().base_texture[1]
|
||||
|
||||
if type(bt) ~= "string" then
|
||||
bt = ""
|
||||
end
|
||||
|
||||
local name = user:get_player_name()
|
||||
local tex = ""
|
||||
|
||||
minetest.show_formspec(name, "mobs_texture", "size[8,4]"
|
||||
.. "field[0.5,1;7.5,0;name;"
|
||||
.. minetest.formspec_escape(S("Enter texture:")) .. ";" .. tex .. "]"
|
||||
.. minetest.formspec_escape(S("Enter texture:")) .. ";" .. bt .. "]"
|
||||
.. "button_exit[2.5,3.5;3,1;mob_texture_change;"
|
||||
.. minetest.formspec_escape(S("Change")) .. "]")
|
||||
end
|
||||
@ -339,17 +359,17 @@ minetest.register_node("mobs:meatblock", {
|
||||
tiles = {"mobs_meat_top.png", "mobs_meat_bottom.png", "mobs_meat_side.png"},
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy = 1, oddly_breakable_by_hand = 1, flammable = 2},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
sounds = default and default.node_sound_leaves_defaults(),
|
||||
on_place = minetest.rotate_node,
|
||||
on_use = minetest.item_eat(20),
|
||||
on_use = minetest.item_eat(20)
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "mobs:meatblock",
|
||||
type = "shapeless",
|
||||
-- type = "shapeless",
|
||||
recipe = {
|
||||
"group:food_meat", "group:food_meat", "group:food_meat",
|
||||
"group:food_meat", "group:food_meat", "group:food_meat",
|
||||
"group:food_meat", "group:food_meat", "group:food_meat"
|
||||
{"group:food_meat", "group:food_meat", "group:food_meat"},
|
||||
{"group:food_meat", "group:food_meat", "group:food_meat"},
|
||||
{"group:food_meat", "group:food_meat", "group:food_meat"}
|
||||
}
|
||||
})
|
||||
|
@ -1,4 +1,4 @@
|
||||
default
|
||||
default?
|
||||
tnt?
|
||||
dye?
|
||||
farming?
|
||||
@ -7,3 +7,5 @@ intllib?
|
||||
lucky_block?
|
||||
cmi?
|
||||
toolranks?
|
||||
pathfinder?
|
||||
player_api?
|
||||
|
8
init.lua
8
init.lua
@ -1,6 +1,12 @@
|
||||
|
||||
local path = minetest.get_modpath("mobs")
|
||||
|
||||
-- Peaceful player privilege
|
||||
minetest.register_privilege("peaceful_player", {
|
||||
description = "Prevents Mobs Redo mobs from attacking player",
|
||||
give_to_singleplayer = false
|
||||
})
|
||||
|
||||
-- Mob API
|
||||
dofile(path .. "/api.lua")
|
||||
|
||||
@ -16,4 +22,4 @@ dofile(path .. "/spawner.lua")
|
||||
-- Lucky Blocks
|
||||
dofile(path .. "/lucky_block.lua")
|
||||
|
||||
minetest.log("action", "[MOD] Mobs Redo loaded")
|
||||
print("[MOD] Mobs Redo loaded")
|
||||
|
@ -1,3 +0,0 @@
|
||||
-- Support for the old multi-load method
|
||||
dofile(minetest.get_modpath("intllib").."/init.lua")
|
||||
|
@ -11,7 +11,7 @@ msgstr ""
|
||||
"PO-Revision-Date: 2017-07-02 14:27+0200\n"
|
||||
"Last-Translator: Wuzzy <almikes@aol.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: de_DE\n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
3
mod.conf
3
mod.conf
@ -1 +1,4 @@
|
||||
name = mobs
|
||||
depends =
|
||||
optional_depends = default, tnt, dye, farming, invisibility, intllib, lucky_block, cmi, toolranks, pathfinder, player_api
|
||||
description = Adds a mob api for mods to add animals or monsters etc.
|
||||
|
244
mount.lua
244
mount.lua
@ -1,10 +1,9 @@
|
||||
|
||||
-- lib_mount by Blert2112 (edited by TenPlus1)
|
||||
|
||||
local enable_crash = false
|
||||
local crash_threshold = 6.5 -- ignored if enable_crash=false
|
||||
local is_50 = minetest.get_modpath("player_api") -- 5.x compatibility
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
local abs, cos, floor, sin, sqrt, pi =
|
||||
math.abs, math.cos, math.floor, math.sin, math.sqrt, math.pi
|
||||
|
||||
--
|
||||
-- Helper functions
|
||||
@ -55,27 +54,29 @@ local function get_sign(i)
|
||||
if i == 0 then
|
||||
return 0
|
||||
else
|
||||
return i / math.abs(i)
|
||||
return i / abs(i)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function get_velocity(v, yaw, y)
|
||||
|
||||
local x = -math.sin(yaw) * v
|
||||
local z = math.cos(yaw) * v
|
||||
local x = -sin(yaw) * v
|
||||
local z = cos(yaw) * v
|
||||
|
||||
return {x = x, y = y, z = z}
|
||||
end
|
||||
|
||||
|
||||
local function get_v(v)
|
||||
return math.sqrt(v.x * v.x + v.z * v.z)
|
||||
return sqrt(v.x * v.x + v.z * v.z)
|
||||
end
|
||||
|
||||
|
||||
local function force_detach(player)
|
||||
|
||||
if not player then return end
|
||||
|
||||
local attached_to = player:get_attach()
|
||||
|
||||
if not attached_to then
|
||||
@ -86,43 +87,83 @@ local function force_detach(player)
|
||||
|
||||
if entity and entity.driver
|
||||
and entity.driver == player then
|
||||
|
||||
entity.driver = nil
|
||||
end
|
||||
|
||||
player:set_detach()
|
||||
default.player_attached[player:get_player_name()] = false
|
||||
player:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
|
||||
default.player_set_animation(player, "stand" , 30)
|
||||
player:set_properties({visual_size = {x = 1, y = 1} })
|
||||
|
||||
local name = player:get_player_name()
|
||||
|
||||
if is_50 then
|
||||
player_api.player_attached[name] = false
|
||||
player_api.set_animation(player, "stand", 30)
|
||||
else
|
||||
default.player_attached[name] = false
|
||||
default.player_set_animation(player, "stand", 30)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
player:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
|
||||
player:set_properties({visual_size = {x = 1, y = 1}})
|
||||
end
|
||||
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
force_detach(player)
|
||||
end)
|
||||
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
|
||||
local players = minetest.get_connected_players()
|
||||
|
||||
for i = 1, #players do
|
||||
force_detach(players[i])
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
minetest.register_on_dieplayer(function(player)
|
||||
force_detach(player)
|
||||
return true
|
||||
end)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
-- Just for correct detaching
|
||||
local function find_free_pos(pos)
|
||||
|
||||
local check = {
|
||||
{x = 1, y = 0, z = 0},
|
||||
{x = 1, y = 1, z = 0},
|
||||
{x = -1, y = 0, z = 0},
|
||||
{x = -1, y = 1, z = 0},
|
||||
{x = 0, y = 0, z = 1},
|
||||
{x = 0, y = 1, z = 1},
|
||||
{x = 0, y = 0, z = -1},
|
||||
{x = 0, y = 1, z = -1}
|
||||
}
|
||||
|
||||
for _, c in pairs(check) do
|
||||
|
||||
local npos = {x = pos.x + c.x, y = pos.y + c.y, z = pos.z + c.z}
|
||||
local node = minetest.get_node_or_nil(npos)
|
||||
|
||||
if node and node.name then
|
||||
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
|
||||
if def and not def.walkable and
|
||||
def.liquidtype == "none" then
|
||||
return npos
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return pos
|
||||
end
|
||||
|
||||
|
||||
function mobs.attach(entity, player)
|
||||
|
||||
local attach_at, eye_offset = {}, {}
|
||||
|
||||
entity.player_rotation = entity.player_rotation or {x = 0, y = 0, z = 0}
|
||||
entity.driver_attach_at = entity.driver_attach_at or {x = 0, y = 0, z = 0}
|
||||
entity.driver_eye_offset = entity.driver_eye_offset or {x = 0, y = 0, z = 0}
|
||||
@ -131,17 +172,23 @@ function mobs.attach(entity, player)
|
||||
local rot_view = 0
|
||||
|
||||
if entity.player_rotation.y == 90 then
|
||||
rot_view = math.pi / 2
|
||||
rot_view = pi / 2
|
||||
end
|
||||
|
||||
attach_at = entity.driver_attach_at
|
||||
eye_offset = entity.driver_eye_offset
|
||||
local attach_at = entity.driver_attach_at
|
||||
local eye_offset = entity.driver_eye_offset
|
||||
|
||||
entity.driver = player
|
||||
|
||||
force_detach(player)
|
||||
|
||||
player:set_attach(entity.object, "", attach_at, entity.player_rotation)
|
||||
if is_50 then
|
||||
player_api.player_attached[player:get_player_name()] = true
|
||||
else
|
||||
default.player_attached[player:get_player_name()] = true
|
||||
end
|
||||
|
||||
player:set_attach(entity.object, "", attach_at, entity.player_rotation)
|
||||
player:set_eye_offset(eye_offset, {x = 0, y = 0, z = 0})
|
||||
|
||||
player:set_properties({
|
||||
@ -151,64 +198,63 @@ function mobs.attach(entity, player)
|
||||
}
|
||||
})
|
||||
|
||||
minetest.after(0.2, function(name)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
if player then
|
||||
minetest.after(0.2, function()
|
||||
|
||||
if player and player:is_player() then
|
||||
|
||||
if is_50 then
|
||||
player_api.set_animation(player, "sit", 30)
|
||||
else
|
||||
default.player_set_animation(player, "sit", 30)
|
||||
end
|
||||
end, player:get_player_name())
|
||||
end
|
||||
end)
|
||||
|
||||
player:set_look_horizontal(entity.object:get_yaw() - rot_view)
|
||||
end
|
||||
|
||||
|
||||
function mobs.detach(player, offset)
|
||||
function mobs.detach(player)
|
||||
|
||||
force_detach(player)
|
||||
|
||||
default.player_set_animation(player, "stand" , 30)
|
||||
minetest.after(0.1, function()
|
||||
|
||||
local pos = player:get_pos()
|
||||
if player and player:is_player() then
|
||||
|
||||
pos = {
|
||||
x = pos.x + offset.x,
|
||||
y = pos.y + 0.2 + offset.y,
|
||||
z = pos.z + offset.z
|
||||
}
|
||||
local pos = find_free_pos(player:get_pos())
|
||||
|
||||
pos.y = pos.y + 0.5
|
||||
|
||||
minetest.after(0.1, function(name, pos)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
if player then
|
||||
player:set_pos(pos)
|
||||
end
|
||||
end, player:get_player_name(), pos)
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||
|
||||
local rot_steer, rot_view = math.pi/2, 0
|
||||
local yaw = entity.object:get_yaw() or 0
|
||||
local rot_view = 0
|
||||
|
||||
if entity.player_rotation.y == 90 then
|
||||
rot_steer, rot_view = 0, math.pi/2
|
||||
rot_view = pi / 2
|
||||
end
|
||||
|
||||
local acce_y = 0
|
||||
local velo = entity.object:get_velocity()
|
||||
local velo = entity.object:get_velocity() ; if not velo then return end
|
||||
|
||||
entity.v = get_v(velo) * get_sign(entity.v)
|
||||
|
||||
-- process controls
|
||||
if entity.driver then
|
||||
|
||||
--print ("---velo", get_v(velo))
|
||||
|
||||
local ctrl = entity.driver:get_player_control()
|
||||
|
||||
-- move forwards
|
||||
if ctrl.up then
|
||||
|
||||
entity.v = entity.v + entity.accel / 10
|
||||
entity.v = entity.v + entity.accel * dtime
|
||||
|
||||
-- move backwards
|
||||
elseif ctrl.down then
|
||||
@ -217,37 +263,58 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||
return
|
||||
end
|
||||
|
||||
entity.v = entity.v - entity.accel / 10
|
||||
entity.v = entity.v - entity.accel * dtime
|
||||
end
|
||||
|
||||
-- mob rotation
|
||||
local horz
|
||||
|
||||
if entity.alt_turn == true then
|
||||
|
||||
horz = yaw
|
||||
|
||||
if ctrl.left then
|
||||
horz = horz + 0.05
|
||||
|
||||
elseif ctrl.right then
|
||||
horz = horz - 0.05
|
||||
end
|
||||
else
|
||||
horz = entity.driver:get_look_horizontal() or 0
|
||||
end
|
||||
|
||||
-- fix mob rotation
|
||||
local horz = entity.driver:get_look_horizontal() or 0
|
||||
entity.object:set_yaw(horz - entity.rotate)
|
||||
|
||||
if can_fly then
|
||||
|
||||
-- fly up
|
||||
if ctrl.jump then
|
||||
|
||||
velo.y = velo.y + 1
|
||||
|
||||
if velo.y > entity.accel then velo.y = entity.accel end
|
||||
|
||||
elseif velo.y > 0 then
|
||||
velo.y = velo.y - 0.1
|
||||
|
||||
velo.y = velo.y - dtime
|
||||
|
||||
if velo.y < 0 then velo.y = 0 end
|
||||
end
|
||||
|
||||
-- fly down
|
||||
if ctrl.sneak then
|
||||
|
||||
velo.y = velo.y - 1
|
||||
|
||||
if velo.y < -entity.accel then velo.y = -entity.accel end
|
||||
|
||||
elseif velo.y < 0 then
|
||||
velo.y = velo.y + 0.1
|
||||
|
||||
velo.y = velo.y + dtime
|
||||
|
||||
if velo.y > 0 then velo.y = 0 end
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
-- jump
|
||||
if ctrl.jump then
|
||||
|
||||
@ -283,24 +350,23 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||
|
||||
entity.object:set_velocity({x = 0, y = 0, z = 0})
|
||||
entity.v = 0
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
-- enforce speed limit forward and reverse
|
||||
local max_spd = entity.max_speed_reverse
|
||||
|
||||
if get_sign(entity.v) >= 0 then
|
||||
max_spd = entity.max_speed_forward
|
||||
end
|
||||
|
||||
if math.abs(entity.v) > max_spd then
|
||||
entity.v = entity.v - get_sign(entity.v)
|
||||
if entity.v > entity.max_speed_forward then
|
||||
entity.v = entity.max_speed_forward
|
||||
elseif entity.v < -entity.max_speed_reverse then
|
||||
entity.v = -entity.max_speed_reverse
|
||||
end
|
||||
|
||||
-- Set position, velocity and acceleration
|
||||
local p = entity.object:get_pos()
|
||||
local new_velo
|
||||
local new_acce = {x = 0, y = -9.8, z = 0}
|
||||
|
||||
if not p then return end
|
||||
|
||||
local new_acce = {x = 0, y = entity.fall_speed, z = 0}
|
||||
|
||||
p.y = p.y - 0.5
|
||||
|
||||
@ -335,8 +401,9 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||
end
|
||||
end
|
||||
|
||||
if entity.terrain_type == 2
|
||||
or entity.terrain_type == 3 then
|
||||
local terrain_type = entity.terrain_type
|
||||
|
||||
if terrain_type == 2 or terrain_type == 3 then
|
||||
|
||||
new_acce.y = 0
|
||||
p.y = p.y + 1
|
||||
@ -351,9 +418,13 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||
new_acce.y = 5
|
||||
end
|
||||
else
|
||||
if math.abs(velo.y) < 1 then
|
||||
if abs(velo.y) < 1 then
|
||||
|
||||
local pos = entity.object:get_pos()
|
||||
pos.y = math.floor(pos.y) + 0.5
|
||||
|
||||
if not pos then return end
|
||||
|
||||
pos.y = floor(pos.y) + 0.5
|
||||
entity.object:set_pos(pos)
|
||||
velo.y = 0
|
||||
end
|
||||
@ -363,48 +434,29 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||
end
|
||||
end
|
||||
|
||||
new_velo = get_velocity(v, entity.object:get_yaw() - rot_view, velo.y)
|
||||
local new_velo = get_velocity(v, yaw - rot_view, velo.y)
|
||||
|
||||
new_acce.y = new_acce.y + acce_y
|
||||
|
||||
entity.object:set_velocity(new_velo)
|
||||
entity.object:set_acceleration(new_acce)
|
||||
|
||||
-- CRASH!
|
||||
if enable_crash then
|
||||
|
||||
local intensity = entity.v2 - v
|
||||
|
||||
if intensity >= crash_threshold then
|
||||
|
||||
--print("----------- crash", intensity)
|
||||
|
||||
entity.object:punch(entity.object, 1.0, {
|
||||
full_punch_interval = 1.0,
|
||||
damage_groups = {fleshy = intensity}
|
||||
}, nil)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
entity.v2 = v
|
||||
end
|
||||
|
||||
|
||||
-- directional flying routine by D00Med (edited by TenPlus1)
|
||||
function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim)
|
||||
|
||||
function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
|
||||
|
||||
local ctrl = entity.driver:get_player_control()
|
||||
local ctrl = entity.driver:get_player_control() ; if not ctrl then return end
|
||||
local velo = entity.object:get_velocity()
|
||||
local dir = entity.driver:get_look_dir()
|
||||
local yaw = entity.driver:get_look_horizontal() + 1.57 -- offset fix between old and new commands
|
||||
local rot_steer, rot_view = math.pi / 2, 0
|
||||
local yaw = entity.driver:get_look_horizontal() + 1.57
|
||||
|
||||
if entity.player_rotation.y == 90 then
|
||||
rot_steer, rot_view = 0, math.pi / 2
|
||||
end
|
||||
if not ctrl or not velo then return end
|
||||
|
||||
if ctrl.up then
|
||||
|
||||
entity.object:set_velocity({
|
||||
x = dir.x * speed,
|
||||
y = dir.y * speed + 2,
|
||||
@ -412,6 +464,7 @@ function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
|
||||
})
|
||||
|
||||
elseif ctrl.down then
|
||||
|
||||
entity.object:set_velocity({
|
||||
x = -dir.x * speed,
|
||||
y = dir.y * speed + 2,
|
||||
@ -422,7 +475,7 @@ function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
|
||||
entity.object:set_velocity({x = 0, y = -2, z = 0})
|
||||
end
|
||||
|
||||
entity.object:set_yaw(yaw + math.pi + math.pi / 2 - entity.rotate)
|
||||
entity.object:set_yaw(yaw + pi + pi / 2 - entity.rotate)
|
||||
|
||||
-- firing arrows
|
||||
if ctrl.LMB and ctrl.sneak and shoots then
|
||||
@ -434,12 +487,16 @@ function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
|
||||
z = pos.z + 0 + dir.z * 2.5}, arrow)
|
||||
|
||||
local ent = obj:get_luaentity()
|
||||
|
||||
if ent then
|
||||
|
||||
ent.switch = 1 -- for mob specific arrows
|
||||
ent.owner_id = tostring(entity.object) -- so arrows dont hurt entity you are riding
|
||||
local vec = {x = dir.x * 6, y = dir.y * 6, z = dir.z * 6}
|
||||
local yaw = entity.driver:get_look_horizontal()
|
||||
obj:set_yaw(yaw + math.pi / 2)
|
||||
|
||||
yaw = entity.driver:get_look_horizontal()
|
||||
|
||||
obj:set_yaw(yaw + pi / 2)
|
||||
obj:set_velocity(vec)
|
||||
else
|
||||
obj:remove()
|
||||
@ -448,7 +505,6 @@ function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
|
||||
|
||||
-- change animation if stopped
|
||||
if velo.x == 0 and velo.y == 0 and velo.z == 0 then
|
||||
|
||||
mobs:set_animation(entity, stand_anim)
|
||||
else
|
||||
-- moving animation
|
||||
|
@ -23,6 +23,9 @@ Lucky Blocks: 9
|
||||
|
||||
|
||||
Changelog:
|
||||
- 1.56 - Added arrow_override function to mob definition to tweak arrow entity settings, tamed monsters no longer despawn when outside loaded map area.
|
||||
- 1.55 - Add 'peaceful_player' privelage and setting so mobs don't attack specific players (thanks sfence), add support for MarkBu's pathfinder mod, remove need for default mod
|
||||
- 1.54 - Simplified animal breeding function, added editable settings (thanks Wuzzy), Child mobs now take 20 mins to grow up, reverted to simple mob spawning with setting to use area checks, on_flop added, air_damage added.
|
||||
- 1.53 - Added 'on_map_load' settings to mobs:spawn so that mobs will only spawn when new areas of map are loaded.
|
||||
- 1.52 - Added 'mob_active_limit' in settings to set number of mobs in game,
|
||||
(default is 0 for unlimited), removed {immortal} from mob armor, fluid viscocity slows mobs
|
||||
|
@ -13,6 +13,9 @@ mobs_griefing (Griefing Mobs) bool true
|
||||
# If false then Mobs no longer spawn inside player protected areas
|
||||
mobs_spawn_protected (Spawn Mobs in protected areas) bool true
|
||||
|
||||
# If false then Monsters no longer spawn inside player protected areas
|
||||
mobs_spawn_monster_protected (Spawn Monsters in protected areas) bool true
|
||||
|
||||
# If true Mobs will be removed once a map chunk is out of view
|
||||
remove_far_mobs (Remove far Mobs) bool true
|
||||
|
||||
@ -33,3 +36,12 @@ mob_nospawn_range (Mob no-spawn range) float 12.0
|
||||
|
||||
# Sets maximum number of active mobs in game (0 for unlimited)
|
||||
mob_active_limit (Mob Active Limit) float 0
|
||||
|
||||
# Enables area check when spawning mobs
|
||||
mob_area_spawn (Mob Area Spawn) bool false
|
||||
|
||||
# Enable peaceful player attack prevention
|
||||
enable_peaceful_player (Mobs do not attack peaceful player without reason) bool false
|
||||
|
||||
# Enable mobs smooth rotation
|
||||
mob_smooth_rotate (Smooth rotation for mobs) bool true
|
||||
|
13
spawner.lua
13
spawner.lua
@ -23,9 +23,9 @@ minetest.register_node("mobs:spawner", {
|
||||
|
||||
-- text entry formspec
|
||||
meta:set_string("formspec",
|
||||
"size[9,3.5]"
|
||||
"size[10,3.5]"
|
||||
.. "label[0.15,0.5;" .. minetest.formspec_escape(head) .. "]"
|
||||
.. "field[1,2.5;7.5,0.8;text;" .. S("Command:")
|
||||
.. "field[1,2.5;8.5,0.8;text;" .. S("Command:")
|
||||
.. ";${command}]")
|
||||
|
||||
meta:set_string("infotext", S("Spawner Not Active (enter settings)"))
|
||||
@ -162,10 +162,17 @@ minetest.register_abm({
|
||||
end
|
||||
end
|
||||
|
||||
-- set medium mob usually spawns in (defaults to air)
|
||||
local reg = minetest.registered_entities[mob].fly_in
|
||||
|
||||
if not reg or type(reg) == "string" then
|
||||
reg = {(reg or "air")}
|
||||
end
|
||||
|
||||
-- find air blocks within 5 nodes of spawner
|
||||
local air = minetest.find_nodes_in_area(
|
||||
{x = pos.x - 5, y = pos.y + yof, z = pos.z - 5},
|
||||
{x = pos.x + 5, y = pos.y + yof, z = pos.z + 5}, {"air"})
|
||||
{x = pos.x + 5, y = pos.y + yof, z = pos.z + 5}, reg)
|
||||
|
||||
-- spawn in random air block
|
||||
if air and #air > 0 then
|
||||
|
BIN
textures/mobs_protector2.png
Normal file
BIN
textures/mobs_protector2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 164 B |
Reference in New Issue
Block a user